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 Resource getResource(String name) {
126                                                    return new FileSystemResource(
127                                                            new File(docRootDir, name));
128                                            }
129    
130                                            @Override
131                                            public ClassLoader getClassLoader() {
132                                                    return AxisServlet.class.getClassLoader();
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(12);
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=");
223                    sb.append("http://model.knowledgebase.liferay.com\n");
224    
225                    sb.append(soapNamespace);
226                    sb.append(".service.http=");
227                    sb.append("urn:http.service.knowledgebase.liferay.com\n");
228    
229                    FileUtil.write(mappingFile, sb.toString());
230            }
231    
232            private final HttpServlet _axisHttpServlet;
233    
234            private class DirectURLConnection extends URLConnection {
235    
236                    public DirectURLConnection(URL url) {
237                            super(url);
238                    }
239    
240                    @Override
241                    public void connect() {
242                    }
243    
244                    @Override
245                    public InputStream getInputStream() throws IOException {
246                            return new UnsyncByteArrayInputStream(_getWSDLContent(url));
247                    }
248    
249                    @Override
250                    public OutputStream getOutputStream() {
251                            return new DummyOutputStream();
252                    }
253    
254            }
255    
256            private class DirectURLStreamHandler extends URLStreamHandler {
257    
258                    @Override
259                    protected URLConnection openConnection(URL url) {
260                            return new DirectURLConnection(url);
261                    }
262    
263            }
264    
265            private class DirectURLStreamHandlerFactory
266                    implements URLStreamHandlerFactory {
267    
268                    @Override
269                    public URLStreamHandler createURLStreamHandler(String protocol) {
270                            return new DirectURLStreamHandler();
271                    }
272    
273            }
274    
275    }