001    /**
002     * Copyright (c) 2000-2013 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.CharPool;
018    import com.liferay.portal.kernel.util.FileUtil;
019    import com.liferay.portal.kernel.util.HtmlUtil;
020    import com.liferay.portal.kernel.util.StringBundler;
021    import com.liferay.portal.kernel.util.StringPool;
022    import com.liferay.portal.kernel.util.StringUtil;
023    import com.liferay.portal.kernel.util.Time;
024    import com.liferay.portal.kernel.xml.Attribute;
025    import com.liferay.portal.kernel.xml.Document;
026    import com.liferay.portal.kernel.xml.Element;
027    import com.liferay.portal.kernel.xml.UnsecureSAXReaderUtil;
028    
029    import java.io.File;
030    
031    import java.util.Arrays;
032    import java.util.Map;
033    import java.util.TreeMap;
034    
035    import org.apache.axis.tools.ant.wsdl.Java2WsdlAntTask;
036    import org.apache.axis.tools.ant.wsdl.NamespaceMapping;
037    import org.apache.axis.tools.ant.wsdl.Wsdl2javaAntTask;
038    import org.apache.tools.ant.Project;
039    
040    /**
041     * @author Brian Wing Shun Chan
042     */
043    public class Java2WsddTask {
044    
045            public static String[] generateWsdd(String className, String serviceName)
046                    throws Exception {
047    
048                    // Create temp directory
049    
050                    File tempDir = new File(Time.getTimestamp());
051    
052                    tempDir.mkdir();
053    
054                    // axis-java2wsdl
055    
056                    String wsdlFileName = tempDir + "/service.wsdl";
057    
058                    int pos = className.lastIndexOf(".");
059    
060                    String packagePath = className.substring(0, pos);
061    
062                    String[] packagePaths = StringUtil.split(packagePath, '.');
063    
064                    String namespace = "urn:";
065    
066                    for (int i = packagePaths.length - 1; i >= 0; i--) {
067                            namespace += packagePaths[i];
068    
069                            if (i > 0) {
070                                    namespace += ".";
071                            }
072                    }
073    
074                    String location = "http://localhost/services/" + serviceName;
075    
076                    String mappingPackage = packagePath.substring(
077                            0, packagePath.lastIndexOf(".")) + ".ws";
078    
079                    Project project = AntUtil.getProject();
080    
081                    Java2WsdlAntTask java2Wsdl = new Java2WsdlAntTask();
082    
083                    NamespaceMapping mapping = new NamespaceMapping();
084    
085                    mapping.setNamespace(namespace);
086                    mapping.setPackage(mappingPackage);
087    
088                    java2Wsdl.setProject(project);
089                    java2Wsdl.setClassName(className);
090                    java2Wsdl.setOutput(new File(wsdlFileName));
091                    java2Wsdl.setLocation(location);
092                    java2Wsdl.setNamespace(namespace);
093                    java2Wsdl.addMapping(mapping);
094    
095                    java2Wsdl.execute();
096    
097                    // axis-wsdl2java
098    
099                    Wsdl2javaAntTask wsdl2Java = new Wsdl2javaAntTask();
100    
101                    wsdl2Java.setProject(project);
102                    wsdl2Java.setURL(wsdlFileName);
103                    wsdl2Java.setOutput(tempDir);
104                    wsdl2Java.setServerSide(true);
105                    wsdl2Java.setTestCase(false);
106                    wsdl2Java.setVerbose(false);
107    
108                    wsdl2Java.execute();
109    
110                    // Get content
111    
112                    String deployContent = FileUtil.read(
113                            tempDir + "/" + StringUtil.replace(packagePath, ".", "/") +
114                                    "/deploy.wsdd");
115    
116                    deployContent = StringUtil.replace(
117                            deployContent, packagePath + "." + serviceName + "SoapBindingImpl",
118                            className);
119    
120                    deployContent = _format(deployContent);
121    
122                    String undeployContent = FileUtil.read(
123                            tempDir + "/" + StringUtil.replace(packagePath, ".", "/") +
124                                    "/undeploy.wsdd");
125    
126                    undeployContent = _format(undeployContent);
127    
128                    // Delete temp directory
129    
130                    DeleteTask.deleteDirectory(tempDir);
131    
132                    return new String[] {deployContent, undeployContent};
133            }
134    
135            private static void _addElements(
136                    Element element, Map<String, Element> elements) {
137    
138                    for (Map.Entry<String, Element> entry : elements.entrySet()) {
139                            Element childElement = entry.getValue();
140    
141                            element.add(childElement);
142                    }
143            }
144    
145            private static String _format(String content) throws Exception {
146                    content = HtmlUtil.stripComments(content);
147    
148                    Document document = UnsecureSAXReaderUtil.read(content);
149    
150                    Element rootElement = document.getRootElement();
151    
152                    Element serviceElement = rootElement.element("service");
153    
154                    Map<String, Element> arrayMappingElements =
155                            new TreeMap<String, Element>();
156                    Map<String, Element> typeMappingElements =
157                            new TreeMap<String, Element>();
158                    Map<String, Element> operationElements = new TreeMap<String, Element>();
159                    Map<String, Element> parameterElements = new TreeMap<String, Element>();
160    
161                    for (Element element : serviceElement.elements()) {
162                            String elementName = element.getName();
163    
164                            if (elementName.equals("arrayMapping")) {
165                                    element.detach();
166    
167                                    arrayMappingElements.put(element.formattedString(), element);
168                            }
169                            else if (elementName.equals("operation")) {
170                                    element.detach();
171    
172                                    StringBundler sb = new StringBundler();
173    
174                                    String name = element.attributeValue("name");
175    
176                                    sb.append(name);
177                                    sb.append("_METHOD_");
178    
179                                    for (Element parameterElement : element.elements("parameter")) {
180                                            String type = parameterElement.attributeValue("type");
181    
182                                            sb.append(type);
183                                            sb.append("_PARAMETER_");
184                                    }
185    
186                                    operationElements.put(sb.toString(), element);
187                            }
188                            else if (elementName.equals("parameter")) {
189                                    element.detach();
190    
191                                    String name = element.attributeValue("name");
192    
193                                    if (name.equals("allowedMethods")) {
194                                            Attribute valueAttribute = element.attribute("value");
195    
196                                            String[] values = StringUtil.split(
197                                                    valueAttribute.getValue(), CharPool.SPACE);
198    
199                                            Arrays.sort(values);
200    
201                                            valueAttribute.setValue(
202                                                    StringUtil.merge(values, StringPool.SPACE));
203                                    }
204                                    else if (name.equals("schemaUnqualified")) {
205                                            Attribute valueAttribute = element.attribute("value");
206    
207                                            String[] values = StringUtil.split(
208                                                    valueAttribute.getValue());
209    
210                                            Arrays.sort(values);
211    
212                                            valueAttribute.setValue(StringUtil.merge(values));
213                                    }
214    
215                                    parameterElements.put(name, element);
216                            }
217                            else if (elementName.equals("typeMapping")) {
218                                    element.detach();
219    
220                                    typeMappingElements.put(element.formattedString(), element);
221                            }
222                    }
223    
224                    _addElements(serviceElement, arrayMappingElements);
225                    _addElements(serviceElement, typeMappingElements);
226                    _addElements(serviceElement, operationElements);
227                    _addElements(serviceElement, parameterElements);
228    
229                    content = StringUtil.replace(
230                            document.formattedString(), "\"/>", "\" />");
231    
232                    return content;
233            }
234    
235    }