| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.apache.axis2.wsdl.codegen.writer; |
| |
| import org.apache.axis2.description.AxisService; |
| import org.apache.axis2.util.FileWriter; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.NamedNodeMap; |
| import org.w3c.dom.Node; |
| import org.w3c.dom.NodeList; |
| |
| import javax.wsdl.Definition; |
| import javax.wsdl.Import; |
| import javax.wsdl.Service; |
| import javax.wsdl.Types; |
| import javax.wsdl.extensions.schema.Schema; |
| import javax.wsdl.factory.WSDLFactory; |
| import javax.wsdl.xml.WSDLWriter; |
| import java.io.File; |
| import java.io.FileOutputStream; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Vector; |
| |
| public class WSDL11Writer { |
| |
| public static final String IMPORT_TAG = "import"; |
| public static final String INCLUDE_TAG = "include"; |
| public static final String SCHEMA_LOCATION = "schemaLocation"; |
| |
| private File baseFolder = null; |
| private int count; |
| |
| |
| public WSDL11Writer(File baseFolder) { |
| this.baseFolder = baseFolder; |
| this.count = 0; |
| } |
| |
| public void writeWSDL(AxisService axisService) { |
| try { |
| if (axisService != null) { |
| //create a output file |
| File outputFile = FileWriter.createClassFile(baseFolder, |
| null, |
| axisService.getName(), |
| ".wsdl"); |
| FileOutputStream fos = new FileOutputStream(outputFile); |
| axisService.printWSDL(fos); |
| fos.flush(); |
| fos.close(); |
| } |
| } catch (Exception e) { |
| throw new RuntimeException("WSDL writing failed!", e); |
| } |
| } |
| |
| public void writeWSDL(AxisService axisService, Definition definition, Map changedMap) { |
| try { |
| if (axisService != null) { |
| Map baseURIwsdlNameMap = new HashMap(); |
| // add the initial definition to the map |
| baseURIwsdlNameMap.put(definition.getDocumentBaseURI(),axisService.getName() + ".wsdl"); |
| writeWSDL(definition, axisService.getName() + ".wsdl", changedMap, baseURIwsdlNameMap); |
| } |
| } catch (Exception e) { |
| throw new RuntimeException("WSDL writing failed!", e); |
| } |
| } |
| |
| private void writeWSDL(Definition definition, |
| String fileName, |
| Map changedMap, |
| Map baseURIwsdlNameMap) throws Exception { |
| // first process the imports and save them. |
| Map imports = definition.getImports(); |
| if (imports != null && (imports.size() > 0)) { |
| Vector importsVector = null; |
| Import wsdlImport = null; |
| String wsdlName = null; |
| String wsdlLocation = null; |
| for (Iterator improtsVectorIter = imports.values().iterator(); |
| improtsVectorIter.hasNext();) { |
| importsVector = (Vector)improtsVectorIter.next(); |
| for (Iterator importsIter = importsVector.iterator(); importsIter.hasNext();) { |
| wsdlImport = (Import)importsIter.next(); |
| wsdlLocation = wsdlImport.getDefinition().getDocumentBaseURI(); |
| // we have to process this wsdl file only if it has not been processed earlier |
| if (!baseURIwsdlNameMap.containsKey(wsdlLocation)) { |
| wsdlName = wsdlLocation.substring(wsdlLocation.lastIndexOf('/') + 1); |
| if (!wsdlName.endsWith(".wsdl") && !wsdlName.endsWith(".xsd")){ |
| // this seems to be an online wsdl so we generate a dummy name |
| if (wsdlName.indexOf("xsd") > -1){ |
| wsdlName = "xsd" + count++ + ".xsd"; |
| } else { |
| wsdlName = "wsdl" + count++ + ".wsdl"; |
| } |
| } |
| |
| //trim the wsdl part |
| while (baseURIwsdlNameMap.containsValue(wsdlName)) { |
| // import file name can either be xsd or wsdl |
| String fileNamePart = wsdlName.substring(0,wsdlName.lastIndexOf(".")); |
| String extension = wsdlName.substring(wsdlName.lastIndexOf(".")); |
| wsdlName = fileNamePart + count++ + extension; |
| } |
| baseURIwsdlNameMap.put(wsdlLocation, wsdlName); |
| Definition innerDefinition = wsdlImport.getDefinition(); |
| writeWSDL(innerDefinition, wsdlName, changedMap, baseURIwsdlNameMap); |
| } |
| |
| wsdlImport.setLocationURI((String)baseURIwsdlNameMap.get(wsdlLocation)); |
| } |
| } |
| } |
| // change the locations on the imported schemas |
| adjustWSDLSchemaLocations(definition, changedMap); |
| // finally save the file |
| WSDLWriter wsdlWriter = WSDLFactory.newInstance().newWSDLWriter(); |
| File outputFile = FileWriter.createClassFile(baseFolder, |
| null, fileName, null); |
| FileOutputStream out = new FileOutputStream(outputFile); |
| |
| // we have a catch here |
| // if there are multimple services in the definition object |
| // we have to write only the relavent service. |
| |
| |
| if (definition.getServices().size() > 1){ |
| List removedServices = new ArrayList(); |
| List servicesList = new ArrayList(); |
| |
| Map services = definition.getServices(); |
| // populate the services list |
| for (Iterator iter = services.values().iterator();iter.hasNext();){ |
| servicesList.add(iter.next()); |
| } |
| Service service; |
| String serviceNameFromFileName = fileName; |
| if (fileName.indexOf(".wsdl") > -1){ |
| serviceNameFromFileName = fileName.substring(0,fileName.lastIndexOf(".wsdl")); |
| } |
| |
| if (fileName.indexOf(".xsd") > -1){ |
| serviceNameFromFileName = fileName.substring(0,fileName.lastIndexOf(".xsd")); |
| } |
| for (Iterator iter = servicesList.iterator();iter.hasNext();){ |
| service = (Service) iter.next(); |
| if (!service.getQName().getLocalPart().equals(serviceNameFromFileName)){ |
| definition.removeService(service.getQName()); |
| removedServices.add(service); |
| } |
| } |
| |
| //now we have only the required service so write it |
| wsdlWriter.writeWSDL(definition, out); |
| |
| // again add the removed services |
| for (Iterator iter = removedServices.iterator(); iter.hasNext();){ |
| service = (Service) iter.next(); |
| definition.addService(service); |
| } |
| } else { |
| // no problem proceed normaly |
| wsdlWriter.writeWSDL(definition, out); |
| } |
| out.flush(); |
| out.close(); |
| } |
| |
| /** |
| * @deprecated please use adjustWSDLSchemaLocations |
| * @param definition |
| * @param changedSchemaLocations |
| */ |
| public void adjustWSDLSchemaLocatins(Definition definition, Map changedSchemaLocations) { |
| adjustWSDLSchemaLocations(definition, changedSchemaLocations); |
| } |
| |
| /** |
| * adjust the schema locations in the original wsdl |
| * |
| * @param definition |
| * @param changedSchemaLocations |
| */ |
| public void adjustWSDLSchemaLocations(Definition definition, Map changedSchemaLocations) { |
| Types wsdlTypes = definition.getTypes(); |
| if (wsdlTypes != null) { |
| List extensibilityElements = wsdlTypes.getExtensibilityElements(); |
| Object currentObject; |
| Schema schema; |
| for (Iterator iter = extensibilityElements.iterator(); iter.hasNext();) { |
| currentObject = iter.next(); |
| if (currentObject instanceof Schema) { |
| schema = (Schema)currentObject; |
| changeLocations(schema.getElement(), changedSchemaLocations); |
| } |
| } |
| } |
| } |
| |
| private void changeLocations(Element element, Map changedSchemaLocations) { |
| NodeList nodeList = element.getChildNodes(); |
| String tagName; |
| for (int i = 0; i < nodeList.getLength(); i++) { |
| tagName = nodeList.item(i).getLocalName(); |
| if (IMPORT_TAG.equals(tagName) || INCLUDE_TAG.equals(tagName)) { |
| processImport(nodeList.item(i), changedSchemaLocations); |
| } |
| } |
| } |
| |
| private void processImport(Node importNode, Map changedSchemaLocations) { |
| NamedNodeMap nodeMap = importNode.getAttributes(); |
| Node attribute; |
| String attributeValue; |
| for (int i = 0; i < nodeMap.getLength(); i++) { |
| attribute = nodeMap.item(i); |
| if (attribute.getNodeName().equals("schemaLocation")) { |
| attributeValue = attribute.getNodeValue(); |
| if (changedSchemaLocations.get(attributeValue) != null) { |
| attribute.setNodeValue( |
| (String)changedSchemaLocations.get(attributeValue)); |
| } |
| } |
| } |
| } |
| |
| |
| } |