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.io.unsync.UnsyncStringReader;
018    import com.liferay.portal.kernel.io.unsync.UnsyncStringWriter;
019    import com.liferay.portal.kernel.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    
022    import com.yahoo.platform.yui.compressor.CssCompressor;
023    import com.yahoo.platform.yui.compressor.JavaScriptCompressor;
024    import com.yahoo.platform.yui.mozilla.javascript.ErrorReporter;
025    import com.yahoo.platform.yui.mozilla.javascript.EvaluatorException;
026    
027    /**
028     * @author Brian Wing Shun Chan
029     * @author Raymond Aug??
030     */
031    public class MinifierUtil {
032    
033            public static String minifyCss(String content) {
034                    if (!PropsValues.MINIFIER_ENABLED) {
035                            return content;
036                    }
037    
038                    return _instance._minifyCss(content);
039            }
040    
041            public static String minifyJavaScript(String content) {
042                    if (!PropsValues.MINIFIER_ENABLED) {
043                            return content;
044                    }
045    
046                    return _instance._minifyJavaScript(content);
047            }
048    
049            private MinifierUtil() {
050            }
051    
052            private String _minifyCss(String content) {
053                    UnsyncStringWriter unsyncStringWriter = new UnsyncStringWriter();
054    
055                    try {
056                            CssCompressor cssCompressor = new CssCompressor(
057                                    new UnsyncStringReader(content));
058    
059                            cssCompressor.compress(
060                                    unsyncStringWriter, PropsValues.YUI_COMPRESSOR_CSS_LINE_BREAK);
061                    }
062                    catch (Exception e) {
063                            _log.error("CSS Minifier failed for\n" + content);
064    
065                            unsyncStringWriter.append(content);
066                    }
067    
068                    return unsyncStringWriter.toString();
069            }
070    
071            private String _minifyJavaScript(String content) {
072                    UnsyncStringWriter unsyncStringWriter = new UnsyncStringWriter();
073    
074                    try {
075                            JavaScriptCompressor javaScriptCompressor =
076                                    new JavaScriptCompressor(
077                                            new UnsyncStringReader(content),
078                                            new JavaScriptErrorReporter());
079    
080                            javaScriptCompressor.compress(
081                                    unsyncStringWriter, PropsValues.YUI_COMPRESSOR_JS_LINE_BREAK,
082                                    PropsValues.YUI_COMPRESSOR_JS_MUNGE,
083                                    PropsValues.YUI_COMPRESSOR_JS_VERBOSE,
084                                    PropsValues.YUI_COMPRESSOR_JS_PRESERVE_ALL_SEMICOLONS,
085                                    PropsValues.YUI_COMPRESSOR_JS_DISABLE_OPTIMIZATIONS);
086                    }
087                    catch (Exception e) {
088                            _log.error("JavaScript Minifier failed for\n" + content);
089    
090                            unsyncStringWriter.append(content);
091                    }
092    
093                    return unsyncStringWriter.toString();
094            }
095    
096            private static Log _log = LogFactoryUtil.getLog(MinifierUtil.class);
097    
098            private static MinifierUtil _instance = new MinifierUtil();
099    
100            private class JavaScriptErrorReporter implements ErrorReporter {
101    
102                    @Override
103                    public void error(
104                            String message, String sourceName, int line, String lineSource,
105                            int lineOffset) {
106    
107                            if (line < 0) {
108                                    _log.error(message);
109                            }
110                            else {
111                                    _log.error(line + ": " + lineOffset + ": " + message);
112                            }
113                    }
114    
115                    @Override
116                    public EvaluatorException runtimeError(
117                            String message, String sourceName, int line, String lineSource,
118                            int lineOffset) {
119    
120                            error(message, sourceName, line, lineSource, lineOffset);
121    
122                            return new EvaluatorException(message);
123                    }
124    
125                    @Override
126                    public void warning(
127                            String message, String sourceName, int line, String lineSource,
128                            int lineOffset) {
129    
130                            if (!_log.isWarnEnabled()) {
131                                    return;
132                            }
133    
134                            if (line < 0) {
135                                    _log.warn(message);
136                            }
137                            else {
138                                    _log.warn(line + ": " + lineOffset + ": " + message);
139                            }
140                    }
141    
142            }
143    
144    }