1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.springframework.roo.addon.surf;
20
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.util.List;
24 import java.util.logging.Logger;
25
26 import org.springframework.roo.addon.surf.site.SiteOperations;
27 import org.springframework.roo.addon.surf.util.SurfUtils;
28 import org.springframework.roo.metadata.MetadataService;
29 import org.springframework.roo.process.manager.FileManager;
30 import org.springframework.roo.process.manager.MutableFile;
31 import org.springframework.roo.project.Dependency;
32 import org.springframework.roo.project.Path;
33 import org.springframework.roo.project.PathResolver;
34 import org.springframework.roo.project.ProjectMetadata;
35 import org.springframework.roo.project.ProjectOperations;
36 import org.springframework.roo.project.ProjectType;
37 import org.springframework.roo.support.lifecycle.ScopeDevelopment;
38 import org.springframework.roo.support.util.Assert;
39 import org.springframework.roo.support.util.FileCopyUtils;
40 import org.springframework.roo.support.util.TemplateUtils;
41 import org.springframework.roo.support.util.XmlUtils;
42
43 import org.w3c.dom.Comment;
44 import org.w3c.dom.Document;
45 import org.w3c.dom.Element;
46 import org.w3c.dom.Node;
47
48
49
50
51
52
53
54 @ScopeDevelopment
55 public class SurfOperations
56 {
57 private static final String RELATIVE_PATH_POM_XML = "pom.xml";
58 private static final String RELATIVE_PATH_SURF_CONFIG_XML = "WEB-INF/config/surf-config.xml";
59 private static final String RELATIVE_PATH_SURF_INTEROP_XML = "WEB-INF/config/surf-interop-config.xml";
60 private static final String RELATIVE_PATH_WEB_APPLICATION_CONFIG_XML = "WEB-INF/config/web-application-config.xml";
61 private static final String RELATIVE_PATH_WEB_XML = "WEB-INF/web.xml";
62 private static final String RELATIVE_PATH_SURF_XML = "WEB-INF/surf.xml";
63 private static final String RELATIVE_RATH_URLREWRITE_XML = "WEB-INF/urlrewrite.xml";
64
65 private static final String RELATIVE_PATH_WEB_XML_TEMPLATE = "web.xml";
66 private static final String RELATIVE_PATH_DEPENDENCIES_TEMPLATE = "dependencies.xml";
67 private static final String RELATIVE_PATH_PHP_DEPENDENCIES_TEMPLATE = "php-dependencies.xml";
68 private static final String RELATIVE_PATH_GROOVY_DEPENDENCIES_TEMPLATE = "groovy-dependencies.xml";
69 private static final String RELATIVE_PATH_WEBSTUDIO_DEPENDENCIES_TEMPLATE = "webstudio-dependencies.xml";
70
71 private static final String FILENAME_SURF_SAMPLE_SITE = "surf-sample-site";
72 private static final String FILENAME_CMIS_SAMPLES = "surf-cmis-samples";
73 private static final String FILENAME_ALFRESCO_SAMPLES = "surf-alfresco-samples";
74
75 private static final String DEFAULT_HOME_PAGE_NAME = "home";
76
77 Logger logger = Logger.getLogger(SurfOperations.class.getName());
78
79 private FileManager fileManager;
80 private PathResolver pathResolver;
81 private MetadataService metadataService;
82 private ProjectOperations projectOperations;
83
84
85
86
87
88
89
90 public SurfOperations(FileManager fileManager, PathResolver pathResolver, MetadataService metadataService, ProjectOperations projectOperations)
91 {
92 Assert.notNull(fileManager, "File manager required");
93 Assert.notNull(pathResolver, "Path resolver required");
94 Assert.notNull(metadataService, "Metadata service required");
95 Assert.notNull(projectOperations, "Project operations required");
96 this.fileManager = fileManager;
97 this.pathResolver = pathResolver;
98 this.metadataService = metadataService;
99 this.projectOperations = projectOperations;
100 }
101
102
103
104
105
106 public boolean isInstallSurfAvailable()
107 {
108 return getPathResolver() != null && !fileManager.exists(getPathResolver().getIdentifier(Path.SRC_MAIN_WEBAPP, RELATIVE_PATH_SURF_XML));
109 }
110
111
112
113
114
115 public boolean isManageSurfAvailable() {
116 return fileManager.exists(getPathResolver().getIdentifier(Path.SRC_MAIN_WEBAPP, RELATIVE_PATH_SURF_XML));
117 }
118
119
120
121
122
123 public void installSurf(String siteName)
124 {
125
126 if (siteName==null || siteName.equals(""))
127 {
128 ProjectMetadata projectMetadata = (ProjectMetadata) metadataService.get(ProjectMetadata.getProjectIdentifier());
129 siteName = projectMetadata.getProjectName();
130 }
131
132
133 installSurfConfigXmls();
134
135
136 processWebXml();
137
138
139 processMavenXml();
140
141
142 processUrlRewrite();
143
144
145 processSurfXml();
146
147
148 updateDependencies();
149
150
151
152 installSurfSampleSite();
153
154
155 SiteOperations siteOperations = new SiteOperations(fileManager, pathResolver, metadataService, projectOperations);
156 siteOperations.newSite(null, DEFAULT_HOME_PAGE_NAME);
157
158 }
159
160
161
162
163 private void processMavenXml(){
164
165
166
167 }
168
169
170
171
172 private void processUrlRewrite()
173 {
174 if ( copySurfTemplate(Path.SRC_MAIN_WEBAPP, RELATIVE_RATH_URLREWRITE_XML, false) ) {
175
176
177 String urlrewritePath = pathResolver.getIdentifier(Path.SRC_MAIN_WEBAPP, RELATIVE_RATH_URLREWRITE_XML);
178
179 Document urlrewrite = getXmlDocument(urlrewritePath);
180
181 Element root = urlrewrite.getDocumentElement();
182
183
184 updateRule(urlrewrite,root,"/**", "/page/$1");
185 updateRule(urlrewrite,root,"/page/**", "/page/$1");
186 updateRule(urlrewrite,root,"/res/**", "/page/resource/$1");
187 updateRule(urlrewrite,root,"/endpoint/**", "/page/endpoint/$1");
188 Element newRuleElem1 = updateRule(urlrewrite,root,"/proxy**", "/page/proxy/$1");
189
190
191 root.insertBefore(urlrewrite.createTextNode("\n"), newRuleElem1);
192 root.insertBefore(urlrewrite.createTextNode("\t"), newRuleElem1);
193 root.insertBefore(urlrewrite.createComment("Required for Surf - Redirects"), newRuleElem1);
194 root.insertBefore(urlrewrite.createTextNode("\n"), newRuleElem1);
195
196
197 updateOutboundRule(urlrewrite,root,"/page/**", "/$1");
198
199
200 updateXmlDocument(urlrewritePath,urlrewrite);
201 }
202 }
203
204
205
206
207
208
209 private void installSurfConfigXmls()
210 {
211
212 copySurfTemplate(Path.SRC_MAIN_WEBAPP, RELATIVE_PATH_SURF_CONFIG_XML, false);
213
214 copySurfTemplate(Path.SRC_MAIN_WEBAPP, RELATIVE_PATH_SURF_INTEROP_XML, false);
215
216 copySurfTemplate(Path.SRC_MAIN_WEBAPP, RELATIVE_PATH_WEB_APPLICATION_CONFIG_XML, false);
217
218 }
219
220
221
222
223 private void processWebXml(){
224
225 String webXmlPath = pathResolver.getIdentifier(Path.SRC_MAIN_WEBAPP, RELATIVE_PATH_WEB_XML);
226
227 if ( copySurfTemplate(Path.SRC_MAIN_WEBAPP, RELATIVE_PATH_WEB_XML, false)) {
228
229 Document webXml = getXmlDocument(webXmlPath);
230 Element root = webXml.getDocumentElement();
231
232 Document webXmlTemplate = getTemplateDocument(RELATIVE_PATH_WEB_XML_TEMPLATE);
233 Element webXmlElement = webXmlTemplate.getDocumentElement();
234
235 Element webAppElem = XmlUtils.findFirstElement("/web-app", root);
236
237 if ( webAppElem==null ) {
238 throw new IllegalStateException("This command cannot be run for an invalid web.xml.");
239 }
240
241
242 List<Element> surfFilters = XmlUtils.findElements("/web-app/surf/filter", webXmlElement);
243 for(Element filter : surfFilters)
244 {
245 if (filter.hasChildNodes() && filter.getElementsByTagName("filter-name").getLength() > 0) {
246 String filterName = filter.getElementsByTagName("filter-name").item(0).getTextContent().trim();
247
248 Element filterElem = XmlUtils.findFirstElement("/web-app/filter[filter-name='"+filterName+"']", root);
249
250 if ( filterElem != null) {
251 webAppElem.removeChild(filterElem);
252 }
253
254 webAppElem.appendChild(webXml.importNode(filter,true));
255 }
256 }
257
258
259 List<Element> surfFilterMappings = XmlUtils.findElements("/web-app/surf/filter-mapping", webXmlElement);
260 for(Element filterMapping : surfFilterMappings)
261 {
262 if (filterMapping.hasChildNodes() && filterMapping.getElementsByTagName("filter-name").getLength() > 0) {
263 String filterName = filterMapping.getElementsByTagName("filter-name").item(0).getTextContent().trim();
264
265 Element filterMappingElem = XmlUtils.findFirstElement("/web-app/filter-mapping[filter-name='"+filterName+"']", root);
266
267 if ( filterMappingElem != null) {
268 webAppElem.removeChild(filterMappingElem);
269 }
270
271 webAppElem.appendChild(webXml.importNode(filterMapping,true));
272 }
273 }
274
275
276 List<Element> surfServlets = XmlUtils.findElements("/web-app/surf/servlet", webXmlElement);
277 for(Element servlet : surfServlets)
278 {
279 if (servlet.hasChildNodes() && servlet.getElementsByTagName("servlet-name").getLength() > 0) {
280 String servletName = servlet.getElementsByTagName("servlet-name").item(0).getTextContent().trim();
281
282 Element servletElem = XmlUtils.findFirstElement("/web-app/servlet[servlet-name='"+servletName+"']", root);
283
284 if ( servletElem != null) {
285 webAppElem.removeChild(servletElem);
286 }
287 webAppElem.appendChild(webXml.importNode(servlet,true));
288 }
289 }
290
291
292 List<Element> surfServletMappings = XmlUtils.findElements("/web-app/surf/servlet-mapping", webXmlElement);
293 for(Element servletMapping : surfServletMappings)
294 {
295 if (servletMapping.hasChildNodes() && servletMapping.getElementsByTagName("servlet-name").getLength() > 0) {
296 String servletName = servletMapping.getElementsByTagName("servlet-name").item(0).getTextContent().trim();
297
298 Element servletMappingElem = XmlUtils.findFirstElement("/web-app/servlet-mapping[servlet-name='"+servletName+"']", root);
299
300 if ( servletMappingElem != null) {
301 webAppElem.removeChild(servletMappingElem);
302 }
303
304 webAppElem.appendChild(webXml.importNode(servletMapping,true));
305 }
306 }
307
308
309 updateXmlDocument(webXmlPath,webXml);
310 }
311
312 }
313
314
315
316
317 private void processSurfXml(){
318 copySurfTemplate(Path.SRC_MAIN_WEBAPP, RELATIVE_PATH_SURF_XML, false);
319 }
320
321
322
323
324 private void updateDependencies()
325 {
326 addPOMDependenciesFromFile(RELATIVE_PATH_DEPENDENCIES_TEMPLATE);
327 }
328
329
330
331
332
333 private PathResolver getPathResolver() {
334 ProjectMetadata projectMetadata = (ProjectMetadata) metadataService.get(ProjectMetadata.getProjectIdentifier());
335 if (projectMetadata == null) {
336 return null;
337 }
338 return projectMetadata.getPathResolver();
339 }
340
341
342
343
344
345
346
347
348 private Comment addComment(Document doc,Element root,String commentText) {
349
350 Comment comment = doc.createComment(commentText);
351 root.getParentNode().insertBefore(comment, root);
352
353 return comment;
354
355 }
356
357
358
359
360
361
362
363
364 private Element updateInterceptor(Document webmvcxml,Element root,String beanName)
365 {
366 Element interceptorElem = XmlUtils.findFirstElement("/ref[@bean='"+beanName+"']", root);
367 if ( interceptorElem != null )
368 {
369 interceptorElem.setAttribute("bean", beanName);
370 }
371 else
372 {
373 interceptorElem = webmvcxml.createElement("ref");
374 interceptorElem.setAttribute("bean", beanName);
375 }
376
377
378 Element firstChild = XmlUtils.findFirstElement("bean", root);
379 root.insertBefore(interceptorElem, firstChild);
380 root.insertBefore(webmvcxml.createTextNode("\n"), interceptorElem);
381
382 return interceptorElem;
383 }
384
385
386
387
388
389
390
391
392
393 private Element updateRule(Document urlrewrite,Element root,String from, String to)
394 {
395 Element ruleElem = XmlUtils.findFirstElement("/urlrewrite/rule[from='"+from+"']", root);
396
397 if ( ruleElem != null ) {
398 XmlUtils.findRequiredElement("to", ruleElem).setTextContent(to);
399 } else {
400 ruleElem = urlrewrite.createElement("rule");
401 Element toElem = urlrewrite.createElement("to");
402 toElem.setTextContent(to);
403 Element fromElem = urlrewrite.createElement("from");
404 fromElem.setTextContent(from);
405 ruleElem.appendChild(fromElem);
406 ruleElem.appendChild(toElem);
407
408 Element firstChild = XmlUtils.findFirstElement("rule", root);
409
410 root.insertBefore(urlrewrite.createTextNode("\n"), firstChild);
411 root.insertBefore(urlrewrite.createTextNode("\t"), firstChild);
412 root.insertBefore(ruleElem, firstChild);
413 root.insertBefore(urlrewrite.createTextNode("\n"), firstChild);
414 }
415
416 return ruleElem;
417 }
418
419
420
421
422
423
424
425
426
427 private Element updateOutboundRule(Document urlrewrite,Element root,String from, String to) {
428 Element ruleElem = XmlUtils.findFirstElement("/urlrewrite/outbound-rule[from='"+from+"']", root);
429
430 if ( ruleElem != null ) {
431 XmlUtils.findRequiredElement("to", ruleElem).setTextContent(to);
432 } else {
433 ruleElem = urlrewrite.createElement("outbound-rule");
434 Element toElem = urlrewrite.createElement("to");
435 toElem.setTextContent(to);
436 Element fromElem = urlrewrite.createElement("from");
437 fromElem.setTextContent(from);
438 ruleElem.appendChild(fromElem);
439 ruleElem.appendChild(toElem);
440
441 Element firstChild = XmlUtils.findFirstElement("outbound-rule", root);
442
443 root.insertBefore(urlrewrite.createTextNode("\n"), firstChild);
444 root.insertBefore(urlrewrite.createTextNode("\t"), firstChild);
445 root.insertBefore(ruleElem, firstChild);
446 root.insertBefore(urlrewrite.createTextNode("\n"), firstChild);
447
448 }
449 return ruleElem;
450 }
451
452
453
454
455 public void installSurfSampleSite()
456 {
457 installSurfPackage(FILENAME_SURF_SAMPLE_SITE);
458 }
459
460
461
462
463
464
465
466 public void installSurfPackage(String packageName)
467 {
468
469
470 boolean existsRemotely = false;
471
472
473 if (!existsRemotely)
474 {
475
476 installSurfPackageLocal(packageName, true);
477 }
478 }
479
480
481
482
483
484
485
486
487 public void installSurfPackageLocal(String packageName, boolean deleteOnFinish)
488 {
489 Assert.hasText(packageName);
490
491
492 String sampleZipName = packageName + ".zip";
493 String sampleZipPath = pathResolver.getIdentifier(Path.SRC_MAIN_WEBAPP, sampleZipName);
494
495
496 try
497 {
498 if (fileManager.exists(sampleZipPath))
499 {
500 FileCopyUtils.copy(TemplateUtils.getTemplate(getClass(), sampleZipName), fileManager.updateFile(sampleZipPath).getOutputStream());
501 }
502 else
503 {
504 FileCopyUtils.copy(TemplateUtils.getTemplate(getClass(), sampleZipName), fileManager.createFile(sampleZipPath).getOutputStream());
505 }
506 }
507 catch (IOException e)
508 {
509 throw new IllegalStateException(e);
510 }
511 SurfUtils.unzip(fileManager, sampleZipPath, pathResolver.getIdentifier(Path.SRC_MAIN_WEBAPP,""));
512
513
514 if (deleteOnFinish)
515 {
516 try {
517 fileManager.delete(sampleZipPath);
518 } catch (Exception e) {
519 throw new IllegalStateException(e);
520 }
521 }
522
523 fileManager.scan();
524 }
525
526
527
528
529
530 public void installSurfPHP()
531 {
532 addPOMDependenciesFromFile(RELATIVE_PATH_PHP_DEPENDENCIES_TEMPLATE);
533 }
534
535
536
537
538 public void installSurfGroovy()
539 {
540 addPOMDependenciesFromFile(RELATIVE_PATH_GROOVY_DEPENDENCIES_TEMPLATE);
541 }
542
543
544
545
546 public void installSurfStudio()
547 {
548 addPOMDependenciesFromFile(RELATIVE_PATH_WEBSTUDIO_DEPENDENCIES_TEMPLATE);
549 }
550
551
552
553
554 public void installSurfCmisSamples()
555 {
556 installSurfPackage(FILENAME_CMIS_SAMPLES);
557 }
558
559
560
561
562 public void installSurfAlfrescoSamples()
563 {
564 installSurfPackage(FILENAME_ALFRESCO_SAMPLES);
565 }
566
567
568
569
570
571
572 public void addPOMDependenciesFromFile(String filePath)
573 {
574
575 Document dependencyDoc = getTemplateDocument(filePath);
576 Element dependenciesElement = dependencyDoc.getDocumentElement();
577
578
579 List<Element> springDependencies = XmlUtils.findElements("/dependencies/surf/dependency", dependenciesElement);
580 for(Element dependency : springDependencies)
581 {
582 projectOperations.dependencyUpdate(new Dependency(dependency));
583 }
584
585
586 projectOperations.updateProjectType(ProjectType.WAR);
587
588
589
590 String pomPath = pathResolver.getIdentifier(Path.ROOT, RELATIVE_PATH_POM_XML);
591
592 Document pom = getXmlDocument(pomPath);
593 Element root = pom.getDocumentElement();
594
595 for(Element dependency : springDependencies)
596 {
597
598 if (dependency.hasChildNodes() && dependency.getElementsByTagName("type").getLength() > 0) {
599 String t = dependency.getElementsByTagName("type").item(0).getTextContent().trim().toUpperCase();
600 if (!t.equals("JAR") && !t.equals("ZIP")) {
601 String groupId = dependency.getElementsByTagName("groupId").item(0).getTextContent().trim();
602 String artifactId = dependency.getElementsByTagName("artifactId").item(0).getTextContent().trim();
603 Element dependencyElem = XmlUtils.findFirstElement("/project/dependencies/dependency[groupId='"+groupId+"'][artifactId='"+artifactId+"']", root);
604 if ( dependencyElem != null) {
605 Node typeElem = dependencyElem.getElementsByTagName("type").item(0);
606 if (typeElem!=null) {
607 typeElem.setTextContent(t);
608 } else {
609 typeElem = pom.createElement("type");
610 typeElem.setTextContent(t);
611 dependencyElem.insertBefore(typeElem, dependencyElem.getLastChild());
612 }
613 }
614 }
615 }
616
617 if (dependency.hasChildNodes() && dependency.getElementsByTagName("scope").getLength() > 0) {
618 String s = dependency.getElementsByTagName("scope").item(0).getTextContent().trim();
619 String groupId = dependency.getElementsByTagName("groupId").item(0).getTextContent().trim();
620 String artifactId = dependency.getElementsByTagName("artifactId").item(0).getTextContent().trim();
621 Element dependencyElem = XmlUtils.findFirstElement("/project/dependencies/dependency[groupId='"+groupId+"'][artifactId='"+artifactId+"']", root);
622 if ( dependencyElem != null) {
623 Node scopeElem = dependencyElem.getElementsByTagName("scope").item(0);
624 if (scopeElem!=null) {
625 scopeElem.setTextContent(s);
626 } else {
627 scopeElem = pom.createElement("scope");
628 scopeElem.setTextContent(s);
629 dependencyElem.insertBefore(scopeElem, dependencyElem.getLastChild());
630 }
631 }
632 }
633 }
634
635
636 updateXmlDocument(pomPath,pom);
637
638 }
639
640
641
642
643
644
645
646
647 private boolean copySurfTemplate(Path rootPath,String relativePath,boolean forced) {
648
649 boolean fileExists = fileManager.exists(pathResolver.getIdentifier(rootPath, relativePath));
650
651 if (!fileExists || forced )
652 {
653 try
654 {
655 FileCopyUtils.copy(TemplateUtils.getTemplate(getClass(), relativePath), fileManager.createFile(pathResolver.getIdentifier(rootPath, relativePath)).getOutputStream());
656 }
657 catch (IOException e)
658 {
659 new IllegalStateException("Encountered an error during copying of template "+relativePath, e);
660 }
661 }
662
663 return fileExists;
664
665 }
666
667
668
669
670
671
672 private Document getXmlDocument(String path) {
673 InputStream docInputStream = fileManager.getInputStream(path);
674 Document doc;
675 try {
676 doc = XmlUtils.getDocumentBuilder().parse(docInputStream);
677 } catch (Exception ex) {
678 throw new IllegalStateException("Failed to open XML document "+path,ex);
679 }
680 return doc;
681 }
682
683
684
685
686
687
688 private Document getTemplateDocument(String relativePath) {
689
690 InputStream templateInputStream = TemplateUtils.getTemplate(getClass(), relativePath);
691
692 Document doc;
693 try {
694 doc = XmlUtils.getDocumentBuilder().parse(templateInputStream);
695 } catch (Exception e) {
696 throw new IllegalStateException("Faile to open template document "+relativePath+e);
697 }
698 return doc;
699 }
700
701
702
703
704
705
706 private void updateXmlDocument(String path,Document document) {
707 MutableFile urlrewriteMutableFile = fileManager.updateFile(path);
708 XmlUtils.writeXml(urlrewriteMutableFile.getOutputStream(), document);
709 fileManager.scan();
710 }
711
712 }