1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    *
5    *
6    *
7    * The contents of this file are subject to the terms of the Liferay Enterprise
8    * Subscription License ("License"). You may not use this file except in
9    * compliance with the License. You can obtain a copy of the License by
10   * contacting Liferay, Inc. See the License for the specific language governing
11   * permissions and limitations under the License, including but not limited to
12   * distribution rights 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.CharPool;
26  import com.liferay.portal.kernel.util.ClassUtil;
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.FileImpl;
32  import com.liferay.portal.util.PropsValues;
33  
34  import java.io.BufferedReader;
35  import java.io.File;
36  import java.io.InputStream;
37  import java.io.IOException;
38  import java.io.StringReader;
39  import java.net.URL;
40  import java.util.ArrayList;
41  import java.util.Arrays;
42  import java.util.HashSet;
43  import java.util.List;
44  import java.util.Properties;
45  import java.util.Set;
46  import java.util.TreeSet;
47  import java.util.regex.Matcher;
48  import java.util.regex.Pattern;
49  
50  import org.apache.tools.ant.DirectoryScanner;
51  
52  /**
53   * <a href="SourceFormatter.java.html"><b><i>View Source</i></b></a>
54   *
55   * @author Brian Wing Shun Chan
56   */
57  public class SourceFormatter {
58  
59      public static void main(String[] args) {
60          try {
61              _readExclusions();
62  
63              Thread thread1 = new Thread () {
64                  public void run() {
65                      try {
66                          _checkPersistenceTestSuite();
67                          _checkWebXML();
68                          _formatJSP();
69                      }
70                      catch (Exception e) {
71                          e.printStackTrace();
72                      }
73                  }
74              };
75  
76              Thread thread2 = new Thread () {
77                  public void run() {
78                      try {
79                          _formatJava();
80                      }
81                      catch (Exception e) {
82                          e.printStackTrace();
83                      }
84                  }
85              };
86  
87              thread1.start();
88              thread2.start();
89  
90              thread1.join();
91              thread2.join();
92          }
93          catch (Exception e) {
94              e.printStackTrace();
95          }
96      }
97  
98      public static String stripImports(
99              String content, String packageDir, String className)
100         throws IOException {
101 
102         int x = content.indexOf("import ");
103 
104         if (x == -1) {
105             return content;
106         }
107 
108         int y = content.indexOf("{", x);
109 
110         y = content.substring(0, y).lastIndexOf(";") + 1;
111 
112         String imports = _formatImports(content.substring(x, y));
113 
114         content =
115             content.substring(0, x) + imports +
116                 content.substring(y + 1, content.length());
117 
118         Set<String> classes = ClassUtil.getClasses(
119             new StringReader(content), className);
120 
121         x = content.indexOf("import ");
122 
123         y = content.indexOf("{", x);
124 
125         y = content.substring(0, y).lastIndexOf(";") + 1;
126 
127         imports = content.substring(x, y);
128 
129         StringBuilder sb = new StringBuilder();
130 
131         BufferedReader br = new BufferedReader(new StringReader(imports));
132 
133         String line = null;
134 
135         while ((line = br.readLine()) != null) {
136             if (line.indexOf("import ") != -1) {
137                 int importX = line.indexOf(" ");
138                 int importY = line.lastIndexOf(".");
139 
140                 String importPackage = line.substring(importX + 1, importY);
141                 String importClass = line.substring(
142                     importY + 1, line.length() - 1);
143 
144                 if (!packageDir.equals(importPackage)) {
145                     if (!importClass.equals("*")) {
146                         if (classes.contains(importClass)) {
147                             sb.append(line);
148                             sb.append("\n");
149                         }
150                     }
151                     else {
152                         sb.append(line);
153                         sb.append("\n");
154                     }
155                 }
156             }
157         }
158 
159         imports = _formatImports(sb.toString());
160 
161         content =
162             content.substring(0, x) + imports +
163                 content.substring(y + 1, content.length());
164 
165         return content;
166     }
167 
168     public static void _checkPersistenceTestSuite() throws IOException {
169         String basedir = "./portal-impl/test";
170 
171         if (!_fileUtil.exists(basedir)) {
172             return;
173         }
174 
175         DirectoryScanner ds = new DirectoryScanner();
176 
177         ds.setBasedir(basedir);
178         ds.setIncludes(new String[] {"**\\*PersistenceTest.java"});
179 
180         ds.scan();
181 
182         String[] files = ds.getIncludedFiles();
183 
184         Set<String> persistenceTests = new HashSet<String>();
185 
186         for (String file : files) {
187             String persistenceTest = file.substring(0, file.length() - 5);
188 
189             persistenceTest = persistenceTest.substring(
190                 persistenceTest.lastIndexOf(File.separator) + 1,
191                 persistenceTest.length());
192 
193             persistenceTests.add(persistenceTest);
194         }
195 
196         String persistenceTestSuite = _fileUtil.read(
197             basedir + "/com/liferay/portal/service/persistence/" +
198                 "PersistenceTestSuite.java");
199 
200         for (String persistenceTest : persistenceTests) {
201             if (persistenceTestSuite.indexOf(persistenceTest) == -1) {
202                 System.out.println("PersistenceTestSuite: " + persistenceTest);
203             }
204         }
205     }
206 
207     private static void _checkWebXML() throws IOException {
208         String basedir = "./";
209 
210         if (_fileUtil.exists(basedir + "portal-impl")) {
211             String[] locales = (String[])PropsValues.LOCALES.clone();
212 
213             Arrays.sort(locales);
214 
215             String previousLanguageCode = null;
216 
217             Set<String> urlPatterns = new TreeSet<String>();
218 
219             for (String locale : locales) {
220                 int pos = locale.indexOf(StringPool.UNDERLINE);
221 
222                 String languageCode = locale.substring(0, pos);
223 
224                 urlPatterns.add(languageCode);
225                 urlPatterns.add(locale);
226             }
227 
228             StringBuilder sb = new StringBuilder();
229 
230             for (String urlPattern : urlPatterns) {
231                 sb.append("\t<servlet-mapping>\n");
232                 sb.append("\t\t<servlet-name>I18n Servlet</servlet-name>\n");
233                 sb.append(
234                     "\t\t<url-pattern>/" + urlPattern +"/*</url-pattern>\n");
235                 sb.append("\t</servlet-mapping>\n");
236             }
237 
238             File file = new File(
239                 basedir + "portal-web/docroot/WEB-INF/web.xml");
240 
241             String content = _fileUtil.read(file);
242 
243             int x = content.indexOf("<servlet-mapping>");
244 
245             x = content.indexOf("<servlet-name>I18n Servlet</servlet-name>", x);
246 
247             x = content.lastIndexOf("<servlet-mapping>", x) - 1;
248 
249             int y = content.lastIndexOf(
250                 "<servlet-name>I18n Servlet</servlet-name>");
251 
252             y = content.indexOf("</servlet-mapping>", y) + 19;
253 
254             String newContent =
255                 content.substring(0, x) + sb.toString() + content.substring(y);
256 
257             if ((newContent != null) && !content.equals(newContent)) {
258                 _fileUtil.write(file, newContent);
259 
260                 System.out.println(file);
261             }
262         }
263         else {
264             String webXML = ContentUtil.get(
265                 "com/liferay/portal/deploy/dependencies/web.xml");
266 
267             DirectoryScanner ds = new DirectoryScanner();
268 
269             ds.setBasedir(basedir);
270             ds.setIncludes(new String[] {"**\\web.xml"});
271 
272             ds.scan();
273 
274             String[] files = ds.getIncludedFiles();
275 
276             for (String file : files) {
277                 String content = _fileUtil.read(basedir + file);
278 
279                 if (content.equals(webXML)) {
280                     System.out.println(file);
281                 }
282             }
283         }
284     }
285 
286     private static void _checkXSS(String fileName, String jspContent) {
287         Matcher matcher = _xssPattern.matcher(jspContent);
288 
289         while (matcher.find()) {
290             boolean xssVulnerable = false;
291 
292             String jspVariable = matcher.group(1);
293 
294             String inputVulnerability =
295                 "<input[^>]* value=\"<%= " + jspVariable + " %>";
296 
297             Pattern inputVulnerabilityPattern =
298                 Pattern.compile(inputVulnerability, Pattern.CASE_INSENSITIVE);
299 
300             Matcher inputVulnerabilityMatcher =
301                 inputVulnerabilityPattern.matcher(jspContent);
302 
303             if (inputVulnerabilityMatcher.find()) {
304                 xssVulnerable = true;
305             }
306 
307             String anchorVulnerability = " href=\"<%= " + jspVariable + " %>";
308 
309             if (jspContent.indexOf(anchorVulnerability) != -1) {
310                 xssVulnerable = true;
311             }
312 
313             String inlineStringVulnerability1 = "'<%= " + jspVariable + " %>";
314 
315             if (jspContent.indexOf(inlineStringVulnerability1) != -1) {
316                 xssVulnerable = true;
317             }
318 
319             String inlineStringVulnerability2 = "(\"<%= " + jspVariable + " %>";
320 
321             if (jspContent.indexOf(inlineStringVulnerability2) != -1) {
322                 xssVulnerable = true;
323             }
324 
325             String inlineStringVulnerability3 = " \"<%= " + jspVariable + " %>";
326 
327             if (jspContent.indexOf(inlineStringVulnerability3) != -1) {
328                 xssVulnerable = true;
329             }
330 
331             String documentIdVulnerability = ".<%= " + jspVariable + " %>";
332 
333             if (jspContent.indexOf(documentIdVulnerability) != -1) {
334                 xssVulnerable = true;
335             }
336 
337             if (xssVulnerable) {
338                 System.out.println(
339                     "(xss): " + fileName + " (" + jspVariable + ")");
340             }
341         }
342     }
343 
344     public static String _formatImports(String imports) throws IOException {
345         if ((imports.indexOf("/*") != -1) ||
346             (imports.indexOf("*/") != -1) ||
347             (imports.indexOf("//") != -1)) {
348 
349             return imports + "\n";
350         }
351 
352         List<String> importsList = new ArrayList<String>();
353 
354         BufferedReader br = new BufferedReader(new StringReader(imports));
355 
356         String line = null;
357 
358         while ((line = br.readLine()) != null) {
359             if (line.indexOf("import ") != -1) {
360                 if (!importsList.contains(line)) {
361                     importsList.add(line);
362                 }
363             }
364         }
365 
366         importsList = ListUtil.sort(importsList);
367 
368         StringBuilder sb = new StringBuilder();
369 
370         String temp = null;
371 
372         for (int i = 0; i < importsList.size(); i++) {
373             String s = importsList.get(i);
374 
375             int pos = s.indexOf(".");
376 
377             pos = s.indexOf(".", pos + 1);
378 
379             if (pos == -1) {
380                 pos = s.indexOf(".");
381             }
382 
383             String packageLevel = s.substring(7, pos);
384 
385             if ((i != 0) && (!packageLevel.equals(temp))) {
386                 sb.append("\n");
387             }
388 
389             temp = packageLevel;
390 
391             sb.append(s);
392             sb.append("\n");
393         }
394 
395         return sb.toString();
396     }
397 
398     private static void _formatJava() throws IOException {
399         String basedir = "./";
400 
401         String copyright = _getCopyright();
402 
403         boolean portalJavaFiles = true;
404 
405         String[] files = null;
406 
407         if (_fileUtil.exists(basedir + "portal-impl")) {
408             files = _getPortalJavaFiles();
409         }
410         else {
411             portalJavaFiles = false;
412 
413             files = _getPluginJavaFiles();
414         }
415 
416         for (int i = 0; i < files.length; i++) {
417             File file = new File(basedir + files[i]);
418 
419             String content = _fileUtil.read(file);
420 
421             String className = file.getName();
422 
423             className = className.substring(0, className.length() - 5);
424 
425             String packagePath = files[i];
426 
427             int packagePathX = packagePath.indexOf(
428                 File.separator + "src" + File.separator);
429             int packagePathY = packagePath.lastIndexOf(File.separator);
430 
431             if ((packagePathX + 5) >= packagePathY) {
432                 packagePath = StringPool.BLANK;
433             }
434             else {
435                 packagePath = packagePath.substring(
436                     packagePathX + 5, packagePathY);
437             }
438 
439             packagePath = StringUtil.replace(
440                 packagePath, File.separator, StringPool.PERIOD);
441 
442             if (packagePath.endsWith(".model")) {
443                 if (content.indexOf(
444                         "extends " + className + "Model {") != -1) {
445 
446                     continue;
447                 }
448             }
449 
450             String newContent = _formatJavaContent(files[i], content);
451 
452             if (newContent.indexOf("$\n */") != -1) {
453                 System.out.println("*: " + files[i]);
454 
455                 newContent = StringUtil.replace(
456                     newContent, "$\n */", "$\n *\n */");
457             }
458 
459             if (newContent.indexOf(copyright) == -1) {
460                 System.out.println("(c): " + files[i]);
461             }
462 
463             if (newContent.indexOf(className + ".java.html") == -1) {
464                 System.out.println("Java2HTML: " + files[i]);
465             }
466 
467             if (newContent.contains(" * @author Raymond Aug") && 
468                 !newContent.contains(" * @author Raymond Aug\u00e9")) {
469 
470                 newContent = newContent.replaceFirst(
471                     "Raymond Aug.++", "Raymond Aug\u00e9");
472 
473                 System.out.println("UTF-8: " + files[i]);
474             }
475 
476             newContent = stripImports(newContent, packagePath, className);
477 
478             if (newContent.indexOf(";\n/**") != -1) {
479                 newContent = StringUtil.replace(
480                     newContent,
481                     ";\n/**",
482                     ";\n\n/**");
483             }
484 
485             if (newContent.indexOf("\t/*\n\t *") != -1) {
486                 newContent = StringUtil.replace(
487                     newContent,
488                     "\t/*\n\t *",
489                     "\t/**\n\t *");
490             }
491 
492             if (newContent.indexOf("if(") != -1) {
493                 newContent = StringUtil.replace(
494                     newContent,
495                     "if(",
496                     "if (");
497             }
498 
499             if (newContent.indexOf("while(") != -1) {
500                 newContent = StringUtil.replace(
501                     newContent,
502                     "while(",
503                     "while (");
504             }
505 
506             if (newContent.indexOf("\n\n\n") != -1) {
507                 newContent = StringUtil.replace(
508                     newContent,
509                     "\n\n\n",
510                     "\n\n");
511             }
512 
513             if (newContent.indexOf("*/\npackage ") != -1) {
514                 System.out.println("package: " + files[i]);
515             }
516 
517             if (newContent.indexOf("    ") != -1) {
518                 if (!files[i].endsWith("StringPool.java")) {
519                     System.out.println("tab: " + files[i]);
520                 }
521             }
522 
523             if (newContent.indexOf("  {") != -1) {
524                 System.out.println("{:" + files[i]);
525             }
526 
527             if (!newContent.endsWith("\n\n}") &&
528                 !newContent.endsWith("{\n}")) {
529 
530                 System.out.println("}: " + files[i]);
531             }
532 
533             if (portalJavaFiles && className.endsWith("ServiceImpl") &&
534                 (newContent.indexOf("ServiceUtil.") != -1)) {
535 
536                 System.out.println("ServiceUtil: " + files[i]);
537             }
538 
539             if ((newContent != null) && !content.equals(newContent)) {
540                 _fileUtil.write(file, newContent);
541 
542                 System.out.println(file);
543             }
544         }
545     }
546 
547     private static String _formatJavaContent(String fileName, String content)
548         throws IOException {
549 
550         boolean longLogFactoryUtil = false;
551 
552         StringBuilder sb = new StringBuilder();
553 
554         BufferedReader br = new BufferedReader(new StringReader(content));
555 
556         int lineCount = 0;
557 
558         String line = null;
559 
560         while ((line = br.readLine()) != null) {
561             lineCount++;
562 
563             if (line.trim().length() == 0) {
564                 line = StringPool.BLANK;
565             }
566 
567             line = StringUtil.trimTrailing(line);
568 
569             line = StringUtil.replace(
570                 line,
571                 new String[] {
572                     "* Copyright (c) 2000-2008 Liferay, Inc.",
573                     "* Copyright 2008 Sun Microsystems Inc."
574                 },
575                 new String[] {
576                     "* Copyright (c) 2000-2009 Liferay, Inc.",
577                     "* Copyright 2009 Sun Microsystems Inc."
578                 });
579 
580             sb.append(line);
581             sb.append("\n");
582 
583             StringBuilder lineSB = new StringBuilder();
584 
585             int spacesPerTab = 4;
586 
587             for (char c : line.toCharArray()) {
588                 if (c == CharPool.TAB) {
589                     for (int i = 0; i < spacesPerTab; i++) {
590                         lineSB.append(CharPool.SPACE);
591                     }
592 
593                     spacesPerTab = 4;
594                 }
595                 else {
596                     lineSB.append(c);
597 
598                     spacesPerTab--;
599 
600                     if (spacesPerTab <= 0) {
601                         spacesPerTab = 4;
602                     }
603                 }
604             }
605 
606             line = lineSB.toString();
607 
608             String excluded = _exclusions.getProperty(
609                 StringUtil.replace(fileName, "\\", "/") + StringPool.AT +
610                     lineCount);
611 
612             if (excluded == null) {
613                 excluded = _exclusions.getProperty(
614                     StringUtil.replace(fileName, "\\", "/"));
615             }
616 
617             if ((excluded == null) && (line.length() > 80) &&
618                 (!line.startsWith("import "))) {
619 
620                 if (line.contains(
621                         "private static Log _log = LogFactoryUtil.getLog(")) {
622 
623                     longLogFactoryUtil = true;
624                 }
625 
626                 if (fileName.endsWith("Table.java") &&
627                     line.contains("String TABLE_SQL_CREATE = ")) {
628                 }
629                 else {
630                     System.out.println("> 80: " + fileName + " " + lineCount);
631                 }
632             }
633         }
634 
635         br.close();
636 
637         String newContent = sb.toString();
638 
639         if (newContent.endsWith("\n")) {
640             newContent = newContent.substring(0, newContent.length() -1);
641         }
642 
643         if (longLogFactoryUtil) {
644             newContent = StringUtil.replace(
645                 newContent, "private static Log _log = ",
646                 "private static Log _log =\n\t\t");
647         }
648 
649         return newContent;
650     }
651 
652     private static void _formatJSP() throws IOException {
653         String basedir = "./";
654 
655         List<String> list = new ArrayList<String>();
656 
657         DirectoryScanner ds = new DirectoryScanner();
658 
659         ds.setBasedir(basedir);
660         ds.setExcludes(
661             new String[] {"**\\null.jsp", "**\\tmp\\**", "**\\tools\\tck\\**"});
662         ds.setIncludes(new String[] {"**\\*.jsp", "**\\*.jspf", "**\\*.vm"});
663 
664         ds.scan();
665 
666         list.addAll(ListUtil.fromArray(ds.getIncludedFiles()));
667 
668         String copyright = _getCopyright();
669 
670         String[] files = list.toArray(new String[list.size()]);
671 
672         for (int i = 0; i < files.length; i++) {
673             File file = new File(basedir + files[i]);
674 
675             String content = _fileUtil.read(file);
676             String newContent = _formatJSPContent(files[i], content);
677 
678             newContent = StringUtil.replace(
679                 newContent,
680                 new String[] {
681                     "<br/>", "\"/>", "\" >", "@page import", "\"%>", ")%>",
682                     "javascript: "
683                 },
684                 new String[] {
685                     "<br />", "\" />", "\">", "@ page import", "\" %>", ") %>",
686                     "javascript:"
687                 });
688 
689             newContent = StringUtil.replace(
690                 newContent,
691                 new String[] {
692                     "* Copyright (c) 2000-2008 Liferay, Inc.",
693                     "* Copyright 2008 Sun Microsystems Inc."
694                 },
695                 new String[] {
696                     "* Copyright (c) 2000-2009 Liferay, Inc.",
697                     "* Copyright 2009 Sun Microsystems Inc."
698                 });
699 
700             if (files[i].endsWith(".jsp")) {
701                 if (newContent.indexOf(copyright) == -1) {
702                     System.out.println("(c): " + files[i]);
703                 }
704             }
705 
706             if (newContent.indexOf("alert('<%= LanguageUtil.") != -1) {
707                 newContent = StringUtil.replace(newContent,
708                     "alert('<%= LanguageUtil.",
709                     "alert('<%= UnicodeLanguageUtil.");
710             }
711 
712             if (newContent.indexOf("alert(\"<%= LanguageUtil.") != -1) {
713                 newContent = StringUtil.replace(newContent,
714                     "alert(\"<%= LanguageUtil.",
715                     "alert(\"<%= UnicodeLanguageUtil.");
716             }
717 
718             if (newContent.indexOf("confirm('<%= LanguageUtil.") != -1) {
719                 newContent = StringUtil.replace(newContent,
720                     "confirm('<%= LanguageUtil.",
721                     "confirm('<%= UnicodeLanguageUtil.");
722             }
723 
724             if (newContent.indexOf("confirm(\"<%= LanguageUtil.") != -1) {
725                 newContent = StringUtil.replace(newContent,
726                     "confirm(\"<%= LanguageUtil.",
727                     "confirm(\"<%= UnicodeLanguageUtil.");
728             }
729 
730             if (newContent.indexOf("    ") != -1) {
731                 if (!files[i].endsWith("template.vm")) {
732                     System.out.println("tab: " + files[i]);
733                 }
734             }
735 
736             _checkXSS(files[i], content);
737 
738             if ((newContent != null) && !content.equals(newContent)) {
739                 _fileUtil.write(file, newContent);
740 
741                 System.out.println(file);
742             }
743         }
744     }
745 
746     private static String _formatJSPContent(String fileName, String content)
747         throws IOException {
748 
749         StringBuilder sb = new StringBuilder();
750 
751         BufferedReader br = new BufferedReader(new StringReader(content));
752 
753         String line = null;
754 
755         while ((line = br.readLine()) != null) {
756             if (line.trim().length() == 0) {
757                 line = StringPool.BLANK;
758             }
759 
760             line = StringUtil.trimTrailing(line);
761 
762             sb.append(line);
763             sb.append("\n");
764         }
765 
766         br.close();
767 
768         content = sb.toString();
769 
770         if (content.endsWith("\n")) {
771             content = content.substring(0, content.length() -1);
772         }
773 
774         content = _formatTaglibQuotes(fileName, content, StringPool.QUOTE);
775         content = _formatTaglibQuotes(fileName, content, StringPool.APOSTROPHE);
776 
777         return content;
778     }
779 
780     private static String _formatTaglibQuotes(
781         String fileName, String content, String quoteType) {
782 
783         String quoteFix = StringPool.APOSTROPHE;
784 
785         if (quoteFix.equals(quoteType)) {
786             quoteFix = StringPool.QUOTE;
787         }
788 
789         Pattern pattern = Pattern.compile(_getTaglibRegex(quoteType));
790 
791         Matcher matcher = pattern.matcher(content);
792 
793         while (matcher.find()) {
794             int x = content.indexOf(quoteType + "<%=", matcher.start());
795             int y = content.indexOf("%>" + quoteType, x);
796 
797             while ((x != -1) && (y != -1)) {
798                 String result = content.substring(x + 1, y + 2);
799 
800                 if (result.indexOf(quoteType) != -1) {
801                     int lineCount = 1;
802 
803                     char contentCharArray[] = content.toCharArray();
804 
805                     for (int i = 0; i < x; i++) {
806                         if (contentCharArray[i] == CharPool.NEW_LINE) {
807                             lineCount++;
808                         }
809                     }
810 
811                     if (result.indexOf(quoteFix) == -1) {
812                         StringBuilder sb = new StringBuilder();
813 
814                         sb.append(content.substring(0, x));
815                         sb.append(quoteFix);
816                         sb.append(result);
817                         sb.append(quoteFix);
818                         sb.append(content.substring(y + 3, content.length()));
819 
820                         content = sb.toString();
821                     }
822                     else {
823                         System.out.println(
824                             "taglib: " + fileName + " " + lineCount);
825                     }
826                 }
827 
828                 x = content.indexOf(quoteType + "<%=", y);
829 
830                 if (x > matcher.end()) {
831                     break;
832                 }
833 
834                 y = content.indexOf("%>" + quoteType, x);
835             }
836         }
837 
838         return content;
839     }
840 
841     private static String _getCopyright() throws IOException {
842         try {
843             return _fileUtil.read("copyright.txt");
844         }
845         catch (Exception e1) {
846             try {
847                 return _fileUtil.read("../copyright.txt");
848             }
849             catch (Exception e2) {
850                 return _fileUtil.read("../../copyright.txt");
851             }
852         }
853     }
854 
855     private static String[] _getPluginJavaFiles() {
856         String basedir = "./";
857 
858         List<String> list = new ArrayList<String>();
859 
860         DirectoryScanner ds = new DirectoryScanner();
861 
862         ds.setBasedir(basedir);
863         ds.setExcludes(
864             new String[] {
865                 "**\\model\\*Clp.java", "**\\model\\*Model.java",
866                 "**\\model\\*Soap.java", "**\\model\\*Wrapper.java",
867                 "**\\model\\impl\\*ModelImpl.java",
868                 "**\\service\\*Service.java", "**\\service\\*ServiceClp.java",
869                 "**\\service\\*ServiceFactory.java",
870                 "**\\service\\*ServiceUtil.java",
871                 "**\\service\\*ServiceWrapper.java",
872                 "**\\service\\ClpSerializer.java",
873                 "**\\service\\base\\*ServiceBaseImpl.java",
874                 "**\\service\\http\\*JSONSerializer.java",
875                 "**\\service\\http\\*ServiceHttp.java",
876                 "**\\service\\http\\*ServiceJSON.java",
877                 "**\\service\\http\\*ServiceSoap.java",
878                 "**\\service\\messaging\\*ClpMessageListener.java",
879                 "**\\service\\persistence\\*Finder.java",
880                 "**\\service\\persistence\\*Persistence.java",
881                 "**\\service\\persistence\\*PersistenceImpl.java",
882                 "**\\service\\persistence\\*Util.java", "**\\tmp\\**"
883             });
884         ds.setIncludes(new String[] {"**\\*.java"});
885 
886         ds.scan();
887 
888         list.addAll(ListUtil.fromArray(ds.getIncludedFiles()));
889 
890         return list.toArray(new String[list.size()]);
891     }
892 
893     private static String[] _getPortalJavaFiles() {
894         String basedir = "./";
895 
896         List<String> list = new ArrayList<String>();
897 
898         DirectoryScanner ds = new DirectoryScanner();
899 
900         ds.setBasedir(basedir);
901         ds.setExcludes(
902             new String[] {
903                 "**\\classes\\*", "**\\jsp\\*", "**\\tmp\\**",
904                 "**\\EARXMLBuilder.java", "**\\EJBXMLBuilder.java",
905                 "**\\PropsKeys.java", "**\\InstanceWrapperBuilder.java",
906                 "**\\ServiceBuilder.java", "**\\SourceFormatter.java",
907                 "**\\UserAttributes.java", "**\\WebKeys.java",
908                 "**\\*_IW.java", "**\\XHTMLComplianceFormatter.java",
909                 "**\\portal-service\\**\\model\\*Model.java",
910                 "**\\portal-service\\**\\model\\*Soap.java",
911                 "**\\portal-service\\**\\model\\*Wrapper.java",
912                 "**\\model\\impl\\*ModelImpl.java",
913                 "**\\portal\\service\\**", "**\\portal-client\\**",
914                 "**\\portal-web\\classes\\**\\*.java",
915                 "**\\portal-web\\test\\**\\*Test.java",
916                 "**\\portlet\\**\\service\\**", "**\\tools\\ext_tmpl\\**",
917                 "**\\tools\\tck\\**"
918             });
919         ds.setIncludes(new String[] {"**\\*.java"});
920 
921         ds.scan();
922 
923         list.addAll(ListUtil.fromArray(ds.getIncludedFiles()));
924 
925         ds = new DirectoryScanner();
926 
927         ds.setBasedir(basedir);
928         ds.setExcludes(
929             new String[] {
930                  "**\\portal-client\\**", "**\\tools\\ext_tmpl\\**",
931                 "**\\*_IW.java", "**\\test\\**\\*PersistenceTest.java"
932             });
933         ds.setIncludes(
934             new String[] {
935                 "**\\com\\liferay\\portal\\service\\ServiceContext*.java",
936                 "**\\model\\BaseModel.java",
937                 "**\\model\\impl\\BaseModelImpl.java",
938                 "**\\service\\base\\PrincipalBean.java",
939                 "**\\service\\http\\*HttpTest.java",
940                 "**\\service\\http\\*SoapTest.java",
941                 "**\\service\\http\\TunnelUtil.java",
942                 "**\\service\\impl\\*.java", "**\\service\\jms\\*.java",
943                 "**\\service\\permission\\*.java",
944                 "**\\service\\persistence\\BasePersistence.java",
945                 "**\\service\\persistence\\BatchSession*.java",
946                 "**\\service\\persistence\\*FinderImpl.java",
947                 "**\\service\\persistence\\*Query.java",
948                 "**\\service\\persistence\\impl\\BasePersistenceImpl.java",
949                 "**\\portal-impl\\test\\**\\*.java",
950                 "**\\portal-service\\**\\liferay\\counter\\**.java",
951                 "**\\portal-service\\**\\liferay\\documentlibrary\\**.java",
952                 "**\\portal-service\\**\\liferay\\lock\\**.java",
953                 "**\\portal-service\\**\\liferay\\mail\\**.java",
954                 "**\\util-bridges\\**\\*.java"
955             });
956 
957         ds.scan();
958 
959         list.addAll(ListUtil.fromArray(ds.getIncludedFiles()));
960 
961         return list.toArray(new String[list.size()]);
962     }
963 
964     private static String _getTaglibRegex(String quoteType) {
965         StringBuilder sb = new StringBuilder();
966 
967         sb.append("<(");
968 
969         for (int i = 0; i < _TAG_LIBRARIES.length; i++) {
970             sb.append(_TAG_LIBRARIES[i]);
971             sb.append(StringPool.PIPE);
972         }
973 
974         sb.deleteCharAt(sb.length() - 1);
975         sb.append("):([^>]|%>)*");
976         sb.append(quoteType);
977         sb.append("<%=.*");
978         sb.append(quoteType);
979         sb.append(".*%>");
980         sb.append(quoteType);
981         sb.append("([^>]|%>)*>");
982 
983         return sb.toString();
984     }
985 
986     private static void _readExclusions() throws IOException {
987         _exclusions = new Properties();
988 
989         ClassLoader classLoader = SourceFormatter.class.getClassLoader();
990 
991         String sourceFormatterExclusions = System.getProperty(
992             "source-formatter-exclusions",
993             "com/liferay/portal/tools/dependencies/" +
994                 "source_formatter_exclusions.properties");
995 
996         URL url = classLoader.getResource(sourceFormatterExclusions);
997 
998         if (url == null) {
999             return;
1000        }
1001
1002        InputStream is = url.openStream();
1003
1004        _exclusions.load(is);
1005
1006        is.close();
1007    }
1008
1009    private static final String[] _TAG_LIBRARIES = new String[] {
1010        "c", "html", "jsp", "liferay-portlet", "liferay-security",
1011        "liferay-theme", "liferay-ui", "liferay-util", "portlet", "struts",
1012        "tiles"
1013    };
1014
1015    private static FileImpl _fileUtil = FileImpl.getInstance();
1016    private static Properties _exclusions;
1017    private static Pattern _xssPattern = Pattern.compile(
1018        "String\\s+([^\\s]+)\\s*=\\s*ParamUtil\\.getString\\(");
1019
1020}