1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 public class ArtifactInstaller {
27 private Log log;
28 static final String FILE_SEP = System.getProperty("file.separator");
29 Project antProject;
30 String pojoName;
31 String pojoNameLower;
32 String destinationDirectory;
33 String sourceDirectory;
34 MavenProject project;
35 boolean genericCore;
36 StringUtils util;
37
38 public ArtifactInstaller(MavenProject project, String pojoName, String sourceDirectory, String destinationDirectory, boolean genericCore) {
39 this.project = project;
40 this.pojoName = pojoName;
41 this.pojoNameLower = pojoLowerCase(pojoName);
42 this.sourceDirectory = sourceDirectory;
43 this.destinationDirectory = destinationDirectory;
44 this.genericCore = genericCore;
45 this.util = new StringUtils();
46 }
47
48 public void execute() {
49 antProject = AntUtils.createProject();
50
51 boolean hasDbUnit = projectContainsPluginArtifact("dbunit");
52
53 if (hasDbUnit) {
54 log("Installing sample data for DbUnit...");
55 installSampleData();
56 }
57
58
59 if (project.getPackaging().equals("jar") || (project.getPackaging().equals("war") && project.getParent() == null)) {
60 copyGeneratedObjects(this.sourceDirectory, this.destinationDirectory, "**/model/**/*.java");
61 copyGeneratedObjects(this.sourceDirectory, this.destinationDirectory, "**/dao/**/*.java");
62 copyGeneratedObjects(this.sourceDirectory, this.destinationDirectory, "**/service/**/*.java");
63 if (genericCore) {
64 log("Installing Spring bean definitions (genericCore == true)...");
65 installGenericBeanDefinitions();
66 } else {
67
68
69 }
70
71 installiBATISFiles();
72 }
73
74 if (project.getPackaging().equalsIgnoreCase("war")) {
75 copyGeneratedObjects(this.sourceDirectory, this.destinationDirectory, "**/webapp/**/*.java");
76
77 String webFramework = project.getProperties().getProperty("web.framework");
78
79 if ("jsf".equalsIgnoreCase(webFramework)) {
80 log("Installing JSF views and configuring...");
81 installJSFNavigationAndBeans();
82 installJSFViews();
83 } else if ("struts".equalsIgnoreCase(webFramework)) {
84 log("Installing Struts views and configuring...");
85
86
87 installStrutsActionDefinitions();
88 copyGeneratedObjects(sourceDirectory + "/src/main/resources",
89 destinationDirectory + "/src/main/resources", "**/model/*.xml");
90 copyGeneratedObjects(sourceDirectory + "/src/main/resources",
91 destinationDirectory + "/src/main/resources", "**/webapp/action/*.xml");
92 installStrutsViews();
93 } else if ("spring".equalsIgnoreCase(webFramework)) {
94 log("Installing Spring views and configuring...");
95
96
97 installSpringValidation();
98 installSpringViews();
99 } else if ("tapestry".equalsIgnoreCase(webFramework)) {
100 log("Installing Tapestry views and configuring...");
101 installTapestryViews();
102 }
103
104 log("Installing i18n messages...");
105 installInternationalizationKeys(webFramework);
106
107 log("Installing menu...");
108 installMenu();
109
110 log("Installing UI tests...");
111 installUITests();
112 }
113 }
114
115 private boolean projectContainsPluginArtifact(String artifactId) {
116 for (Object artifact : project.getPluginArtifacts()) {
117 if (((Artifact) artifact).getArtifactId().contains(artifactId)) {
118 return true;
119 }
120 }
121 return false;
122 }
123
124 private boolean projectContainsArtifact(String artifactId) {
125 for (Object artifact : project.getArtifacts()) {
126 if (((Artifact) artifact).getArtifactId().contains(artifactId)) {
127 return true;
128 }
129 }
130 return false;
131 }
132
133
134
135
136
137
138
139
140
141 protected void copyGeneratedObjects(final String inSourceDirectory, final String inDestinationDirectory,
142 final String inPattern) {
143 Copy copyTask = (Copy) antProject.createTask("copy");
144
145 FileSet fileSet = AntUtils.createFileset(inSourceDirectory, inPattern, new ArrayList());
146 log("Installing generated files (pattern: " + inPattern + ")...");
147 copyTask.setTodir(new File(inDestinationDirectory));
148 copyTask.addFileset(fileSet);
149 copyTask.execute();
150 }
151
152 private String pojoLowerCase(String name) {
153 return name.substring(0, 1).toLowerCase() + name.substring(1);
154 }
155
156 private String getPathToApplicationContext() {
157 if (project.getPackaging().equalsIgnoreCase("war")) {
158 return "/src/main/webapp/WEB-INF/applicationContext.xml";
159 } else {
160 return "/src/main/resources/applicationContext.xml";
161 }
162 }
163
164
165
166
167 private void installSampleData() {
168 createLoadFileTask("src/test/resources/" + pojoName + "-sample-data.xml", "sample.data").execute();
169 File existingFile = new File(destinationDirectory + "/src/test/resources/sample-data.xml");
170
171 parseXMLFile(existingFile, null, "</dataset>", "sample.data");
172 }
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187 private void installiBATISFiles() {
188 if (project.getProperties().getProperty("dao.framework").equals("ibatis")) {
189 log("Installing iBATIS SQL Maps...");
190 createLoadFileTask("src/main/resources/" + pojoName + "-sql-map-config.xml", "sql.map.config").execute();
191 File sqlMapConfig = new File(destinationDirectory + "/src/main/resources/sql-map-config.xml");
192 parseXMLFile(sqlMapConfig, null, "</sqlMapConfig>", "sql.map.config");
193
194 File sqlMapsDir = new File(destinationDirectory + "/src/main/resources/sqlmaps");
195 if (sqlMapsDir.exists()) {
196 sqlMapsDir.mkdir();
197 }
198
199 Copy copy = (Copy) antProject.createTask("copy");
200 copy.setFile(new File(sourceDirectory + "/src/main/resources/sqlmaps/" + pojoName + "SQL.xml"));
201 copy.setTodir(new File(destinationDirectory + "/src/main/resources/sqlmaps"));
202 copy.execute();
203
204
205 File ctx = new File(destinationDirectory + "/src/main/webapp/WEB-INF/applicationContext.xml");
206 try {
207 File appCtx = new File(destinationDirectory + "/src/main/webapp/WEB-INF/applicationContext.xml");
208 String appCtxAsString = FileUtils.readFileToString(ctx);
209 if (!appCtxAsString.contains("SqlMapClientGpsDevice")) {
210 log("Adding compassGps bean to applicationContext.xml");
211 createLoadFileTask("src/main/resources/compass-gps.xml", "compass.gps").execute();
212 parseXMLFile(appCtx, null, "<!-- Add new DAOs here -->", "compass.gps");
213 }
214
215 if (!appCtxAsString.contains("<value>get" + pojoName)) {
216
217 createLoadFileTask("src/main/resources/" + pojoName + "-select-ids.xml", "select.ids").execute();
218 parseXMLFile(appCtx, null, "<value>getUsers</value>", "select.ids");
219 }
220 } catch (IOException e) {
221 log("Failed to read project's applicationContext.xml!");
222 e.printStackTrace();
223 }
224 }
225 }
226
227 private void installGenericBeanDefinitions() {
228 createLoadFileTask("src/main/resources/" + pojoName + "-generic-beans.xml", "context.file").execute();
229 File generatedFile = new File(destinationDirectory + getPathToApplicationContext());
230
231 parseXMLFile(generatedFile, pojoName + "Manager", "<!-- Add new Managers here -->", "context.file");
232 }
233
234 private void installJSFNavigationAndBeans() {
235 createLoadFileTask("src/main/webapp/WEB-INF/" + pojoName + "-navigation.xml", "navigation.rules").execute();
236 File generatedFile = new File(destinationDirectory + "/src/main/webapp/WEB-INF/faces-config.xml");
237 parseXMLFile(generatedFile, pojoName + "-nav", "<!-- Add additional rules here -->", "navigation.rules");
238
239
240
241
242
243 }
244
245 private void installSpringControllerBeanDefinitions() {
246
247
248
249
250
251 }
252
253 private void installSpringValidation() {
254 createLoadFileTask("src/main/webapp/WEB-INF/" + pojoName + "-validation.xml", "spring.validation").execute();
255 File generatedFile = new File(destinationDirectory + "/src/main/webapp/WEB-INF/validation.xml");
256
257 parseXMLFile(generatedFile, pojoName, " </formset>", "spring.validation");
258 }
259
260 private void installStrutsActionDefinitions() {
261 createLoadFileTask("src/main/resources/" + pojoName + "-struts.xml", "struts.file").execute();
262 File existingFile = new File(destinationDirectory + "/src/main/resources/struts.xml");
263
264 parseXMLFile(existingFile, pojoName + "Action", "<!-- Add additional actions here -->", "struts.file");
265 }
266
267
268
269 private void installJSFViews() {
270 Copy copy = (Copy) antProject.createTask("copy");
271 copy.setFile(new File(sourceDirectory + "/src/main/webapp/" + pojoName + "Form.xhtml"));
272 copy.setTofile(new File(destinationDirectory + "/src/main/webapp/" + pojoNameLower + "Form.xhtml"));
273 copy.execute();
274
275 copy.setFile(new File(sourceDirectory + "/src/main/webapp/" + pojoName + "s.xhtml"));
276 copy.setTofile(new File(destinationDirectory + "/src/main/webapp/" + util.getPluralForWord(pojoNameLower) + ".xhtml"));
277 copy.execute();
278 }
279
280 private void installSpringViews() {
281 Copy copy = (Copy) antProject.createTask("copy");
282 copy.setFile(new File(sourceDirectory + "/src/main/webapp/WEB-INF/pages/" + pojoName + "form.jsp"));
283 copy.setTofile(new File(destinationDirectory + "/src/main/webapp/WEB-INF/pages/" + pojoNameLower + "form.jsp"));
284 copy.execute();
285
286 copy.setFile(new File(sourceDirectory + "/src/main/webapp/WEB-INF/pages/" + pojoName + "s.jsp"));
287 copy.setTofile(new File(destinationDirectory + "/src/main/webapp/WEB-INF/pages/" + util.getPluralForWord(pojoNameLower) + ".jsp"));
288 copy.execute();
289 }
290
291 private void installStrutsViews() {
292 Copy copy = (Copy) antProject.createTask("copy");
293 copy.setFile(new File(sourceDirectory + "/src/main/webapp/WEB-INF/pages/" + pojoName + "Form.jsp"));
294 copy.setTofile(new File(destinationDirectory + "/src/main/webapp/WEB-INF/pages/" + pojoNameLower + "Form.jsp"));
295 copy.execute();
296
297 copy.setFile(new File(sourceDirectory + "/src/main/webapp/WEB-INF/pages/" + pojoName + "List.jsp"));
298 copy.setTofile(new File(destinationDirectory + "/src/main/webapp/WEB-INF/pages/" + pojoNameLower + "List.jsp"));
299 copy.execute();
300 }
301
302 private void installTapestryViews() {
303 Copy copy = (Copy) antProject.createTask("copy");
304 copy.setFile(new File(sourceDirectory + "/src/main/webapp/" + pojoName + "Form.tml"));
305 copy.setTodir(new File(destinationDirectory + "/src/main/webapp"));
306 copy.execute();
307
308 copy.setFile(new File(sourceDirectory + "/src/main/webapp/" + pojoName + "List.tml"));
309 copy.execute();
310 }
311
312
313
314 private void installMenu() {
315 boolean hasStrutsMenu;
316 File menuConfig = new File(destinationDirectory + "/src/main/webapp/WEB-INF/menu-config.xml");
317 hasStrutsMenu = menuConfig.exists();
318
319 if (hasStrutsMenu) {
320 createLoadFileTask("src/main/webapp/common/" + pojoName + "-menu.jsp", "menu.jsp").execute();
321 File existingFile = new File(destinationDirectory + "/src/main/webapp/common/menu.jsp");
322
323 parseXMLFile(existingFile, pojoName, "</ul>", "menu.jsp");
324
325 createLoadFileTask("src/main/webapp/WEB-INF/" + pojoName + "-menu-config.xml", "menu.config").execute();
326 existingFile = new File(destinationDirectory + "/src/main/webapp/WEB-INF/menu-config.xml");
327
328 parseXMLFile(existingFile, pojoName, " </Menus>", "menu.config");
329 } else {
330 createLoadFileTask("src/main/webapp/common/" + pojoName + "-menu-light.jsp", "menu-light.jsp").execute();
331 File existingFile = new File(destinationDirectory + "/src/main/webapp/decorators/default.jsp");
332
333 parseXMLFile(existingFile, pojoName, "<!-- Add new menu items here -->", "menu-light.jsp");
334 }
335 }
336
337 private void installInternationalizationKeys(String webFramework) {
338 createLoadFileTask("src/main/resources/" + pojoName + "-ApplicationResources.properties", "i18n.file").execute();
339 File existingFile = new File(destinationDirectory + "/src/main/resources/ApplicationResources.properties");
340
341
342 if (!existingFile.exists()) {
343 existingFile = new File(destinationDirectory + "/src/main/resources/messages.properties");
344
345
346
347
348
349
350 }
351
352 parsePropertiesFile(existingFile, pojoName);
353
354 Echo echoTask = (Echo) antProject.createTask("echo");
355 echoTask.setFile(existingFile);
356 echoTask.setAppend(true);
357 echoTask.setMessage(antProject.getProperty("i18n.file"));
358 echoTask.execute();
359 }
360
361 private void installUITests() {
362
363 boolean webTestsExist = new File("src/test/resources/" + pojoName + "-web-tests.xml").exists();
364 File existingFile = new File(destinationDirectory + "/src/test/resources/web-tests.xml");
365 if (webTestsExist && existingFile.exists()) {
366 createLoadFileTask("src/test/resources/" + pojoName + "-web-tests.xml", "web.tests").execute();
367 parseXMLFile(existingFile, pojoName, "</project>", "web.tests");
368
369
370 Replace replace = (Replace) antProject.createTask("replace");
371 replace.setFile(existingFile);
372
373 try {
374 if (FileUtils.readFileToString(existingFile).contains("FileUpload")) {
375
376
377 replace.setToken(",FileUpload");
378 replace.setValue(",FileUpload," + pojoName + "Tests");
379 } else {
380
381 replace.setToken("depends=\"UserTests");
382 replace.setValue("depends=\"UserTests," + pojoName + "Tests");
383 }
384 } catch (IOException e) {
385 e.printStackTrace();
386 }
387 replace.execute();
388 } else {
389 log("Project doesn't use Canoo WebTest, disabling UI test generation.");
390 log("Support for jWebUnit will be added in a future release.");
391 log("See http://issues.appfuse.org/browse/EQX-215 for more information.");
392 }
393 }
394
395
396
397
398
399
400
401
402
403 protected LoadFile createLoadFileTask(String inFile, String propName) {
404 inFile = sourceDirectory + FILE_SEP + inFile;
405 LoadFile loadFileTask = (LoadFile) antProject.createTask("loadfile");
406 loadFileTask.init();
407 loadFileTask.setProperty(propName);
408 loadFileTask.setSrcFile(new File(inFile));
409
410 return loadFileTask;
411 }
412
413 private void parseXMLFile(File existingFile, String beanName, String tokenToReplace, String fileVariable) {
414 String nameInComment = beanName;
415 if (beanName == null) {
416 nameInComment = pojoName;
417 }
418 Replace replace1 = (Replace) antProject.createTask("replace");
419 replace1.setFile(existingFile);
420 replace1.setToken("<!--" + nameInComment + "-START-->");
421 replace1.setValue("REGULAR-START");
422 replace1.execute();
423
424 Replace replace2 = (Replace) antProject.createTask("replace");
425 replace2.setFile(existingFile);
426 replace2.setToken("<!--" + nameInComment + "-END-->");
427 replace2.setValue("REGULAR-END");
428 replace2.execute();
429
430 ReplaceRegExp regExpTask = (ReplaceRegExp) antProject.createTask("replaceregexp");
431 regExpTask.setFile(existingFile);
432 regExpTask.setMatch("REGULAR-START(?s:.)*REGULAR-END");
433 regExpTask.setReplace("");
434 regExpTask.setFlags("g");
435 regExpTask.execute();
436
437 Replace replaceData = (Replace) antProject.createTask("replace");
438 replaceData.setFile(existingFile);
439 replaceData.setToken(tokenToReplace);
440 String stringWithProperLineEndings = adjustLineEndingsForOS(antProject.getProperty(fileVariable));
441 replaceData.setValue(stringWithProperLineEndings);
442 replaceData.execute();
443 }
444
445
446
447
448
449
450
451
452 private void parsePropertiesFile(File existingFile, String beanName) {
453 String nameInComment = beanName;
454 if (beanName == null) {
455 nameInComment = pojoName;
456 }
457
458 Replace replace1 = (Replace) antProject.createTask("replace");
459 replace1.setFile(existingFile);
460 replace1.setToken("# -- " + nameInComment + "-START");
461 replace1.setValue("REGULAR-START");
462 replace1.execute();
463
464 Replace replace2 = (Replace) antProject.createTask("replace");
465 replace2.setFile(existingFile);
466 replace2.setToken("# -- " + nameInComment + "-END");
467 replace2.setValue("REGULAR-END");
468 replace2.execute();
469
470 ReplaceRegExp regExpTask = (ReplaceRegExp) antProject.createTask("replaceregexp");
471 regExpTask.setFile(existingFile);
472 regExpTask.setMatch("REGULAR-START(?s:.)*REGULAR-END");
473 regExpTask.setReplace("");
474 regExpTask.setFlags("g");
475 regExpTask.execute();
476 }
477
478 private static String adjustLineEndingsForOS(String property) {
479 String os = System.getProperty("os.name");
480
481 if (os.startsWith("Linux") || os.startsWith("Mac")) {
482
483 property = property.replaceAll("\r", "");
484 } else if (os.startsWith("Windows")) {
485
486 property = property.replaceAll(">\n", ">\r\n");
487 }
488
489 return property;
490 }
491
492 private void log(String msg) {
493 getLog().info("[AppFuse] " + msg);
494 }
495
496 public Log getLog() {
497 if (log == null) {
498 log = new SystemStreamLog();
499 }
500
501 return log;
502 }
503
504 public void setProject(MavenProject project) {
505 this.project = project;
506 }
507
508 public void setGenericCore(boolean genericCore) {
509 this.genericCore = genericCore;
510 }
511 }