001/*
002 * Minify Maven Plugin
003 * https://github.com/samaxes/minify-maven-plugin
004 *
005 * Copyright (c) 2009 samaxes.com
006 *
007 * Licensed under the Apache License, Version 2.0 (the "License");
008 * you may not use this file except in compliance with the License.
009 * You may obtain a copy of the License at
010 *
011 *      http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 */
019package com.samaxes.maven.minify.common;
020
021import com.google.common.base.Strings;
022import com.google.javascript.jscomp.*;
023import com.google.javascript.jscomp.CompilerOptions.LanguageMode;
024import com.google.javascript.jscomp.SourceMap.Format;
025
026import java.util.HashMap;
027import java.util.List;
028import java.util.Map;
029
030/**
031 * <a href="https://developers.google.com/closure/compiler/">Google Closure Compiler</a> configuration.
032 */
033public class ClosureConfig {
034
035    private final LanguageMode languageIn;
036
037    private final LanguageMode languageOut;
038
039    private final CompilerOptions.Environment environment;
040
041    private final CompilationLevel compilationLevel;
042
043    private final DependencyOptions dependencyOptions;
044
045    private final List<SourceFile> externs;
046
047    private final Format sourceMapFormat;
048
049    private final Map<DiagnosticGroup, CheckLevel> warningLevels;
050
051    private final Boolean colorizeErrorOutput;
052
053    private final Boolean angularPass;
054
055    private final List<String> extraAnnotations;
056
057    private final Map<String, Object> defineReplacements = new HashMap<>();
058
059    /**
060     * Init Closure Compiler values.
061     *
062     * @param languageIn         the version of ECMAScript used to report errors in the code
063     * @param languageOut        the version of ECMAScript the code will be returned in
064     * @param environment        the set of builtin externs to load
065     * @param compilationLevel   the degree of compression and optimization to apply to JavaScript
066     * @param dependencyOptions  options for how to manage dependencies between input files
067     * @param externs            preserve symbols that are defined outside of the code you are compiling
068     * @param createSourceMap    create a source map for the minifed/combined production files
069     * @param warningLevels      a map of warnings to enable or disable in the compiler
070     * @param angularPass        use {@code @ngInject} annotation to generate Angular injections
071     * @param extraAnnotations   make extra annotations known to the closure engine
072     * @param defineReplacements replacements for {@code @defines}
073     */
074    public ClosureConfig(LanguageMode languageIn, LanguageMode languageOut, CompilerOptions.Environment environment,
075                         CompilationLevel compilationLevel, DependencyOptions dependencyOptions,
076                         List<SourceFile> externs, boolean createSourceMap,
077                         Map<DiagnosticGroup, CheckLevel> warningLevels, boolean angularPass,
078                         List<String> extraAnnotations, Map<String, String> defineReplacements) {
079        this.languageIn = languageIn;
080        this.languageOut = languageOut;
081        this.environment = environment;
082        this.compilationLevel = compilationLevel;
083        this.dependencyOptions = dependencyOptions;
084        this.externs = externs;
085        this.sourceMapFormat = (createSourceMap) ? SourceMap.Format.V3 : null;
086        this.warningLevels = warningLevels;
087        this.colorizeErrorOutput = Boolean.TRUE;
088        this.angularPass = angularPass;
089        this.extraAnnotations = extraAnnotations;
090
091        for (Map.Entry<String, String> defineReplacement : defineReplacements.entrySet()) {
092            if (Strings.isNullOrEmpty(defineReplacement.getValue())) {
093                throw new RuntimeException("Define replacement " + defineReplacement.getKey() + " does not have a value.");
094            }
095
096            if (String.valueOf(true).equals(defineReplacement.getValue()) ||
097                    String.valueOf(false).equals(defineReplacement.getValue())) {
098                this.defineReplacements.put(defineReplacement.getKey(), Boolean.valueOf(defineReplacement.getValue()));
099                continue;
100            }
101
102            try {
103                this.defineReplacements.put(defineReplacement.getKey(), Integer.valueOf(defineReplacement.getValue()));
104                continue;
105            } catch (NumberFormatException e) {
106                // Not a valid Integer, try next type
107            }
108
109            try {
110                this.defineReplacements.put(defineReplacement.getKey(), Double.valueOf(defineReplacement.getValue()));
111                continue;
112            } catch (NumberFormatException e) {
113                // Not a valid Double, try next type
114            }
115
116            this.defineReplacements.put(defineReplacement.getKey(), defineReplacement.getValue());
117        }
118    }
119
120    /**
121     * Gets the languageIn.
122     *
123     * @return the languageIn
124     */
125    public LanguageMode getLanguageIn() {
126        return languageIn;
127    }
128
129    /**
130     * Gets the languageOut.
131     *
132     * @return the languageOut
133     */
134    public LanguageMode getLanguageOut() {
135        return languageOut;
136    }
137
138    /**
139     * Gets the environment.
140     *
141     * @return the environment
142     */
143    public CompilerOptions.Environment getEnvironment() {
144        return environment;
145    }
146
147    /**
148     * Gets the compilationLevel.
149     *
150     * @return the compilationLevel
151     */
152    public CompilationLevel getCompilationLevel() {
153        return compilationLevel;
154    }
155
156    /**
157     * Gets the dependencyOptions.
158     *
159     * @return the dependencyOptions
160     */
161    public DependencyOptions getDependencyOptions() {
162        return dependencyOptions;
163    }
164
165    /**
166     * Gets the externs.
167     *
168     * @return the externs
169     */
170    public List<SourceFile> getExterns() {
171        return externs;
172    }
173
174    /**
175     * Gets the sourceMapFormat.
176     *
177     * @return the sourceMapFormat
178     */
179    public Format getSourceMapFormat() {
180        return sourceMapFormat;
181    }
182
183    /**
184     * Gets the warningLevels.
185     *
186     * @return the warningLevels
187     */
188    public Map<DiagnosticGroup, CheckLevel> getWarningLevels() {
189        return warningLevels;
190    }
191
192    /**
193     * Gets the colorizeErrorOutput.
194     *
195     * @return the colorizeErrorOutput
196     */
197    public Boolean getColorizeErrorOutput() {
198        return colorizeErrorOutput;
199    }
200
201    /**
202     * Gets the angularPass.
203     *
204     * @return the angularPass
205     */
206    public Boolean getAngularPass() {
207        return angularPass;
208    }
209
210    /**
211     * Gets the extraAnnotations.
212     *
213     * @return the extraAnnotations
214     */
215    public List<String> getExtraAnnotations() {
216        return extraAnnotations;
217    }
218
219    /**
220     * Gets the defineReplacements.
221     *
222     * @return the defineReplacements
223     */
224    public Map<String, Object> getDefineReplacements() {
225        return defineReplacements;
226    }
227}