Package org.wso2.carbon.wsdl2code

Source Code of org.wso2.carbon.wsdl2code.WSDL2Code

/*
* Copyright (c) 2008, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* Licensed 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.wso2.carbon.wsdl2code;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMAttribute;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.axiom.om.xpath.AXIOMXPath;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.description.TransportInDescription;
import org.apache.axis2.engine.AxisConfiguration;
import org.apache.axis2.util.CommandLineOption;
import org.apache.axis2.util.CommandLineOptionConstants;
import org.apache.axis2.util.CommandLineOptionParser;
import org.apache.axis2.wsdl.codegen.CodeGenerationEngine;
import org.apache.axis2.wsdl.util.WSDL2JavaOptionsValidator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jaxen.JaxenException;
import org.jaxen.XPath;
import org.wso2.carbon.core.AbstractAdmin;
import org.wso2.carbon.core.transports.http.HttpTransportListener;
import org.wso2.carbon.utils.ArchiveManipulator;
import org.wso2.carbon.utils.FileManipulator;
import org.wso2.carbon.utils.NetworkUtils;
import org.wso2.carbon.utils.WSO2Constants;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
* Tool that generate code for the given options
*/
public class WSDL2Code extends AbstractAdmin {

    private static Log log = LogFactory.getLog(WSDL2Code.class);
    private static final String CODEGEN_POM_XSL = "org/wso2/carbon/wsdl2code/codegen-pom.xsl";

