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 <= <code>'\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 }