public static JAXBContext getJAXBContext()

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;
    }