/*
* Copyright (C) 2013,2014 The Cat Hive Developers.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.cathive.fx.cdi;
import com.cathive.fx.inject.core.FXMLLoaderParams;
import javafx.fxml.FXMLLoader;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.Annotated;
import javax.enterprise.inject.spi.InjectionPoint;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ResourceBundle;
import static com.cathive.fx.cdi.CdiFXMLLoader.*;
/**
* This factory is responsible for the production of CDI-aware {@link javafx.fxml.FXMLLoader} instances.
*
* @author Benjamin P. Jung
*/
@ApplicationScoped
class CdiFXMLLoaderFactory {
/**
* Create a CDI-aware FXMLLoader.
* If an annotation of type @FXMLLoaderParams can be found, use it's parameters
* to configure the FXMLLoader instance that shall be used to perform the loading
* of the FXML file.
*
* @param injectionPoint
* Injection point.
* @return
* A new FXMLLoader instance.
*/
@Produces
@FXMLLoaderParams
FXMLLoader createCdiFXMLLoader(final InjectionPoint injectionPoint) {
final CdiFXMLLoader fxmlLoader = new CdiFXMLLoader();
final Annotated annotated = injectionPoint.getAnnotated();
final Class<?> declaringClass = injectionPoint.getMember().getDeclaringClass();
if (annotated.isAnnotationPresent(FXMLLoaderParams.class)) {
final FXMLLoaderParams annotation = annotated.getAnnotation(FXMLLoaderParams.class);
initializeFXMLLoader(fxmlLoader, declaringClass, annotation.location(), annotation.resources(), annotation.charset());
}
return fxmlLoader;
}
/**
* Initializes the given FXMLLoader instance using the provided parameters.
*
* @param fxmlLoader never <code>null</code>
* @param targetClass never <code>null</code>
* @param location never <code>null</code>
* @param resources never <code>null</code>
* @param charset never <code>null</code>
*/
static void initializeFXMLLoader(final FXMLLoader fxmlLoader, final Class<?> targetClass, final String location, final String resources, final String charset) {
checkAndSetLocation(fxmlLoader, targetClass, location);
if (charset != null && !charset.equals(CHARSET_UNSPECIFIED)) {
fxmlLoader.setCharset(Charset.forName(charset));
}
if (resources != null && !resources.equals(RESOURCES_UNSPECIFIED)) {
fxmlLoader.setResources(ResourceBundle.getBundle(resources));
}
}
/**
* Checks the location that has been specified (if any) and uses the default
* class loader to create an URL that points to a FXML file on the classpath.
*
* @param fxmlLoader never <code>null</code>
* @param targetClass never <code>null</code>
* @param location never <code>null</code> and should point to an existing FXML file, an Exception is thrown otherwise
*/
private static void checkAndSetLocation(FXMLLoader fxmlLoader, Class<?> targetClass, String location) {
if (location != null && !location.equals(LOCATION_UNSPECIFIED)) {
final URL locationUrl = targetClass.getResource(location);
if (locationUrl == null) {
throw new IllegalArgumentException(String.format("Couldn't find FXML file: \"%s\".", location));
}
fxmlLoader.setLocation(locationUrl);
}
}
}