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