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: */package org.apache.openejb.server.axis2;
019:
020: import org.apache.axis2.description.AxisService;
021: import org.apache.openejb.util.Logger;
022: import org.apache.openejb.util.LogCategory;
023: import org.w3c.dom.Element;
024: import org.w3c.dom.Node;
025: import org.w3c.dom.NodeList;
026:
027: import javax.wsdl.Definition;
028: import javax.wsdl.Import;
029: import javax.wsdl.Port;
030: import javax.wsdl.Service;
031: import javax.wsdl.Types;
032: import javax.wsdl.extensions.ExtensibilityElement;
033: import javax.wsdl.extensions.schema.Schema;
034: import javax.wsdl.extensions.schema.SchemaImport;
035: import javax.wsdl.extensions.schema.SchemaReference;
036: import javax.wsdl.extensions.soap.SOAPAddress;
037: import javax.wsdl.extensions.soap12.SOAP12Address;
038: import javax.wsdl.factory.WSDLFactory;
039: import javax.wsdl.xml.WSDLReader;
040: import javax.wsdl.xml.WSDLWriter;
041: import javax.xml.namespace.QName;
042: import javax.xml.transform.OutputKeys;
043: import javax.xml.transform.Source;
044: import javax.xml.transform.Transformer;
045: import javax.xml.transform.TransformerException;
046: import javax.xml.transform.TransformerFactory;
047: import javax.xml.transform.dom.DOMSource;
048: import javax.xml.transform.stream.StreamResult;
049: import java.io.OutputStream;
050: import java.net.MalformedURLException;
051: import java.net.URISyntaxException;
052: import java.net.URL;
053: import java.util.ArrayList;
054: import java.util.Collection;
055: import java.util.Iterator;
056: import java.util.List;
057: import java.util.Map;
058: import java.util.concurrent.ConcurrentHashMap;
059:
060: public class WsdlQueryHandler {
061: private static final Logger logger = Logger.getInstance(
062: LogCategory.AXIS2, WsdlQueryHandler.class);
063:
064: private Map<String, Definition> mp = new ConcurrentHashMap<String, Definition>();
065: private Map<String, SchemaReference> smp = new ConcurrentHashMap<String, SchemaReference>();
066: private AxisService service;
067:
068: public WsdlQueryHandler(AxisService service) {
069: this .service = service;
070: }
071:
072: public void writeResponse(String baseUri, String wsdlUri,
073: OutputStream os) throws Exception {
074: int idx = baseUri.toLowerCase().indexOf("?wsdl");
075: String base = null;
076: String wsdl = "";
077: String xsd = null;
078: if (idx != -1) {
079: base = baseUri.substring(0, baseUri.toLowerCase().indexOf(
080: "?wsdl"));
081: wsdl = baseUri.substring(baseUri.toLowerCase().indexOf(
082: "?wsdl") + 5);
083: if (wsdl.length() > 0) {
084: wsdl = wsdl.substring(1);
085: }
086: } else {
087: base = baseUri.substring(0, baseUri.toLowerCase().indexOf(
088: "?xsd="));
089: xsd = baseUri.substring(baseUri.toLowerCase().indexOf(
090: "?xsd=") + 5);
091: }
092:
093: if (!mp.containsKey(wsdl)) {
094: WSDLFactory factory = WSDLFactory.newInstance();
095: WSDLReader reader = factory.newWSDLReader();
096: reader.setFeature("javax.wsdl.importDocuments", true);
097: reader.setFeature("javax.wsdl.verbose", false);
098: Definition def = reader.readWSDL(wsdlUri);
099: updateDefinition(def, mp, smp, base);
100: updateServices(this .service.getName(), this .service
101: .getEndpointName(), def, base);
102: mp.put("", def);
103: }
104:
105: Element rootElement;
106:
107: if (xsd == null) {
108: Definition def = mp.get(wsdl);
109:
110: WSDLFactory factory = WSDLFactory.newInstance();
111: WSDLWriter writer = factory.newWSDLWriter();
112:
113: rootElement = writer.getDocument(def).getDocumentElement();
114: } else {
115: SchemaReference si = smp.get(xsd);
116: rootElement = si.getReferencedSchema().getElement();
117: }
118:
119: NodeList nl = rootElement.getElementsByTagNameNS(
120: "http://www.w3.org/2001/XMLSchema", "import");
121: for (int x = 0; x < nl.getLength(); x++) {
122: Element el = (Element) nl.item(x);
123: String sl = el.getAttribute("schemaLocation");
124: if (smp.containsKey(sl)) {
125: el.setAttribute("schemaLocation", base + "?xsd=" + sl);
126: }
127: }
128: nl = rootElement.getElementsByTagNameNS(
129: "http://www.w3.org/2001/XMLSchema", "include");
130: for (int x = 0; x < nl.getLength(); x++) {
131: Element el = (Element) nl.item(x);
132: String sl = el.getAttribute("schemaLocation");
133: if (smp.containsKey(sl)) {
134: el.setAttribute("schemaLocation", base + "?xsd=" + sl);
135: }
136: }
137: nl = rootElement.getElementsByTagNameNS(
138: "http://schemas.xmlsoap.org/wsdl/", "import");
139: for (int x = 0; x < nl.getLength(); x++) {
140: Element el = (Element) nl.item(x);
141: String sl = el.getAttribute("location");
142: if (mp.containsKey(sl)) {
143: el.setAttribute("location", base + "?wsdl=" + sl);
144: }
145: }
146:
147: writeTo(rootElement, os);
148: }
149:
150: protected void updateDefinition(Definition def,
151: Map<String, Definition> done,
152: Map<String, SchemaReference> doneSchemas, String base) {
153: Collection<List> imports = def.getImports().values();
154: for (List lst : imports) {
155: List<Import> impLst = lst;
156: for (Import imp : impLst) {
157: String start = imp.getLocationURI();
158: try {
159: //check to see if it's aleady in a URL format. If so, leave it.
160: new URL(start);
161: } catch (MalformedURLException e) {
162: done.put(start, imp.getDefinition());
163: updateDefinition(imp.getDefinition(), done,
164: doneSchemas, base);
165: }
166: }
167: }
168:
169: /* This doesn't actually work. Setting setSchemaLocationURI on the import
170: * for some reason doesn't actually result in the new URI being written
171: * */
172: Types types = def.getTypes();
173: if (types != null) {
174: for (ExtensibilityElement el : (List<ExtensibilityElement>) types
175: .getExtensibilityElements()) {
176: if (el instanceof Schema) {
177: Schema see = (Schema) el;
178: updateSchemaImports(see, doneSchemas, base);
179: }
180: }
181: }
182: }
183:
184: protected void updateSchemaImports(Schema schema,
185: Map<String, SchemaReference> doneSchemas, String base) {
186: Collection<List> imports = schema.getImports().values();
187: for (List lst : imports) {
188: List<SchemaImport> impLst = lst;
189: for (SchemaImport imp : impLst) {
190: String start = imp.getSchemaLocationURI();
191: if (start != null) {
192: try {
193: //check to see if it's aleady in a URL format. If so, leave it.
194: new URL(start);
195: } catch (MalformedURLException e) {
196: if (!doneSchemas.containsKey(start)) {
197: doneSchemas.put(start, imp);
198: updateSchemaImports(imp
199: .getReferencedSchema(),
200: doneSchemas, base);
201: }
202: }
203: }
204: }
205: }
206: List<SchemaReference> includes = schema.getIncludes();
207: for (SchemaReference included : includes) {
208: String start = included.getSchemaLocationURI();
209: if (start != null) {
210: try {
211: //check to see if it's aleady in a URL format. If so, leave it.
212: new URL(start);
213: } catch (MalformedURLException e) {
214: if (!doneSchemas.containsKey(start)) {
215: doneSchemas.put(start, included);
216: updateSchemaImports(included
217: .getReferencedSchema(), doneSchemas,
218: base);
219: }
220: }
221: }
222: }
223: }
224:
225: public static void writeTo(Node node, OutputStream os) {
226: writeTo(new DOMSource(node), os);
227: }
228:
229: public static void writeTo(Source src, OutputStream os) {
230: Transformer it;
231: try {
232: it = TransformerFactory.newInstance().newTransformer();
233: it.setOutputProperty(OutputKeys.METHOD, "xml");
234: it.setOutputProperty(OutputKeys.INDENT, "yes");
235: it.setOutputProperty(
236: "{http://xml.apache.org/xslt}indent-amount", "4");
237: it.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,
238: "false");
239: it.setOutputProperty(OutputKeys.ENCODING, "utf-8");
240: it.transform(src, new StreamResult(os));
241: } catch (TransformerException e) {
242: // TODO Auto-generated catch block
243: e.printStackTrace();
244: }
245: }
246:
247: private void updateServices(String serviceName, String portName,
248: Definition def, String baseUri) throws Exception {
249: boolean updated = false;
250: Map services = def.getServices();
251: if (services != null) {
252: ArrayList<QName> servicesToRemove = new ArrayList<QName>();
253:
254: Iterator serviceIterator = services.entrySet().iterator();
255: while (serviceIterator.hasNext()) {
256: Map.Entry serviceEntry = (Map.Entry) serviceIterator
257: .next();
258: QName currServiceName = (QName) serviceEntry.getKey();
259: if (currServiceName.getLocalPart().equals(serviceName)) {
260: Service service = (Service) serviceEntry.getValue();
261: updatePorts(portName, service, baseUri);
262: updated = true;
263: } else {
264: servicesToRemove.add(currServiceName);
265: }
266: }
267:
268: for (QName serviceToRemove : servicesToRemove) {
269: def.removeService(serviceToRemove);
270: }
271: }
272: if (!updated) {
273: logger.warning("WSDL '" + serviceName
274: + "' service not found.");
275: }
276: }
277:
278: private void updatePorts(String portName, Service service,
279: String baseUri) throws Exception {
280: boolean updated = false;
281: Map ports = service.getPorts();
282: if (ports != null) {
283: ArrayList<String> portsToRemove = new ArrayList<String>();
284:
285: Iterator portIterator = ports.entrySet().iterator();
286: while (portIterator.hasNext()) {
287: Map.Entry portEntry = (Map.Entry) portIterator.next();
288: String currPortName = (String) portEntry.getKey();
289: if (currPortName.equals(portName)) {
290: Port port = (Port) portEntry.getValue();
291: updatePortLocation(port, baseUri);
292: updated = true;
293: } else {
294: portsToRemove.add(currPortName);
295: }
296: }
297:
298: for (String portToRemove : portsToRemove) {
299: service.removePort(portToRemove);
300: }
301: }
302: if (!updated) {
303: logger.warning("WSDL '" + portName + "' port not found.");
304: }
305: }
306:
307: private void updatePortLocation(Port port, String baseUri)
308: throws URISyntaxException {
309: List<?> exts = port.getExtensibilityElements();
310: if (exts != null && exts.size() > 0) {
311: ExtensibilityElement el = (ExtensibilityElement) exts
312: .get(0);
313: if (el instanceof SOAP12Address) {
314: SOAP12Address add = (SOAP12Address) el;
315: add.setLocationURI(baseUri);
316: } else if (el instanceof SOAPAddress) {
317: SOAPAddress add = (SOAPAddress) el;
318: add.setLocationURI(baseUri);
319: }
320: }
321: }
322: }
|