in modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/JAXBUtils.java [198:361]
public static JAXBContext getJAXBContext(TreeSet<String> contextPackages,
Holder<CONSTRUCTION_TYPE> constructionType,
boolean forceArrays,
String key,
ClassLoader cacheKey,
Map<String, ?> properties)
throws JAXBException {
// JAXBContexts for the same class can be reused and are supposed to be thread-safe
if (log.isDebugEnabled()) {
log.debug("Following packages are in this batch of getJAXBContext() :");
for (String pkg : contextPackages) {
log.debug(pkg);
}
}
if (JAXBUtilsMonitor.isMonitoring()) {
JAXBUtilsMonitor.addPackageKey(contextPackages.toString());
}
// Get or Create The InnerMap using the package key
ConcurrentHashMap<ClassLoader, JAXBContextValue> innerMap = null;
SoftReference<ConcurrentHashMap<ClassLoader, JAXBContextValue>>
softRef = jaxbMap.get(key);
if (softRef != null) {
innerMap = softRef.get();
}
if (innerMap == null) {
synchronized(jaxbMap) {
softRef = jaxbMap.get(key);
if (softRef != null) {
innerMap = softRef.get();
}
if (innerMap == null) {
innerMap = new ConcurrentHashMap<ClassLoader, JAXBContextValue>();
softRef =
new SoftReference<ConcurrentHashMap<ClassLoader, JAXBContextValue>>(innerMap);
jaxbMap.put(key, softRef);
}
}
}
// Now get the contextValue using either the classloader key or
// the current Classloader
ClassLoader cl = getContextClassLoader();
JAXBContextValue contextValue = null;
if(cacheKey != null) {
if(log.isDebugEnabled()) {
log.debug("Using supplied classloader to retrieve JAXBContext: " +
cacheKey);
}
contextValue = innerMap.get(cacheKey);
} else {
if(log.isDebugEnabled()) {
log.debug("Using classloader from Thread to retrieve JAXBContext: " +
cl);
}
contextValue = innerMap.get(cl);
}
// If the context value is found, but the caller requested that the JAXBContext
// contain arrays, then rebuild the JAXBContext value
if (forceArrays &&
contextValue != null &&
contextValue.constructionType != JAXBUtils.CONSTRUCTION_TYPE.BY_CLASS_ARRAY_PLUS_ARRAYS) {
if(log.isDebugEnabled()) {
log.debug("Found a JAXBContextValue with constructionType=" +
contextValue.constructionType + " but the caller requested a JAXBContext " +
" that includes arrays. A new JAXBContext will be built");
}
contextValue = null;
}
if (contextPackages == null) {
contextPackages = new TreeSet<String>();
}
if (contextValue == null) {
synchronized (innerMap) {
// Try to get the contextValue once more since sync was temporarily exited.
ClassLoader clKey = (cacheKey != null) ? cacheKey:cl;
if (clKey == null) {
log.warn("getJAXBContext() detected null clKey");
}
contextValue = innerMap.get(clKey);
adjustPoolSize(innerMap);
if (forceArrays &&
contextValue != null &&
contextValue.constructionType != JAXBUtils.CONSTRUCTION_TYPE.BY_CLASS_ARRAY_PLUS_ARRAYS) {
contextValue = null;
}
if (contextValue==null) {
// Create a copy of the contextPackages. This new TreeSet will
// contain only the valid contextPackages.
// Note: The original contextPackage set is accessed by multiple
// threads and should not be altered.
TreeSet<String> validContextPackages = new TreeSet<String>(contextPackages);
List<String> classRefs = pruneDirectives(validContextPackages);
int numPackages = validContextPackages.size();
contextValue = createJAXBContextValue(validContextPackages,
clKey,
forceArrays,
properties,
classRefs);
if (contextValue == null) {
log.warn("getJAXBContext() detected null contextValue on validContextPackages.size: " + validContextPackages.size() + " , classRefs.size: " + classRefs.size() + " , numPackages: " + numPackages + " , properties.size: " + properties.size());
}
synchronized (jaxbMap) {
// Add the context value with the original package set
ConcurrentHashMap<ClassLoader, JAXBContextValue> map1 = null;
SoftReference<ConcurrentHashMap<ClassLoader, JAXBContextValue>>
softRef1 = jaxbMap.get(key);
if (softRef1 != null) {
map1 = softRef1.get();
}
if (map1 == null) {
map1 = new ConcurrentHashMap<ClassLoader, JAXBContextValue>();
softRef1 =
new SoftReference<ConcurrentHashMap<ClassLoader, JAXBContextValue>>(map1);
jaxbMap.put(key, softRef1);
}
map1.put(clKey, contextValue);
String validPackagesKey = validContextPackages.toString();
// Add the context value with the new package set
ConcurrentHashMap<ClassLoader, JAXBContextValue> map2 = null;
SoftReference<ConcurrentHashMap<ClassLoader, JAXBContextValue>>
softRef2 = jaxbMap.get(validPackagesKey);
if (softRef2 != null) {
map2 = softRef2.get();
}
if (map2 == null) {
map2 = new ConcurrentHashMap<ClassLoader, JAXBContextValue>();
softRef2 =
new SoftReference<ConcurrentHashMap<ClassLoader, JAXBContextValue>>(map2);
jaxbMap.put(validPackagesKey, softRef2);
}
map2.put(clKey, contextValue);
if (log.isDebugEnabled()) {
log.debug("JAXBContext [created] for " + key);
log.debug("JAXBContext also stored by the list of valid packages:" + validPackagesKey);
}
}
}
}
} else {
if (log.isDebugEnabled()) {
log.debug("JAXBContext [from pool] for " + key);
}
}
if (log.isDebugEnabled()) {
log.debug("JAXBContext constructionType= " + contextValue.constructionType);
log.debug("JAXBContextValue = " + JavaUtils.getObjectIdentity(contextValue));
log.debug("JAXBContext = " + JavaUtils.getObjectIdentity(contextValue.jaxbContext));
}
constructionType.value = contextValue.constructionType;
return contextValue.jaxbContext;
}