    /**
     * This method will generate the code based on the options array. Options arrya should be as
     * follows,
     * new String[] {"-uri", "location of wsdl", "-g" ...}. Thus, the incoming XML should be as
     * follows,
     * <p/>
     * <ns:codegenRequest xmlns:ns="http://org.wso2.wsf/tools">
     * <options>-uri</options>
     * <options>file://foo</options>
     * ...
     * </ns:codegenRequest>
     * <p/>
     * Once codegenerated, location of genereated code will be send as an ID, thus, one could easily
     * download artifact as a zip file or jar file.
     *
     * @param options
     * @return String
     * @throws AxisFault
     */
    public String codegen(String[] options) throws AxisFault {

        String uuid = String.valueOf(System.currentTimeMillis() + Math.random());
        ConfigurationContext configContext = getConfigContext();
        String codegenOutputDir =
                configContext
                        .getProperty(WSO2Constants.WORK_DIR) + File.separator + "tools_codegen" +
                File.separator + uuid + File.separator;
        System.getProperties().remove("project.base.dir");
        System.getProperties().remove("name");
        System.setProperty("project.base.dir", codegenOutputDir);

        ArrayList<String> optionsList = new ArrayList<String>();
        for (int j = 0; j < options.length; j++) {
            String option = options[j];
            optionsList.add(option);
        }
        optionsList.add("-o");
        optionsList.add(codegenOutputDir);
        String[] args = optionsList.toArray(new String[optionsList.size()]);
        Map allOptions;
        try {
            CommandLineOptionParser commandLineOptionParser = new CommandLineOptionParser(args);
            allOptions = commandLineOptionParser.getAllOptions();
            //validation
            List list = commandLineOptionParser.getInvalidOptions(new WSDL2JavaOptionsValidator());
            if (list.size() > 0) {
                String faultOptions = "";
                for (Iterator iterator = list.iterator(); iterator.hasNext();) {
                    CommandLineOption commandLineOption = (CommandLineOption) iterator.next();
                    String optionValue = commandLineOption.getOptionValue();
                    faultOptions += "Invalid input for [ " + commandLineOption.getOptionType() +
                                    (optionValue != null ? " : " + optionValue + " ]" : " ]") +
                                    "\n";
                }

                log.error(faultOptions);
                throw new AxisFault(faultOptions);
            }
            CommandLineOption commandLineOption = (CommandLineOption) allOptions.get("uri");
            if (commandLineOption == null) {
                throw new AxisFault("WSDL URI or Path Cannot be empty");
            }
            String uriValue = commandLineOption.getOptionValue().trim();
            if ("".equals(uriValue)) {
                throw new AxisFault("WSDL URI or Path Cannot be empty");
            } else if (!(uriValue.startsWith("https://") || uriValue.startsWith("http://"))) {
                File file = new File(uriValue);
                if (!(file.exists() && file.isFile())) {
                    throw new AxisFault("The wsdl uri should be a URL or a valid path on the file system");
                }
            }
            new CodeGenerationEngine(commandLineOptionParser).generate();
        } catch (Exception e) {
            String rootMsg = "Code generation failed";
            Throwable throwable = e.getCause();
            if (throwable != null) {
                String msg = throwable.getMessage();
                if (msg != null) {
                    log.error(rootMsg + " " + msg, throwable);
                    throw new AxisFault(throwable.toString());
                }
            }
            log.error(rootMsg, e);
            throw AxisFault.makeFault(e);
        }
        //set the output name
        CommandLineOption option =
                (CommandLineOption) allOptions.
                        get(CommandLineOptionConstants.WSDL2JavaConstants.SERVICE_NAME_OPTION);

        try {
            //achive destination
            uuid = String.valueOf(System.currentTimeMillis() + Math.random());
            File destDir = new File(configContext.getProperty(WSO2Constants.WORK_DIR) + File.separator + "tools_codegen" +
                                    File.separator +
                                    uuid);
            if (!destDir.exists()) {
                destDir.mkdirs();
            }
            String destFileName = uuid.substring(2) + ".zip";
            String destArchive = destDir.getAbsolutePath() + File.separator + destFileName;
            InputStream pomXslInputStream = getClass().getResourceAsStream(CODEGEN_POM_XSL);
            if (pomXslInputStream == null) {
                pomXslInputStream = Thread.currentThread().getContextClassLoader()
                        .getResourceAsStream(CODEGEN_POM_XSL);
            }

            String name = uuid;
            boolean isBuildXml = false;
            String version = "1.0";
            File buildXml = new File(codegenOutputDir, "build.xml");
            if (buildXml.exists() && buildXml.isFile()) {
                isBuildXml = true;
                InputStream buildInputStream = new FileInputStream(buildXml);
                XMLStreamReader streamReader =
                        XMLInputFactory.newInstance().createXMLStreamReader(buildInputStream);
                StAXOMBuilder builder = new StAXOMBuilder(streamReader);
                XPath xp = new AXIOMXPath("/project/property[@name='name']");
                OMElement documentElement = builder.getDocumentElement();
                OMElement nameEle = (OMElement) xp.selectSingleNode(documentElement);
                if (nameEle != null) {
                    OMAttribute omAttribute = nameEle.getAttribute(new QName("value"));
                    String nameVal = omAttribute.getAttributeValue();
                    if (nameVal != null) {
                        name = nameVal;
                    }
                }
            }
            OMFactory fac = OMAbstractFactory.getOMFactory();
            OMElement infoEle = fac.createOMElement(new QName("info"));
            OMElement nameEle = fac.createOMElement(new QName("name"));
            nameEle.setText(formatServiceName(name));
            infoEle.addChild(nameEle);
            OMElement isBuildXmlEle = fac.createOMElement(new QName("isBuildXml"));
            isBuildXmlEle.setText(Boolean.valueOf(isBuildXml).toString());
            infoEle.addChild(isBuildXmlEle);
            OMElement versionEle = fac.createOMElement(new QName("version"));
            versionEle.setText(version);
            infoEle.addChild(versionEle);
            ByteArrayOutputStream bao = new ByteArrayOutputStream();
            infoEle.serialize(bao);
            InputStream xmlInputStream = new ByteArrayInputStream(bao.toByteArray());

            if (pomXslInputStream != null) {
                File pomFileOut = new File(codegenOutputDir, "pom.xml");
                FileOutputStream pomFileOutputStream = new FileOutputStream(pomFileOut);
                Source xmlSource = new StreamSource(xmlInputStream);
                Source xslSource = new StreamSource(pomXslInputStream);
                Result result = new StreamResult(pomFileOutputStream);
                Transformer transformer =
                        TransformerFactory.newInstance().newTransformer(xslSource);
                transformer.transform(xmlSource, result);
            }

            new ArchiveManipulator().archiveDir(destArchive, new File(codegenOutputDir).getPath());
            FileManipulator.deleteDir(new File(codegenOutputDir));
            Map fileResourcesMap =
                    (Map) configContext.getProperty(WSO2Constants.FILE_RESOURCE_MAP);

            if (fileResourcesMap == null) {
                fileResourcesMap = new Hashtable();
                configContext.setProperty(WSO2Constants.FILE_RESOURCE_MAP, fileResourcesMap);
            }
            fileResourcesMap.put(destFileName, destArchive);
            return "../../filedownload?id=" + destFileName;

        } catch (IOException e) {
            String msg = WSDL2Code.class.getName() + " IOException has occured.";
            log.error(msg, e);
            throw new AxisFault(msg, e);
        } catch (XMLStreamException e) {
            String msg =
                    WSDL2Code.class.getName() + " error encountred while reading the build.xml";
            log.error(msg, e);
            throw new AxisFault(msg, e);
        } catch (JaxenException e) {
            String msg = WSDL2Code.class.getName() + " xpath error has occured";
            log.error(msg, e);
            throw new AxisFault(msg, e);
        } catch (TransformerConfigurationException e) {
            String msg = WSDL2Code.class.getName() + " transformation error has occured";
            log.error(msg, e);
            throw new AxisFault(msg, e);
        } catch (TransformerException e) {
            String msg = WSDL2Code.class.getName() + " transformation error has occured";
            log.error(msg, e);
            throw new AxisFault(msg, e);
        }
    }

    private String getWsdlInformation(String serviceName, AxisConfiguration axisConfig)
            throws AxisFault {
        String ip;
        try {
            ip = NetworkUtils.getLocalHostname();
        } catch (SocketException e) {
            throw new AxisFault("Cannot get local host name", e);
        }
        TransportInDescription http = axisConfig.getTransportIn("http");
        if (http != null) {
            EndpointReference epr =
                    ((HttpTransportListener) http.getReceiver()).
                            getEPRForService(serviceName, ip);
            String wsdlUrlPrefix = epr.getAddress();
            if (wsdlUrlPrefix.endsWith("/")) {
                wsdlUrlPrefix = wsdlUrlPrefix.substring(0, wsdlUrlPrefix.length() - 1);
            }
            return wsdlUrlPrefix + "?wsdl";
        }
        return null;
    }

    /**
     * When the service is a hierarchical service, the service name contains '/' charactors. But
     * if the artifact id of the generated pom.xml file contains '/' charactors, it will fail to
     * build. Therefore, we have to replace '/' with '-'.
     *
     * @param name - original service name
     * @return - formatted name
     */
    private String formatServiceName(String name) {
        String newName = name;
        if (newName.indexOf('/') != -1) {
            newName = newName.replace('/', '-');
        }
        return newName;
    }

}
TOP

Related Classes of org.wso2.carbon.wsdl2code.WSDL2Code

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.