1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.theme;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.apache.log4j.Logger;
20 import org.codehaus.plexus.util.FileUtils;
21 import org.kuali.common.util.Assert;
22 import org.kuali.rice.krad.theme.util.ThemeBuilderConstants;
23 import org.kuali.rice.krad.theme.util.ThemeBuilderUtils;
24
25 import java.io.File;
26 import java.io.IOException;
27 import java.util.ArrayList;
28 import java.util.Arrays;
29 import java.util.HashMap;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Properties;
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 public class ThemeBuilderOverlays {
50 private static final Logger LOG = Logger.getLogger(ThemeBuilder.class);
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 protected static void copyAssetsToWorkingDir(String webappSourceDir, String themeBuilderOutputDir,
71 List<String> additionalThemeDirectories, List<String> additionalPluginDirectories)
72 throws IOException {
73 Assert.hasText(themeBuilderOutputDir, "Working directory for theme builder not set");
74
75 File webappSource = new File(webappSourceDir);
76 if (!webappSource.exists()) {
77 throw new RuntimeException("Webapp source directory does not exist");
78 }
79
80 File workingDir = new File(themeBuilderOutputDir);
81 if (!workingDir.exists()) {
82 workingDir.mkdir();
83 }
84
85 workingDir.setWritable(true);
86
87 if (LOG.isDebugEnabled()) {
88 LOG.debug("Copying script, theme, plugin resource to working dir: " + themeBuilderOutputDir);
89 }
90
91 ThemeBuilderUtils.copyDirectory(
92 webappSourceDir + ThemeBuilderConstants.KRAD_SCRIPTS_DIRECTORY,
93 themeBuilderOutputDir + ThemeBuilderConstants.KRAD_SCRIPTS_DIRECTORY);
94
95 ThemeBuilderUtils.copyDirectory(
96 webappSourceDir + ThemeBuilderConstants.DEFAULT_THEMES_DIRECTORY,
97 themeBuilderOutputDir + ThemeBuilderConstants.DEFAULT_THEMES_DIRECTORY);
98
99 if (additionalThemeDirectories != null) {
100 for (String additionalThemeDirectory : additionalThemeDirectories) {
101 ThemeBuilderUtils.copyDirectory(webappSourceDir + additionalThemeDirectory,
102 themeBuilderOutputDir + additionalThemeDirectory);
103 }
104 }
105
106 ThemeBuilderUtils.copyDirectory(
107 webappSourceDir + ThemeBuilderConstants.DEFAULT_PLUGINS_DIRECTORY,
108 themeBuilderOutputDir + ThemeBuilderConstants.DEFAULT_PLUGINS_DIRECTORY);
109
110 if (additionalPluginDirectories != null) {
111 for (String additionalPluginDirectory : additionalPluginDirectories) {
112 ThemeBuilderUtils.copyDirectory(webappSourceDir + additionalPluginDirectory,
113 themeBuilderOutputDir + additionalPluginDirectory);
114 }
115 }
116 }
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138 protected static void overlayParentAssets(String themeName, File themeDirectory, Properties themeProperties,
139 Map<String, String> themeNamePathMapping) {
140 if (!themeProperties.containsKey(ThemeBuilderConstants.ThemeConfiguration.PARENT)) {
141 return;
142 }
143
144 String parentThemeName = themeProperties.getProperty(ThemeBuilderConstants.ThemeConfiguration.PARENT);
145 if (StringUtils.isBlank(parentThemeName)) {
146 return;
147 }
148
149 LOG.info("Overlaying assets from parent " + parentThemeName + " to child " + themeName);
150
151 String[] parentExcludes = ThemeBuilderUtils.getPropertyValueAsArray(
152 ThemeBuilderConstants.ThemeConfiguration.PARENT_EXCLUDES, themeProperties);
153
154 String parentThemePath = themeNamePathMapping.get(parentThemeName);
155
156 File parentThemeDirectory = new File(parentThemePath);
157 if (!parentThemeDirectory.exists()) {
158 throw new RuntimeException("Parent theme does not exist at path: " + parentThemePath);
159 }
160
161 List<String> copyDirectoryExcludes = new ArrayList<String>();
162 copyDirectoryExcludes.add(ThemeBuilderConstants.THEME_PROPERTIES_FILE);
163
164 if (parentExcludes != null) {
165 copyDirectoryExcludes.addAll(Arrays.asList(parentExcludes));
166 }
167
168 try {
169 ThemeBuilderUtils.copyMissingContent(parentThemeDirectory, themeDirectory, copyDirectoryExcludes);
170 } catch (IOException e) {
171 throw new RuntimeException("Unable to copy parent theme directory", e);
172 }
173 }
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192 protected static void overlayAdditionalDirs(File themeDirectory, Properties themeProperties, String webappSourceDir,
193 String themeBuilderOutputDir) {
194 if (!themeProperties.containsKey(ThemeBuilderConstants.ThemeConfiguration.ADDITIONAL_OVERLAYS)) {
195 return;
196 }
197
198 String additionalOverlaysStr = themeProperties.getProperty(
199 ThemeBuilderConstants.ThemeConfiguration.ADDITIONAL_OVERLAYS);
200
201 Map<String, String> additionalOverlays = parseAdditionalOverlaysStr(additionalOverlaysStr);
202
203 for (Map.Entry<String, String> overlayMapping : additionalOverlays.entrySet()) {
204 String fromSource = overlayMapping.getKey();
205 String toThemeDir = overlayMapping.getValue();
206
207 if (StringUtils.isBlank(fromSource)) {
208 throw new RuntimeException("Invalid additional overlay mapping, from directory is blank");
209 }
210
211 File sourceFile = null;
212 if (fromSource.startsWith("/")) {
213
214
215 sourceFile = new File(themeBuilderOutputDir + fromSource);
216 if (!sourceFile.exists()) {
217 sourceFile = new File(webappSourceDir + fromSource);
218 }
219 } else {
220
221 sourceFile = new File(themeDirectory, fromSource);
222 }
223
224 if (!sourceFile.exists()) {
225 throw new RuntimeException(
226 "Source directory/file for additional overlay does not exist at " + sourceFile.getPath());
227 }
228
229 File targetDir = null;
230 if (StringUtils.isBlank(toThemeDir)) {
231 targetDir = themeDirectory;
232 } else {
233 if (toThemeDir.startsWith("/")) {
234 toThemeDir = toThemeDir.substring(1);
235 }
236
237 targetDir = new File(themeDirectory, toThemeDir);
238 }
239
240 if (!targetDir.exists()) {
241 targetDir.mkdir();
242 }
243
244 try {
245 if (sourceFile.isDirectory()) {
246 ThemeBuilderUtils.copyMissingContent(sourceFile, targetDir, null);
247 } else {
248 File targetFile = new File(targetDir, sourceFile.getName());
249
250 FileUtils.copyFile(sourceFile, targetFile);
251 }
252 } catch (IOException e) {
253 throw new RuntimeException("Unable to perform additional overlay", e);
254 }
255 }
256 }
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272 protected static Map<String, String> parseAdditionalOverlaysStr(String additionalOverlaysStr) {
273 Map<String, String> additionalOverlays = new HashMap<String, String>();
274
275 if (StringUtils.isBlank(additionalOverlaysStr)) {
276 return additionalOverlays;
277 }
278
279 String[] additionalOverlaysArray = additionalOverlaysStr.split(",");
280 for (String additionalOverlay : additionalOverlaysArray) {
281 String fromDir = "";
282 String toDir = "";
283
284 if (additionalOverlay.contains("(") && additionalOverlay.contains(")")) {
285 fromDir = StringUtils.substringBefore(additionalOverlay, "(");
286 toDir = StringUtils.substringBetween(additionalOverlay, "(", ")");
287 } else {
288 fromDir = additionalOverlay;
289 }
290
291 additionalOverlays.put(StringUtils.trimToEmpty(fromDir), StringUtils.trimToEmpty(toDir));
292 }
293
294 return additionalOverlays;
295 }
296
297 }