View Javadoc

1   /*
2    *  Copyright (c) 2005, 2006, 2007 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   
9   
10  package it.imolinfo.jbi4cics.jbi.wsdl;
11  
12  import static it.imolinfo.jbi4cics.jbi.wsdl.Jbi4CicsExtension.CODE_PAGE_NAME_ATTRIBUTE;
13  import static it.imolinfo.jbi4cics.jbi.wsdl.Jbi4CicsExtension.Q_ELEM_JBI4CICS_COPY_COBOL;
14  import static it.imolinfo.jbi4cics.jbi.wsdl.Jbi4CicsExtension.Q_ELEM_JBI4CICS_OUTPUT_COPY_COBOL;
15  import static it.imolinfo.jbi4cics.jbi.wsdl.Jbi4CicsExtension.SAME_COPY_COBOL_ATTRIBUTE;
16  import static it.imolinfo.jbi4cics.jbi.wsdl.Jbi4CicsExtension.SERVICE_PACKAGE_NAME_ATTRIBUTE;
17  import it.imolinfo.jbi4cics.Logger;
18  import it.imolinfo.jbi4cics.LoggerFactory;
19  import it.imolinfo.jbi4cics.jbi.Messages;
20  import javax.wsdl.Definition;
21  import javax.wsdl.WSDLException;
22  import javax.wsdl.extensions.ExtensibilityElement;
23  import javax.wsdl.extensions.ExtensionDeserializer;
24  import javax.wsdl.extensions.ExtensionRegistry;
25  import javax.xml.namespace.QName;
26  import org.w3c.dom.Element;
27  import com.ibm.wsdl.util.xml.DOMUtils;
28  import com.ibm.wsdl.util.xml.QNameUtils;
29  
30  /**
31   * Deserializer for the Jbi4Cics WSDL Extension (binding element), according
32   * with JWSDL specs. See JSR 110.
33   *
34   * @author marcopiraccini
35   * @author <a href="mailto:mcimatti@imolinfo.it">Marco Cimatti</a>
36   */
37  public final class Jbi4CicsBindingDeserializer
38          implements ExtensionDeserializer {
39  
40      /**
41       * The logger for this class and its instances.
42       */
43      private static final Logger LOG
44              = LoggerFactory.getLogger(Jbi4CicsBindingDeserializer.class);
45  
46      /**
47       * The responsible to translate localized messages.
48       */
49      private static final Messages MESSAGES
50              = Messages.getMessages(Jbi4CicsBindingDeserializer.class);
51  
52      /**
53       * Initializes a new instance of this class.
54       */
55      Jbi4CicsBindingDeserializer() {
56      }
57  
58      /**
59       * Deserializes elements into instances of classes which implement the
60       * <code>ExtensibilityElement</code> interface. The return value should be
61       * explicitly cast to the more-specific implementing type.
62       *
63       * @param   parentType     a class object indicating where in the WSDL
64       *                         document this extensibility element was
65       *                         encountered. For example,
66       *                         <code>javax.wsdl.Binding.class</code> would be
67       *                         used to indicate this element was encountered as
68       *                         an immediate child of a element.
69       * @param   elementType    the qname of the extensibility element.
70       * @param   elem           the extensibility element to deserialize.
71       * @param   def            the definition this extensibility element was
72       *                         encountered in.
73       * @param   extReg         the <code>ExtensionRegistry</code> to use (if
74       *                         needed again).
75       * @return  the unmarshalled Jbi4Cics binding element, instance of
76       *          {@link Jbi4CicsBinding} class.
77       * @throws  WSDLException  if the copy Cobol is not present in the
78       *                         unmarshalled Jbi4Cics binding element, the input 
79       *                         or output copy Cobol are found more than one
80       *                         time in the element, the output copy Cobol is
81       *                         required but not contained in the document to 
82       *                         parse.
83       */
84      public ExtensibilityElement unmarshall(Class parentType, QName elementType,
85              Element elem, Definition def, ExtensionRegistry extReg)
86              throws WSDLException {
87          Jbi4CicsBinding binding = (Jbi4CicsBinding)
88                  extReg.createExtension(parentType, elementType);
89          String sameCopyCobol = DOMUtils.getAttribute(elem,
90                                                       SAME_COPY_COBOL_ATTRIBUTE);
91  
92          // Attributes
93          binding.setServicePackageName(
94                  DOMUtils.getAttribute(elem, SERVICE_PACKAGE_NAME_ATTRIBUTE));
95          binding.setCodePage(
96                  DOMUtils.getAttribute(elem, CODE_PAGE_NAME_ATTRIBUTE));
97          if (isNullOrBlank(sameCopyCobol)) {
98              binding.setSameCopyCobol(null);
99          } else {
100             binding.setSameCopyCobol(Boolean.valueOf(sameCopyCobol));
101         }
102 
103         // Elements
104         unmarshallCopiesCobol(binding, elem);
105 
106         return binding;
107     }
108 
109     /**
110      * Tests if the specified string is <code>null</code>, empty or contains 
111      * only blank characters.
112      * <p>
113      * A <i>blank</i> character has code &lt;= <code>'&#92;u0020'</code> (the
114      * space character).
115      *
116      * @param   str  the string to test.
117      * @return  <code>true</code> if and only if <code>str</code> is 
118      *          <code>null</code>, has length zero or is made only by blank 
119      *          characters.
120      */
121     private static boolean isNullOrBlank(final String str) {
122         if (str != null) {
123             for (int i = str.length() - 1; i >= 0; --i) {
124                 if (str.charAt(i) > ' ') {
125                     return false;
126                 }
127             }
128         }
129         return true;
130     }
131     
132     /**
133      * Deserializes the input and output copies Cobol, updating the specified
134      * <code>Jbi4CicsBinding</code> instance.
135      *
136      * @param   elem           the extensibility element to deserialize.
137      * @param   binding        the unmarshalled Jbi4Cics binding element to 
138      *                         update with copies Cobol.
139      * @throws  WSDLException  if the (input) copy Cobol is not present in the
140      *                         unmarshalled Jbi4Cics binding element, the input 
141      *                         or output copy Cobol are found more than one
142      *                         time in the element, the output copy Cobol is
143      *                         required but not contained in the document to
144      *                         parse.
145      */
146     private void unmarshallCopiesCobol(Jbi4CicsBinding binding, Element elem)
147             throws WSDLException {
148         boolean copyCobolFound = false;
149         boolean outCopyCobolFound = false;
150 
151         for (Element e = DOMUtils.getFirstChildElement(elem);
152              e != null;
153              e = DOMUtils.getNextSiblingElement(e)) {
154             if (QNameUtils.matches(Q_ELEM_JBI4CICS_OUTPUT_COPY_COBOL, e)) {
155                 if (outCopyCobolFound) {
156                     throw createWSDLException(
157                             "CIC001314_Element_found_many_times",
158                             Q_ELEM_JBI4CICS_OUTPUT_COPY_COBOL);
159                 }
160                 binding.setOutputCopyCobol(e.getTextContent());
161                 outCopyCobolFound = true;
162             } else if (QNameUtils.matches(Q_ELEM_JBI4CICS_COPY_COBOL, e)) {
163                 if (copyCobolFound) {
164                     throw createWSDLException(
165                             "CIC001314_Element_found_many_times",
166                             Q_ELEM_JBI4CICS_COPY_COBOL);
167                 }
168                 binding.setCopyCobol(e.getTextContent());
169                 copyCobolFound = true;
170             }
171         }
172 
173         if (!copyCobolFound) {
174             throw createWSDLException("CIC001309_Copy_cobol_not_found",
175                                       Q_ELEM_JBI4CICS_COPY_COBOL);
176         }
177         if (Boolean.FALSE.equals(binding.getSameCopyCobol())
178                 && !outCopyCobolFound) {
179             throw createWSDLException("CIC001315_Output_copy_Cobol_required",
180                                       null);
181         }
182     }
183 
184     /**
185      * Creates a new <code>WSDLException</code> with the specific error message,
186      * logging also the error message itself.
187      *
188      * @param   msgKey  the error message bundle key. Must be not
189      *                  <code>null</code>.
190      * @param   msgArg  the optional error message argument, used to format the
191      *                  resulting message. If not <code>null</code>, the message
192      *                  identified by <code>msgKey</code> is assumed to be
193      *                  parametric and it must contain one argument, needed to
194      *                  compose the final message shown thru the returned
195      *                  exception. Use <code>null</code> for messages that don't
196      *                  contain parameters.
197      * @return  the newly created <code>WSDLException</code> containing the
198      *          error message retrieved using the received key and the optional
199      *          parameter.
200      */
201     private static WSDLException createWSDLException(final String msgKey,
202                                                      final Object msgArg) {
203         String msg;
204 
205         if (msgArg == null) {
206             LOG.error(msgKey);
207             msg = MESSAGES.getString(msgKey);
208         } else {
209             LOG.error(msgKey, msgArg);
210             msg = MESSAGES.getString(msgKey, msgArg);
211         }
212 
213         // No fault code...
214         return new WSDLException(null, msg);
215     }
216 }