View Javadoc

1   /****************************************************************************
2    * Copyright (c) 2005, 2006, 2007, 2008, 2009 Imola Informatica.
3    * All rights reserved. This program and the accompanying materials
4    * are made available under the terms of the LGPL License v2.1
5    * which accompanies this distribution, and is available at
6    * http://www.gnu.org/licenses/lgpl.html
7    ****************************************************************************/
8   package it.imolinfo.jbi4corba.jbi.cxf;
9   
10  import com.sun.tools.internal.xjc.runtime.JAXBContextFactory;
11  import it.imolinfo.jbi4corba.Logger;
12  import it.imolinfo.jbi4corba.LoggerFactory;
13  import it.imolinfo.jbi4corba.jbi.Messages;
14  
15  import java.io.OutputStream;
16  import java.lang.reflect.Array;
17  import java.util.Collection;
18  import java.util.List;
19  
20  import javax.xml.bind.JAXBContext;
21  import javax.xml.bind.JAXBElement;
22  import javax.xml.bind.JAXBException;
23  import javax.xml.bind.Marshaller;
24  import javax.xml.bind.annotation.adapters.HexBinaryAdapter;
25  import javax.xml.namespace.QName;
26  import javax.xml.stream.XMLEventWriter;
27  import javax.xml.stream.XMLStreamWriter;
28  
29  import org.apache.cxf.common.logging.LogUtils;
30  import org.apache.cxf.interceptor.Fault;
31  import org.apache.cxf.service.model.MessagePartInfo;
32  import org.w3c.dom.Node;
33  
34  /**
35   * Helper class for the jaxb mapping of the returned results.
36   * Derived from the JxbEncoderDecoder class.
37   * 
38   * @author mpiraccini@imolinfo.it
39   *
40   */
41  public final class OutMarshallerHelper {
42  
43      /**
44       * Logger.
45       */
46      private static final transient Logger LOG = LoggerFactory.getLogger(OutMarshallerHelper.class);
47      /** The messages. */
48      @SuppressWarnings("unused")
49      private static final Messages MESSAGES =
50              Messages.getMessages(OutMarshallerHelper.class);
51      /** The CXF Logger (needed by the Fault constructors) */
52      private static final java.util.logging.Logger CXFLOG = LogUtils.getLogger(Jbi4CorbaBareOutInterceptor.class);
53  
54      /**
55       * Writes out the object on the marshaler.
56       * @param u
57       * @param source
58       * @param mObj
59       * @throws Fault
60       * @throws JAXBException
61       */
62      public static void writeObject(Marshaller u, Object source, Object mObj)
63              throws Fault, JAXBException {
64          if (source instanceof XMLStreamWriter) {
65              u.marshal(mObj, (XMLStreamWriter) source);
66          } else if (source instanceof OutputStream) {
67              u.marshal(mObj, (OutputStream) source);
68          } else if (source instanceof Node) {
69              u.marshal(mObj, (Node) source);
70          } else if (source instanceof XMLEventWriter) {
71              u.marshal(mObj, (XMLEventWriter) source);
72          } else {
73              throw new Fault(new org.apache.cxf.common.i18n.Message(
74                      "UNKNOWN_SOURCE", CXFLOG, source.getClass().getName()));
75          }
76      }
77  
78      /**
79       * Marshal an object using jabx.
80       * This implementation supports array as return values.
81       * @param marshaller
82       * @param elValue
83       * @param part
84       * @param source
85       * @throws Fault
86       */
87      @SuppressWarnings("unchecked")
88      public static void marshal(Marshaller marshaller, Object elValue,
89              MessagePartInfo part, Object source) throws Fault {
90  
91          try {
92              // The Marshaller.JAXB_FRAGMENT will tell the Marshaller not to
93              // generate the xml declaration.
94              marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
95              marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false);
96          } catch (javax.xml.bind.PropertyException e) {
97              // intentionally empty.
98              LOG.debug(e.getMessage());
99          }
100 
101         Class<?> cls = null;
102         if (part != null) {
103             cls = part.getTypeClass();
104         }
105 
106         if (cls == null) {
107             cls = null != elValue ? elValue.getClass() : null;
108         }
109 
110         if (cls != null && cls.isArray() && elValue instanceof Collection) {
111             Collection<?> col = (Collection<?>) elValue;
112             elValue = col.toArray((Object[]) Array.newInstance(cls.getComponentType(), col.size()));
113         }
114 
115         try {
116             Object mObj = elValue;
117             QName elName = null;
118             if (part != null) {
119                 elName = part.getConcreteName();
120             }
121 
122             if (null != elName) {
123 
124                 if (part != null) {
125                     //	&& part.getXmlSchema() instanceof XmlSchemaElement) {
126 
127                     //XmlSchemaElement el = (XmlSchemaElement) part
128                     //		.getXmlSchema();
129 
130                     //if (mObj.getClass().isArray()
131                     // && el.getSchemaType() instanceof XmlSchemaSimpleType
132                     // && part.getXmlSchema() instanceof XmlSchemaSimpleType
133                     //&& ((XmlSchemaSimpleType) el.getSchemaType())
134                     //		.getContent() instanceof XmlSchemaSimpleTypeList
135                     // ) {
136                     // mObj = Arrays.asList((Object[]) mObj);
137                     // writeObject(marshaller, source, M);
138                     if (mObj == null) {
139                         Class clazz = part.getTypeClass();
140                         LOG.debug("null value deducting type class: "+clazz.toString());
141 //                      OutMarshallerHelper.writeObject(marshaller, source,
142 //                                new JAXBElement(elName, Array.newInstance(Class.forName("AlarmIRPConstDefs.BadAcknowledgeAlarmInfo", true, Thread.currentThread().getContextClassLoader()), 0).getClass(), null));
143 
144                         //09-04-2010 Added By lacquaviva
145                         //ISSUE 27 changed clazz with generic Object.class to manage OUT only with Array[][]
146                         //Fix issue 27, to fix bug relative to a OUT only scenario we have changed the type clazz with the generic Object.class
147                         //if there are problem with this fix decomment line 315 on class it.imolinfo.jbi4corba.webservice.generator.bcm.WebServiceAnnotationAdapter
148                         //and change Object.class below with clazz
149                         OutMarshallerHelper.writeObject(marshaller, source, new JAXBElement(elName, Object.class, null));
150                         //OutMarshallerHelper.writeObject(marshaller, source, new JAXBElement(new JAXBElement(elName, clazz, null, null), clazz, null));
151                         return;
152                     }
153 
154 
155                     if (mObj.getClass().isArray()) {
156                         // Have to handle this ourselves.... which really
157                         // sucks.... but what can we do?
158                         Object objArray;
159                         if (mObj instanceof List) {
160                             List l = (List) mObj;
161                             objArray = l.toArray(new Object[l.size()]);
162                             cls = null;
163                         } else {
164                             objArray = mObj;
165                             cls = objArray.getClass().getComponentType();
166                         }
167                         int len = Array.getLength(objArray);
168                         for (int x = 0; x < len; x++) {
169                             Object o = Array.get(objArray, x);
170                             OutMarshallerHelper.writeObject(marshaller, source,
171                                     new JAXBElement(elName, cls == null ? o.getClass() : cls, o));
172                         }
173                     } else {
174                         OutMarshallerHelper.writeObject(marshaller, source, new JAXBElement(elName,
175                                 cls, mObj));
176                     }
177                 } else if (byte[].class == cls && part.getTypeQName() != null && part.getTypeQName().getLocalPart().equals(
178                         "hexBinary")) {
179                     mObj = new HexBinaryAdapter().marshal((byte[]) mObj);
180                     OutMarshallerHelper.writeObject(marshaller, source, new JAXBElement(elName,
181                             String.class, mObj));
182                 } else if (mObj instanceof JAXBElement) {
183                     OutMarshallerHelper.writeObject(marshaller, source, mObj);
184                 } else {
185                     OutMarshallerHelper.writeObject(marshaller, source, new JAXBElement(elName,
186                             cls, mObj));
187                 }
188             } else {
189                 OutMarshallerHelper.writeObject(marshaller, source, mObj);
190             }
191         } catch (Fault ex) {
192             ex.printStackTrace();
193             throw (Fault) ex.fillInStackTrace();
194         } catch (Exception ex) {
195             ex.printStackTrace();
196             if (ex instanceof javax.xml.bind.MarshalException) {
197                 javax.xml.bind.MarshalException marshalEx = (javax.xml.bind.MarshalException) ex;
198                 org.apache.cxf.common.i18n.Message faultMessage = new org.apache.cxf.common.i18n.Message("MARSHAL_ERROR", CXFLOG, marshalEx.getLinkedException().getMessage());
199                 throw new Fault(faultMessage, ex);
200             } else {
201                 throw new Fault(new org.apache.cxf.common.i18n.Message("MARSHAL_ERROR", CXFLOG, ex.getMessage()), ex);
202             }
203         }
204     }
205 }