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