1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.theme.postprocessor;
17
18 import com.google.javascript.jscomp.CompilationLevel;
19 import com.google.javascript.jscomp.Compiler;
20 import com.google.javascript.jscomp.CompilerOptions;
21 import com.google.javascript.jscomp.SourceFile;
22 import org.apache.commons.lang.StringUtils;
23 import org.apache.log4j.Logger;
24 import org.kuali.rice.krad.theme.util.ThemeBuilderConstants;
25 import org.kuali.rice.krad.theme.util.ThemeBuilderUtils;
26
27 import java.io.File;
28 import java.io.FileInputStream;
29 import java.io.FileOutputStream;
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.io.InputStreamReader;
33 import java.io.OutputStream;
34 import java.io.OutputStreamWriter;
35 import java.util.ArrayList;
36 import java.util.Arrays;
37 import java.util.Collections;
38 import java.util.List;
39 import java.util.Map;
40 import java.util.Properties;
41 import java.util.Set;
42 import java.util.HashSet;
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 public class ThemeJsFilesProcessor extends ThemeFilesProcessor {
58 private static final Logger LOG = Logger.getLogger(ThemeJsFilesProcessor.class);
59
60 public ThemeJsFilesProcessor(String themeName, File themeDirectory, Properties themeProperties,
61 Map<String, File> themePluginDirsMap, File workingDir, String projectVersion) {
62 super(themeName, themeDirectory, themeProperties, themePluginDirsMap, workingDir, projectVersion);
63 }
64
65
66
67
68 @Override
69 protected String getFileTypeExtension() {
70 return ThemeBuilderConstants.FileExtensions.JS;
71 }
72
73
74
75
76 @Override
77 protected String getExcludesConfigKey() {
78 return ThemeBuilderConstants.ThemeConfiguration.JS_EXCLUDES;
79 }
80
81
82
83
84 @Override
85 protected String getFileTypeDirectoryName() {
86 return ThemeBuilderConstants.ThemeDirectories.SCRIPTS;
87 }
88
89
90
91
92 @Override
93 protected String getFileListingConfigKey() {
94 return ThemeBuilderConstants.DerivedConfiguration.THEME_JS_FILES;
95 }
96
97
98
99
100
101
102 @Override
103 protected void addAdditionalFiles(List<File> themeFiles) {
104 File kradScriptDir = new File(this.workingDir, ThemeBuilderConstants.KRAD_SCRIPTS_DIRECTORY);
105
106 themeFiles.addAll(ThemeBuilderUtils.getDirectoryFiles(kradScriptDir, getFileIncludes(), null));
107 }
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130 @Override
131 protected List<File> sortThemeFiles(List<File> pluginFiles, List<File> subDirFiles) {
132 List<String> loadJsFirst = getThemePropertyValue(ThemeBuilderConstants.ThemeConfiguration.JS_LOAD_FIRST);
133 List<String> loadJsLast = getThemePropertyValue(ThemeBuilderConstants.ThemeConfiguration.JS_LOAD_LAST);
134
135 List<String> pluginJsLoadOrder = getThemePropertyValue(
136 ThemeBuilderConstants.ThemeConfiguration.PLUGIN_JS_LOAD_ORDER);
137 List<String> jsLoadOrder = getThemePropertyValue(ThemeBuilderConstants.ThemeConfiguration.THEME_JS_LOAD_ORDER);
138
139
140 List<String> kradScriptOrder = null;
141 try {
142 kradScriptOrder = retrieveKradScriptLoadOrder();
143 } catch (IOException e) {
144 throw new RuntimeException("Unable to pull KRAD load order property key", e);
145 }
146
147 if (kradScriptOrder != null) {
148 if (jsLoadOrder == null) {
149 jsLoadOrder = new ArrayList<String>();
150 }
151
152 jsLoadOrder.addAll(0, kradScriptOrder);
153 }
154
155 return ThemeBuilderUtils.orderFiles(pluginFiles, subDirFiles, loadJsFirst, loadJsLast, pluginJsLoadOrder,
156 jsLoadOrder);
157 }
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174 protected List<String> retrieveKradScriptLoadOrder() throws IOException {
175 List<String> scriptLoadOrder = new ArrayList<String>();
176
177 File kradScriptsDir = new File(this.workingDir, ThemeBuilderConstants.KRAD_SCRIPTS_DIRECTORY);
178
179 File loadPropertiesFile = new File(kradScriptsDir, ThemeBuilderConstants.KRAD_SCRIPT_LOAD_PROPERTIES_FILE);
180 if (!loadPropertiesFile.exists()) {
181 throw new RuntimeException("load.properties file not found in KRAD scripts directory");
182 }
183
184 Properties loadProperties = null;
185
186 FileInputStream fileInputStream = null;
187 try {
188 fileInputStream = new FileInputStream(loadPropertiesFile);
189
190 loadProperties = new Properties();
191 loadProperties.load(fileInputStream);
192 } finally {
193 if (fileInputStream != null) {
194 fileInputStream.close();
195 }
196 }
197
198
199 if (loadProperties.containsKey(ThemeBuilderConstants.LOAD_ORDER_PROPERTY_KEY)) {
200 scriptLoadOrder = ThemeBuilderUtils.getPropertyValueAsList(ThemeBuilderConstants.LOAD_ORDER_PROPERTY_KEY,
201 loadProperties);
202 }
203
204
205 List<String> scriptFileNames = ThemeBuilderUtils.getDirectoryFileNames(kradScriptsDir, null, null);
206 if (scriptFileNames != null) {
207 for (String scriptFileName : scriptFileNames) {
208
209 String baseScriptFileName = StringUtils.substringBeforeLast(scriptFileName, ".");
210
211 if (!scriptLoadOrder.contains(baseScriptFileName)) {
212 scriptLoadOrder.add(baseScriptFileName);
213 }
214 }
215 }
216
217 return scriptLoadOrder;
218 }
219
220
221
222
223
224
225
226 @Override
227 protected String processMergeFileContents(String fileContents, File fileToMerge, File mergedFile)
228 throws IOException {
229 if ((fileContents != null) && !fileContents.matches(
230 ThemeBuilderConstants.Patterns.JS_SEMICOLON_PATTERN)) {
231 fileContents += ";";
232 }
233
234 return fileContents;
235 }
236
237
238
239
240
241
242
243
244
245
246
247
248 @Override
249 protected void minify(File mergedFile, File minifiedFile) throws IOException {
250 InputStream in = null;
251 OutputStream out = null;
252 OutputStreamWriter writer = null;
253 InputStreamReader reader = null;
254
255 LOG.info("Populating minified JS file: " + minifiedFile.getPath());
256
257 try {
258 out = new FileOutputStream(minifiedFile);
259 writer = new OutputStreamWriter(out);
260
261 in = new FileInputStream(mergedFile);
262 reader = new InputStreamReader(in);
263
264 CompilerOptions options = new CompilerOptions();
265 CompilationLevel.SIMPLE_OPTIMIZATIONS.setOptionsForCompilationLevel(options);
266 options.setLanguageIn(CompilerOptions.LanguageMode.ECMASCRIPT5);
267 options.setExtraAnnotationNames(ignoredAnnotations());
268
269 SourceFile input = SourceFile.fromInputStream(mergedFile.getName(), in);
270 List<SourceFile> externs = Collections.emptyList();
271
272 Compiler compiler = new Compiler();
273 compiler.compile(externs, Arrays.asList(input), options);
274
275 writer.append(compiler.toSource());
276 writer.flush();
277 } finally {
278 if (in != null) {
279 in.close();
280 }
281
282 if (out != null) {
283 out.close();
284 }
285 }
286 }
287
288
289
290
291
292
293 protected Set<String> ignoredAnnotations() {
294 Set<String> annotations = new HashSet<String>();
295 annotations.add("dtopt");
296 annotations.add("result");
297 annotations.add("cat");
298 annotations.add("parm");
299
300 return annotations;
301 }
302
303 }