![JAR search and dependency download from the Maven repository](/logo.png)
org.nlab.xml.stream.factory.AbstractStaxCachedFactory Maven / Gradle / Ivy
package org.nlab.xml.stream.factory;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.lang3.Validate;
/**
* @author nlabrot
*
* Factory aware of the following issue http://java.net/jira/browse/JAXP-68
* JAXP RI has an issue on factory in a multithread context
*/
public abstract class AbstractStaxCachedFactory {
private static final String WOODSTOX_FACTORY_PREFIX = "Wstx";
private Map> factoriesMap = new ConcurrentHashMap>();
protected T getOrCreateFactory(Object... properties) {
Validate.isTrue(properties.length % 2 == 0);
long key = createKey(properties);
if (factoriesMap.containsKey(key) && factoriesMap.get(key).get() != null) {
return factoriesMap.get(key).get();
}
T factory = createFactory(properties);
if (factoriesMap.get(key) == null) {
factoriesMap.put(key, createHolder(factory));
} else {
factoriesMap.get(key).set(factory);
}
return factory;
}
protected static long createKey(Object... properties) {
long key = 0;
for (Object prop : properties) {
key = key + (long) prop.hashCode();
}
return key;
}
protected abstract T createFactory(Object[] properties);
private Holder createHolder(T value) {
if (value.getClass().getSimpleName().startsWith(WOODSTOX_FACTORY_PREFIX)) {
return new GlobalHolder<>(value);
} else {
return new ThreadLocalHolder<>(value);
}
}
//Holder
public interface Holder {
void set(T t);
T get();
}
/**
* Holder bounded to a thread
*/
private final class ThreadLocalHolder extends ThreadLocal implements Holder {
public ThreadLocalHolder(T value) {
this.set(value);
}
}
/**
* Holder bounded to the application
*/
private final class GlobalHolder implements Holder {
protected volatile T value;
private GlobalHolder(T value) {
this.value = value;
}
@Override
public void set(T t) {
this.value = t;
}
@Override
public T get() {
return value;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy