/* * 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.tuscany.tools.wsdl2java.generate; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import javax.wsdl.Binding; import javax.wsdl.Definition; import javax.wsdl.Fault; import javax.wsdl.Message; import javax.wsdl.Operation; import javax.wsdl.Part; import javax.wsdl.Port; import javax.wsdl.PortType; import javax.wsdl.Service; import javax.wsdl.WSDLException; import javax.wsdl.factory.WSDLFactory; import javax.wsdl.xml.WSDLReader; import javax.xml.namespace.QName; import javax.xml.parsers.ParserConfigurationException; import org.apache.axis2.AxisFault; import org.apache.axis2.description.AxisService; import org.apache.axis2.description.WSDL11ToAxisServiceBuilder; import org.apache.axis2.util.FileWriter; import org.apache.axis2.util.XMLUtils; import org.apache.axis2.wsdl.codegen.CodeGenConfiguration; import org.apache.axis2.wsdl.codegen.CodeGenerationException; import org.apache.axis2.wsdl.codegen.extension.CodeGenExtension; import org.apache.axis2.wsdl.codegen.extension.DefaultDatabindingExtension; import org.apache.axis2.wsdl.codegen.extension.PackageFinder; import org.apache.axis2.wsdl.codegen.extension.WSDLValidatorExtension; import org.apache.axis2.wsdl.databinding.JavaTypeMapper; import org.w3c.dom.Document; import org.xml.sax.SAXException; import com.sun.tools.xjc.api.XJC; public class JavaInterfaceGenerator { private List codegenExtensions = new ArrayList(); private List codegenConfigurations= new LinkedList(); private String outputLocation; public JavaInterfaceGenerator(String uri, String ports[], String outputLocation, String packageName, Map typeMapping) throws CodeGenerationException { this.outputLocation = outputLocation; Definition definition; try { definition = readWSDL(uri); } catch (WSDLException e) { throw new CodeGenerationException(e); } HashSet interestedPorts = ports == null ? null : new HashSet(Arrays.asList(ports)); // Service service=(Service)definition.getServices().values().().next(); HashSet donePortTypes= new HashSet(); for (Iterator sIter = definition.getServices().values().iterator(); sIter.hasNext(); ) { Service service = (Service) sIter.next(); QName serviceQname = service.getQName(); for (Iterator pIter= service.getPorts().values().iterator(); pIter.hasNext(); ) { Port port= (Port) pIter.next(); if(interestedPorts != null && ! interestedPorts.contains(port.getName())) continue;//not iterested. PortType portType= getPortType(port); if(null == portType) continue; // not connected. QName pQName= portType.getQName(); if(donePortTypes.contains(pQName)) continue; //allready did it. donePortTypes.add(pQName); if (packageName == null) { //use JAXWS/JAXB NS->package default algorithm, not the SDO/EMF one packageName = XJC.getDefaultPackageName(definition.getTargetNamespace()); } // // Use WSDL4J object to generate exception classes // generateFaults(packageName, portType, typeMapping); JavaTypeMapper typeMapper = new JavaTypeMapper(); for (Map.Entry e : typeMapping.entrySet()) { typeMapper.addTypeMappingObject(e.getKey(), e.getValue()); // Added for generation of exceptions from faults typeMapper.addTypeMappingName(e.getKey(), e.getValue().getClassName()); } AxisService axisService; WSDL11ToAxisServiceBuilder builder; try { // // Added since at a newer level of Axis2, this doesn't work // without the setCodegen(true) // builder = new WSDL11ToAxisServiceBuilder(definition, serviceQname, port.getName()); builder.setCodegen(true); axisService = builder.populateService(); } catch (AxisFault e) { throw new CodeGenerationException(e); } axisService.setName(port.getBinding().getPortType().getQName().getLocalPart()); CodeGenConfiguration codegenConfiguration = new CodeGenConfiguration(Collections.EMPTY_MAP); codegenConfigurations.add(codegenConfiguration); codegenConfiguration.setAxisService(axisService); codegenConfiguration.setAdvancedCodeGenEnabled(false); codegenConfiguration.setAsyncOn(false); codegenConfiguration.setDatabindingType("sdo"); codegenConfiguration.setGenerateAll(true); codegenConfiguration.setGenerateDeployementDescriptor(false); codegenConfiguration.setOutputLanguage("java"); codegenConfiguration.setOutputLocation(new File(outputLocation)); codegenConfiguration.setPackageName(packageName); codegenConfiguration.setPackClasses(false); codegenConfiguration.setPolicyMap(Collections.EMPTY_MAP); codegenConfiguration.setPortName(port.getName()); codegenConfiguration.setServerSide(false); codegenConfiguration.setServiceName(service.getQName().getLocalPart()); // This lines up with the sync/async variable from the XSL template codegenConfiguration.setSyncOn(true); codegenConfiguration.setTypeMapper(typeMapper); // JIRA TUSCANY-1561 Port to Axis2 1.3 // codegenConfiguration.setWriteMessageReceiver(false); codegenConfiguration.setSkipMessageReceiver(true); codegenConfiguration.setWriteTestCase(false); addExtension(new WSDLValidatorExtension(), codegenConfiguration); addExtension(new PackageFinder(), codegenConfiguration); addExtension(new SDODataBindingCodegenExtension(typeMapper), codegenConfiguration); addExtension(new DefaultDatabindingExtension(), codegenConfiguration); } } } private PortType getPortType(Port port) { Binding binding = port.getBinding(); if(null != binding){ return binding.getPortType(); } return null; } @SuppressWarnings("unchecked") private void addExtension(CodeGenExtension ext, CodeGenConfiguration codegenConfiguration) { //ext.init(codegenConfiguration); codegenExtensions.add(new Object[]{ext, codegenConfiguration}); } public void generate() throws CodeGenerationException { try { for (int i = 0; i < codegenExtensions.size(); i++) { // CodeGenExtension Object[] pair = (Object[])codegenExtensions.get(i); CodeGenExtension cge = (CodeGenExtension)pair[0]; CodeGenConfiguration cgf = (CodeGenConfiguration)pair[1]; cge.engage(cgf); } for (CodeGenConfiguration codegenConfiguration : codegenConfigurations) { JavaInterfaceEmitter emitter = new JavaInterfaceEmitter(); emitter.setCodeGenConfiguration(codegenConfiguration); emitter.setMapper(codegenConfiguration.getTypeMapper()); emitter.writeInterface(false); } } catch (Exception e) { throw new CodeGenerationException(e); } } /** * Read the WSDL file * * @param uri * @return * @throws WSDLException */ private Definition readWSDL(String uri) throws WSDLException { WSDLReader reader = WSDLFactory.newInstance().newWSDLReader(); reader.setFeature("javax.wsdl.importDocuments", true); File file = new File(uri); String baseURI; if (uri.startsWith("http://")) { baseURI = uri; } else { if (file.getParentFile() == null) { try { baseURI = new File(".").getCanonicalFile().toURI().toString(); } catch (IOException e) { throw new RuntimeException(e); } } else { baseURI = file.getParentFile().toURI().toString(); } } Document doc; try { doc = XMLUtils.newDocument(uri); } catch (ParserConfigurationException e) { throw new WSDLException(WSDLException.PARSER_ERROR, "Parser Configuration Error", e); } catch (SAXException e) { throw new WSDLException(WSDLException.PARSER_ERROR, "Parser SAX Error", e); } catch (IOException e) { throw new WSDLException(WSDLException.INVALID_WSDL, "IO Error", e); } return reader.readWSDL(baseURI, doc); } private void generateFaults(String packageName, PortType portType, Map typeMapping) throws CodeGenerationException{ for (Object o: portType.getOperations()) { Operation op = (Operation)o; Map messageMap = op.getFaults(); Iterator iter = messageMap.values().iterator(); while (iter.hasNext()) { Fault fault = (Fault)iter.next(); Message faultMsg = fault.getMessage(); Iterator iter2 = faultMsg.getParts().values().iterator(); Part faultMsgPart = (Part)iter2.next(); // TODO - if other parts throw exc QName faultMsgQName = faultMsg.getQName(); QName faultMsgPartElementQName = faultMsgPart.getElementName(); String faultClassName = typeMapping.get(faultMsgPartElementQName).getClassName(); writeException(packageName, faultMsgQName, faultClassName, faultMsgPartElementQName); } } } private void writeException(String packageName, QName faultMsgQName, String faultClassName, QName faultMsgPartElementQName) throws CodeGenerationException{ try { String faultWrapperClassName = WSDL2JavaGenerator.normalizeClassName(faultMsgQName.getLocalPart()); File outputDir = new File(this.outputLocation); if (!outputDir.exists()) { outputDir.mkdirs(); } File outputFile = FileWriter.createClassFile(outputDir, packageName, faultWrapperClassName, ".java"); FileOutputStream fileStream = new FileOutputStream(outputFile); PrintStream stream = new PrintStream(fileStream); System.out.println(">> Generating Java exception class " + packageName + "." + faultWrapperClassName); stream.println(); stream.println("package " + packageName + ";"); stream.println(); stream.println("import javax.xml.ws.WebFault;"); stream.println(); stream.println("@WebFault(name=\"" + faultMsgPartElementQName.getLocalPart() + "\", targetNamespace=\"" + faultMsgPartElementQName.getNamespaceURI() + "\")"); stream.println("public class " + faultWrapperClassName + " extends Exception {"); stream.println(); stream.println(" private " + faultClassName + " fault;"); stream.println(); stream.println(" public " + faultWrapperClassName + "(String message, " + faultClassName + " fault) {"); stream.println(" super(message);"); stream.println(" this.fault = fault;"); stream.println(" }"); stream.println(); stream.println(" public " + faultWrapperClassName + "(String message, " + faultClassName + " fault, Throwable cause) {"); stream.println(" super(message, cause);"); stream.println(" this.fault = fault;"); stream.println(" }"); stream.println(); stream.println(" public " + faultClassName + " getFaultInfo() {"); stream.println(" return this.fault;"); stream.println(" }"); stream.println("}"); stream.println(); } catch (Exception e) { throw new CodeGenerationException(e); } } }