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.xuggler;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.util.ClassLoaderUtil;
020    import com.liferay.portal.kernel.util.ProgressStatusConstants;
021    import com.liferay.portal.kernel.util.ProgressTracker;
022    import com.liferay.portal.kernel.util.PropsKeys;
023    import com.liferay.portal.kernel.util.StringBundler;
024    import com.liferay.portal.kernel.xuggler.Xuggler;
025    import com.liferay.portal.util.JarUtil;
026    import com.liferay.portal.util.PrefsPropsUtil;
027    import com.liferay.portal.util.PropsValues;
028    import com.liferay.util.log4j.Log4JUtil;
029    
030    import com.xuggle.ferry.JNILibraryLoader;
031    import com.xuggle.xuggler.IContainer;
032    
033    import java.net.URL;
034    import java.net.URLClassLoader;
035    
036    /**
037     * @author Alexander Chow
038     */
039    public class XugglerImpl implements Xuggler {
040    
041            @Override
042            public void installNativeLibraries(
043                            String name, ProgressTracker progressTracker)
044                    throws Exception {
045    
046                    ClassLoader classLoader = ClassLoaderUtil.getPortalClassLoader();
047    
048                    if (!(classLoader instanceof URLClassLoader)) {
049                            _log.error(
050                                    "Unable to install JAR because the portal class loader is " +
051                                            "not an instance of URLClassLoader");
052    
053                            return;
054                    }
055    
056                    try {
057                            if (progressTracker != null) {
058                                    progressTracker.setStatus(ProgressStatusConstants.DOWNLOADING);
059                            }
060    
061                            JarUtil.downloadAndInstallJar(
062                                    new URL(PropsValues.XUGGLER_JAR_URL + name),
063                                    PropsValues.LIFERAY_LIB_PORTAL_DIR, name,
064                                    (URLClassLoader)classLoader);
065                    }
066                    catch (Exception e) {
067                            _log.error("Unable to install jar " + name, e);
068    
069                            throw e;
070                    }
071            }
072    
073            @Override
074            public boolean isEnabled() {
075                    return isEnabled(true);
076            }
077    
078            @Override
079            public boolean isEnabled(boolean checkNativeLibraries) {
080                    boolean enabled = false;
081    
082                    try {
083                            enabled = PrefsPropsUtil.getBoolean(
084                                    PropsKeys.XUGGLER_ENABLED, PropsValues.XUGGLER_ENABLED);
085                    }
086                    catch (Exception e) {
087                            if (_log.isWarnEnabled()) {
088                                    _log.warn(e, e);
089                            }
090                    }
091    
092                    if (!checkNativeLibraries) {
093                            return enabled;
094                    }
095    
096                    if (enabled) {
097                            return isNativeLibraryInstalled();
098                    }
099    
100                    return false;
101            }
102    
103            @Override
104            public boolean isNativeLibraryInstalled() {
105                    if (_nativeLibraryInstalled) {
106                            return _nativeLibraryInstalled;
107                    }
108    
109                    String originalLevel = Log4JUtil.getOriginalLevel(
110                            JNILibraryLoader.class.getName());
111    
112                    try {
113                            Log4JUtil.setLevel(JNILibraryLoader.class.getName(), "OFF", false);
114    
115                            IContainer.make();
116    
117                            _nativeLibraryInstalled = true;
118                    }
119                    catch (NoClassDefFoundError ncdfe) {
120                            informAdministrator(ncdfe.getMessage());
121                    }
122                    catch (UnsatisfiedLinkError ule) {
123                            informAdministrator(ule.getMessage());
124                    }
125                    finally {
126                            Log4JUtil.setLevel(
127                                    JNILibraryLoader.class.getName(), originalLevel.toString(),
128                                    false);
129                    }
130    
131                    return _nativeLibraryInstalled;
132            }
133    
134            protected void informAdministrator(String errorMessage) {
135                    if (!_informAdministrator) {
136                            return;
137                    }
138    
139                    _informAdministrator = false;
140    
141                    StringBundler sb = new StringBundler(7);
142    
143                    sb.append("Liferay does not have the Xuggler native libraries ");
144                    sb.append("installed. In order to generate video and audio previews, ");
145                    sb.append("please follow the instructions for Xuggler in the Server ");
146                    sb.append("Administration section of the Control Panel at: ");
147                    sb.append("http://<server>/group/control_panel/manage/-/server/");
148                    sb.append("external-services. Error message is: ");
149                    sb.append(errorMessage);
150    
151                    _log.error(sb.toString());
152            }
153    
154            private static final Log _log = LogFactoryUtil.getLog(XugglerImpl.class);
155    
156            private static boolean _informAdministrator = true;
157            private static boolean _nativeLibraryInstalled;
158    
159    }