001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */package org.apache.cxf.wsdl;
019:
020: import java.io.PrintWriter;
021: import java.lang.reflect.Method;
022: import java.util.Iterator;
023: import java.util.Map;
024:
025: import javax.wsdl.Definition;
026: import javax.wsdl.WSDLException;
027: import javax.wsdl.extensions.ExtensibilityElement;
028: import javax.wsdl.extensions.ExtensionDeserializer;
029: import javax.wsdl.extensions.ExtensionRegistry;
030: import javax.wsdl.extensions.ExtensionSerializer;
031: import javax.xml.bind.JAXBContext;
032: import javax.xml.bind.JAXBElement;
033: import javax.xml.bind.JAXBException;
034: import javax.xml.bind.Marshaller;
035: import javax.xml.bind.Unmarshaller;
036: import javax.xml.bind.annotation.XmlElementDecl;
037: import javax.xml.namespace.QName;
038: import javax.xml.stream.XMLStreamWriter;
039:
040: import org.w3c.dom.Element;
041:
042: import org.apache.cxf.common.util.PackageUtils;
043:
044: /**
045: * JAXBExtensionHelper
046: * @author dkulp
047: *
048: */
049: public class JAXBExtensionHelper implements ExtensionSerializer,
050: ExtensionDeserializer {
051: JAXBContext context;
052: final Class<? extends TExtensibilityElementImpl> typeClass;
053:
054: public JAXBExtensionHelper(
055: Class<? extends TExtensibilityElementImpl> cls) {
056: typeClass = cls;
057: }
058:
059: public static void addExtensions(ExtensionRegistry registry,
060: String parentType, String elementType, ClassLoader cl)
061: throws JAXBException, ClassNotFoundException {
062: Class<?> parentTypeClass = Class.forName(parentType, true, cl);
063:
064: Class<? extends TExtensibilityElementImpl> elementTypeClass = Class
065: .forName(elementType, true, cl).asSubclass(
066: TExtensibilityElementImpl.class);
067: addExtensions(registry, parentTypeClass, elementTypeClass);
068: }
069:
070: public static void addExtensions(ExtensionRegistry registry,
071: Class<?> parentType,
072: Class<? extends TExtensibilityElementImpl> cls)
073: throws JAXBException {
074:
075: JAXBExtensionHelper helper = new JAXBExtensionHelper(cls);
076:
077: try {
078: Class<?> objectFactory = Class.forName(PackageUtils
079: .getPackageName(cls)
080: + ".ObjectFactory");
081: Method methods[] = objectFactory.getDeclaredMethods();
082: for (Method method : methods) {
083: if (method.getParameterTypes().length == 1
084: && method.getParameterTypes()[0].equals(cls)) {
085:
086: XmlElementDecl elementDecl = method
087: .getAnnotation(XmlElementDecl.class);
088: if (null != elementDecl) {
089: QName elementType = new QName(elementDecl
090: .namespace(), elementDecl.name());
091: registry.registerDeserializer(parentType,
092: elementType, helper);
093: registry.registerSerializer(parentType,
094: elementType, helper);
095: registry.mapExtensionTypes(parentType,
096: elementType, cls);
097: registry.createExtension(parentType,
098: elementType);
099: }
100: }
101: }
102:
103: } catch (WSDLException we) {
104: // TODO
105: we.printStackTrace();
106:
107: } catch (ClassNotFoundException ex) {
108: // TODO
109: ex.printStackTrace();
110: }
111: }
112:
113: protected JAXBContext getJAXBContext() {
114: if (context == null) {
115: try {
116: createJAXBContext();
117: } catch (JAXBException e) {
118: throw new RuntimeException(e);
119: }
120: }
121: return context;
122: }
123:
124: protected synchronized void createJAXBContext()
125: throws JAXBException {
126: if (context != null) {
127: return;
128: }
129:
130: context = JAXBContext.newInstance(PackageUtils
131: .getPackageName(typeClass), typeClass.getClassLoader());
132: }
133:
134: /* (non-Javadoc)
135: * @see javax.wsdl.extensions.ExtensionSerializer#marshall(java.lang.Class,
136: * javax.xml.namespace.QName, javax.wsdl.extensions.ExtensibilityElement,
137: * java.io.PrintWriter, javax.wsdl.Definition, javax.wsdl.extensions.ExtensionRegistry)
138: */
139: public void marshall(Class parent, QName qname,
140: ExtensibilityElement obj, PrintWriter pw,
141: final Definition wsdl, ExtensionRegistry registry)
142: throws WSDLException {
143: // TODO Auto-generated method stub
144: try {
145: Marshaller u = getJAXBContext().createMarshaller();
146: u.setProperty("jaxb.encoding", "UTF-8");
147: u.setProperty("jaxb.fragment", Boolean.TRUE);
148: u.setProperty("jaxb.formatted.output", Boolean.TRUE);
149:
150: Object mObj = obj;
151:
152: Class<?> objectFactory = Class.forName(PackageUtils
153: .getPackageName(typeClass)
154: + ".ObjectFactory");
155: Method methods[] = objectFactory.getDeclaredMethods();
156: for (Method method : methods) {
157: if (method.getParameterTypes().length == 1
158: && method.getParameterTypes()[0]
159: .equals(typeClass)) {
160:
161: mObj = method.invoke(objectFactory.newInstance(),
162: new Object[] { obj });
163: }
164: }
165:
166: javax.xml.stream.XMLOutputFactory fact = javax.xml.stream.XMLOutputFactory
167: .newInstance();
168: XMLStreamWriter writer = new PrettyPrintXMLStreamWriter(
169: fact.createXMLStreamWriter(pw), parent);
170: writer
171: .setNamespaceContext(new javax.xml.namespace.NamespaceContext() {
172:
173: public String getNamespaceURI(String arg) {
174: return wsdl.getNamespace(arg);
175: }
176:
177: public String getPrefix(String arg) {
178: for (Object ent : wsdl.getNamespaces()
179: .entrySet()) {
180: Map.Entry entry = (Map.Entry) ent;
181: if (arg.equals(entry.getValue())) {
182: return (String) entry.getKey();
183: }
184: }
185: return null;
186: }
187:
188: public Iterator getPrefixes(String arg) {
189: return wsdl.getNamespaces().keySet()
190: .iterator();
191: }
192: });
193:
194: u.marshal(mObj, writer);
195: writer.flush();
196: } catch (Exception ex) {
197: throw new WSDLException(WSDLException.PARSER_ERROR, "", ex);
198: }
199:
200: }
201:
202: /* (non-Javadoc)
203: * @see javax.wsdl.extensions.ExtensionDeserializer#unmarshall(java.lang.Class,
204: * javax.xml.namespace.QName, org.w3c.dom.Element,
205: * javax.wsdl.Definition,
206: * javax.wsdl.extensions.ExtensionRegistry)
207: */
208: public ExtensibilityElement unmarshall(Class parent, QName qname,
209: Element element, Definition wsdl, ExtensionRegistry registry)
210: throws WSDLException {
211: try {
212: Unmarshaller u = getJAXBContext().createUnmarshaller();
213:
214: Object o = u.unmarshal(element);
215: if (o instanceof JAXBElement<?>) {
216: JAXBElement<?> el = (JAXBElement<?>) o;
217: o = el.getValue();
218: }
219:
220: ExtensibilityElement el = o instanceof ExtensibilityElement ? (ExtensibilityElement) o
221: : null;
222: if (null != el) {
223: el.setElementType(qname);
224: }
225: return el;
226: } catch (Exception ex) {
227: throw new WSDLException(WSDLException.PARSER_ERROR,
228: "Error reading element " + qname, ex);
229: }
230: }
231:
232: }
|