001    /**
002     * Copyright (c) 2000-2013 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.util;
016    
017    import com.liferay.portal.kernel.cluster.ClusterExecutorUtil;
018    import com.liferay.portal.kernel.cluster.ClusterRequest;
019    import com.liferay.portal.kernel.cluster.FutureClusterResponses;
020    import com.liferay.portal.kernel.log.Log;
021    import com.liferay.portal.kernel.log.LogFactoryUtil;
022    import com.liferay.portal.kernel.progress.InstallStatus;
023    import com.liferay.portal.kernel.util.FileUtil;
024    import com.liferay.portal.kernel.util.HttpUtil;
025    import com.liferay.portal.kernel.util.MethodHandler;
026    import com.liferay.portal.kernel.util.MethodKey;
027    import com.liferay.portal.kernel.util.StringPool;
028    import com.liferay.portal.model.CompanyConstants;
029    import com.liferay.portlet.documentlibrary.store.DLStoreUtil;
030    
031    import java.io.File;
032    import java.io.InputStream;
033    
034    import java.lang.reflect.Method;
035    
036    import java.net.URI;
037    import java.net.URL;
038    import java.net.URLClassLoader;
039    
040    import java.util.concurrent.TimeUnit;
041    
042    /**
043     * @author Alexander Chow
044     */
045    public class JarUtil {
046    
047            public static void downloadAndInstallJar(
048                            boolean globalClassPath, String url, String name,
049                            InstallStatus installStatus)
050                    throws Exception {
051    
052                    setInstallStatus(installStatus, 0);
053    
054                    if (_log.isInfoEnabled()) {
055                            _log.info("Downloading " + url);
056                    }
057    
058                    byte[] bytes = HttpUtil.URLtoByteArray(url);
059    
060                    setInstallStatus(installStatus, 1);
061    
062                    if (PropsValues.CLUSTER_LINK_ENABLED) {
063                            try {
064                                    DLStoreUtil.deleteFile(
065                                            _REPOSITORY, _REPOSITORY, _FILE_PATH + name);
066                            }
067                            catch (Exception e) {
068                            }
069    
070                            DLStoreUtil.addFile(
071                                    _REPOSITORY, _REPOSITORY, _FILE_PATH + name, bytes);
072    
073                            try {
074                                    ClusterRequest clusterRequest =
075                                            ClusterRequest.createMulticastRequest(
076                                                    new MethodHandler(
077                                                            _installJarKey, globalClassPath, name));
078    
079                                    FutureClusterResponses futureClusterResponses =
080                                            ClusterExecutorUtil.execute(clusterRequest);
081    
082                                    futureClusterResponses.get(30, TimeUnit.SECONDS);
083                            }
084                            finally {
085                                    try {
086                                            setInstallStatus(installStatus, 2);
087    
088                                            DLStoreUtil.deleteFile(
089                                                    _REPOSITORY, _REPOSITORY, _FILE_PATH + name);
090                                    }
091                                    catch (Exception e) {
092                                    }
093                            }
094                    }
095                    else {
096                            setInstallStatus(installStatus, 1);
097    
098                            installJar(bytes, globalClassPath, name);
099    
100                            setInstallStatus(installStatus, 2);
101                    }
102            }
103    
104            public static void installJar(boolean globalClassPath, String name)
105                    throws Exception {
106    
107                    installJar(null, globalClassPath, name);
108            }
109    
110            protected static void addJarFileToClassLoader(File file) throws Exception {
111                    Class<?> clazz = URLClassLoader.class;
112    
113                    Method method = clazz.getDeclaredMethod(
114                            "addURL", new Class[] {URL.class});
115    
116                    method.setAccessible(true);
117    
118                    URI uri = file.toURI();
119    
120                    method.invoke(
121                            ClassLoader.getSystemClassLoader(), new Object[] {uri.toURL()});
122            }
123    
124            protected static void installJar(
125                            byte[] bytes, boolean globalClassPath, String name)
126                    throws Exception {
127    
128                    String libPath = PropsValues.LIFERAY_LIB_PORTAL_DIR;
129    
130                    if (globalClassPath) {
131                            libPath = PropsValues.LIFERAY_LIB_GLOBAL_DIR;
132                    }
133    
134                    File file = new File(libPath + StringPool.SLASH + name);
135    
136                    InputStream is = null;
137    
138                    try {
139                            if (_log.isInfoEnabled()) {
140                                    _log.info("Writing " + file);
141                            }
142    
143                            if (bytes != null) {
144                                    FileUtil.write(file, bytes);
145                            }
146                            else {
147                                    is = DLStoreUtil.getFileAsStream(
148                                            _REPOSITORY, _REPOSITORY, _FILE_PATH + name);
149    
150                                    FileUtil.write(file, is);
151                            }
152                    }
153                    finally {
154                            if (is != null) {
155                                    is.close();
156                            }
157                    }
158    
159                    addJarFileToClassLoader(file);
160            }
161    
162            protected static void setInstallStatus(
163                    InstallStatus installStatus, int status) {
164    
165                    if (installStatus == null) {
166                            return;
167                    }
168    
169                    installStatus.setStatus(status);
170            }
171    
172            private static final String _FILE_PATH = "jar_temp/";
173    
174            private static final long _REPOSITORY = CompanyConstants.SYSTEM;
175    
176            private static Log _log = LogFactoryUtil.getLog(JarUtil.class);
177    
178            private static MethodKey _installJarKey = new MethodKey(
179                    JarUtil.class.getName(), "installJar", boolean.class, String.class);
180    
181    }