1   /**
2    * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.tools;
24  
25  import com.liferay.portal.kernel.util.ClassUtil;
26  import com.liferay.portal.kernel.util.StringMaker;
27  import com.liferay.portal.kernel.util.StringPool;
28  import com.liferay.portal.kernel.util.StringUtil;
29  import com.liferay.util.FileUtil;
30  import com.liferay.util.ListUtil;
31  
32  import java.io.BufferedReader;
33  import java.io.File;
34  import java.io.IOException;
35  import java.io.StringReader;
36  import java.util.ArrayList;
37  import java.util.Collections;
38  import java.util.HashSet;
39  import java.util.List;
40  import java.util.Set;
41  
42  import org.apache.tools.ant.DirectoryScanner;
43  
44  /**
45   * <a href="SourceFormatter.java.html"><b><i>View Source</i></b></a>
46   *
47   * @author Brian Wing Shun Chan
48   *
49   */
50  public class SourceFormatter {
51  
52      public static void main(String[] args) {
53          try {
54              _checkPersistenceTestSuite();
55              _formatJava();
56              _formatJSP();
57          }
58          catch (Exception e) {
59              e.printStackTrace();
60          }
61      }
62  
63      public static String stripImports(
64              String content, String packageDir, String className)
65          throws IOException {
66  
67          int x = content.indexOf("import ");
68  
69          if (x == -1) {
70              return content;
71          }
72  
73          int y = content.indexOf("{", x);
74  
75          y = content.substring(0, y).lastIndexOf(";") + 1;
76  
77          String imports = _formatImports(content.substring(x, y));
78  
79          content =
80              content.substring(0, x) + imports +
81                  content.substring(y + 1, content.length());
82  
83          Set<String> classes = ClassUtil.getClasses(
84              new StringReader(content), className);
85  
86          classes.add("_getMarkup");
87          classes.add("_performBlockingInteraction");
88  
89          x = content.indexOf("import ");
90  
91          y = content.indexOf("{", x);
92  
93          y = content.substring(0, y).lastIndexOf(";") + 1;
94  
95          imports = content.substring(x, y);
96  
97          StringMaker sm = new StringMaker();
98  
99          BufferedReader br = new BufferedReader(new StringReader(imports));
100 
101         String line = null;
102 
103         while ((line = br.readLine()) != null) {
104             if (line.indexOf("import ") != -1) {
105                 int importX = line.indexOf(" ");
106                 int importY = line.lastIndexOf(".");
107 
108                 String importPackage = line.substring(importX + 1, importY);
109                 String importClass = line.substring(
110                     importY + 1, line.length() - 1);
111 
112                 if (!packageDir.equals(importPackage)) {
113                     if (!importClass.equals("*")) {
114                         if (classes.contains(importClass)) {
115                             sm.append(line);
116                             sm.append("\n");
117                         }
118                     }
119                     else {
120                         sm.append(line);
121                         sm.append("\n");
122                     }
123                 }
124             }
125         }
126 
127         imports = _formatImports(sm.toString());
128 
129         content =
130             content.substring(0, x) + imports +
131                 content.substring(y + 1, content.length());
132 
133         return content;
134     }
135 
136     public static void _checkPersistenceTestSuite() throws IOException {
137         String basedir = "../portal-impl/test";
138 
139         if (!FileUtil.exists(basedir)) {
140             return;
141         }
142 
143         DirectoryScanner ds = new DirectoryScanner();
144 
145         ds.setBasedir(basedir);
146         ds.setIncludes(new String[] {"**\\*PersistenceTest.java"});
147 
148         ds.scan();
149 
150         String[] files = ds.getIncludedFiles();
151 
152         Set<String> persistenceTests = new HashSet<String>();
153 
154         for (String file : files) {
155             String persistenceTest = file.substring(0, file.length() - 5);
156 
157             persistenceTest = persistenceTest.substring(
158                 persistenceTest.lastIndexOf(File.separator) + 1,
159                 persistenceTest.length());
160 
161             persistenceTests.add(persistenceTest);
162         }
163 
164         String persistenceTestSuite = FileUtil.read(
165             basedir + "/com/liferay/portal/service/persistence/" +
166                 "PersistenceTestSuite.java");
167 
168         for (String persistenceTest : persistenceTests) {
169             if (persistenceTestSuite.indexOf(persistenceTest) == -1) {
170                 System.out.println("PersistenceTestSuite: " + persistenceTest);
171             }
172         }
173     }
174 
175     public static String _formatImports(String imports) throws IOException {
176         if ((imports.indexOf("/*") != -1) ||
177             (imports.indexOf("*/") != -1) ||
178             (imports.indexOf("//") != -1)) {
179 
180             return imports + "\n";
181         }
182 
183         List<String> importsList = new ArrayList<String>();
184 
185         BufferedReader br = new BufferedReader(new StringReader(imports));
186 
187         String line = null;
188 
189         while ((line = br.readLine()) != null) {
190             if (line.indexOf("import ") != -1) {
191                 if (!importsList.contains(line)) {
192                     importsList.add(line);
193                 }
194             }
195         }
196 
197         Collections.sort(importsList);
198 
199         StringMaker sm = new StringMaker();
200 
201         String temp = null;
202 
203         for (int i = 0; i < importsList.size(); i++) {
204             String s = importsList.get(i);
205 
206             int pos = s.indexOf(".");
207 
208             pos = s.indexOf(".", pos + 1);
209 
210             if (pos == -1) {
211                 pos = s.indexOf(".");
212             }
213 
214             String packageLevel = s.substring(7, pos);
215 
216             if ((i != 0) && (!packageLevel.equals(temp))) {
217                 sm.append("\n");
218             }
219 
220             temp = packageLevel;
221 
222             sm.append(s);
223             sm.append("\n");
224         }
225 
226         return sm.toString();
227     }
228 
229     private static void _formatJava() throws IOException {
230         String basedir = "../";
231 
232         List<File> list = new ArrayList<File>();
233 
234         DirectoryScanner ds = new DirectoryScanner();
235 
236         ds.setBasedir(basedir);
237         ds.setExcludes(
238             new String[] {
239                 "**\\classes\\*", "**\\jsp\\*", "**\\tmp\\**",
240                 "**\\EARXMLBuilder.java", "**\\EJBXMLBuilder.java",
241                 "**\\JSMin.java", "**\\PropsUtil.java",
242                 "**\\InstanceWrapperBuilder.java",
243                 "**\\ServiceBuilder.java", "**\\SourceFormatter.java",
244                 "**\\UserAttributes.java", "**\\WebKeys.java",
245                 "**\\*_IW.java", "**\\XHTMLComplianceFormatter.java",
246                 "**\\portal-service\\**\\model\\*Model.java",
247                 "**\\portal-service\\**\\model\\*Soap.java",
248                 "**\\model\\impl\\*ModelImpl.java",
249                 "**\\portal\\service\\**", "**\\portal-client\\**",
250                 "**\\portal-web\\test\\**\\*Test.java",
251                 "**\\portlet\\**\\service\\**", "**\\tools\\ext_tmpl\\**",
252                 "**\\util-wsrp\\**"
253             });
254         ds.setIncludes(new String[] {"**\\*.java"});
255 
256         ds.scan();
257 
258         list.addAll(ListUtil.fromArray(ds.getIncludedFiles()));
259 
260         ds = new DirectoryScanner();
261 
262         ds.setBasedir(basedir);
263         ds.setExcludes(
264             new String[] {
265                 "**\\tools\\ext_tmpl\\**", "**\\*_IW.java",
266                 "**\\test\\**\\*PersistenceTest.java"
267             });
268         ds.setIncludes(
269             new String[] {
270                 "**\\service\\http\\*HttpTest.java",
271                 "**\\service\\http\\*SoapTest.java",
272                 "**\\service\\impl\\*.java", "**\\service\\jms\\*.java",
273                 "**\\service\\permission\\*.java",
274                 "**\\service\\persistence\\BasePersistence.java",
275                 "**\\service\\persistence\\*FinderImpl.java",
276                 "**\\portal-impl\\test\\**\\*.java",
277                 "**\\portal-service\\**\\liferay\\counter\\**.java",
278                 "**\\portal-service\\**\\liferay\\documentlibrary\\**.java",
279                 "**\\portal-service\\**\\liferay\\lock\\**.java",
280                 "**\\portal-service\\**\\liferay\\mail\\**.java",
281                 "**\\util-bridges\\**\\*.java"
282             });
283 
284         ds.scan();
285 
286         list.addAll(ListUtil.fromArray(ds.getIncludedFiles()));
287 
288         String copyright = FileUtil.read("../copyright.txt");
289 
290         String[] files = list.toArray(new String[list.size()]);
291 
292         for (int i = 0; i < files.length; i++) {
293             File file = new File(basedir + files[i]);
294 
295             String content = FileUtil.read(file);
296 
297             String className = file.getName();
298 
299             className = className.substring(0, className.length() - 5);
300 
301             String packagePath = files[i];
302 
303             int packagePathX = packagePath.indexOf(
304                 File.separator + "src" + File.separator);
305             int packagePathY = packagePath.lastIndexOf(File.separator);
306 
307             packagePath = packagePath.substring(packagePathX + 5, packagePathY);
308             packagePath = StringUtil.replace(
309                 packagePath, File.separator, StringPool.PERIOD);
310 
311             if (packagePath.endsWith(".model")) {
312                 if (content.indexOf(
313                         "extends " + className + "Model {") != -1) {
314 
315                     continue;
316                 }
317             }
318 
319             String newContent = _formatJavaContent(files[i], content);
320 
321             if (newContent.indexOf("$\n */") != -1) {
322                 System.out.println("*: " + files[i]);
323 
324                 newContent = StringUtil.replace(
325                     newContent, "$\n */", "$\n *\n */");
326             }
327 
328             if (newContent.indexOf(copyright) == -1) {
329                 System.out.println("(c): " + files[i]);
330             }
331 
332             if (newContent.indexOf(className + ".java.html") == -1) {
333                 System.out.println("Java2HTML: " + files[i]);
334             }
335 
336             newContent = stripImports(newContent, packagePath, className);
337 
338             newContent = StringUtil.replace(
339                 newContent, "@author Raymond Aug?", "@author Raymond Augé");
340 
341             if (newContent.indexOf(";\n/**") != -1) {
342                 newContent = StringUtil.replace(
343                     newContent,
344                     ";\n/**",
345                     ";\n\n/**");
346             }
347 
348             if (newContent.indexOf("\t/*\n\t *") != -1) {
349                 newContent = StringUtil.replace(
350                     newContent,
351                     "\t/*\n\t *",
352                     "\t/**\n\t *");
353             }
354 
355             if (newContent.indexOf("if(") != -1) {
356                 newContent = StringUtil.replace(
357                     newContent,
358                     "if(",
359                     "if (");
360             }
361 
362             if (newContent.indexOf("while(") != -1) {
363                 newContent = StringUtil.replace(
364                     newContent,
365                     "while(",
366                     "while (");
367             }
368 
369             if (newContent.indexOf("\n\n\n") != -1) {
370                 newContent = StringUtil.replace(
371                     newContent,
372                     "\n\n\n",
373                     "\n\n");
374             }
375 
376             if  (newContent.indexOf("*/\npackage ") != -1) {
377                 System.out.println("package: " + files[i]);
378             }
379 
380             if (!newContent.endsWith("\n\n}") &&
381                 !newContent.endsWith("{\n}")) {
382 
383                 System.out.println("}: " + files[i]);
384             }
385 
386             if ((newContent != null) && !content.equals(newContent)) {
387                 FileUtil.write(file, newContent);
388 
389                 System.out.println(file.toString());
390             }
391         }
392     }
393 
394     private static String _formatJavaContent(String fileName, String content)
395         throws IOException {
396 
397         StringMaker sm = new StringMaker();
398 
399         BufferedReader br = new BufferedReader(new StringReader(content));
400 
401         int lineCount = 0;
402 
403         String line = null;
404 
405         while ((line = br.readLine()) != null) {
406             lineCount++;
407 
408             if (line.trim().length() == 0) {
409                 line = StringPool.BLANK;
410             }
411 
412             line = StringUtil.trimTrailing(line);
413 
414             sm.append(line);
415             sm.append("\n");
416 
417             line = StringUtil.replace(line, "\t", "    ");
418 
419             if (((line.length() - 1) > 79) && !line.startsWith("import ")) {
420                 System.out.println("> 80: " + fileName + " " + lineCount);
421             }
422         }
423 
424         br.close();
425 
426         String newContent = sm.toString();
427 
428         if (newContent.endsWith("\n")) {
429             newContent = newContent.substring(0, newContent.length() -1);
430         }
431 
432         return newContent;
433     }
434 
435     private static void _formatJSP() throws IOException {
436         String basedir = "../";
437 
438         List<File> list = new ArrayList<File>();
439 
440         DirectoryScanner ds = new DirectoryScanner();
441 
442         ds.setBasedir(basedir);
443         ds.setExcludes(new String[] {"**\\null.jsp", "**\\tmp\\**"});
444         ds.setIncludes(new String[] {"**\\*.jsp", "**\\*.jspf", "**\\*.vm"});
445 
446         ds.scan();
447 
448         list.addAll(ListUtil.fromArray(ds.getIncludedFiles()));
449 
450         String copyright = FileUtil.read("../copyright.txt");
451 
452         String[] files = list.toArray(new String[list.size()]);
453 
454         for (int i = 0; i < files.length; i++) {
455             File file = new File(basedir + files[i]);
456 
457             String content = FileUtil.read(file, true);
458             String newContent = _formatJSPContent(files[i], content);
459 
460             newContent = StringUtil.replace(
461                 newContent,
462                 new String[] {"<br/>", "\"/>"},
463                 new String[] {"<br />", "\" />"});
464 
465             if (files[i].endsWith(".jsp")) {
466                 if (newContent.indexOf(copyright) == -1) {
467                     System.out.println("(c): " + files[i]);
468                 }
469             }
470 
471             if (newContent.indexOf("alert('<%= LanguageUtil.") != -1) {
472                 newContent = StringUtil.replace(newContent,
473                     "alert('<%= LanguageUtil.",
474                     "alert('<%= UnicodeLanguageUtil.");
475             }
476 
477             if (newContent.indexOf("alert(\"<%= LanguageUtil.") != -1) {
478                 newContent = StringUtil.replace(newContent,
479                     "alert(\"<%= LanguageUtil.",
480                     "alert(\"<%= UnicodeLanguageUtil.");
481             }
482 
483             if (newContent.indexOf("confirm('<%= LanguageUtil.") != -1) {
484                 newContent = StringUtil.replace(newContent,
485                     "confirm('<%= LanguageUtil.",
486                     "confirm('<%= UnicodeLanguageUtil.");
487             }
488 
489             if (newContent.indexOf("confirm(\"<%= LanguageUtil.") != -1) {
490                 newContent = StringUtil.replace(newContent,
491                     "confirm(\"<%= LanguageUtil.",
492                     "confirm(\"<%= UnicodeLanguageUtil.");
493             }
494 
495             if ((newContent != null) && !content.equals(newContent)) {
496                 FileUtil.write(file, newContent);
497 
498                 System.out.println(file.toString());
499             }
500         }
501     }
502 
503     private static String _formatJSPContent(String fileName, String content)
504         throws IOException {
505 
506         StringMaker sm = new StringMaker();
507 
508         BufferedReader br =
509             new BufferedReader(new StringReader(content));
510 
511         int lineCount = 0;
512 
513         String line = null;
514 
515         while ((line = br.readLine()) != null) {
516             lineCount++;
517 
518             int x = line.indexOf("\"<%=");
519             int y = line.indexOf("%>\"", x);
520 
521             boolean hasTagLibrary = false;
522 
523             for (int i = 0; i < _TAG_LIBRARIES.length; i++) {
524                 if (line.indexOf("<" + _TAG_LIBRARIES[i] + ":") != -1) {
525                     hasTagLibrary = true;
526 
527                     break;
528                 }
529             }
530 
531             if ((x != -1) && (y != -1) && hasTagLibrary) {
532                 String regexp = line.substring(x, y + 3);
533 
534                 if (regexp.indexOf("\\\"") == -1) {
535                     regexp = regexp.substring(1, regexp.length() - 1);
536 
537                     if (regexp.indexOf("\"") != -1) {
538                         line =
539                             line.substring(0, x) + "'" + regexp + "'" +
540                                 line.substring(y + 3, line.length());
541                     }
542                 }
543             }
544 
545             if (line.trim().length() == 0) {
546                 line = StringPool.BLANK;
547             }
548 
549             line = StringUtil.trimTrailing(line);
550 
551             sm.append(line);
552             sm.append("\n");
553         }
554 
555         br.close();
556 
557         String newContent = sm.toString();
558 
559         if (newContent.endsWith("\n")) {
560             newContent = newContent.substring(0, newContent.length() -1);
561         }
562 
563         return newContent;
564     }
565 
566     private static final String[] _TAG_LIBRARIES = new String[] {
567         "c", "html", "jsp", "liferay-portlet", "liferay-security",
568         "liferay-theme", "liferay-ui", "liferay-util", "portlet", "struts",
569         "tiles"
570     };
571 
572 }