001
014
015 package com.liferay.portlet.documentlibrary.util;
016
017 import com.liferay.portal.kernel.configuration.Filter;
018 import com.liferay.portal.kernel.io.DummyOutputStream;
019 import com.liferay.portal.kernel.log.Log;
020 import com.liferay.portal.kernel.log.LogFactoryUtil;
021 import com.liferay.portal.kernel.process.ClassPathUtil;
022 import com.liferay.portal.kernel.process.ProcessException;
023 import com.liferay.portal.kernel.util.FileUtil;
024 import com.liferay.portal.kernel.util.HttpUtil;
025 import com.liferay.portal.kernel.util.OSDetector;
026 import com.liferay.portal.kernel.util.ProgressStatusConstants;
027 import com.liferay.portal.kernel.util.ProgressTracker;
028 import com.liferay.portal.kernel.util.PropsKeys;
029 import com.liferay.portal.kernel.util.ReflectionUtil;
030 import com.liferay.portal.kernel.util.SetUtil;
031 import com.liferay.portal.kernel.util.Validator;
032 import com.liferay.portal.kernel.xuggler.Xuggler;
033 import com.liferay.portal.util.FileImpl;
034 import com.liferay.portal.util.HttpImpl;
035 import com.liferay.portal.util.PropsUtil;
036 import com.liferay.portal.xuggler.XugglerImpl;
037
038 import com.xuggle.ferry.JNILibrary;
039
040 import java.io.File;
041 import java.io.PrintStream;
042
043 import java.lang.reflect.Field;
044
045 import java.net.URL;
046 import java.net.URLClassLoader;
047
048 import java.util.Iterator;
049 import java.util.Properties;
050 import java.util.Set;
051 import java.util.concurrent.Callable;
052 import java.util.logging.Level;
053 import java.util.logging.Logger;
054 import java.util.regex.Matcher;
055 import java.util.regex.Pattern;
056
057
060 public class XugglerAutoInstallHelper {
061
062 public static void installNativeLibraries() throws ProcessException {
063 if (isNativeLibraryInstalled()) {
064 if (_log.isDebugEnabled()) {
065 _log.debug("Xuggler is already installed");
066 }
067
068 return;
069 }
070
071 String xugglerJarFile = getXugglerJarFileName();
072
073 if (xugglerJarFile == null) {
074 _log.error(
075 "Xuggler auto install is not supported on system: " +
076 System.getProperty("os.name") + "/" +
077 System.getProperty("os.arch"));
078
079 return;
080 }
081
082 FileUtil fileUtil = new FileUtil();
083
084 fileUtil.setFile(new FileImpl());
085
086 HttpUtil httpUtil = new HttpUtil();
087
088 httpUtil.setHttp(new HttpImpl());
089
090 Xuggler xuggler = new XugglerImpl();
091
092 try {
093 ProgressTracker progressTracker = new ProgressTracker(
094 "XugglerInstaller");
095
096 progressTracker.addProgress(
097 ProgressStatusConstants.DOWNLOADING, 15, "downloading-xuggler");
098 progressTracker.addProgress(
099 ProgressStatusConstants.COPYING, 70, "copying-xuggler-files");
100
101 xuggler.installNativeLibraries(xugglerJarFile, progressTracker);
102 }
103 catch (Exception e) {
104 throw new ProcessException(e);
105 }
106
107 if (xuggler.isNativeLibraryInstalled()) {
108 if (_log.isInfoEnabled()) {
109 _log.info("Xuggler installed successfully");
110 }
111 }
112 else {
113 _log.error("Xuggler auto install failed");
114 }
115 }
116
117 public static class IsNativeLibraryInstalledCallable
118 implements Callable<Boolean> {
119
120 @Override
121 public Boolean call() throws Exception {
122 PrintStream printStream = System.out;
123
124 System.setOut(new PrintStream(new DummyOutputStream()));
125
126 Package pkg = JNILibrary.class.getPackage();
127
128 Logger logger = Logger.getLogger(pkg.getName());
129
130 Level level = logger.getLevel();
131
132 logger.setLevel(Level.OFF);
133
134 String property = System.getProperty(
135 "java.util.logging.config.file");
136
137 System.setProperty("java.util.logging.config.file", "configFile");
138
139 Xuggler xuggler = new XugglerImpl();
140
141 Field informAdministratorField = ReflectionUtil.getDeclaredField(
142 XugglerImpl.class, "_informAdministrator");
143
144 informAdministratorField.setBoolean(xuggler, false);
145
146 try {
147 return xuggler.isNativeLibraryInstalled();
148 }
149 finally {
150 if (property == null) {
151 System.clearProperty("java.util.logging.config.file");
152 }
153 else {
154 System.setProperty(
155 "java.util.logging.config.file", property);
156 }
157
158 logger.setLevel(level);
159
160 System.setOut(printStream);
161 }
162 }
163
164 }
165
166 private static String getXugglerJarFileName() {
167 String bitmode = OSDetector.getBitmode();
168
169 if (Validator.isNull(bitmode) ||
170 (!bitmode.equals("32") && !bitmode.equals("64"))) {
171
172 return null;
173 }
174
175 if (OSDetector.isApple()) {
176 return PropsUtil.get(
177 PropsKeys.XUGGLER_JAR_FILE, new Filter(bitmode + "-mac"));
178 }
179
180 if (OSDetector.isLinux()) {
181 return PropsUtil.get(
182 PropsKeys.XUGGLER_JAR_FILE, new Filter(bitmode + "-linux"));
183 }
184
185 if (OSDetector.isWindows()) {
186 return PropsUtil.get(
187 PropsKeys.XUGGLER_JAR_FILE, new Filter(bitmode + "-win"));
188 }
189
190 return null;
191 }
192
193 private static boolean isNativeLibraryInstalled() {
194 Properties properties = PropsUtil.getProperties(
195 PropsKeys.XUGGLER_JAR_FILE, false);
196
197 Set<Object> jarFiles = SetUtil.fromCollection(properties.values());
198
199 jarFiles.remove(getXugglerJarFileName());
200
201 Thread currentThread = Thread.currentThread();
202
203 ClassLoader contextClassLoader = currentThread.getContextClassLoader();
204
205 Set<URL> urls = ClassPathUtil.getClassPathURLs(contextClassLoader);
206
207 Iterator<URL> iterator = urls.iterator();
208
209 while (iterator.hasNext()) {
210 URL url = iterator.next();
211
212 String protocol = url.getProtocol();
213
214 if (protocol.equals("file")) {
215 File file = new File(url.getPath());
216
217 Matcher matcher = _pattern.matcher(file.getName());
218
219 if (matcher.matches()) {
220 if (jarFiles.contains(matcher.replaceAll("$1$2"))) {
221 file.delete();
222
223 iterator.remove();
224 }
225 }
226 }
227 }
228
229 URLClassLoader urlClassLoader = new URLClassLoader(
230 urls.toArray(new URL[urls.size()]), null);
231
232 currentThread.setContextClassLoader(urlClassLoader);
233
234 try {
235 Class<Callable<Boolean>> clazz = (Class<Callable<Boolean>>)
236 urlClassLoader.loadClass(
237 IsNativeLibraryInstalledCallable.class.getName());
238
239 Callable<Boolean> callable = clazz.newInstance();
240
241 return callable.call();
242 }
243 catch (Exception e) {
244 return false;
245 }
246 finally {
247 currentThread.setContextClassLoader(contextClassLoader);
248 }
249 }
250
251 private static final Log _log = LogFactoryUtil.getLog(
252 XugglerAutoInstallHelper.class);
253
254 private static final Pattern _pattern = Pattern.compile(
255 "(.*)-\\d+-\\d+(\\.jar)");
256
257 }