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: */
019:
020: package org.apache.axis2.jaxws.wsdl.impl;
021:
022: import org.apache.axis2.jaxws.i18n.Messages;
023: import org.apache.axis2.jaxws.util.WSDLWrapper;
024: import org.apache.axis2.jaxws.utility.JavaUtils;
025: import org.apache.axis2.jaxws.wsdl.SchemaReader;
026: import org.apache.axis2.jaxws.wsdl.SchemaReaderException;
027: import org.apache.commons.logging.Log;
028: import org.apache.commons.logging.LogFactory;
029: import org.w3c.dom.NamedNodeMap;
030: import org.w3c.dom.Node;
031: import org.w3c.dom.NodeList;
032:
033: import javax.wsdl.Definition;
034: import javax.wsdl.Types;
035: import javax.wsdl.extensions.ExtensibilityElement;
036: import javax.wsdl.extensions.schema.Schema;
037: import javax.wsdl.extensions.schema.SchemaImport;
038: import java.util.ArrayList;
039: import java.util.Collection;
040: import java.util.Iterator;
041: import java.util.List;
042: import java.util.Map;
043: import java.util.Set;
044: import java.util.TreeSet;
045: import java.util.Vector;
046:
047: public class SchemaReaderImpl implements SchemaReader {
048:
049: private static String JAXB_SCHEMA_BINDING = "schemaBindings";
050: private static String JAXB_SCHEMA_BINDING_PACKAGE = "package";
051: private static String JAXB_SCHEMA_Binding_PACKAGENAME = "name";
052: private static String SCHEMA_TARGETNAMESPACE = "targetNamespace";
053: private Definition wsdlDefinition = null;
054: private static Log log = LogFactory.getLog(SchemaReaderImpl.class);
055:
056: /* (non-Javadoc)
057: * @see org.apache.axis2.jaxws.wsdl.SchemaReader#readPackagesFromSchema(javax.wsdl.Definition)
058: */
059: public Set<String> readPackagesFromSchema(Definition wsdlDefinition)
060: throws SchemaReaderException {
061: if (wsdlDefinition == null) {
062: if (log.isDebugEnabled()) {
063: log.debug("Invalid wsdl definition provided, NULL");
064: }
065: throw new SchemaReaderException(Messages
066: .getMessage("SchemaReaderErr1"));
067: }
068: this .wsdlDefinition = wsdlDefinition;
069: List<Schema> schemaList = new ArrayList<Schema>();
070: Set<String> packageList = new TreeSet<String>();
071: //Add WSDL TargetNamespace
072: String namespace = wsdlDefinition.getTargetNamespace();
073: String packageString = JavaUtils
074: .getPackageFromNamespace(namespace);
075: packageList.add(packageString);
076:
077: //Read All Schema Definition in wsdl;
078: Types types = wsdlDefinition.getTypes();
079: if (types == null) {
080: if (log.isDebugEnabled()) {
081: log
082: .debug("WARNING: Could not find any Scheam/Types from WSDL");
083: log.debug("no packages will derived from WSDL schema");
084: }
085: return packageList;
086: }
087: List extensibilityElements = types.getExtensibilityElements();
088: for (Object obj : extensibilityElements) {
089: if (obj != null && isSchema((ExtensibilityElement) obj)) {
090: Schema schema = (Schema) obj;
091: //process schemas and read packages from them.
092: processSchema(schema, schemaList, packageList);
093: }
094: }
095:
096: //Set always stores unique objects, so I dont have to worry about removing duplicates from this set.
097: return packageList;
098: }
099:
100: private void processSchema(Schema schema, List<Schema> schemaList,
101: Set<String> packageList) throws SchemaReaderException {
102: if (schemaList.contains(schema)) {
103: return;
104: }
105: List<SchemaImport> importList = new ArrayList<SchemaImport>();
106: //Start reading inline schema
107: //Check if there is Binding customization and read package from it.
108: String packageString = readSchemaBindingPackageName(schema);
109: //No binding customization present then get the Targetnamespace of Schema
110: if (packageString == null) {
111: //no Schema Binding package name found, this means no jaxb customizations in schema, lets read wsdl
112: //targetnamespace. Thats what will be used by RI tooling to store java Beans
113: String namespace = readSchemaTargetnamespace(schema);
114: if (namespace != null) {
115: packageString = JavaUtils
116: .getPackageFromNamespace(namespace);
117: }
118: }
119: //Gather all imports and process Schema from these imports
120: Map map = schema.getImports();
121: Collection collection = map.values();
122: for (Iterator i = collection.iterator(); i.hasNext();) {
123: Vector value = (Vector) i.next();
124: for (Object vectorObj : value) {
125: SchemaImport si = (SchemaImport) vectorObj;
126: importList.add(si);
127: if (log.isDebugEnabled()) {
128: if (si != null)
129: log.debug("Reading import for SchemaLocation ="
130: + si.getSchemaLocationURI());
131: }
132: }
133: }
134:
135: //Get namespace and flag the schema as read
136: schemaList.add(schema);
137: //Package String could be null if there is no schema defintion inside types
138: if (packageString != null) {
139: packageList.add(packageString);
140: }
141: for (SchemaImport si : importList) {
142: processImport(si, schemaList, packageList);
143: }
144:
145: }
146:
147: private void processImport(SchemaImport si,
148: List<Schema> schemaList, Set<String> packageList)
149: throws SchemaReaderException {
150: Schema refSchema = si.getReferencedSchema();
151: if (refSchema != null) {
152: processSchema(refSchema, schemaList, packageList);
153: }
154: }
155:
156: private String readSchemaTargetnamespace(Schema schema) {
157: Node root = schema.getElement();
158: if (root != null) {
159: NamedNodeMap nodeMap = root.getAttributes();
160: Node attributeNode = nodeMap
161: .getNamedItem(SCHEMA_TARGETNAMESPACE);
162: if (attributeNode != null) {
163: return attributeNode.getNodeValue();
164: }
165: }
166: return null;
167: }
168:
169: private String readSchemaBindingPackageName(Schema schema) {
170:
171: /* JAXB Specification section 7.6 have following important points
172: * 1) <schemaBindings> binding declaration have schema scope
173: * 2) For inline annotation a <schemaBindings> is valid only in the annotation element of the <schema> element.
174: * 3) There must only be a single instance of <schemaBindings> declaration in the annotation element of the <schema> element.
175: */
176:
177: //Get root node for schema.
178: Node root = schema.getElement();
179: if (root.hasChildNodes()) {
180:
181: //get all child nodes for schema
182: NodeList list = root.getChildNodes();
183:
184: //search for JAXB schemaBinding customization in schema element definitions.
185: for (int i = 0; i < list.getLength(); i++) {
186: Node childNode = list.item(i);
187: if (isElementName(JAXB_SCHEMA_BINDING, childNode)) {
188:
189: //SchemaBinding has been defined, so lets look for package element.
190: NodeList schemaBindingNodeList = childNode
191: .getChildNodes();
192: for (int j = 0; j < schemaBindingNodeList
193: .getLength(); j++) {
194: Node schemaBindingNode = schemaBindingNodeList
195: .item(j);
196: if (isElementName(JAXB_SCHEMA_BINDING_PACKAGE,
197: schemaBindingNode)) {
198:
199: //Package Element found, so lets read the package name attribute and return that.
200: NamedNodeMap nodeMap = schemaBindingNode
201: .getAttributes();
202: Node attributeNode = nodeMap
203: .getNamedItem(JAXB_SCHEMA_Binding_PACKAGENAME);
204: return attributeNode.getNodeValue();
205: }
206: }
207: }
208: }
209: }
210: return null;
211: }
212:
213: private boolean isElementName(String name, Node domNode) {
214: if (domNode == null) {
215: return false;
216: }
217: if (domNode.getNodeType() == Node.ELEMENT_NODE) {
218: String localName = domNode.getLocalName();
219: return localName != null && localName.equals(name);
220: }
221: return false;
222: }
223:
224: private boolean isSchema(ExtensibilityElement exElement) {
225: return WSDLWrapper.SCHEMA.equals(exElement.getElementType());
226: }
227:
228: }
|