001    /**
002     * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.util.ant;
016    
017    import com.liferay.portal.kernel.util.FileUtil;
018    import com.liferay.portal.kernel.util.HtmlUtil;
019    import com.liferay.portal.kernel.util.StringBundler;
020    import com.liferay.portal.kernel.util.StringUtil;
021    import com.liferay.portal.kernel.util.Time;
022    import com.liferay.portal.kernel.xml.Attribute;
023    import com.liferay.portal.kernel.xml.Document;
024    import com.liferay.portal.kernel.xml.Element;
025    import com.liferay.portal.kernel.xml.SAXReaderUtil;
026    
027    import java.io.File;
028    
029    import java.util.Arrays;
030    import java.util.Map;
031    import java.util.TreeMap;
032    
033    import org.apache.axis.tools.ant.wsdl.Java2WsdlAntTask;
034    import org.apache.axis.tools.ant.wsdl.NamespaceMapping;
035    import org.apache.axis.tools.ant.wsdl.Wsdl2javaAntTask;
036    import org.apache.tools.ant.Project;
037    
038    /**
039     * @author Brian Wing Shun Chan
040     */
041    public class Java2WsddTask {
042    
043            public static String[] generateWsdd(String className, String serviceName)
044                    throws Exception {
045    
046                    // Create temp directory
047    
048                    File tempDir = new File(Time.getTimestamp());
049    
050                    tempDir.mkdir();
051    
052                    // axis-java2wsdl
053    
054                    String wsdlFileName = tempDir + "/service.wsdl";
055    
056                    int pos = className.lastIndexOf(".");
057    
058                    String packagePath = className.substring(0, pos);
059    
060                    String[] packagePaths = StringUtil.split(packagePath, ".");
061    
062                    String namespace = "urn:";
063    
064                    for (int i = packagePaths.length - 1; i >= 0; i--) {
065                            namespace += packagePaths[i];
066    
067                            if (i > 0) {
068                                    namespace += ".";
069                            }
070                    }
071    
072                    String location = "http://localhost/services/" + serviceName;
073    
074                    String mappingPackage = packagePath.substring(
075                            0, packagePath.lastIndexOf(".")) + ".ws";
076    
077                    Project project = AntUtil.getProject();
078    
079                    Java2WsdlAntTask java2Wsdl = new Java2WsdlAntTask();
080    
081                    NamespaceMapping mapping = new NamespaceMapping();
082    
083                    mapping.setNamespace(namespace);
084                    mapping.setPackage(mappingPackage);
085    
086                    java2Wsdl.setProject(project);
087                    java2Wsdl.setClassName(className);
088                    java2Wsdl.setOutput(new File(wsdlFileName));
089                    java2Wsdl.setLocation(location);
090                    java2Wsdl.setNamespace(namespace);
091                    java2Wsdl.addMapping(mapping);
092    
093                    java2Wsdl.execute();
094    
095                    // axis-wsdl2java
096    
097                    Wsdl2javaAntTask wsdl2Java = new Wsdl2javaAntTask();
098    
099                    wsdl2Java.setProject(project);
100                    wsdl2Java.setURL(wsdlFileName);
101                    wsdl2Java.setOutput(tempDir);
102                    wsdl2Java.setServerSide(true);
103                    wsdl2Java.setTestCase(false);
104                    wsdl2Java.setVerbose(false);
105    
106                    wsdl2Java.execute();
107    
108                    // Get content
109    
110                    String deployContent = FileUtil.read(
111                            tempDir + "/" + StringUtil.replace(packagePath, ".", "/") +
112                                    "/deploy.wsdd");
113    
114                    deployContent = StringUtil.replace(
115                            deployContent, packagePath + "." + serviceName + "SoapBindingImpl",
116                            className);
117    
118                    deployContent = _format(deployContent);
119    
120                    String undeployContent = FileUtil.read(
121                            tempDir + "/" + StringUtil.replace(packagePath, ".", "/") +
122                                    "/undeploy.wsdd");
123    
124                    undeployContent = _format(undeployContent);
125    
126                    // Delete temp directory
127    
128                    DeleteTask.deleteDirectory(tempDir);
129    
130                    return new String[] {deployContent, undeployContent};
131            }
132    
133            private static void _addElements(
134                    Element element, Map<String, Element> elements) {
135    
136                    for (Map.Entry<String, Element> entry : elements.entrySet()) {
137                            Element childElement = entry.getValue();
138    
139                            element.add(childElement);
140                    }
141            }
142    
143            private static String _format(String content) throws Exception {
144                    content = HtmlUtil.stripComments(content);
145    
146                    Document document = SAXReaderUtil.read(content);
147    
148                    Element rootElement = document.getRootElement();
149    
150                    Element serviceElement = rootElement.element("service");
151    
152                    Map<String, Element> arrayMappingElements =
153                            new TreeMap<String, Element>();
154                    Map<String, Element> typeMappingElements =
155                            new TreeMap<String, Element>();
156                    Map<String, Element> operationElements = new TreeMap<String, Element>();
157                    Map<String, Element> parameterElements = new TreeMap<String, Element>();
158    
159                    for (Element element : serviceElement.elements()) {
160                            String elementName = element.getName();
161    
162                            if (elementName.equals("arrayMapping")) {
163                                    element.detach();
164    
165                                    arrayMappingElements.put(element.toString(), element);
166                            }
167                            else if (elementName.equals("operation")) {
168                                    element.detach();
169    
170                                    StringBundler sb = new StringBundler();
171    
172                                    String name = element.attributeValue("name");
173    
174                                    sb.append(name);
175                                    sb.append("_METHOD_");
176    
177                                    for (Element parameterElement : element.elements("parameter")) {
178                                            String type = parameterElement.attributeValue("type");
179    
180                                            sb.append(type);
181                                            sb.append("_PARAMETER_");
182                                    }
183    
184                                    operationElements.put(sb.toString(), element);
185                            }
186                            else if (elementName.equals("parameter")) {
187                                    element.detach();
188    
189                                    String name = element.attributeValue("name");
190    
191                                    if (name.equals("allowedMethods")) {
192                                            Attribute valueAttribute = element.attribute("value");
193    
194                                            String[] allowedMethods = StringUtil.split(
195                                                    valueAttribute.getValue(), " ");
196    
197                                            Arrays.sort(allowedMethods);
198    
199                                            valueAttribute.setValue(
200                                                    StringUtil.merge(allowedMethods, " "));
201                                    }
202    
203                                    parameterElements.put(name, element);
204                            }
205                            else if (elementName.equals("typeMapping")) {
206                                    element.detach();
207    
208                                    typeMappingElements.put(element.toString(), element);
209                            }
210                    }
211    
212                    _addElements(serviceElement, arrayMappingElements);
213                    _addElements(serviceElement, typeMappingElements);
214                    _addElements(serviceElement, operationElements);
215                    _addElements(serviceElement, parameterElements);
216    
217                    content = StringUtil.replace(
218                            document.formattedString(), "\"/>", "\" />");
219    
220                    return content;
221            }
222    
223    }