blob: 425ea40f9e521452139878bb41c8298020510968 [file] [log] [blame]
/*
* 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));
}
}
}
}
}