Author: dkulp Date: Fri Dec 11 20:41:48 2009 New Revision: 889810 URL: http://svn.apache.org/viewvc?rev=889810&view=rev Log: Merged revisions 889805 via svnmerge from https://svn.apache.org/repos/asf/cxf/branches/2.2.x-fixes
................ r889805 | dkulp | 2009-12-11 15:37:24 -0500 (Fri, 11 Dec 2009) | 13 lines Merged revisions 889790,889796 via svnmerge from https://svn.apache.org/repos/asf/cxf/trunk ........ r889790 | dkulp | 2009-12-11 14:55:59 -0500 (Fri, 11 Dec 2009) | 1 line [CXF-1510] Support for anonymous root types ........ r889796 | dkulp | 2009-12-11 15:24:14 -0500 (Fri, 11 Dec 2009) | 1 line [CXF-1510] Only if it's not in a wrapper element ........ ................ Modified: cxf/branches/2.1.x-fixes/ (props changed) cxf/branches/2.1.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBContextInitializer.java cxf/branches/2.1.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBDataBinding.java cxf/branches/2.1.x-fixes/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/CodeFirstTest.java Propchange: cxf/branches/2.1.x-fixes/ ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Fri Dec 11 20:41:48 2009 @@ -1,2 +1,2 @@ -/cxf/branches/2.2.x-fixes:889428 -/cxf/trunk:889426 +/cxf/branches/2.2.x-fixes:889428,889805 +/cxf/trunk:889426,889790-889796 Propchange: cxf/branches/2.1.x-fixes/ ------------------------------------------------------------------------------ Binary property 'svnmerge-integrated' - no diff available. Modified: cxf/branches/2.1.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBContextInitializer.java URL: http://svn.apache.org/viewvc/cxf/branches/2.1.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBContextInitializer.java?rev=889810&r1=889809&r2=889810&view=diff ============================================================================== --- cxf/branches/2.1.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBContextInitializer.java (original) +++ cxf/branches/2.1.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBContextInitializer.java Fri Dec 11 20:41:48 2009 @@ -33,11 +33,16 @@ import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlSeeAlso; import javax.xml.bind.annotation.XmlTransient; +import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.adapters.XmlAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import javax.xml.namespace.QName; +import org.apache.cxf.common.classloader.ClassLoaderUtils; +import org.apache.cxf.common.util.StringUtils; import org.apache.cxf.service.ServiceModelVisitor; import org.apache.cxf.service.model.MessageInfo; import org.apache.cxf.service.model.MessagePartInfo; @@ -51,10 +56,14 @@ class JAXBContextInitializer extends ServiceModelVisitor { private Set<Class<?>> classes; + private Collection<Object> typeReferences; - public JAXBContextInitializer(ServiceInfo serviceInfo, Set<Class<?>> classes) { + public JAXBContextInitializer(ServiceInfo serviceInfo, + Set<Class<?>> classes, + Collection<Object> typeReferences) { super(serviceInfo); this.classes = classes; + this.typeReferences = typeReferences; } @Override @@ -147,9 +156,39 @@ } } if (clazz != null) { + if (!isFromWrapper + && clazz.getAnnotation(XmlRootElement.class) == null + && clazz.getAnnotation(XmlType.class) != null + && StringUtils.isEmpty(clazz.getAnnotation(XmlType.class).name())) { + createTypeReference(part.getName(), clazz); + } + addClass(clazz); } } + + private void createTypeReference(QName n, Class<?> cls) { + Class<?> refClass = null; + try { + refClass = ClassLoaderUtils.loadClass("com.sun.xml.bind.api.TypeReference", this.getClass()); + } catch (Throwable ex) { + try { + refClass = ClassLoaderUtils.loadClass("com.sun.xml.internal.bind.api.TypeReference", + this.getClass()); + } catch (Throwable ex2) { + //ignore + } + } + if (refClass != null) { + try { + Object o = refClass.getConstructor(QName.class, Type.class, new Annotation[0].getClass()) + .newInstance(n, cls, new Annotation[0]); + typeReferences.add(o); + } catch (Throwable e) { + //ignore + } + } + } private void checkForAdapter(Class<?> clazz, Annotation[] anns) { if (anns != null) { Modified: cxf/branches/2.1.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBDataBinding.java URL: http://svn.apache.org/viewvc/cxf/branches/2.1.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBDataBinding.java?rev=889810&r1=889809&r2=889810&view=diff ============================================================================== --- cxf/branches/2.1.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBDataBinding.java (original) +++ cxf/branches/2.1.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBDataBinding.java Fri Dec 11 20:41:48 2009 @@ -67,6 +67,7 @@ import org.xml.sax.SAXException; import org.apache.cxf.common.i18n.Message; +import org.apache.cxf.common.classloader.ClassLoaderUtils; import org.apache.cxf.common.logging.LogUtils; import org.apache.cxf.common.util.CacheMap; import org.apache.cxf.common.util.ModCountCopyOnWriteArrayList; @@ -233,6 +234,7 @@ JAXBContext context; Set<Class<?>> contextClasses; + Collection<Object> typeRefs = new ArrayList<Object>(); Class<?> cls; @@ -340,7 +342,8 @@ contextClasses = new LinkedHashSet<Class<?>>(); for (ServiceInfo serviceInfo : service.getServiceInfos()) { - JAXBContextInitializer initializer = new JAXBContextInitializer(serviceInfo, contextClasses); + JAXBContextInitializer initializer + = new JAXBContextInitializer(serviceInfo, contextClasses, typeRefs); initializer.walk(); if (serviceInfo.getProperty("extra.class") != null) { Set<Class<?>> exClasses = serviceInfo.getProperty("extra.class", Set.class); @@ -533,26 +536,18 @@ } CachedContextAndSchemas cachedContextAndSchemas = null; - synchronized (JAXBCONTEXT_CACHE) { - cachedContextAndSchemas = JAXBCONTEXT_CACHE.get(classes); + if (typeRefs.isEmpty()) { + synchronized (JAXBCONTEXT_CACHE) { + cachedContextAndSchemas = JAXBCONTEXT_CACHE.get(classes); + } } if (cachedContextAndSchemas == null) { - JAXBContext ctx; - try { - ctx = JAXBContext.newInstance(classes.toArray(new Class[classes.size()]), map); - } catch (JAXBException ex) { - if (map.containsKey("com.sun.xml.bind.defaultNamespaceRemap") - && ex.getMessage().contains("com.sun.xml.bind.defaultNamespaceRemap")) { - map.put("com.sun.xml.internal.bind.defaultNamespaceRemap", - map.remove("com.sun.xml.bind.defaultNamespaceRemap")); - ctx = JAXBContext.newInstance(classes.toArray(new Class[classes.size()]), map); - } else { - throw ex; - } - } + JAXBContext ctx = createContext(classes, map); cachedContextAndSchemas = new CachedContextAndSchemas(ctx); synchronized (JAXBCONTEXT_CACHE) { - JAXBCONTEXT_CACHE.put(classes, cachedContextAndSchemas); + if (typeRefs.isEmpty()) { + JAXBCONTEXT_CACHE.put(classes, cachedContextAndSchemas); + } } } @@ -640,6 +635,68 @@ classes.addAll(objectFactories); } + private JAXBContext createContext(Set<Class<?>> classes, + Map<String, Object> map) + throws JAXBException { + JAXBContext ctx; + if (!typeRefs.isEmpty()) { + Class<?> fact = null; + String pfx = "com.sun.xml.bind."; + try { + fact = ClassLoaderUtils.loadClass("com.sun.xml.bind.v2.ContextFactory", + getClass()); + } catch (Throwable t) { + try { + fact = ClassLoaderUtils.loadClass("com.sun.xml.internal.bind.v2.ContextFactory", + getClass()); + pfx = "com.sun.xml.internal.bind."; + } catch (Throwable t2) { + //ignore + } + } + if (fact != null) { + for (Method m : fact.getMethods()) { + if ("createContext".equals(m.getName()) + && m.getParameterTypes().length == 9) { + try { + return (JAXBContext)m.invoke(null, + classes.toArray(new Class[classes.size()]), + typeRefs, + map.get(pfx + "subclassReplacements"), + map.get(pfx + "defaultNamespaceRemap"), + map.get(pfx + "c14n") == null + ? Boolean.FALSE + : map.get(pfx + "c14n"), + map.get(pfx + "v2.model.annotation.RuntimeAnnotationReader"), + map.get(pfx + "XmlAccessorFactory") == null + ? Boolean.FALSE + : map.get(pfx + "XmlAccessorFactory"), + map.get(pfx + "treatEverythingNillable") == null + ? Boolean.FALSE : map.get(pfx + "treatEverythingNillable"), + map.get("retainReferenceToInfo") == null + ? Boolean.FALSE : map.get("retainReferenceToInfo")); + } catch (Throwable e) { + //ignore + } + } + } + } + } + try { + ctx = JAXBContext.newInstance(classes.toArray(new Class[classes.size()]), map); + } catch (JAXBException ex) { + if (map.containsKey("com.sun.xml.bind.defaultNamespaceRemap") + && ex.getMessage().contains("com.sun.xml.bind.defaultNamespaceRemap")) { + map.put("com.sun.xml.internal.bind.defaultNamespaceRemap", + map.remove("com.sun.xml.bind.defaultNamespaceRemap")); + ctx = JAXBContext.newInstance(classes.toArray(new Class[classes.size()]), map); + } else { + throw ex; + } + } + return ctx; + } + private boolean checkObjectFactoryNamespaces(Class<?> clz) { for (Method meth : clz.getMethods()) { XmlElementDecl decl = meth.getAnnotation(XmlElementDecl.class); Modified: cxf/branches/2.1.x-fixes/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/CodeFirstTest.java URL: http://svn.apache.org/viewvc/cxf/branches/2.1.x-fixes/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/CodeFirstTest.java?rev=889810&r1=889809&r2=889810&view=diff ============================================================================== --- cxf/branches/2.1.x-fixes/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/CodeFirstTest.java (original) +++ cxf/branches/2.1.x-fixes/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/CodeFirstTest.java Fri Dec 11 20:41:48 2009 @@ -24,8 +24,14 @@ import java.util.List; import java.util.concurrent.Executor; +import javax.jws.WebService; +import javax.jws.soap.SOAPBinding; import javax.wsdl.Definition; import javax.wsdl.factory.WSDLFactory; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; import javax.xml.namespace.QName; import org.w3c.dom.Document; @@ -310,4 +316,78 @@ assertValid("//xsd:sche...@targetnamespace='http://namespace5']", doc); } + + @Test + public void testCXF1510() throws Exception { + JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean(); + factory.setServiceClass(NoRootBare.class); + factory.setServiceBean(new NoRootBareImpl()); + factory.setAddress("local://localhost/testNoRootBare"); + Server server = factory.create(); + server.start(); + + QName serviceName = new QName("http://service.jaxws.cxf.apache.org/", "NoRootBareService"); + QName portName = new QName("http://service.jaxws.cxf.apache.org/", "NoRootBarePort"); + + ServiceImpl service = new ServiceImpl(getBus(), (URL)null, serviceName, null); + service.addPort(portName, "http://schemas.xmlsoap.org/soap/", + "local://localhost/testNoRootBare"); + + NoRootBare proxy = service.getPort(portName, NoRootBare.class); + assertEquals("hello", proxy.echoString(new NoRootRequest("hello")).getMessage()); + } + + @WebService + @SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE) + public static interface NoRootBare { + NoRootResponse echoString(NoRootRequest request); + } + + @WebService + public static class NoRootBareImpl implements NoRootBare { + public NoRootResponse echoString(NoRootRequest request) { + return new NoRootResponse(request.getMessage()); + } + } + + @XmlType(name = "") + @XmlAccessorType(XmlAccessType.FIELD) + public static class NoRootRequest { + @XmlElement + private String message; + + public NoRootRequest() { + } + public NoRootRequest(String m) { + message = m; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } + } + @XmlType(name = "") + @XmlAccessorType(XmlAccessType.FIELD) + public static class NoRootResponse { + @XmlElement + private String message; + + public NoRootResponse() { + } + public NoRootResponse(String m) { + message = m; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } + } }
