001    /**
002     * Copyright (c) 2000-2012 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.jsonwebservice;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.exception.SystemException;
019    import com.liferay.portal.kernel.jsonwebservice.BaseJSONWebServiceConfigurator;
020    import com.liferay.portal.kernel.jsonwebservice.JSONWebServiceConfigurator;
021    import com.liferay.portal.kernel.log.Log;
022    import com.liferay.portal.kernel.log.LogFactoryUtil;
023    import com.liferay.portal.kernel.util.StringPool;
024    import com.liferay.portal.util.PortalUtil;
025    
026    import java.io.BufferedInputStream;
027    import java.io.File;
028    import java.io.InputStream;
029    import java.io.UnsupportedEncodingException;
030    
031    import java.net.URL;
032    import java.net.URLDecoder;
033    
034    import java.util.ArrayList;
035    import java.util.List;
036    
037    import javax.servlet.ServletContext;
038    
039    import jodd.io.findfile.ClassFinder;
040    import jodd.io.findfile.FindFile;
041    import jodd.io.findfile.RegExpFindFile;
042    
043    import jodd.util.ClassLoaderUtil;
044    
045    import org.apache.commons.lang.time.StopWatch;
046    
047    /**
048     * @author Igor Spasic
049     * @author Raymond Augé
050     */
051    public class JSONWebServiceConfiguratorImpl extends ClassFinder
052            implements JSONWebServiceConfigurator {
053    
054            public JSONWebServiceConfiguratorImpl() {
055    
056                    // We cannot extend two classes, so use an anonymous delegate.
057    
058                    _baseJSONWebServiceConfigurator = new BaseJSONWebServiceConfigurator() {
059    
060                            @Override
061                            public void configure() throws PortalException, SystemException {
062                                    File[] classPathFiles = null;
063    
064                                    if (getClassLoader() !=
065                                                    com.liferay.portal.util.ClassLoaderUtil.
066                                                            getPortalClassLoader()) {
067    
068                                            classPathFiles = getPluginClassPathFiles();
069                                    }
070                                    else {
071                                            classPathFiles = getPortalClassPathFiles();
072                                    }
073    
074                                    _configure(classPathFiles);
075                            }
076    
077                    };
078            }
079    
080            public void clean() {
081                    _baseJSONWebServiceConfigurator.clean();
082            }
083    
084            public void configure() throws PortalException, SystemException {
085                    _baseJSONWebServiceConfigurator.configure();
086            }
087    
088            public int getRegisteredActionsCount() {
089                    return _baseJSONWebServiceConfigurator.getRegisteredActionsCount();
090            }
091    
092            public void init(ServletContext servletContext, ClassLoader classLoader) {
093                    _baseJSONWebServiceConfigurator.init(servletContext, classLoader);
094    
095                    setIncludedJars(
096                            "*_wl_cls_gen.jar", "*-hook-service*.jar", "*-portlet-service*.jar",
097                            "*-web-service*.jar", "*portal-impl.jar", "*portal-service.jar");
098            }
099    
100            public void registerClass(String className, InputStream inputStream)
101                    throws Exception {
102    
103                    _baseJSONWebServiceConfigurator.registerClass(className, inputStream);
104            }
105    
106            protected File[] getPluginClassPathFiles() throws SystemException {
107                    ClassLoader classLoader =
108                            _baseJSONWebServiceConfigurator.getClassLoader();
109    
110                    URL servicePropertiesURL = classLoader.getResource(
111                            "service.properties");
112    
113                    String servicePropertiesPath = null;
114    
115                    try {
116                            servicePropertiesPath = URLDecoder.decode(
117                                    servicePropertiesURL.getPath(), StringPool.UTF8);
118                    }
119                    catch (UnsupportedEncodingException uee) {
120                            throw new SystemException(uee);
121                    }
122    
123                    File classPathFile = null;
124    
125                    File libDir = null;
126    
127                    int pos = servicePropertiesPath.indexOf("_wl_cls_gen.jar!");
128    
129                    if (pos != -1) {
130                            String wlClsGenJarPath = servicePropertiesPath.substring(
131                                    0, pos + 15);
132    
133                            classPathFile = new File(wlClsGenJarPath);
134    
135                            libDir = new File(classPathFile.getParent());
136                    }
137                    else {
138                            File servicePropertiesFile = new File(servicePropertiesPath);
139    
140                            classPathFile = servicePropertiesFile.getParentFile();
141    
142                            libDir = new File(classPathFile.getParent(), "lib");
143                    }
144    
145                    List<File> classPaths = new ArrayList<File>();
146    
147                    classPaths.add(classPathFile);
148    
149                    FindFile findFile = new RegExpFindFile(
150                            ".*-(hook|portlet|web)-service.*\\.jar");
151    
152                    findFile.searchPath(libDir);
153    
154                    File file = null;
155    
156                    while ((file = findFile.nextFile()) != null) {
157                            if (classPaths.contains(file)) {
158                                    continue;
159                            }
160    
161                            classPaths.add(file);
162                    }
163    
164                    File classesDir = new File(libDir.getParent(), "classes");
165    
166                    if (!classPaths.contains(classesDir)) {
167                            classPaths.add(classesDir);
168                    }
169    
170                    return classPaths.toArray(new File[classPaths.size()]);
171            }
172    
173            protected File[] getPortalClassPathFiles() {
174                    File[] classPathFiles = null;
175    
176                    File portalImplJarFile = new File(
177                            PortalUtil.getPortalLibDir(), "portal-impl.jar");
178                    File portalServiceJarFile = new File(
179                            PortalUtil.getGlobalLibDir(), "portal-service.jar");
180    
181                    if (portalImplJarFile.exists() && portalServiceJarFile.exists()) {
182                            classPathFiles = new File[2];
183    
184                            classPathFiles[0] = portalImplJarFile;
185                            classPathFiles[1] = portalServiceJarFile;
186                    }
187                    else {
188                            classPathFiles = ClassLoaderUtil.getDefaultClasspath(
189                                    _baseJSONWebServiceConfigurator.getClassLoader());
190                    }
191    
192                    return classPathFiles;
193            }
194    
195            @Override
196            protected void onEntry(EntryData entryData) throws Exception {
197                    String className = entryData.getName();
198    
199                    InputStream inputStream = new BufferedInputStream(
200                            entryData.openInputStream());
201    
202                    registerClass(className, inputStream);
203            }
204    
205            private void _configure(File... classPathFiles) throws PortalException {
206                    StopWatch stopWatch = null;
207    
208                    if (_log.isDebugEnabled()) {
209                            _log.debug("Configure JSON web service actions");
210    
211                            stopWatch = new StopWatch();
212    
213                            stopWatch.start();
214                    }
215    
216                    try {
217                            scanPaths(classPathFiles);
218                    }
219                    catch (Exception e) {
220                            throw new PortalException(e.getMessage(), e);
221                    }
222    
223                    if (_log.isDebugEnabled()) {
224                            _log.debug(
225                                    "Configured " + getRegisteredActionsCount() + " actions in " +
226                                            stopWatch.getTime() + " ms");
227                    }
228            }
229    
230            private static Log _log = LogFactoryUtil.getLog(
231                    JSONWebServiceConfiguratorImpl.class);
232    
233            private BaseJSONWebServiceConfigurator _baseJSONWebServiceConfigurator;
234    
235    }