static private String getWrapperClass()

in modules/jaxws/src/org/apache/axis2/jaxws/runtime/description/marshal/impl/ArtifactProcessor.java [187:444]


    static private String getWrapperClass(String type,
        String providedValue, 
        String defaultPkg, 
        String defaultClassName, 
        ClassLoader altClassLoader,
        ServiceDescription serviceDesc) {

        if (log.isDebugEnabled()) {
            log.debug("getWrapperClass for " + type + " with value (" + providedValue + ")");
        }

        String wrapperClass = null;
        try {
           
            ClassLoader cl = getContextClassLoader();
            if (providedValue != null  && providedValue.length() > 0) {
                Class cls = null;
                // If a className is provided try to load it with the context classloader
                // and then the alternate classloader.
                // If the class still cannot be loaded, then try inserting the
                // jaxws sub-package.

                if (log.isDebugEnabled()) {
                    log.debug("Try finding the class with the name provided = " + providedValue);
                }
                cls = loadClassOrNull(providedValue, cl);
                if (cls != null) {
                    wrapperClass = providedValue;
                }
                else {
                    cls = loadClassOrNull(providedValue, altClassLoader);
                    if (cls != null) {
                        wrapperClass = providedValue;
                    }
                }
                // Legacy
                if (cls == null) {
                    String origPackage = getPackageName(providedValue);
                    if (origPackage.length() > 0) {
                        String newPackage = origPackage + "." + JAXWS_SUBPACKAGE;
                        String clsName = getSimpleClassName(providedValue);
                        String newValue = newPackage + "." + clsName;
                        if (log.isDebugEnabled()) {
                            log.debug("Did not find the name provided.  Now trying " + newValue);
                        }
                        cls = loadClassOrNull(newValue, cl);
                        if (cls != null) {
                            wrapperClass = newValue;
                        } else {
                            cls = loadClassOrNull(newValue, altClassLoader);
                            if (cls != null) {
                                wrapperClass = newValue;
                            }
                        }
                        
                        if(cls==null && 
                            (type.equals("@RequestWrapper")|| type.equals("@ResponseWrapper")||type.equals("@WebFault")|| type.equals("faultInfo"))){
                            
                            //Support for Fault Bean Generation
                            //As per JAX-WS 2.2 Specification section 3.7 an application programmer can choose not to
                            //package the faultBeans, if we have reached this point in the code then user has choosen
                            //not to package the fault bean. If there is a cache of generated artifacts available then 
                            //lets look for the missing faultBean there.
                            
                            //Support for Wrapper Bean Generation
                            //As per JAX-WS 2.2 Specificaiton section 3.6.2.1 pg 41 an application programmer does not use
                            //the wrapper bean classes, so the application need not package these classes. If we have reached
                            //this point in the code then user has choosen not to package these beans.
                            
                            //NOTE:If we find Generated artifacts from cache this guarantees that we will not use
                            //DocLitWrappedMinimum marshaller code. The advantage of normal DocLitWrappedMarshaller is
                            //that it is very robust and has support of lot more datatypes than in DocLitWrappedMinimum.
                            if(log.isDebugEnabled()){
                                log.debug("Adding cache to classpath");
                            }
                            ClassFinderFactory cff =
                                (ClassFinderFactory)FactoryRegistry.getFactory(ClassFinderFactory.class);
                            ClassFinder cf = cff.getClassFinder();
                            String cachePath = (String)serviceDesc.getAxisConfigContext().getProperty(Constants.WS_CACHE);
                            if(cachePath!=null){
                                //lets add the cache to classpath and retry loading missing artifacts.
                                if(log.isDebugEnabled()){
                                    log.debug("updating classpath with cache location");
                                }
                                cf.updateClassPath(cachePath, cl);
                                if(log.isDebugEnabled()){
                                    log.debug("trying to load class "+newValue+" from cache.");
                                }
                                cls=loadClassOrNull(newValue, cl);
                                if(cls!=null){
                                    wrapperClass=newValue;
                                }
                            }
                        }
                    }
                }
            } else {
                // If no value is provided by the annotation, then the we try default values.
                // The wsgen tool generates classes in the jaxws subpackage.
                // The wsimport tool generates classes in the same package as the SEI.
                // Note that from reading the JAX-WS spec, it seems that WSGen is doing that
                // correctly; See the conformance requirement in JAX-WS 2.0 Spec Section 3.6.2.1 Document
                // Wrapped on page 36: Conformance (Default wrapper bean package): In the absence of
                // customizations, the wrapper beans package MUST be a generated jaxws subpackage of the SEI
                // package.
                // However, if the class is in both places the runtime should prefer the one
                // in the non-jaxws package.  Why ?
                // The other classes in the non-jaxws package will cause the non-jaxws 
                // wrapper to get pulled in first....thus the jaxws wrapper will cause a collision.
                // 
                // Thus the following algorithm with check the non-jaxws package first
                
                Class cls1 = null;  // Class from the non-JAXWS package
                Class cls2 = null;  // Class from the JAX-WS package
                boolean cls1IsJAXB = false;
                boolean cls2IsJAXB = false;
                
                
                // Look for the class in the non-jaxws package first
                String defaultValue = null;
                if (defaultPkg.length() > 0) {
                    defaultValue = defaultPkg + "." + defaultClassName;
                } else {
                    defaultValue = defaultClassName;
                }
                if (log.isDebugEnabled()) {
                    log.debug("No provided value.  Try the default class name =  " + defaultValue);
                }
                cls1 = loadClassOrNull(defaultValue, cl);

                if (cls1 == null) {
                    cls1 = loadClassOrNull(defaultValue, altClassLoader);
                }
                if (cls1 != null) {
                    cls1IsJAXB = isJAXB(cls1);
                }

                // Now try the one in the jaxws subpackage (if cls1 is missing or perhaps not a JAXB class)
                if (cls1 == null || !cls1IsJAXB) {
                    if (defaultPkg.length() > 0) {
                        defaultValue = defaultPkg + "." + JAXWS_SUBPACKAGE + "." + defaultClassName;
                        if (log.isDebugEnabled()) {
                            log.debug("Did not find the default name.  Try a different default class name =  " + defaultValue);
                        }
                        cls2 = loadClassOrNull(defaultValue, cl);
                        if (cls2 == null) {
                            cls2 = loadClassOrNull(defaultValue, altClassLoader);
                        }
                        if(cls2==null && 
                        		(type.equals("@RequestWrapper")|| type.equals("@ResponseWrapper")||type.equals("@WebFault")|| type.equals("faultInfo"))){

                        	//Support for Fault Bean Generation
                        	//As per JAX-WS 2.2 Specification section 3.7 an application programmer can choose not to
                        	//package the faultBeans, if we have reached this point in the code then user has choosen
                        	//not to package the fault bean. If there is a cache of generated artifacts available then 
                        	//lets look for the missing faultBean there.

                        	//Support for Wrapper Bean Generation
                        	//As per JAX-WS 2.2 Specificaiton section 3.6.2.1 pg 41 an application programmer does not use
                        	//the wrapper bean classes, so the application need not package these classes. If we have reached
                        	//this point in the code then user has choosen not to package these beans.

                        	//NOTE:If we find Generated artifacts from cache this guarantees that we will not use
                        	//DocLitWrappedMinimum marshaller code. The advantage of normal DocLitWrappedMarshaller is
                        	//that it is very robust and has support of lot more datatypes than in DocLitWrappedMinimum.
                        	if(log.isDebugEnabled()){
                        		log.debug("Adding cache to classpath");
                        	}
                            if(log.isDebugEnabled()){
                                log.debug("Adding cache to classpath");
                            }
                            ClassFinderFactory cff =
                                (ClassFinderFactory)FactoryRegistry.getFactory(ClassFinderFactory.class);
                            ClassFinder cf = cff.getClassFinder();
                            String cachePath = (String)serviceDesc.getAxisConfigContext().getProperty(Constants.WS_CACHE);
                            if(log.isDebugEnabled()){
                                log.debug("cachePath = "+cachePath);
                            }
                            if(cachePath!=null){
                                //lets add the cache to classpath and retry loading missing artifacts.
                                if(log.isDebugEnabled()){
                                    log.debug("updating classpath with cache location");
                                }
                                cf.updateClassPath(cachePath, cl);
                                if(log.isDebugEnabled()){
                                    log.debug("trying to load class "+defaultValue+" from cache.");
                                }
                                cls2=loadClassOrNull(defaultValue, cl);
                            }
                        }
                    }  
                }
                
                if (cls2 !=null) {
                    cls2IsJAXB = isJAXB(cls2);
                }
                
                // Choose the wrapper class
                if (cls1 == null && cls2 == null) {
                    if(log.isDebugEnabled()){
                        log.debug("Could not find a wrapper class");
                    }
                    wrapperClass = null;
                } else if (cls1 == null) {
                    wrapperClass = cls2.getCanonicalName();
                    if(log.isDebugEnabled()){
                        log.debug("Choosing " + wrapperClass);
                    }
                } else if (cls2 == null) {
                    wrapperClass = cls1.getCanonicalName();
                    if(log.isDebugEnabled()){
                        log.debug("Choosing " + wrapperClass);
                    }
                } else {
                    if(log.isDebugEnabled()){
                        log.debug("There are two classes that are present " + cls1 + " and " + cls2);
                    }
                    // Choose the one that is JAXB enabled
                    if (!cls1IsJAXB && !cls2IsJAXB) {
                        // If neither is JAXB enabled.  Choose the one in the jaxws package.
                        // This is the one most likely provided by tooling.
                        if(log.isDebugEnabled()){
                            log.debug("Neither are JAXB enabled. Choosing " + cls2);
                        }
                        wrapperClass = cls2.getCanonicalName();
                    } else if (cls1IsJAXB && cls2IsJAXB) {
                        // If both are JAXB enabled, choose the one in the non-JAXWS package.
                        // This generally means that multiple tools generated the packages.
                        // Choosing the one in the non-JAXWS package will avoid a JAXBContext collision.
                        if(log.isDebugEnabled()){
                            log.debug("Both are JAXB enabled. Choosing " + cls1);
                        }
                        wrapperClass = cls1.getCanonicalName();
                    } else if (cls1IsJAXB) {
                        if(log.isDebugEnabled()){
                            log.debug("Choosing " + cls1 + " because it is JAXB enabled");
                        }
                        wrapperClass = cls1.getCanonicalName();
                    } else {
                        if(log.isDebugEnabled()){
                            log.debug("Choosing " + cls2 + " because it is JAXB enabled");
                        }
                        wrapperClass = cls2.getCanonicalName();
                    }
                }
                
            } 
        } catch (Throwable t) {
            if (log.isDebugEnabled()) {
                log.debug("Unexpected error.  Processing continues. ", t);
            }
        } 
        if (log.isDebugEnabled()) {
            log.debug("exit getWrapperClass with " + wrapperClass);
        }  
        return wrapperClass;

    }