You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2009/07/08 12:55:19 UTC
svn commit: r792096 - in /cxf/trunk:
common/common/src/main/java/org/apache/cxf/common/util/
common/common/src/main/java/org/apache/cxf/jaxb/
rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/
rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/cl...
Author: sergeyb
Date: Wed Jul 8 10:55:18 2009
New Revision: 792096
URL: http://svn.apache.org/viewvc?rev=792096&view=rev
Log:
Improving the wadl schema generation, moving some of the JAXB databinding utility code to common/utils/jaxb
Added:
cxf/trunk/common/common/src/main/java/org/apache/cxf/common/util/CachedClass.java (with props)
cxf/trunk/common/common/src/main/java/org/apache/cxf/jaxb/JAXBBeanInfo.java (with props)
cxf/trunk/common/common/src/main/java/org/apache/cxf/jaxb/JAXBContextProxy.java (with props)
Removed:
cxf/trunk/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBBeanInfo.java
cxf/trunk/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBContextProxy.java
Modified:
cxf/trunk/common/common/src/main/java/org/apache/cxf/jaxb/JAXBUtils.java
cxf/trunk/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBDataBinding.java
cxf/trunk/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBSchemaInitializer.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/Book.java
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/BookStore.java
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/Chapter.java
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/WadlGeneratorTest.java
Added: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/util/CachedClass.java
URL: http://svn.apache.org/viewvc/cxf/trunk/common/common/src/main/java/org/apache/cxf/common/util/CachedClass.java?rev=792096&view=auto
==============================================================================
--- cxf/trunk/common/common/src/main/java/org/apache/cxf/common/util/CachedClass.java (added)
+++ cxf/trunk/common/common/src/main/java/org/apache/cxf/common/util/CachedClass.java Wed Jul 8 10:55:18 2009
@@ -0,0 +1,37 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.common.util;
+
+import java.lang.ref.WeakReference;
+
+public class CachedClass {
+ private WeakReference<Class<?>> cachedClass;
+
+ public CachedClass(Class<?> cachedClass) {
+ this.cachedClass = new WeakReference<Class<?>>(cachedClass);
+ }
+
+ public Class<?> getCachedClass() {
+ return cachedClass == null ? null : cachedClass.get();
+ }
+
+ public void setCachedClass(Class<?> cachedClass) {
+ this.cachedClass = new WeakReference<Class<?>>(cachedClass);
+ }
+}
Propchange: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/util/CachedClass.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/util/CachedClass.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: cxf/trunk/common/common/src/main/java/org/apache/cxf/jaxb/JAXBBeanInfo.java
URL: http://svn.apache.org/viewvc/cxf/trunk/common/common/src/main/java/org/apache/cxf/jaxb/JAXBBeanInfo.java?rev=792096&view=auto
==============================================================================
--- cxf/trunk/common/common/src/main/java/org/apache/cxf/jaxb/JAXBBeanInfo.java (added)
+++ cxf/trunk/common/common/src/main/java/org/apache/cxf/jaxb/JAXBBeanInfo.java Wed Jul 8 10:55:18 2009
@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.jaxb;
+
+import java.util.Collection;
+
+import javax.xml.namespace.QName;
+
+public interface JAXBBeanInfo {
+
+ boolean isElement();
+
+ Collection<QName> getTypeNames();
+
+ String getElementNamespaceURI(Object object);
+
+ String getElementLocalName(Object object);
+
+}
Propchange: cxf/trunk/common/common/src/main/java/org/apache/cxf/jaxb/JAXBBeanInfo.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/common/common/src/main/java/org/apache/cxf/jaxb/JAXBBeanInfo.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: cxf/trunk/common/common/src/main/java/org/apache/cxf/jaxb/JAXBContextProxy.java
URL: http://svn.apache.org/viewvc/cxf/trunk/common/common/src/main/java/org/apache/cxf/jaxb/JAXBContextProxy.java?rev=792096&view=auto
==============================================================================
--- cxf/trunk/common/common/src/main/java/org/apache/cxf/jaxb/JAXBContextProxy.java (added)
+++ cxf/trunk/common/common/src/main/java/org/apache/cxf/jaxb/JAXBContextProxy.java Wed Jul 8 10:55:18 2009
@@ -0,0 +1,29 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.jaxb;
+
+/**
+ *
+ */
+public interface JAXBContextProxy {
+
+ Object getBeanInfo(Class<?> cls);
+
+}
Propchange: cxf/trunk/common/common/src/main/java/org/apache/cxf/jaxb/JAXBContextProxy.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/common/common/src/main/java/org/apache/cxf/jaxb/JAXBContextProxy.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified: cxf/trunk/common/common/src/main/java/org/apache/cxf/jaxb/JAXBUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/common/common/src/main/java/org/apache/cxf/jaxb/JAXBUtils.java?rev=792096&r1=792095&r2=792096&view=diff
==============================================================================
--- cxf/trunk/common/common/src/main/java/org/apache/cxf/jaxb/JAXBUtils.java (original)
+++ cxf/trunk/common/common/src/main/java/org/apache/cxf/jaxb/JAXBUtils.java Wed Jul 8 10:55:18 2009
@@ -20,18 +20,20 @@
package org.apache.cxf.jaxb;
+import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.Type;
import java.net.URI;
import java.net.URISyntaxException;
-
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -44,11 +46,14 @@
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.PropertyException;
+import javax.xml.bind.SchemaOutputResolver;
import javax.xml.bind.attachment.AttachmentMarshaller;
import javax.xml.bind.attachment.AttachmentUnmarshaller;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.Result;
+import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Element;
@@ -58,10 +63,12 @@
import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.common.util.ASMHelper;
+import org.apache.cxf.common.util.CachedClass;
+import org.apache.cxf.common.util.PackageUtils;
import org.apache.cxf.common.util.ReflectionInvokationHandler;
import org.apache.cxf.common.util.ReflectionInvokationHandler.WrapReturn;
+import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.helpers.JavaUtils;
-
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Label;
@@ -615,6 +622,7 @@
throw new JAXBException(ex);
}
}
+
public static Object createFileCodeWriter(File f) throws JAXBException {
try {
Class<?> cls;
@@ -629,6 +637,7 @@
throw new JAXBException(ex);
}
}
+
public static Class<?> getParamClass(SchemaCompiler sc, String method) {
Object o = ((ReflectionInvokationHandler)Proxy.getInvocationHandler(sc)).getTarget();
for (Method m : o.getClass().getMethods()) {
@@ -638,6 +647,135 @@
}
return null;
}
+
+ public static JAXBBeanInfo getBeanInfo(JAXBContextProxy context, Class<?> cls) {
+ Object o = context.getBeanInfo(cls);
+ if (o == null) {
+ return null;
+ }
+ return ReflectionInvokationHandler.createProxyWrapper(o, JAXBBeanInfo.class);
+ }
+
+ public static List<DOMResult> generateJaxbSchemas(
+ JAXBContext context, final Map<String, DOMResult> builtIns) throws IOException {
+ final List<DOMResult> results = new ArrayList<DOMResult>();
+
+ context.generateSchema(new SchemaOutputResolver() {
+ @Override
+ public Result createOutput(String ns, String file) throws IOException {
+ DOMResult result = new DOMResult();
+
+ if (builtIns.containsKey(ns)) {
+ DOMResult dr = builtIns.get(ns);
+ result.setSystemId(dr.getSystemId());
+ results.add(dr);
+ return result;
+ }
+ result.setSystemId(file);
+ results.add(result);
+ return result;
+ }
+ });
+
+ return results;
+ }
+
+ public static void scanPackages(Set<Class<?>> classes,
+ Map<Package, CachedClass> objectFactoryCache) {
+ // try and read any jaxb.index files that are with the other classes.
+ // This should
+ // allow loading of extra classes (such as subclasses for inheritance
+ // reasons)
+ // that are in the same package. Also check for ObjectFactory classes
+ Map<String, InputStream> packages = new HashMap<String, InputStream>();
+ Map<String, ClassLoader> packageLoaders = new HashMap<String, ClassLoader>();
+ Set<Class<?>> objectFactories = new HashSet<Class<?>>();
+ for (Class<?> jcls : classes) {
+ String pkgName = PackageUtils.getPackageName(jcls);
+ if (!packages.containsKey(pkgName)) {
+ Package pkg = jcls.getPackage();
+
+ packages.put(pkgName, jcls.getResourceAsStream("jaxb.index"));
+ packageLoaders.put(pkgName, jcls.getClassLoader());
+ String objectFactoryClassName = pkgName + "." + "ObjectFactory";
+ Class<?> ofactory = null;
+ CachedClass cachedFactory = null;
+ if (pkg != null && objectFactoryCache != null) {
+ synchronized (objectFactoryCache) {
+ cachedFactory = objectFactoryCache.get(pkg);
+ }
+ }
+ if (cachedFactory != null) {
+ ofactory = cachedFactory.getCachedClass();
+ }
+ if (ofactory == null) {
+ try {
+ ofactory = Class.forName(objectFactoryClassName, false, jcls
+ .getClassLoader());
+ objectFactories.add(ofactory);
+ addToObjectFactoryCache(pkg, ofactory, objectFactoryCache);
+ } catch (ClassNotFoundException e) {
+ addToObjectFactoryCache(pkg, null, objectFactoryCache);
+ }
+ } else {
+ objectFactories.add(ofactory);
+ }
+ }
+ }
+ for (Map.Entry<String, InputStream> entry : packages.entrySet()) {
+ if (entry.getValue() != null) {
+ try {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(entry.getValue(),
+ "UTF-8"));
+ String pkg = entry.getKey();
+ ClassLoader loader = packageLoaders.get(pkg);
+ if (!StringUtils.isEmpty(pkg)) {
+ pkg += ".";
+ }
+
+ String line = reader.readLine();
+ while (line != null) {
+ line = line.trim();
+ if (line.indexOf("#") != -1) {
+ line = line.substring(0, line.indexOf("#"));
+ }
+ if (!StringUtils.isEmpty(line)) {
+ try {
+ Class<?> ncls = Class.forName(pkg + line, false, loader);
+ classes.add(ncls);
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ line = reader.readLine();
+ }
+ } catch (Exception e) {
+ // ignore
+ } finally {
+ try {
+ entry.getValue().close();
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ }
+ }
+ classes.addAll(objectFactories);
+ }
+
+
+ private static void addToObjectFactoryCache(Package objectFactoryPkg,
+ Class<?> ofactory,
+ Map<Package, CachedClass> objectFactoryCache) {
+ if (objectFactoryPkg == null || objectFactoryCache == null) {
+ return;
+ }
+ synchronized (objectFactoryCache) {
+ objectFactoryCache.put(objectFactoryPkg,
+ new CachedClass(ofactory));
+ }
+ }
+
public static interface SchemaCompiler {
void setErrorListener(Object elForRun);
Modified: cxf/trunk/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBDataBinding.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBDataBinding.java?rev=792096&r1=792095&r2=792096&view=diff
==============================================================================
--- cxf/trunk/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBDataBinding.java (original)
+++ cxf/trunk/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBDataBinding.java Wed Jul 8 10:55:18 2009
@@ -19,12 +19,9 @@
package org.apache.cxf.jaxb;
-import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
-import java.io.InputStreamReader;
import java.io.OutputStream;
-import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
@@ -32,7 +29,6 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
@@ -45,7 +41,6 @@
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
-import javax.xml.bind.SchemaOutputResolver;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.ValidationEventHandler;
import javax.xml.bind.annotation.XmlElement;
@@ -55,7 +50,6 @@
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
-import javax.xml.transform.Result;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
@@ -67,6 +61,7 @@
import org.apache.cxf.common.i18n.Message;
import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.common.util.CacheMap;
+import org.apache.cxf.common.util.CachedClass;
import org.apache.cxf.common.util.PackageUtils;
import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.common.xmlschema.SchemaCollection;
@@ -125,27 +120,11 @@
}
- static final class CachedClassOrNull {
- private WeakReference<Class<?>> cachedClass;
-
- public CachedClassOrNull(Class<?> cachedClass) {
- this.cachedClass = new WeakReference<Class<?>>(cachedClass);
- }
-
- public Class<?> getCachedClass() {
- return cachedClass == null ? null : cachedClass.get();
- }
-
- public void setCachedClass(Class<?> cachedClass) {
- this.cachedClass = new WeakReference<Class<?>>(cachedClass);
- }
- }
-
private static final Map<Set<Class<?>>, CachedContextAndSchemas> JAXBCONTEXT_CACHE
= new CacheMap<Set<Class<?>>, CachedContextAndSchemas>();
- private static final Map<Package, CachedClassOrNull> OBJECT_FACTORY_CACHE
- = new CacheMap<Package, CachedClassOrNull>();
+ private static final Map<Package, CachedClass> OBJECT_FACTORY_CACHE
+ = new CacheMap<Package, CachedClass>();
private static final Map<String, DOMResult> BUILT_IN_SCHEMAS = new HashMap<String, DOMResult>();
static {
@@ -452,27 +431,7 @@
// default access for tests.
List<DOMResult> generateJaxbSchemas() throws IOException {
- final List<DOMResult> results = new ArrayList<DOMResult>();
-
- context.generateSchema(new SchemaOutputResolver() {
-
- @Override
- public Result createOutput(String ns, String file) throws IOException {
- DOMResult result = new DOMResult();
-
- if (BUILT_IN_SCHEMAS.containsKey(ns)) {
- DOMResult dr = BUILT_IN_SCHEMAS.get(ns);
- result.setSystemId(dr.getSystemId());
- results.add(dr);
- return result;
- }
- result.setSystemId(file);
- results.add(result);
- return result;
- }
- });
-
- return results;
+ return JAXBUtils.generateJaxbSchemas(context, BUILT_IN_SCHEMAS);
}
public JAXBContext createJAXBContext(Set<Class<?>> classes) throws JAXBException {
@@ -494,7 +453,7 @@
}
}
- scanPackages(classes);
+ JAXBUtils.scanPackages(classes, OBJECT_FACTORY_CACHE);
addWsAddressingTypes(classes);
for (Class<?> clz : classes) {
@@ -542,88 +501,7 @@
return cachedContextAndSchemas;
}
- private void scanPackages(Set<Class<?>> classes) {
- // try and read any jaxb.index files that are with the other classes.
- // This should
- // allow loading of extra classes (such as subclasses for inheritance
- // reasons)
- // that are in the same package. Also check for ObjectFactory classes
- Map<String, InputStream> packages = new HashMap<String, InputStream>();
- Map<String, ClassLoader> packageLoaders = new HashMap<String, ClassLoader>();
- Set<Class<?>> objectFactories = new HashSet<Class<?>>();
- for (Class<?> jcls : classes) {
- String pkgName = PackageUtils.getPackageName(jcls);
- if (!packages.containsKey(pkgName)) {
- Package pkg = jcls.getPackage();
-
- packages.put(pkgName, jcls.getResourceAsStream("jaxb.index"));
- packageLoaders.put(pkgName, jcls.getClassLoader());
- String objectFactoryClassName = pkgName + "." + "ObjectFactory";
- Class<?> ofactory = null;
- CachedClassOrNull cachedFactory = null;
- if (pkg != null) {
- synchronized (OBJECT_FACTORY_CACHE) {
- cachedFactory = OBJECT_FACTORY_CACHE.get(pkg);
- }
- }
- if (cachedFactory != null) {
- ofactory = cachedFactory.getCachedClass();
- }
- if (ofactory == null) {
- try {
- ofactory = Class.forName(objectFactoryClassName, false, jcls
- .getClassLoader());
- objectFactories.add(ofactory);
- addToObjectFactoryCache(pkg, ofactory);
- } catch (ClassNotFoundException e) {
- addToObjectFactoryCache(pkg, null);
- }
- } else {
- objectFactories.add(ofactory);
- }
- }
- }
- for (Map.Entry<String, InputStream> entry : packages.entrySet()) {
- if (entry.getValue() != null) {
- try {
- BufferedReader reader = new BufferedReader(new InputStreamReader(entry.getValue(),
- "UTF-8"));
- String pkg = entry.getKey();
- ClassLoader loader = packageLoaders.get(pkg);
- if (!StringUtils.isEmpty(pkg)) {
- pkg += ".";
- }
-
- String line = reader.readLine();
- while (line != null) {
- line = line.trim();
- if (line.indexOf("#") != -1) {
- line = line.substring(0, line.indexOf("#"));
- }
- if (!StringUtils.isEmpty(line)) {
- try {
- Class<?> ncls = Class.forName(pkg + line, false, loader);
- classes.add(ncls);
- } catch (Exception e) {
- // ignore
- }
- }
- line = reader.readLine();
- }
- } catch (Exception e) {
- // ignore
- } finally {
- try {
- entry.getValue().close();
- } catch (Exception e) {
- // ignore
- }
- }
- }
- }
- classes.addAll(objectFactories);
- }
-
+
private boolean checkObjectFactoryNamespaces(Class<?> clz) {
for (Method meth : clz.getMethods()) {
XmlElementDecl decl = meth.getAnnotation(XmlElementDecl.class);
@@ -637,16 +515,6 @@
return false;
}
- private void addToObjectFactoryCache(Package objectFactoryPkg, Class<?> ofactory) {
- if (objectFactoryPkg == null) {
- return;
- }
- synchronized (OBJECT_FACTORY_CACHE) {
- OBJECT_FACTORY_CACHE.put(objectFactoryPkg,
- new CachedClassOrNull(ofactory));
- }
- }
-
private void addWsAddressingTypes(Set<Class<?>> classes) {
if (classes.contains(ObjectFactory.class)) {
// ws-addressing is used, lets add the specific types
Modified: cxf/trunk/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBSchemaInitializer.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBSchemaInitializer.java?rev=792096&r1=792095&r2=792096&view=diff
==============================================================================
--- cxf/trunk/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBSchemaInitializer.java (original)
+++ cxf/trunk/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBSchemaInitializer.java Wed Jul 8 10:55:18 2009
@@ -94,6 +94,7 @@
}
return null;
}
+
public JAXBBeanInfo getBeanInfo(Type cls) {
if (cls instanceof Class) {
if (((Class)cls).isArray()) {
@@ -115,16 +116,15 @@
return null;
}
+
public JAXBBeanInfo getBeanInfo(Class<?> cls) {
return getBeanInfo(context, cls);
}
+
public static JAXBBeanInfo getBeanInfo(JAXBContextProxy context, Class<?> cls) {
- Object o = context.getBeanInfo(cls);
- if (o == null) {
- return null;
- }
- return ReflectionInvokationHandler.createProxyWrapper(o, JAXBBeanInfo.class);
+ return JAXBUtils.getBeanInfo(context, cls);
}
+
@Override
public void begin(MessagePartInfo part) {
// Check to see if the WSDL information has been filled in for us.
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java?rev=792096&r1=792095&r2=792096&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java Wed Jul 8 10:55:18 2009
@@ -52,7 +52,6 @@
import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.endpoint.ConduitSelector;
import org.apache.cxf.endpoint.Endpoint;
-import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.interceptor.Interceptor;
import org.apache.cxf.jaxrs.impl.MetadataMap;
import org.apache.cxf.jaxrs.impl.UriBuilderImpl;
@@ -321,9 +320,7 @@
if (status >= 400) {
try {
InputStream errorStream = mStream == null ? conn.getErrorStream() : mStream;
- if (errorStream != null) {
- responseBuilder.entity(IOUtils.readStringFromStream(errorStream));
- }
+ responseBuilder.entity(errorStream);
} catch (Exception ex) {
// nothing we can do really
}
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java?rev=792096&r1=792095&r2=792096&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java Wed Jul 8 10:55:18 2009
@@ -268,7 +268,7 @@
Response r = doInvoke(httpMethod, body, responseClass);
- if (r.getStatus() >= 400) {
+ if (r.getStatus() >= 400 && responseClass != null) {
throw new WebApplicationException(r);
}
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java?rev=792096&r1=792095&r2=792096&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java Wed Jul 8 10:55:18 2009
@@ -20,26 +20,48 @@
import java.io.IOException;
import java.io.StringWriter;
+import java.lang.annotation.Annotation;
+import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.IdentityHashMap;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import javax.xml.bind.JAXBContext;
-import javax.xml.bind.SchemaOutputResolver;
-import javax.xml.stream.XMLStreamWriter;
-import javax.xml.transform.Result;
-import javax.xml.transform.sax.SAXResult;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.namespace.QName;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.dom.DOMSource;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.ReflectionInvokationHandler;
+import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.common.util.XmlSchemaPrimitiveUtils;
+import org.apache.cxf.common.xmlschema.SchemaCollection;
import org.apache.cxf.common.xmlschema.XmlSchemaConstants;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.jaxb.JAXBBeanInfo;
+import org.apache.cxf.jaxb.JAXBContextProxy;
+import org.apache.cxf.jaxb.JAXBUtils;
import org.apache.cxf.jaxrs.JAXRSServiceImpl;
import org.apache.cxf.jaxrs.ext.RequestHandler;
import org.apache.cxf.jaxrs.impl.HttpHeadersImpl;
@@ -54,7 +76,7 @@
import org.apache.cxf.message.Message;
import org.apache.cxf.service.Service;
import org.apache.cxf.staxutils.StaxUtils;
-import org.apache.cxf.staxutils.StreamWriterContentHandler;
+import org.apache.ws.commons.schema.XmlSchema;
public class WadlGenerator implements RequestHandler {
@@ -77,7 +99,7 @@
StringBuilder sbMain = new StringBuilder();
sbMain.append("<application xmlns=\"").append(WADL_NS)
- .append("\" xmlns:xs=\"").append(XmlSchemaConstants.XSD_NAMESPACE_URI).append("\">");
+ .append("\" xmlns:xs=\"").append(XmlSchemaConstants.XSD_NAMESPACE_URI).append("\"");
StringBuilder sbGrammars = new StringBuilder();
sbGrammars.append("<grammars>");
@@ -85,14 +107,26 @@
sbResources.append("<resources base=\"").append(ui.getBaseUri().toString()).append("\">");
List<ClassResourceInfo> cris = getResourcesList(m, resource);
+
+ Set<Class<?>> jaxbTypes = getAllJaxbTypes(cris);
+ JAXBContext context = createJaxbContext(jaxbTypes);
+ SchemaCollection coll = getSchemaCollection(context);
+ JAXBContextProxy proxy = null;
+ if (coll != null) {
+ proxy = ReflectionInvokationHandler.createProxyWrapper(context, JAXBContextProxy.class);
+ }
+ Map<Class<?>, QName> clsMap = new IdentityHashMap<Class<?>, QName>();
+
for (ClassResourceInfo cri : cris) {
- handleResource(sbResources, cri, cri.getURITemplate().getValue());
+ handleResource(sbResources, jaxbTypes, proxy, clsMap,
+ cri, cri.getURITemplate().getValue());
}
sbResources.append("</resources>");
-
+ handleGrammars(sbMain, sbGrammars, coll, clsMap);
sbGrammars.append("</grammars>");
+ sbMain.append(">");
sbMain.append(sbGrammars.toString());
sbMain.append(sbResources.toString());
sbMain.append("</application>");
@@ -103,7 +137,37 @@
return Response.ok().type(type).entity(sbMain.toString()).build();
}
- private void handleResource(StringBuilder sb, ClassResourceInfo cri, String path) {
+ private void handleGrammars(StringBuilder sbApp, StringBuilder sbGrammars,
+ SchemaCollection coll, Map<Class<?>, QName> clsMap) {
+ Map<String, String> map = new HashMap<String, String>();
+ for (QName qname : clsMap.values()) {
+ map.put(qname.getPrefix(), qname.getNamespaceURI());
+ }
+ for (Map.Entry<String, String> entry : map.entrySet()) {
+ sbApp.append(" xmlns:").append(entry.getKey()).append("=\"")
+ .append(entry.getValue()).append("\"");
+ }
+
+
+ writeSchemas(sbGrammars, coll);
+ }
+
+ private void writeSchemas(StringBuilder sb, SchemaCollection coll) {
+ if (coll == null) {
+ return;
+ }
+ for (XmlSchema xs : coll.getXmlSchemas()) {
+ if (xs.getItems().getCount() == 0) {
+ continue;
+ }
+ StringWriter writer = new StringWriter();
+ xs.write(writer);
+ sb.append(writer.toString());
+ }
+ }
+
+ private void handleResource(StringBuilder sb, Set<Class<?>> jaxbTypes, JAXBContextProxy jaxbProxy,
+ Map<Class<?>, QName> clsMap, ClassResourceInfo cri, String path) {
sb.append("<resource path=\"").append(path).append("\">");
List<OperationResourceInfo> sortedOps = sortOperationsByPath(
@@ -115,18 +179,20 @@
Class<?> cls = ori.getMethodToInvoke().getReturnType();
ClassResourceInfo subcri = cri.findResource(cls, cls);
if (subcri != null) {
- handleResource(sb, subcri, ori.getURITemplate().getValue());
+ handleResource(sb, jaxbTypes, jaxbProxy, clsMap, subcri,
+ ori.getURITemplate().getValue());
} else {
- handleDynamicSubresource(sb, ori);
+ handleDynamicSubresource(sb, jaxbTypes, jaxbProxy, clsMap, ori);
}
continue;
}
- handleOperation(sb, ori);
+ handleOperation(sb, jaxbTypes, jaxbProxy, clsMap, ori);
}
sb.append("</resource>");
}
- private void handleOperation(StringBuilder sb, OperationResourceInfo ori) {
+ private void handleOperation(StringBuilder sb, Set<Class<?>> jaxbTypes, JAXBContextProxy jaxbProxy,
+ Map<Class<?>, QName> clsMap, OperationResourceInfo ori) {
String path = ori.getURITemplate().getValue();
boolean useResource = useResource(ori);
@@ -139,8 +205,12 @@
sb.append("<method name=\"").append(ori.getHttpMethod()).append("\">");
if (ori.getMethodToInvoke().getParameterTypes().length != 0) {
sb.append("<request>");
- for (Parameter p : ori.getParameters()) {
- handleParameter(sb, ori, p);
+ if (isFormRequest(ori)) {
+ handleRepresentation(sb, jaxbTypes, jaxbProxy, clsMap, ori, null, false);
+ } else {
+ for (Parameter p : ori.getParameters()) {
+ handleParameter(sb, jaxbTypes, jaxbProxy, clsMap, ori, p);
+ }
}
sb.append("</request>");
}
@@ -150,7 +220,8 @@
}
sb.append("<response>");
if (void.class != ori.getMethodToInvoke().getReturnType()) {
- handleRepresentation(sb, ori, ori.getMethodToInvoke().getReturnType(), false);
+ handleRepresentation(sb, jaxbTypes, jaxbProxy, clsMap, ori,
+ ori.getMethodToInvoke().getReturnType(), false);
}
sb.append("</response>");
@@ -174,14 +245,15 @@
return true;
}
- private void handleDynamicSubresource(StringBuilder sb, OperationResourceInfo ori) {
+ private void handleDynamicSubresource(StringBuilder sb, Set<Class<?>> jaxbTypes,
+ JAXBContextProxy jaxbProxy, Map<Class<?>, QName> clsMap, OperationResourceInfo ori) {
sb.append("<!-- Dynamic subresource -->");
sb.append("<resource path=\"").append(ori.getURITemplate().getValue()).append("\">");
if (ori.getMethodToInvoke().getParameterTypes().length != 0) {
sb.append("<request>");
for (Parameter p : ori.getParameters()) {
- handleParameter(sb, ori, p);
+ handleParameter(sb, jaxbTypes, jaxbProxy, clsMap, ori, p);
}
sb.append("</request>");
}
@@ -189,10 +261,11 @@
}
- private void handleParameter(StringBuilder sb, OperationResourceInfo ori, Parameter pm) {
+ private void handleParameter(StringBuilder sb, Set<Class<?>> jaxbTypes, JAXBContextProxy jaxbProxy,
+ Map<Class<?>, QName> clsMap, OperationResourceInfo ori, Parameter pm) {
Class<?> cls = ori.getMethodToInvoke().getParameterTypes()[pm.getIndex()];
if (pm.getType() == ParameterType.REQUEST_BODY) {
- handleRepresentation(sb, ori, cls, true);
+ handleRepresentation(sb, jaxbTypes, jaxbProxy, clsMap, ori, cls, true);
return;
}
if (pm.getType() == ParameterType.PATH || pm.getType() == ParameterType.MATRIX) {
@@ -215,7 +288,8 @@
private void writeParam(StringBuilder sb, Parameter pm, OperationResourceInfo ori) {
sb.append("<param name=\"").append(pm.getName()).append("\" ");
String style = ParameterType.PATH == pm.getType() ? "template"
- : pm.getType().toString().toLowerCase();
+ : ParameterType.FORM == pm.getType() ? "query"
+ : pm.getType().toString().toLowerCase();
sb.append("style=\"").append(style).append("\"");
if (pm.getDefaultValue() != null) {
sb.append(" default=\"").append(pm.getDefaultValue()).append("\"");
@@ -228,51 +302,35 @@
sb.append("/>");
}
- private void handleRepresentation(StringBuilder sb, OperationResourceInfo ori,
+ private void handleRepresentation(StringBuilder sb, Set<Class<?>> jaxbTypes, JAXBContextProxy jaxbProxy,
+ Map<Class<?>, QName> clsMap, OperationResourceInfo ori,
Class<?> type, boolean inbound) {
List<MediaType> types = inbound ? ori.getConsumeTypes() : ori.getProduceTypes();
- if (types.size() == 0) {
- types = Collections.singletonList(MediaType.APPLICATION_ATOM_XML_TYPE);
- }
- for (MediaType mt : types) {
- if (InjectionUtils.isPrimitive(type)) {
- String rep = XmlSchemaPrimitiveUtils.getSchemaRepresentation(type);
- String value = rep == null ? type.getSimpleName() : rep;
- sb.append("<!-- Primitive type : " + value + " -->");
+ if (types.size() == 1 && types.get(0).equals(MediaType.WILDCARD_TYPE)
+ && (type == null || MultivaluedMap.class.isAssignableFrom(type))) {
+ types = Collections.singletonList(MediaType.APPLICATION_FORM_URLENCODED_TYPE);
+ }
+ if (type != null) {
+ for (MediaType mt : types) {
+ if (InjectionUtils.isPrimitive(type)) {
+ String rep = XmlSchemaPrimitiveUtils.getSchemaRepresentation(type);
+ String value = rep == null ? type.getSimpleName() : rep;
+ sb.append("<!-- Primitive type : " + value + " -->");
+ }
+ sb.append("<representation");
+ if (!mt.isWildcardType()) {
+ sb.append(" mediaType=\"").append(mt.toString()).append("\"");
+ }
+ if (jaxbProxy != null && mt.getSubtype().contains("xml") && jaxbTypes.contains(type)) {
+ generateQName(sb, jaxbProxy, clsMap, type);
+ }
+ sb.append("/>");
}
+ } else {
sb.append("<representation");
- if (!mt.isWildcardType()) {
- sb.append(" mediaType=\"").append(mt.toString()).append("\"");
- }
- sb.append(">");
- if (!InjectionUtils.isPrimitive(type) && mt.getSubtype().contains("xml")) {
- // try to use JAXB
- // TODO : reuse JaxbDatabinding code
- JAXBElementProvider jaxb = new JAXBElementProvider();
- try {
- JAXBContext context = jaxb.getPackageContext(type);
- if (context == null) {
- context = jaxb.getClassContext(type);
- }
- if (context != null) {
- StringWriter writer = new StringWriter();
- XMLStreamWriter streamWriter = StaxUtils.createXMLStreamWriter(writer);
- final StreamWriterContentHandler handler =
- new StreamWriterContentHandler(streamWriter);
- context.generateSchema(new SchemaOutputResolver() {
- @Override
- public Result createOutput(String ns, String file) throws IOException {
- SAXResult result = new SAXResult(handler);
- result.setSystemId(file);
- return result;
- }
- });
- streamWriter.flush();
- sb.append(writer.toString());
- }
- } catch (Exception ex) {
- LOG.fine("No schema can be generated from " + type.getName());
- }
+ sb.append(" mediaType=\"").append(types.get(0).toString()).append("\">");
+ for (Parameter pm : ori.getParameters()) {
+ writeParam(sb, pm, ori);
}
sb.append("</representation>");
}
@@ -304,4 +362,217 @@
: ((JAXRSServiceImpl)m.getExchange().get(Service.class)).getClassResourceInfos();
}
+
+ private void generateQName(StringBuilder sb,
+ JAXBContextProxy jaxbProxy,
+ Map<Class<?>, QName> clsMap,
+ Class<?> type) {
+
+ QName typeQName = clsMap.get(type);
+ if (typeQName != null) {
+ writeQName(sb, typeQName);
+ return;
+ }
+ JAXBBeanInfo info = JAXBUtils.getBeanInfo(jaxbProxy, type);
+ if (info == null) {
+ return;
+ }
+ QName qname = getQName(info, type, clsMap);
+
+ if (qname != null && qname.getNamespaceURI().length() > 0) {
+ writeQName(sb, qname);
+ clsMap.put(type, qname);
+ }
+ }
+
+ private void writeQName(StringBuilder sb, QName qname) {
+ sb.append(" element=\"").append(qname.getPrefix()).append(':')
+ .append(qname.getLocalPart()).append("\"");
+ }
+
+ private SchemaCollection getSchemaCollection(JAXBContext context) {
+ if (context == null) {
+ return null;
+ }
+ SchemaCollection xmlSchemaCollection = new SchemaCollection();
+ Collection<DOMSource> schemas = new HashSet<DOMSource>();
+ try {
+ for (DOMResult r : JAXBUtils.generateJaxbSchemas(context,
+ CastUtils.cast(Collections.emptyMap(), String.class, DOMResult.class))) {
+ schemas.add(new DOMSource(r.getNode(), r.getSystemId()));
+ }
+ } catch (IOException e) {
+ LOG.fine("No schema can be generated");
+ return null;
+ }
+
+ boolean hackAroundEmptyNamespaceIssue = false;
+ for (DOMSource r : schemas) {
+ hackAroundEmptyNamespaceIssue =
+ addSchemaDocument(xmlSchemaCollection,
+ (Document)r.getNode(),
+ r.getSystemId(),
+ hackAroundEmptyNamespaceIssue);
+ }
+ return xmlSchemaCollection;
+ }
+
+ private QName getQName(JAXBBeanInfo jaxbInfo, Class<?> type, Map<Class<?>, QName> clsMap) {
+ try {
+ Object instance = type.newInstance();
+ String localName = jaxbInfo.getElementLocalName(instance);
+ String ns = jaxbInfo.getElementNamespaceURI(instance);
+ if (localName != null) {
+ if (ns != null && ns.length() > 0) {
+ String prefix = null;
+ for (QName name : clsMap.values()) {
+ if (name.getNamespaceURI().equals(ns)) {
+ prefix = name.getPrefix();
+ break;
+ }
+ }
+ if (prefix == null) {
+ int size = new HashSet<QName>(clsMap.values()).size();
+ prefix = "prefix" + (size + 1);
+ }
+ return new QName(ns, localName, prefix);
+ } else {
+ return new QName("", localName);
+ }
+ }
+ } catch (Exception ex) {
+ // ignore
+ }
+ return null;
+ }
+
+ private Set<Class<?>> getAllJaxbTypes(List<ClassResourceInfo> cris) {
+ Set<Class<?>> types = new HashSet<Class<?>>();
+ for (ClassResourceInfo root : cris) {
+ for (OperationResourceInfo ori : root.getMethodDispatcher().getOperationResourceInfos()) {
+ checkJaxbType(ori.getMethodToInvoke().getReturnType(), types);
+ for (Parameter pm : ori.getParameters()) {
+ if (pm.getType() == ParameterType.REQUEST_BODY) {
+ checkJaxbType(ori.getMethodToInvoke().getParameterTypes()[pm.getIndex()], types);
+ }
+ }
+ }
+ }
+
+ return types;
+ }
+
+ private void checkJaxbType(Class<?> type, Set<Class<?>> types) {
+ JAXBElementProvider provider = new JAXBElementProvider();
+ if (!InjectionUtils.isPrimitive(type)
+ && !JAXBElement.class.isAssignableFrom(type)
+ && provider.isReadable(type, type, new Annotation[0], MediaType.APPLICATION_XML_TYPE)) {
+ types.add(type);
+ }
+ }
+
+ private JAXBContext createJaxbContext(Set<Class<?>> classes) {
+ if (classes.isEmpty()) {
+ return null;
+ }
+ JAXBUtils.scanPackages(classes, null);
+ JAXBContext ctx;
+ try {
+ ctx = JAXBContext.newInstance(classes.toArray(new Class[classes.size()]));
+ return ctx;
+ } catch (JAXBException ex) {
+ LOG.fine("No JAXB context can be created");
+ }
+ return null;
+ }
+
+ private boolean isFormRequest(OperationResourceInfo ori) {
+ for (Parameter p : ori.getParameters()) {
+ if (p.getType() == ParameterType.FORM) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // TODO : can we reuse this block with JAXBBinding somehow ?
+ public boolean addSchemaDocument(SchemaCollection col,
+ Document d,
+ String systemId,
+ boolean hackAroundEmptyNamespaceIssue) {
+ String ns = d.getDocumentElement().getAttribute("targetNamespace");
+
+ if (StringUtils.isEmpty(ns)) {
+ if (DOMUtils.getFirstElement(d.getDocumentElement()) == null) {
+ hackAroundEmptyNamespaceIssue = true;
+ return hackAroundEmptyNamespaceIssue;
+ }
+ //create a copy of the dom so we
+ //can modify it.
+ d = copy(d);
+ ns = "";
+ d.getDocumentElement().setAttribute("targetNamespace", ns);
+ }
+
+ if (hackAroundEmptyNamespaceIssue) {
+ d = doEmptyNamespaceHack(d);
+ }
+
+ Node n = d.getDocumentElement().getFirstChild();
+ while (n != null) {
+ if (n instanceof Element) {
+ Element e = (Element)n;
+ if (e.getLocalName().equals("import")) {
+ e.removeAttribute("schemaLocation");
+ }
+ }
+ n = n.getNextSibling();
+ }
+
+ synchronized (d) {
+ col.read(d, systemId, null);
+ }
+ return hackAroundEmptyNamespaceIssue;
+ }
+
+ private Document doEmptyNamespaceHack(Document d) {
+ boolean hasStuffToRemove = false;
+ Element el = DOMUtils.getFirstElement(d.getDocumentElement());
+ while (el != null) {
+ if ("import".equals(el.getLocalName())
+ && StringUtils.isEmpty(el.getAttribute("targetNamespace"))) {
+ hasStuffToRemove = true;
+ break;
+ }
+ el = DOMUtils.getNextElement(el);
+ }
+ if (hasStuffToRemove) {
+ //create a copy of the dom so we
+ //can modify it.
+ d = copy(d);
+ el = DOMUtils.getFirstElement(d.getDocumentElement());
+ while (el != null) {
+ if ("import".equals(el.getLocalName())
+ && StringUtils.isEmpty(el.getAttribute("targetNamespace"))) {
+ d.getDocumentElement().removeChild(el);
+ el = DOMUtils.getFirstElement(d.getDocumentElement());
+ } else {
+ el = DOMUtils.getNextElement(el);
+ }
+ }
+ }
+
+ return d;
+ }
+
+ private Document copy(Document doc) {
+ try {
+ return StaxUtils.copy(doc);
+ } catch (XMLStreamException e) {
+ //ignore
+ } catch (ParserConfigurationException e) {
+ //ignore
+ }
+ return doc;
+ }
}
Modified: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/Book.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/Book.java?rev=792096&r1=792095&r2=792096&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/Book.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/Book.java Wed Jul 8 10:55:18 2009
@@ -18,14 +18,23 @@
*/
package org.apache.cxf.jaxrs.model.wadl;
+import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
+import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
-
+@XmlRootElement(name = "thebook", namespace = "http://superbooks")
+@XmlType(name = "book", namespace = "http://superbooks")
public class Book {
private int id;
+ @XmlElement(name = "thechapter", namespace = "http://superbooks")
+ private Chapter chapter;
public Book() {
}
@@ -46,7 +55,17 @@
@Path("/chapter/{cid}")
public Chapter getChapter(@PathParam("cid") int cid) {
- return new Chapter(cid);
+ return chapter;
}
-
+
+ @Path("/form1")
+ @POST
+ public void form1(MultivaluedMap map) {
+ }
+
+ @Path("/form2")
+ @POST
+ public void form2(@FormParam("field1") String f1, @FormParam("field2") String f2) {
+ }
+
}
Modified: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/BookStore.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/BookStore.java?rev=792096&r1=792095&r2=792096&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/BookStore.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/BookStore.java Wed Jul 8 10:55:18 2009
@@ -58,5 +58,10 @@
return new Book(1);
}
+ @GET
+ @Path("chapter")
+ public Chapter getChaper() {
+ return new Chapter(1);
+ }
}
Modified: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/Chapter.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/Chapter.java?rev=792096&r1=792095&r2=792096&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/Chapter.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/Chapter.java Wed Jul 8 10:55:18 2009
@@ -20,10 +20,16 @@
import javax.ws.rs.GET;
import javax.ws.rs.Path;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+@XmlRootElement(name = "thechapter", namespace = "http://superbooks")
+@XmlType(name = "chapter", namespace = "http://superbooks")
public class Chapter {
private int id;
+ public Chapter() {
+ }
public Chapter(int id) {
this.id = id;
}
@@ -34,6 +40,8 @@
return id;
}
-
+ public void setId(int ident) {
+ id = ident;
+ }
}
Modified: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/WadlGeneratorTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/WadlGeneratorTest.java?rev=792096&r1=792095&r2=792096&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/WadlGeneratorTest.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/WadlGeneratorTest.java Wed Jul 8 10:55:18 2009
@@ -18,6 +18,8 @@
*/
package org.apache.cxf.jaxrs.model.wadl;
+import java.io.File;
+import java.io.FileOutputStream;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
@@ -28,6 +30,7 @@
import org.w3c.dom.Document;
import org.w3c.dom.Element;
+import org.apache.cxf.common.xmlschema.XmlSchemaConstants;
import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.jaxrs.JAXRSServiceImpl;
import org.apache.cxf.jaxrs.model.ClassResourceInfo;
@@ -71,7 +74,8 @@
Response r = wg.handleRequest(m, cri);
checkResponse(r);
- List<Element> els = getWadlResourcesInfo("http://localhost:8080/baz", 1, r.getEntity().toString());
+ Document doc = DOMUtils.readXml(new StringReader(r.getEntity().toString()));
+ List<Element> els = getWadlResourcesInfo(doc, "http://localhost:8080/baz", 1);
checkBookStoreInfo(els.get(0));
}
@@ -80,14 +84,14 @@
assertNotNull(r);
assertEquals(WadlGenerator.WADL_TYPE.toString(),
r.getMetadata().getFirst(HttpHeaders.CONTENT_TYPE));
-// File f = new File("test.xml");
-// f.delete();
-// f.createNewFile();
-// System.out.println(f.getAbsolutePath());
-// FileOutputStream fos = new FileOutputStream(f);
-// fos.write(r.getEntity().toString().getBytes());
-// fos.flush();
-// fos.close();
+ File f = new File("test.xml");
+ f.delete();
+ f.createNewFile();
+ System.out.println(f.getAbsolutePath());
+ FileOutputStream fos = new FileOutputStream(f);
+ fos.write(r.getEntity().toString().getBytes());
+ fos.flush();
+ fos.close();
}
@Test
@@ -103,34 +107,69 @@
Message m = mockMessage("http://localhost:8080/baz", "/bar", WadlGenerator.WADL_QUERY, cris);
Response r = wg.handleRequest(m, null);
checkResponse(r);
- List<Element> els = getWadlResourcesInfo("http://localhost:8080/baz", 2, r.getEntity().toString());
+ Document doc = DOMUtils.readXml(new StringReader(r.getEntity().toString()));
+ checkGrammars(doc.getDocumentElement());
+ List<Element> els = getWadlResourcesInfo(doc, "http://localhost:8080/baz", 2);
checkBookStoreInfo(els.get(0));
Element orderResource = els.get(1);
assertEquals("/orders", orderResource.getAttribute("path"));
}
+ private void checkGrammars(Element appElement) {
+ List<Element> grammarEls = DOMUtils.getChildrenWithName(appElement, WadlGenerator.WADL_NS,
+ "grammars");
+ assertEquals(1, grammarEls.size());
+ List<Element> schemasEls = DOMUtils.getChildrenWithName(grammarEls.get(0),
+ XmlSchemaConstants.XSD_NAMESPACE_URI, "schema");
+ assertEquals(1, schemasEls.size());
+ assertEquals("http://superbooks", schemasEls.get(0).getAttribute("targetNamespace"));
+ assertEquals(2, DOMUtils.getChildrenWithName(schemasEls.get(0),
+ XmlSchemaConstants.XSD_NAMESPACE_URI, "element").size());
+ assertEquals(2, DOMUtils.getChildrenWithName(schemasEls.get(0),
+ XmlSchemaConstants.XSD_NAMESPACE_URI, "complexType").size());
+ }
+
private void checkBookStoreInfo(Element resource) {
assertEquals("/bookstore/{id}", resource.getAttribute("path"));
List<Element> resourceEls = DOMUtils.getChildrenWithName(resource,
- "http://research.sun.com/wadl/2006/10", "resource");
- assertEquals(3, resourceEls.size());
+ WadlGenerator.WADL_NS, "resource");
+ assertEquals(4, resourceEls.size());
assertEquals("/", resourceEls.get(0).getAttribute("path"));
assertEquals("/books/{bookid}", resourceEls.get(1).getAttribute("path"));
- assertEquals("/booksubresource", resourceEls.get(2).getAttribute("path"));
+ assertEquals("/chapter", resourceEls.get(2).getAttribute("path"));
+ assertEquals("/booksubresource", resourceEls.get(3).getAttribute("path"));
+
List<Element> methodEls = DOMUtils.getChildrenWithName(resourceEls.get(0),
- "http://research.sun.com/wadl/2006/10", "method");
+ WadlGenerator.WADL_NS, "method");
assertEquals(1, methodEls.size());
assertEquals("GET", methodEls.get(0).getAttribute("name"));
List<Element> paramsEls = DOMUtils.getChildrenWithName(resourceEls.get(1),
- "http://research.sun.com/wadl/2006/10", "param");
+ WadlGenerator.WADL_NS, "param");
assertEquals(3, paramsEls.size());
checkParameter(paramsEls.get(0), "id", "template");
checkParameter(paramsEls.get(1), "bookid", "template");
checkParameter(paramsEls.get(2), "mid", "matrix");
+
+ methodEls = DOMUtils.getChildrenWithName(resourceEls.get(1),
+ WadlGenerator.WADL_NS, "method");
+ assertEquals(1, methodEls.size());
+ assertEquals("POST", methodEls.get(0).getAttribute("name"));
+
+ List<Element> requestEls = DOMUtils.getChildrenWithName(methodEls.get(0),
+ WadlGenerator.WADL_NS, "request");
+ assertEquals(1, requestEls.size());
+ List<Element> repEls = DOMUtils.getChildrenWithName(requestEls.get(0),
+ WadlGenerator.WADL_NS, "representation");
+ assertEquals(2, repEls.size());
+ assertEquals("application/xml", repEls.get(0).getAttribute("mediaType"));
+ assertEquals("prefix1:thebook", repEls.get(0).getAttribute("element"));
+ assertEquals("application/json", repEls.get(1).getAttribute("mediaType"));
+ assertEquals("", repEls.get(1).getAttribute("element"));
+
}
private void checkParameter(Element paramEl, String name, String type) {
@@ -138,19 +177,18 @@
assertEquals(type, paramEl.getAttribute("style"));
}
- private List<Element> getWadlResourcesInfo(String baseURI, int size, String value) throws Exception {
- Document doc = DOMUtils.readXml(new StringReader(value));
+ private List<Element> getWadlResourcesInfo(Document doc, String baseURI, int size) throws Exception {
Element root = doc.getDocumentElement();
- assertEquals("http://research.sun.com/wadl/2006/10", root.getNamespaceURI());
+ assertEquals(WadlGenerator.WADL_NS, root.getNamespaceURI());
assertEquals("application", root.getLocalName());
List<Element> resourcesEls = DOMUtils.getChildrenWithName(root,
- "http://research.sun.com/wadl/2006/10", "resources");
+ WadlGenerator.WADL_NS, "resources");
assertEquals(1, resourcesEls.size());
Element resourcesEl = resourcesEls.get(0);
assertEquals(baseURI, resourcesEl.getAttribute("base"));
List<Element> resourceEls =
DOMUtils.getChildrenWithName(resourcesEl,
- "http://research.sun.com/wadl/2006/10", "resource");
+ WadlGenerator.WADL_NS, "resource");
assertEquals(size, resourceEls.size());
return resourceEls;
}