/* * Copyright (C) 2010 Google Inc. * * 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 org.clearsilver; import java.lang.reflect.Constructor; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.logging.Level; import java.util.logging.Logger; /** * This class holds static methods for getting and setting the CS and HDF * factory used throughout the Java Clearsilver Framework. * Clients are strongly encouraged to not use this class, and * instead directly inject {@link ClearsilverFactory} into the classes that * need to create {@link HDF} and {@link CS} instances. * For now, projects should set the {@link ClearsilverFactory} in FactoryLoader * and use the singleton accessor {@link #getClearsilverFactory()} if proper * dependency injection is not easy to implement. *
* Allows the default implementation to be the original JNI version without
* requiring users that don't want to use the JNI version to have to link
* it in. The ClearsilverFactory object to use can be either passed into the
* {@link #setClearsilverFactory} method or the class name can be specified
* in the Java property {@code org.clearsilver.defaultClearsilverFactory}.
*/
public final class FactoryLoader {
private static final Logger logger =
Logger.getLogger(FactoryLoader.class.getName());
private static final String DEFAULT_CS_FACTORY_CLASS_PROPERTY_NAME =
"org.clearsilver.defaultClearsilverFactory";
private static final String DEFAULT_CS_FACTORY_CLASS_NAME =
"org.clearsilver.jni.JniClearsilverFactory";
// ClearsilverFactory to be used when constructing objects. Allows
// applications to subclass the CS and HDF objects used in Java Clearsilver
private static ClearsilverFactory clearsilverFactory = null;
// Read/Write lock for global factory pointer.
private static final ReadWriteLock factoryLock = new ReentrantReadWriteLock();
// Getters and setters
/**
* Get the {@link org.clearsilver.ClearsilverFactory} object to be used by
* disparate parts of the application.
*/
public static ClearsilverFactory getClearsilverFactory() {
factoryLock.readLock().lock();
if (clearsilverFactory == null) {
factoryLock.readLock().unlock();
factoryLock.writeLock().lock();
try {
if (clearsilverFactory == null) {
clearsilverFactory = newDefaultClearsilverFactory();
}
factoryLock.readLock().lock();
} finally {
factoryLock.writeLock().unlock();
}
}
ClearsilverFactory returned = clearsilverFactory;
factoryLock.readLock().unlock();
return returned;
}
/**
* Set the {@link org.clearsilver.ClearsilverFactory} to be used by
* the application. If parameter is {@code null}, then the default factory
* implementation will be used the next time {@link #getClearsilverFactory()}
* is called.
*
* @return the previous factory (may return {@code null})
*/
public static ClearsilverFactory setClearsilverFactory(
ClearsilverFactory clearsilverFactory) {
factoryLock.writeLock().lock();
try {
ClearsilverFactory previousFactory = FactoryLoader.clearsilverFactory;
FactoryLoader.clearsilverFactory = clearsilverFactory;
return previousFactory;
} finally {
factoryLock.writeLock().unlock();
}
}
private static ClearsilverFactory newDefaultClearsilverFactory() {
String factoryClassName =
System.getProperty(DEFAULT_CS_FACTORY_CLASS_PROPERTY_NAME,
DEFAULT_CS_FACTORY_CLASS_NAME);
try {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Class