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.portal.tools;
016    
017    import com.liferay.portal.kernel.io.DummyOutputStream;
018    import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayInputStream;
019    import com.liferay.portal.kernel.util.ArrayUtil;
020    import com.liferay.portal.kernel.util.CharPool;
021    import com.liferay.portal.kernel.util.FileUtil;
022    import com.liferay.portal.kernel.util.StringBundler;
023    import com.liferay.portal.kernel.util.StringPool;
024    import com.liferay.portal.kernel.util.StringUtil;
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    import com.liferay.util.ant.Wsdl2JavaTask;
029    import com.liferay.util.axis.AxisServlet;
030    
031    import java.io.File;
032    import java.io.IOException;
033    import java.io.InputStream;
034    import java.io.OutputStream;
035    
036    import java.net.URL;
037    import java.net.URLConnection;
038    import java.net.URLStreamHandler;
039    import java.net.URLStreamHandlerFactory;
040    
041    import java.util.List;
042    
043    import javax.servlet.ServletException;
044    import javax.servlet.http.HttpServlet;
045    
046    import org.springframework.core.io.FileSystemResource;
047    import org.springframework.core.io.Resource;
048    import org.springframework.core.io.ResourceLoader;
049    import org.springframework.mock.web.MockHttpServletRequest;
050    import org.springframework.mock.web.MockHttpServletResponse;
051    import org.springframework.mock.web.MockServletConfig;
052    import org.springframework.mock.web.MockServletContext;
053    
054    /**
055     * @author Brian Wing Shun Chan
056     */
057    public class PortalClientBuilder {
058    
059            public static void main(String[] args) throws Exception {
060                    ToolDependencies.wireBasic();
061    
062                    if (args.length == 4) {
063                            new PortalClientBuilder(args[0], args[1], args[2], args[3]);
064                    }
065                    else {
066                            throw new IllegalArgumentException();
067                    }
068            }
069    
070            public PortalClientBuilder(
071                            String fileName, String outputDir, String mappingFile, String url)
072                    throws Exception {
073    
074                    URL.setURLStreamHandlerFactory(new DirectURLStreamHandlerFactory());
075    
076                    File file = new File(fileName);
077    
078                    File parentFile = file.getParentFile();
079    
080                    _axisHttpServlet = _createAxisHttpServlet(parentFile.getParentFile());
081    
082                    Document document = UnsecureSAXReaderUtil.read(new File(fileName));
083    
084                    Element rootElement = document.getRootElement();
085    
086                    List<Element> serviceElements = rootElement.elements("service");
087    
088                    for (Element serviceElement : serviceElements) {
089                            String serviceName = serviceElement.attributeValue("name");
090    
091                            if (serviceName.startsWith("Plugin_") &&
092                                    !FileUtil.exists(mappingFile)) {
093    
094                                    _writePluginMappingFile(mappingFile, serviceElement);
095                            }
096    
097                            if (serviceName.startsWith("Plugin_") ||
098                                    serviceName.startsWith("Portal_") ||
099                                    serviceName.startsWith("Portlet_")) {
100    
101                                    Wsdl2JavaTask.generateJava(
102                                            url + "/" + serviceName + "?wsdl", outputDir, mappingFile);
103                            }
104                    }
105    
106                    File testNamespace = new File(outputDir + "/com/liferay/portal");
107    
108                    if (testNamespace.exists()) {
109                            throw new RuntimeException(
110                                    "Please update " + mappingFile + " from namespace " +
111                                            "com.liferay.portal to com.liferay.client.soap.portal");
112                    }
113            }
114    
115            private HttpServlet _createAxisHttpServlet(final File docRootDir)
116                    throws ServletException {
117    
118                    AxisServlet axisServlet = new AxisServlet();
119    
120                    MockServletConfig mockServletConfig = new MockServletConfig(
121                            new MockServletContext(
122                                    new ResourceLoader() {
123    
124                                            @Override
125                                            public ClassLoader getClassLoader() {
126                                                    return AxisServlet.class.getClassLoader();
127                                            }
128    
129                                            @Override
130                                            public Resource getResource(String name) {
131                                                    return new FileSystemResource(
132                                                            new File(docRootDir, name));
133                                            }
134    
135                                    }),
136                            "Axis Servlet");
137    
138                    axisServlet.init(mockServletConfig);
139    
140                    return axisServlet;
141            }
142    
143            private byte[] _getWSDLContent(URL url) throws IOException {
144                    String path = url.getPath();
145    
146                    int index = path.lastIndexOf(CharPool.SLASH);
147    
148                    String servletPath = path.substring(0, index);
149    
150                    MockHttpServletRequest mockHttpServletRequest =
151                            new MockHttpServletRequest(
152                                    _axisHttpServlet.getServletContext(), "GET", path);
153    
154                    mockHttpServletRequest.setPathInfo(path.substring(index));
155                    mockHttpServletRequest.setQueryString(url.getQuery());
156                    mockHttpServletRequest.setScheme(url.getProtocol());
157                    mockHttpServletRequest.setServerName(url.getHost());
158                    mockHttpServletRequest.setServerPort(url.getPort());
159                    mockHttpServletRequest.setServletPath(servletPath);
160    
161                    MockHttpServletResponse mockHttpServletResponse =
162                            new MockHttpServletResponse();
163    
164                    try {
165                            _axisHttpServlet.service(
166                                    mockHttpServletRequest, mockHttpServletResponse);
167                    }
168                    catch (ServletException se) {
169                            throw new IOException(se);
170                    }
171    
172                    return mockHttpServletResponse.getContentAsByteArray();
173            }
174    
175            private void _writePluginMappingFile(
176                            String mappingFile, Element serviceElement)
177                    throws Exception {
178    
179                    String wsdlTargetNamespace = null;
180    
181                    List<Element> parameterElements = serviceElement.elements("parameter");
182    
183                    for (Element parameterElement : parameterElements) {
184                            String parameterName = parameterElement.attributeValue("name");
185    
186                            if (parameterName.equals("wsdlTargetNamespace")) {
187                                    wsdlTargetNamespace = parameterElement.attributeValue("value");
188    
189                                    break;
190                            }
191                    }
192    
193                    int pos = wsdlTargetNamespace.indexOf(".service.");
194    
195                    String soapNamespace = wsdlTargetNamespace.substring(pos + 9);
196    
197                    String[] soapNamespaceArray = StringUtil.split(
198                            soapNamespace, CharPool.PERIOD);
199    
200                    ArrayUtil.reverse(soapNamespaceArray);
201    
202                    soapNamespace = StringUtil.merge(soapNamespaceArray, StringPool.PERIOD);
203    
204                    pos = soapNamespace.lastIndexOf(StringPool.PERIOD);
205    
206                    soapNamespace =
207                            soapNamespace.substring(0, pos) + ".client.soap" +
208                                    soapNamespace.substring(pos);
209    
210                    StringBundler sb = new StringBundler(10);
211    
212                    sb.append("com.liferay.client.soap.portal.kernel.util=");
213                    sb.append("http://util.kernel.portal.liferay.com\n");
214    
215                    sb.append("com.liferay.client.soap.portal.model=");
216                    sb.append("http://model.portal.liferay.com\n");
217    
218                    sb.append("com.liferay.client.soap.portal.service=");
219                    sb.append("http://service.portal.liferay.com\n");
220    
221                    sb.append(soapNamespace);
222                    sb.append(".model=http://model.knowledgebase.liferay.com\n");
223    
224                    sb.append(soapNamespace);
225                    sb.append(".service.http=urn:http.service.knowledgebase.liferay.com\n");
226    
227                    FileUtil.write(mappingFile, sb.toString());
228            }
229    
230            private final HttpServlet _axisHttpServlet;
231    
232            private class DirectURLConnection extends URLConnection {
233    
234                    public DirectURLConnection(URL url) {
235                            super(url);
236                    }
237    
238                    @Override
239                    public void connect() {
240                    }
241    
242                    @Override
243                    public InputStream getInputStream() throws IOException {
244                            return new UnsyncByteArrayInputStream(_getWSDLContent(url));
245                    }
246    
247                    @Override
248                    public OutputStream getOutputStream() {
249                            return new DummyOutputStream();
250                    }
251    
252            }
253    
254            private class DirectURLStreamHandler extends URLStreamHandler {
255    
256                    @Override
257                    protected URLConnection openConnection(URL url) {
258                            return new DirectURLConnection(url);
259                    }
260    
261            }
262    
263            private class DirectURLStreamHandlerFactory
264                    implements URLStreamHandlerFactory {
265    
266                    @Override
267                    public URLStreamHandler createURLStreamHandler(String protocol) {
268                            return new DirectURLStreamHandler();
269                    }
270    
271            }
272    
273    }