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