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.schema;
9   
10  import it.imolinfo.jbi4corba.utils.HelperFileUtil;
11  
12  import java.io.File;
13  import java.io.FileWriter;
14  import java.io.IOException;
15  import java.net.URISyntaxException;
16  import java.net.URL;
17  import java.util.ArrayList;
18  import java.util.List;
19  import java.util.Map;
20  import java.util.logging.Logger;
21  
22  import javax.wsdl.Definition;
23  import javax.wsdl.extensions.ExtensionRegistry;
24  import javax.wsdl.extensions.schema.Schema;
25  import javax.wsdl.extensions.schema.SchemaImport;
26  import javax.xml.namespace.QName;
27  import javax.xml.parsers.DocumentBuilder;
28  import javax.xml.parsers.DocumentBuilderFactory;
29  import javax.xml.parsers.ParserConfigurationException;
30  import javax.xml.transform.Transformer;
31  import javax.xml.transform.TransformerException;
32  import javax.xml.transform.TransformerFactory;
33  import javax.xml.transform.dom.DOMSource;
34  import javax.xml.transform.stream.StreamResult;
35  
36  import org.apache.cxf.service.model.MessageInfo;
37  import org.apache.cxf.service.model.MessagePartInfo;
38  import org.apache.cxf.service.model.OperationInfo;
39  import org.apache.cxf.service.model.ServiceInfo;
40  import org.w3c.dom.Document;
41  import org.w3c.dom.Element;
42  import org.w3c.dom.Node;
43  import org.w3c.dom.NodeList;
44  
45  import com.ibm.wsdl.Constants;
46  import com.ibm.wsdl.extensions.schema.SchemaConstants;
47  import com.ibm.wsdl.extensions.schema.SchemaDeserializer;
48  import com.ibm.wsdl.extensions.schema.SchemaImpl;
49  import com.ibm.wsdl.extensions.schema.SchemaSerializer;
50  
51  /**
52   * This is an Utility class that contains the utility for the management
53   * Xmlschema.
54   * 
55   * @author <a href="mailto:gvaleri@imolinfo.it">Giancarlo Valeri</a>
56   */
57  @SuppressWarnings("unchecked")
58  public class SchemaUtil {
59  
60      // the logger
61      @SuppressWarnings("unused")
62      private static java.util.logging.Logger LOG = Logger
63              .getLogger(SchemaUtil.class.getName());
64  
65      /**
66       * The namespace prefix for the schema element
67       */
68      private static final String prefix = "xsd";
69  
70      /**
71       * The QName of the schema
72       */
73      public static final QName Q_ELEMENT_SCHEMA = new QName(
74              SchemaConstants.ELEM_SCHEMA);
75  
76      /**
77       * Generates the org.w3c.dom.Element schema from list of SchemaImport
78       * 
79       * @param imports
80       *            list of import tag
81       * @return element schema generated
82       */
83      public final static Element generateElementSchemaFromSchemaImports(
84              List<SchemaImport> imports) throws ParserConfigurationException {
85  
86          Element sc = null;
87  
88          DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance();
89          DocumentBuilder bd = fact.newDocumentBuilder();
90          Document doc = bd.newDocument();
91  
92          // create tag schema
93          sc = doc.createElement(SchemaUtil.prefix + ":"
94                  + SchemaConstants.ELEM_SCHEMA);
95          sc.setAttribute(Constants.ATTR_XMLNS + ":" + SchemaUtil.prefix,
96                  SchemaConstants.NS_URI_XSD_2001);
97  
98          // add import tag
99          for (int i = 0; i < imports.size(); i++) {
100             Element imp = (Element) doc.createElement(SchemaUtil.prefix + ":"
101                     + Constants.ELEM_IMPORT);
102             imp.setAttribute(Constants.ATTR_NAMESPACE, imports.get(i)
103                     .getNamespaceURI());
104             imp.setAttribute(SchemaConstants.ATTR_SCHEMA_LOCATION, imports.get(
105                     i).getSchemaLocationURI());
106             sc.appendChild(imp);
107         }
108         return sc;
109     }
110 
111     /**
112      * Add the attribute schemaLocation in the import tag if need
113      * 
114      * @param element
115      *            element by write
116      * @param service
117      *            name service
118      */
119     private static void addschemaLocationURI(Element element, String service) {
120 
121         String schemaPrefix = element.getPrefix();
122         NodeList nodes = element.getElementsByTagName(schemaPrefix + ":"
123                 + Constants.ELEM_IMPORT);
124         for (int i = 0; i < nodes.getLength(); i++) {
125             Element el = (Element) nodes.item(i);
126             String namespace = el.getAttribute(Constants.ATTR_NAMESPACE);
127             String schemaLocation = el.getAttribute(Constants.ATTR_NAMESPACE);
128             schemaLocation = generateFileNameXSD(schemaLocation, service);
129             if (namespace.equals("http://www.w3.org/2005/08/addressing")) {
130                 schemaLocation = "ws-addr.xsd";
131             }
132 
133             el.setAttribute(SchemaConstants.ATTR_SCHEMA_LOCATION,
134                     schemaLocation);
135         }
136 
137     }
138 
139     /**
140      * Creates XMLSchema from an list of schemas and writes the file
141      * 
142      * @param schemas
143      *            list schema
144      * @param path
145      *            path file
146      * @param service
147      *            name service
148      * @throws java.io.IOException
149      */
150 
151     public static List<String> createXSD(List<Schema> schemas, String path,
152             String service) throws IOException, TransformerException {
153         String xsdFileName = null;
154         String xsdPathName = null;
155         File xsd = null;
156 
157         Element el = null;
158         String targetNamespace = null;
159         FileWriter fw = null;
160         List<String>  xsdFileNames = new ArrayList<String>();
161 
162         if (schemas != null && !schemas.isEmpty()) {
163 
164             for (int i = 0; i < schemas.size(); i++) {
165 
166                 el = schemas.get(i).getElement();
167 
168                 targetNamespace = el
169                         .getAttribute(Constants.ATTR_TARGET_NAMESPACE);
170                 Map map = schemas.get(i).getImports();
171                 // add import if there is needed
172                 if (map != null && !map.isEmpty()) {
173                     addschemaLocationURI(el, service);
174                 }
175                 xsdFileName = generateFileNameXSD(targetNamespace, service);
176                 // xsdFileName = service+".xsd";
177                 xsdPathName = path + File.separatorChar + xsdFileName;
178                 xsd = new File(xsdPathName);
179                 // Collect the file names created
180                 if (!xsdFileNames.contains(xsdPathName)) {
181                 	xsdFileNames.add(xsdPathName);
182                 }
183                 // change the boolean append from true to false for the xsd
184                 // generation
185 
186                 fw = new FileWriter(xsd, false);
187                 // writes schema in the file
188                 writeElement(el, fw);
189 
190             }
191             
192         }
193         return xsdFileNames;
194     }
195 
196     /**
197      * Generates name's file of the file XSD
198      * 
199      * @param targetNamespace
200      *            namespace
201      * @param service
202      *            service name
203      * @return
204      */
205     public static String generateFileNameXSD(String targetNamespace,
206             String service) {
207         String f = null;
208 
209         int length = targetNamespace.length();
210         int lastSlash = targetNamespace.lastIndexOf('/');
211 
212         if (lastSlash == length - 1) {
213             targetNamespace = targetNamespace.substring(0, lastSlash);
214         }
215         int lastSeparator = Math.max(targetNamespace.lastIndexOf('/'),
216                 targetNamespace.lastIndexOf(':'));
217 
218         lastSeparator = Math.max(lastSeparator, targetNamespace
219                 .lastIndexOf('\\'));
220 
221         targetNamespace = targetNamespace.substring(lastSeparator + 1);
222 
223         f = service + "_" + targetNamespace + ".xsd";
224 
225         return f;
226     }
227 
228     /**
229      * Writes the element in the FileWriter
230      * 
231      * @param el
232      *            element by write
233      * @param fw
234      *            filewriter wrote
235      * @throws java.io.IOException
236      */
237     public static void writeElement(Element el, FileWriter fw)
238             throws IOException, TransformerException {
239 
240         try {
241             TransformerFactory factory = TransformerFactory.newInstance();
242             Transformer transformer = factory.newTransformer();
243             DOMSource domSource = new DOMSource(el);
244             StreamResult streamResult = new StreamResult(fw);
245             transformer.transform(domSource, streamResult);
246         } finally {
247             if (fw != null) {
248                 fw.close();
249             }
250         }
251     }
252 
253     /**
254      * Utility method that registers the extensibility elements for WSDL4J.
255      * 
256      * @param registry
257      *            The ExtensionRegistry where the partner link extension is
258      *            registered.
259      */
260     public static void registerSchema(ExtensionRegistry registry) {
261         // schema
262         registry.mapExtensionTypes(javax.wsdl.Types.class, Q_ELEMENT_SCHEMA,
263                 SchemaImpl.class);
264 
265         registry.registerDeserializer(javax.wsdl.Types.class, Q_ELEMENT_SCHEMA,
266                 new SchemaDeserializer());
267 
268         registry.registerSerializer(javax.wsdl.Types.class, Q_ELEMENT_SCHEMA,
269                 new SchemaSerializer());
270     }
271 
272     /**
273      * Returns the Schemas tha contains wrapper elements in a Wrapped-style wsdl
274      * 
275      * @param serviceInfo
276      * @param wsdlDefinition
277      * @return
278      */
279     public static List<Schema> getSchemaWrapperList(
280             final ServiceInfo serviceInfo, final Definition wsdlDefinition) {
281 
282         List<QName> wrapperNames = new ArrayList<QName>();
283 
284         // Gets the wrapperQNames
285         for (OperationInfo opInfo : serviceInfo.getInterface().getOperations()) {
286 
287             if (opInfo.isUnwrappedCapable()) {
288                 MessagePartInfo inf = opInfo.getInput().getMessageParts()
289                         .get(0);
290                 if (inf.getTypeClass() != null) {
291                     // MessageInfo messageInfo =
292                     // opInfo.getUnwrappedOperation().getInput();
293                     wrapperNames.add(inf.getElementQName());
294                 }
295                 MessageInfo messageInfo = opInfo.getUnwrappedOperation()
296                         .getOutput();
297                 if (messageInfo != null) {
298                     inf = opInfo.getOutput().getMessageParts().get(0);
299                     if (inf.getTypeClass() != null) {
300                         wrapperNames.add(inf.getElementQName());
301                     }
302                 }
303             }
304         }
305 
306         // The wrapper schema list. Contains the schemas the includes at least a
307         // wrapper.
308         List<Schema> schemaWrappers = new ArrayList<Schema>();
309 
310         for (int i = 0; i < wsdlDefinition.getTypes()
311                 .getExtensibilityElements().size(); i++) {
312             Schema xmlschema = (Schema) wsdlDefinition.getTypes()
313                     .getExtensibilityElements().get(i);
314             boolean schemaIsWrapper = false;
315             for (int j = 0; j < wrapperNames.size() && !schemaIsWrapper; j++) {
316                 NodeList elements = xmlschema.getElement().getChildNodes();
317                 QName wrapperName = wrapperNames.get(j);
318                 String schemaTargetNameSpace = xmlschema.getElement()
319                         .getAttribute("targetNamespace");
320                 if ((elements != null) && (elements.getLength() != 0)) {
321                     for (int k = 0; k < elements.getLength(); k++) {
322                         Node element = elements.item(k); // 
323                         if ((element.getAttributes() != null)
324                                 && (element.getAttributes()
325                                         .getNamedItem("name") != null)) {
326                             String elementName = element.getAttributes()
327                                     .getNamedItem("name").getNodeValue();
328                             if ((elementName != null)
329                                     && (elementName.equals(wrapperName
330                                             .getLocalPart()))
331                                     && (schemaTargetNameSpace != null)
332                                     && (schemaTargetNameSpace
333                                             .equals(wrapperName
334                                                     .getNamespaceURI()))) {
335                                 // If one element match, the schema contains a
336                                 // wrapper
337                                 // We check if the schema has been already
338                                 // added, to avoid duplicates.
339                                 if (!schemaIsWrapper) {
340                                     schemaWrappers.add(xmlschema);
341                                     schemaIsWrapper = true;
342                                 }
343                             }
344                         }
345                     }
346                 }
347             }
348         }
349         return schemaWrappers;
350     }
351 
352     /**
353      *This method create a ws-addr schema in the target Folder
354      **/
355     public static void createW3CSchema(String path) throws IOException,
356             URISyntaxException {
357 
358         File ws = new File(path + File.separator + "ws-addr.xsd");
359        
360         URL schemaUrl =  SchemaUtil.class.getResource("/xsdSchema/ws-addr.xsd");
361 
362         // Copy the schema from resources
363         HelperFileUtil.copyFile(schemaUrl, ws);
364     }
365 
366 }