1
22
23 package com.liferay.portal.tools;
24
25 import com.liferay.portal.kernel.util.ClassUtil;
26 import com.liferay.portal.kernel.util.FileUtil;
27 import com.liferay.portal.kernel.util.ListUtil;
28 import com.liferay.portal.kernel.util.StringPool;
29 import com.liferay.portal.kernel.util.StringUtil;
30 import com.liferay.portal.util.ContentUtil;
31 import com.liferay.portal.util.InitUtil;
32
33 import java.io.BufferedReader;
34 import java.io.File;
35 import java.io.InputStream;
36 import java.io.IOException;
37 import java.io.StringReader;
38 import java.net.URL;
39 import java.util.ArrayList;
40 import java.util.Collections;
41 import java.util.HashSet;
42 import java.util.List;
43 import java.util.Properties;
44 import java.util.Set;
45 import java.util.regex.Matcher;
46 import java.util.regex.Pattern;
47
48 import org.apache.tools.ant.DirectoryScanner;
49
50
56 public class SourceFormatter {
57
58 public static void main(String[] args) {
59 InitUtil.initWithSpring();
60
61 try {
62 _readExclusions();
63
64 _checkPersistenceTestSuite();
65 _checkWebXML();
66 _formatJava();
67 _formatJSP();
68 }
69 catch (Exception e) {
70 e.printStackTrace();
71 }
72 }
73
74 public static String stripImports(
75 String content, String packageDir, String className)
76 throws IOException {
77
78 int x = content.indexOf("import ");
79
80 if (x == -1) {
81 return content;
82 }
83
84 int y = content.indexOf("{", x);
85
86 y = content.substring(0, y).lastIndexOf(";") + 1;
87
88 String imports = _formatImports(content.substring(x, y));
89
90 content =
91 content.substring(0, x) + imports +
92 content.substring(y + 1, content.length());
93
94 Set<String> classes = ClassUtil.getClasses(
95 new StringReader(content), className);
96
97 classes.add("_getMarkup");
98 classes.add("_performBlockingInteraction");
99
100 x = content.indexOf("import ");
101
102 y = content.indexOf("{", x);
103
104 y = content.substring(0, y).lastIndexOf(";") + 1;
105
106 imports = content.substring(x, y);
107
108 StringBuilder sb = new StringBuilder();
109
110 BufferedReader br = new BufferedReader(new StringReader(imports));
111
112 String line = null;
113
114 while ((line = br.readLine()) != null) {
115 if (line.indexOf("import ") != -1) {
116 int importX = line.indexOf(" ");
117 int importY = line.lastIndexOf(".");
118
119 String importPackage = line.substring(importX + 1, importY);
120 String importClass = line.substring(
121 importY + 1, line.length() - 1);
122
123 if (!packageDir.equals(importPackage)) {
124 if (!importClass.equals("*")) {
125 if (classes.contains(importClass)) {
126 sb.append(line);
127 sb.append("\n");
128 }
129 }
130 else {
131 sb.append(line);
132 sb.append("\n");
133 }
134 }
135 }
136 }
137
138 imports = _formatImports(sb.toString());
139
140 content =
141 content.substring(0, x) + imports +
142 content.substring(y + 1, content.length());
143
144 return content;
145 }
146
147 public static void _checkPersistenceTestSuite() throws IOException {
148 String basedir = "./portal-impl/test";
149
150 if (!FileUtil.exists(basedir)) {
151 return;
152 }
153
154 DirectoryScanner ds = new DirectoryScanner();
155
156 ds.setBasedir(basedir);
157 ds.setIncludes(new String[] {"**\\*PersistenceTest.java"});
158
159 ds.scan();
160
161 String[] files = ds.getIncludedFiles();
162
163 Set<String> persistenceTests = new HashSet<String>();
164
165 for (String file : files) {
166 String persistenceTest = file.substring(0, file.length() - 5);
167
168 persistenceTest = persistenceTest.substring(
169 persistenceTest.lastIndexOf(File.separator) + 1,
170 persistenceTest.length());
171
172 persistenceTests.add(persistenceTest);
173 }
174
175 String persistenceTestSuite = FileUtil.read(
176 basedir + "/com/liferay/portal/service/persistence/" +
177 "PersistenceTestSuite.java");
178
179 for (String persistenceTest : persistenceTests) {
180 if (persistenceTestSuite.indexOf(persistenceTest) == -1) {
181 System.out.println("PersistenceTestSuite: " + persistenceTest);
182 }
183 }
184 }
185
186 private static void _checkWebXML() throws IOException {
187 String basedir = "./";
188
189 if (FileUtil.exists(basedir + "portal-impl")) {
190 return;
191 }
192
193 String webXML = ContentUtil.get(
194 "com/liferay/portal/deploy/dependencies/web.xml");
195
196 DirectoryScanner ds = new DirectoryScanner();
197
198 ds.setBasedir(basedir);
199 ds.setIncludes(new String[] {"**\\web.xml"});
200
201 ds.scan();
202
203 String[] files = ds.getIncludedFiles();
204
205 for (String file : files) {
206 String content = FileUtil.read(basedir + file);
207
208 if (content.equals(webXML)) {
209 System.out.println(file);
210 }
211 }
212 }
213
214 private static void _checkXSS(String fileName, String jspContent) {
215 Matcher matcher = _xssPattern.matcher(jspContent);
216
217 while (matcher.find()) {
218 boolean xssVulnerable = false;
219
220 String jspVariable = matcher.group(1);
221
222 String inputVulnerability =
223 " type=\"hidden\" value=\"<%= " + jspVariable + " %>";
224
225 if (jspContent.indexOf(inputVulnerability) != -1) {
226 xssVulnerable = true;
227 }
228
229 String anchorVulnerability = " href=\"<%= " + jspVariable + " %>";
230
231 if (jspContent.indexOf(anchorVulnerability) != -1) {
232 xssVulnerable = true;
233 }
234
235 String inlineStringVulnerability1 = "'<%= " + jspVariable + " %>";
236
237 if (jspContent.indexOf(inlineStringVulnerability1) != -1) {
238 xssVulnerable = true;
239 }
240
241 String inlineStringVulnerability2 = "(\"<%= " + jspVariable + " %>";
242
243 if (jspContent.indexOf(inlineStringVulnerability2) != -1) {
244 xssVulnerable = true;
245 }
246
247 String inlineStringVulnerability3 = " \"<%= " + jspVariable + " %>";
248
249 if (jspContent.indexOf(inlineStringVulnerability3) != -1) {
250 xssVulnerable = true;
251 }
252
253 String documentIdVulnerability = ".<%= " + jspVariable + " %>";
254
255 if (jspContent.indexOf(documentIdVulnerability) != -1) {
256 xssVulnerable = true;
257 }
258
259 if (xssVulnerable) {
260 System.out.println(
261 "(xss): " + fileName + " (" + jspVariable + ")");
262 }
263 }
264 }
265
266 public static String _formatImports(String imports) throws IOException {
267 if ((imports.indexOf("/*") != -1) ||
268 (imports.indexOf("*/") != -1) ||
269 (imports.indexOf("//") != -1)) {
270
271 return imports + "\n";
272 }
273
274 List<String> importsList = new ArrayList<String>();
275
276 BufferedReader br = new BufferedReader(new StringReader(imports));
277
278 String line = null;
279
280 while ((line = br.readLine()) != null) {
281 if (line.indexOf("import ") != -1) {
282 if (!importsList.contains(line)) {
283 importsList.add(line);
284 }
285 }
286 }
287
288 Collections.sort(importsList);
289
290 StringBuilder sb = new StringBuilder();
291
292 String temp = null;
293
294 for (int i = 0; i < importsList.size(); i++) {
295 String s = importsList.get(i);
296
297 int pos = s.indexOf(".");
298
299 pos = s.indexOf(".", pos + 1);
300
301 if (pos == -1) {
302 pos = s.indexOf(".");
303 }
304
305 String packageLevel = s.substring(7, pos);
306
307 if ((i != 0) && (!packageLevel.equals(temp))) {
308 sb.append("\n");
309 }
310
311 temp = packageLevel;
312
313 sb.append(s);
314 sb.append("\n");
315 }
316
317 return sb.toString();
318 }
319
320 private static void _formatJava() throws IOException {
321 String basedir = "./";
322
323 String copyright = _getCopyright();
324
325 String[] files = null;
326
327 if (FileUtil.exists(basedir + "portal-impl")) {
328 files = _getPortalJavaFiles();
329 }
330 else {
331 files = _getPluginJavaFiles();
332 }
333
334 for (int i = 0; i < files.length; i++) {
335 File file = new File(basedir + files[i]);
336
337 String content = FileUtil.read(file);
338
339 String className = file.getName();
340
341 className = className.substring(0, className.length() - 5);
342
343 String packagePath = files[i];
344
345 int packagePathX = packagePath.indexOf(
346 File.separator + "src" + File.separator);
347 int packagePathY = packagePath.lastIndexOf(File.separator);
348
349 packagePath = packagePath.substring(packagePathX + 5, packagePathY);
350 packagePath = StringUtil.replace(
351 packagePath, File.separator, StringPool.PERIOD);
352
353 if (packagePath.endsWith(".model")) {
354 if (content.indexOf(
355 "extends " + className + "Model {") != -1) {
356
357 continue;
358 }
359 }
360
361 String newContent = _formatJavaContent(files[i], content);
362
363 if (newContent.indexOf("$\n */") != -1) {
364 System.out.println("*: " + files[i]);
365
366 newContent = StringUtil.replace(
367 newContent, "$\n */", "$\n *\n */");
368 }
369
370 if (newContent.indexOf(copyright) == -1) {
371 System.out.println("(c): " + files[i]);
372 }
373
374 if (newContent.indexOf(className + ".java.html") == -1) {
375 System.out.println("Java2HTML: " + files[i]);
376 }
377
378 newContent = stripImports(newContent, packagePath, className);
379
380 newContent = StringUtil.replace(
381 newContent, "@author Raymond Aug?", "@author Raymond Augé");
382
383 if (newContent.indexOf(";\n/**") != -1) {
384 newContent = StringUtil.replace(
385 newContent,
386 ";\n/**",
387 ";\n\n/**");
388 }
389
390 if (newContent.indexOf("\t/*\n\t *") != -1) {
391 newContent = StringUtil.replace(
392 newContent,
393 "\t/*\n\t *",
394 "\t/**\n\t *");
395 }
396
397 if (newContent.indexOf("if(") != -1) {
398 newContent = StringUtil.replace(
399 newContent,
400 "if(",
401 "if (");
402 }
403
404 if (newContent.indexOf("while(") != -1) {
405 newContent = StringUtil.replace(
406 newContent,
407 "while(",
408 "while (");
409 }
410
411 if (newContent.indexOf("\n\n\n") != -1) {
412 newContent = StringUtil.replace(
413 newContent,
414 "\n\n\n",
415 "\n\n");
416 }
417
418 if (newContent.indexOf("*/\npackage ") != -1) {
419 System.out.println("package: " + files[i]);
420 }
421
422 if (newContent.indexOf(" ") != -1) {
423 if (!files[i].endsWith("StringPool.java")) {
424 System.out.println("tab: " + files[i]);
425 }
426 }
427
428 if (newContent.indexOf(" {") != -1) {
429 System.out.println("{:" + files[i]);
430 }
431
432 if (!newContent.endsWith("\n\n}") &&
433 !newContent.endsWith("{\n}")) {
434
435 System.out.println("}: " + files[i]);
436 }
437
438 if ((newContent != null) && !content.equals(newContent)) {
439 FileUtil.write(file, newContent);
440
441 System.out.println(file);
442 }
443 }
444 }
445
446 private static String _formatJavaContent(String fileName, String content)
447 throws IOException {
448
449 StringBuilder sb = new StringBuilder();
450
451 BufferedReader br = new BufferedReader(new StringReader(content));
452
453 int lineCount = 0;
454
455 String line = null;
456
457 while ((line = br.readLine()) != null) {
458 lineCount++;
459
460 if (line.trim().length() == 0) {
461 line = StringPool.BLANK;
462 }
463
464 line = StringUtil.trimTrailing(line);
465
466 sb.append(line);
467 sb.append("\n");
468
469 line = StringUtil.replace(line, "\t", " ");
470
471 String excluded = _exclusions.getProperty(
472 StringUtil.replace(fileName, "\\", "/") + StringPool.AT +
473 lineCount);
474
475 if ((excluded == null) && ((line.length() - 1) > 79) &&
476 (!line.startsWith("import "))) {
477
478 System.out.println("> 80: " + fileName + " " + lineCount);
479 }
480 }
481
482 br.close();
483
484 String newContent = sb.toString();
485
486 if (newContent.endsWith("\n")) {
487 newContent = newContent.substring(0, newContent.length() -1);
488 }
489
490 return newContent;
491 }
492
493 private static void _formatJSP() throws IOException {
494 String basedir = "./";
495
496 List<File> list = new ArrayList<File>();
497
498 DirectoryScanner ds = new DirectoryScanner();
499
500 ds.setBasedir(basedir);
501 ds.setExcludes(new String[] {"**\\null.jsp", "**\\tmp\\**"});
502 ds.setIncludes(new String[] {"**\\*.jsp", "**\\*.jspf", "**\\*.vm"});
503
504 ds.scan();
505
506 list.addAll(ListUtil.fromArray(ds.getIncludedFiles()));
507
508 String copyright = _getCopyright();
509
510 String[] files = list.toArray(new String[list.size()]);
511
512 for (int i = 0; i < files.length; i++) {
513 File file = new File(basedir + files[i]);
514
515 String content = FileUtil.read(file, true);
516 String newContent = _formatJSPContent(files[i], content);
517
518 newContent = StringUtil.replace(
519 newContent,
520 new String[] {"<br/>", "\"/>"},
521 new String[] {"<br />", "\" />"});
522
523 if (files[i].endsWith(".jsp")) {
524 if (newContent.indexOf(copyright) == -1) {
525 System.out.println("(c): " + files[i]);
526 }
527 }
528
529 if (newContent.indexOf("alert('<%= LanguageUtil.") != -1) {
530 newContent = StringUtil.replace(newContent,
531 "alert('<%= LanguageUtil.",
532 "alert('<%= UnicodeLanguageUtil.");
533 }
534
535 if (newContent.indexOf("alert(\"<%= LanguageUtil.") != -1) {
536 newContent = StringUtil.replace(newContent,
537 "alert(\"<%= LanguageUtil.",
538 "alert(\"<%= UnicodeLanguageUtil.");
539 }
540
541 if (newContent.indexOf("confirm('<%= LanguageUtil.") != -1) {
542 newContent = StringUtil.replace(newContent,
543 "confirm('<%= LanguageUtil.",
544 "confirm('<%= UnicodeLanguageUtil.");
545 }
546
547 if (newContent.indexOf("confirm(\"<%= LanguageUtil.") != -1) {
548 newContent = StringUtil.replace(newContent,
549 "confirm(\"<%= LanguageUtil.",
550 "confirm(\"<%= UnicodeLanguageUtil.");
551 }
552
553 if (newContent.indexOf(" ") != -1) {
554 if (!files[i].endsWith("template.vm")) {
555 System.out.println("tab: " + files[i]);
556 }
557 }
558
559 _checkXSS(files[i], content);
560
561 if ((newContent != null) && !content.equals(newContent)) {
562 FileUtil.write(file, newContent);
563
564 System.out.println(file);
565 }
566 }
567 }
568
569 private static String _formatJSPContent(String fileName, String content)
570 throws IOException {
571
572 StringBuilder sb = new StringBuilder();
573
574 BufferedReader br =
575 new BufferedReader(new StringReader(content));
576
577 int lineCount = 0;
578
579 String line = null;
580
581 while ((line = br.readLine()) != null) {
582 lineCount++;
583
584 int x = line.indexOf("\"<%=");
585 int y = line.indexOf("%>\"", x);
586
587 boolean hasTagLibrary = false;
588
589 for (int i = 0; i < _TAG_LIBRARIES.length; i++) {
590 if (line.indexOf("<" + _TAG_LIBRARIES[i] + ":") != -1) {
591 hasTagLibrary = true;
592
593 break;
594 }
595 }
596
597 if ((x != -1) && (y != -1) && hasTagLibrary) {
598 String regexp = line.substring(x, y + 3);
599
600 if (regexp.indexOf("\\\"") == -1) {
601 regexp = regexp.substring(1, regexp.length() - 1);
602
603 if (regexp.indexOf("\"") != -1) {
604 line =
605 line.substring(0, x) + "'" + regexp + "'" +
606 line.substring(y + 3, line.length());
607 }
608 }
609 }
610
611 if (line.trim().length() == 0) {
612 line = StringPool.BLANK;
613 }
614
615 line = StringUtil.trimTrailing(line);
616
617 sb.append(line);
618 sb.append("\n");
619 }
620
621 br.close();
622
623 String newContent = sb.toString();
624
625 if (newContent.endsWith("\n")) {
626 newContent = newContent.substring(0, newContent.length() -1);
627 }
628
629 return newContent;
630 }
631
632 private static String _getCopyright() throws IOException {
633 try {
634 return FileUtil.read("copyright.txt");
635 }
636 catch (Exception e1) {
637 try {
638 return FileUtil.read("../copyright.txt");
639 }
640 catch (Exception e2) {
641 return FileUtil.read("../../copyright.txt");
642 }
643 }
644 }
645
646 private static String[] _getPluginJavaFiles() {
647 String basedir = "./";
648
649 List<File> list = new ArrayList<File>();
650
651 DirectoryScanner ds = new DirectoryScanner();
652
653 ds.setBasedir(basedir);
654 ds.setExcludes(
655 new String[] {
656 "**\\model\\*Clp.java", "**\\model\\*Model.java",
657 "**\\model\\*Soap.java", "**\\model\\impl\\*ModelImpl.java",
658 "**\\service\\*Service.java", "**\\service\\*ServiceClp.java",
659 "**\\service\\*ServiceFactory.java",
660 "**\\service\\*ServiceUtil.java",
661 "**\\service\\ClpSerializer.java",
662 "**\\service\\base\\*ServiceBaseImpl.java",
663 "**\\service\\http\\*JSONSerializer.java",
664 "**\\service\\http\\*ServiceHttp.java",
665 "**\\service\\http\\*ServiceJSON.java",
666 "**\\service\\http\\*ServiceSoap.java",
667 "**\\service\\persistence\\*Finder.java",
668 "**\\service\\persistence\\*Persistence.java",
669 "**\\service\\persistence\\*PersistenceImpl.java",
670 "**\\service\\persistence\\*Util.java"
671 });
672 ds.setIncludes(new String[] {"**\\*.java"});
673
674 ds.scan();
675
676 list.addAll(ListUtil.fromArray(ds.getIncludedFiles()));
677
678 return list.toArray(new String[list.size()]);
679 }
680
681 private static String[] _getPortalJavaFiles() {
682 String basedir = "./";
683
684 List<File> list = new ArrayList<File>();
685
686 DirectoryScanner ds = new DirectoryScanner();
687
688 ds.setBasedir(basedir);
689 ds.setExcludes(
690 new String[] {
691 "**\\classes\\*", "**\\jsp\\*", "**\\tmp\\**",
692 "**\\EARXMLBuilder.java", "**\\EJBXMLBuilder.java",
693 "**\\JSMin.java", "**\\PropsKeys.java",
694 "**\\InstanceWrapperBuilder.java",
695 "**\\ServiceBuilder.java", "**\\SourceFormatter.java",
696 "**\\UserAttributes.java", "**\\WebKeys.java",
697 "**\\*_IW.java", "**\\XHTMLComplianceFormatter.java",
698 "**\\portal-service\\**\\model\\*Model.java",
699 "**\\portal-service\\**\\model\\*Soap.java",
700 "**\\model\\impl\\*ModelImpl.java",
701 "**\\portal\\service\\**", "**\\portal-client\\**",
702 "**\\portal-web\\test\\**\\*Test.java",
703 "**\\portlet\\**\\service\\**", "**\\tools\\ext_tmpl\\**",
704 "**\\util-wsrp\\**"
705 });
706 ds.setIncludes(new String[] {"**\\*.java"});
707
708 ds.scan();
709
710 list.addAll(ListUtil.fromArray(ds.getIncludedFiles()));
711
712 ds = new DirectoryScanner();
713
714 ds.setBasedir(basedir);
715 ds.setExcludes(
716 new String[] {
717 "**\\tools\\ext_tmpl\\**", "**\\*_IW.java",
718 "**\\test\\**\\*PersistenceTest.java"
719 });
720 ds.setIncludes(
721 new String[] {
722 "**\\service\\http\\*HttpTest.java",
723 "**\\service\\http\\*SoapTest.java",
724 "**\\service\\impl\\*.java", "**\\service\\jms\\*.java",
725 "**\\service\\permission\\*.java",
726 "**\\service\\persistence\\BasePersistence.java",
727 "**\\service\\persistence\\*FinderImpl.java",
728 "**\\portal-impl\\test\\**\\*.java",
729 "**\\portal-service\\**\\liferay\\counter\\**.java",
730 "**\\portal-service\\**\\liferay\\documentlibrary\\**.java",
731 "**\\portal-service\\**\\liferay\\lock\\**.java",
732 "**\\portal-service\\**\\liferay\\mail\\**.java",
733 "**\\util-bridges\\**\\*.java"
734 });
735
736 ds.scan();
737
738 list.addAll(ListUtil.fromArray(ds.getIncludedFiles()));
739
740 return list.toArray(new String[list.size()]);
741 }
742
743 private static void _readExclusions() throws IOException {
744 _exclusions = new Properties();
745
746 ClassLoader classLoader = SourceFormatter.class.getClassLoader();
747
748 URL url = classLoader.getResource(
749 "com/liferay/portal/tools/dependencies/" +
750 "source_formatter_exclusions.properties");
751
752 if (url == null) {
753 return;
754 }
755
756 InputStream is = url.openStream();
757
758 _exclusions.load(is);
759
760 is.close();
761 }
762
763 private static final String[] _TAG_LIBRARIES = new String[] {
764 "c", "html", "jsp", "liferay-portlet", "liferay-security",
765 "liferay-theme", "liferay-ui", "liferay-util", "portlet", "struts",
766 "tiles"
767 };
768
769 private static Properties _exclusions;
770 private static Pattern _xssPattern = Pattern.compile(
771 "String\\s+([^\\s]+)\\s*=\\s*ParamUtil\\.getString\\(");
772
773 }