001
014
015 package com.liferay.portal.tools.sourceformatter;
016
017 import com.liferay.portal.kernel.io.unsync.UnsyncBufferedReader;
018 import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
019 import com.liferay.portal.kernel.util.ArrayUtil;
020 import com.liferay.portal.kernel.util.CharPool;
021 import com.liferay.portal.kernel.util.GetterUtil;
022 import com.liferay.portal.kernel.util.ListUtil;
023 import com.liferay.portal.kernel.util.ReleaseInfo;
024 import com.liferay.portal.kernel.util.StringBundler;
025 import com.liferay.portal.kernel.util.StringPool;
026 import com.liferay.portal.kernel.util.StringUtil;
027 import com.liferay.portal.kernel.util.TextFormatter;
028 import com.liferay.portal.kernel.util.Validator;
029 import com.liferay.portal.util.FileImpl;
030 import com.liferay.portal.xml.SAXReaderImpl;
031
032 import java.io.File;
033 import java.io.FileInputStream;
034 import java.io.FileNotFoundException;
035 import java.io.IOException;
036 import java.io.InputStream;
037
038 import java.net.URL;
039
040 import java.util.ArrayList;
041 import java.util.HashMap;
042 import java.util.List;
043 import java.util.Map;
044 import java.util.Properties;
045 import java.util.regex.Matcher;
046 import java.util.regex.Pattern;
047
048 import org.apache.tools.ant.DirectoryScanner;
049
050
056 public abstract class BaseSourceProcessor implements SourceProcessor {
057
058 @Override
059 public void format(
060 boolean useProperties, boolean printErrors, boolean autoFix)
061 throws Exception {
062
063 _init(useProperties, printErrors, autoFix);
064
065 format();
066
067 sourceFormatterHelper.close();
068 }
069
070 @Override
071 public String format(
072 String fileName, boolean useProperties, boolean printErrors,
073 boolean autoFix)
074 throws Exception {
075
076 try {
077 _init(useProperties, printErrors, autoFix);
078
079 return format(fileName);
080 }
081 finally {
082 sourceFormatterHelper.close();
083 }
084 }
085
086 @Override
087 public List<String> getErrorMessages() {
088 return _errorMessages;
089 }
090
091 protected static String formatImports(String imports, int classStartPos)
092 throws IOException {
093
094 if (imports.contains("") ||
095 imports.contains("
096
097 return imports + "\n";
098 }
099
100 List<ImportPackage> importPackages = new ArrayList<ImportPackage>();
101
102 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
103 new UnsyncStringReader(imports));
104
105 String line = null;
106
107 while ((line = unsyncBufferedReader.readLine()) != null) {
108 ImportPackage importPackage = ImportPackageFactoryUtil.create(line);
109
110 if ((importPackage != null) &&
111 !importPackages.contains(importPackage)) {
112
113 importPackages.add(importPackage);
114 }
115 }
116
117 importPackages = ListUtil.sort(importPackages);
118
119 StringBundler sb = new StringBundler();
120
121 String temp = null;
122
123 for (int i = 0; i < importPackages.size(); i++) {
124 ImportPackage importPackage = importPackages.get(i);
125
126 String s = importPackage.getLine();
127
128 int pos = s.indexOf(".");
129
130 pos = s.indexOf(".", pos + 1);
131
132 if (pos == -1) {
133 pos = s.indexOf(".");
134 }
135
136 String packageLevel = s.substring(classStartPos, pos);
137
138 if ((i != 0) && !packageLevel.equals(temp)) {
139 sb.append("\n");
140 }
141
142 temp = packageLevel;
143
144 sb.append(s);
145 sb.append("\n");
146 }
147
148 return sb.toString();
149 }
150
151 protected void checkIfClauseParentheses(
152 String ifClause, String fileName, int lineCount) {
153
154 int quoteCount = StringUtil.count(ifClause, StringPool.QUOTE);
155
156 if ((quoteCount % 2) == 1) {
157 return;
158 }
159
160 ifClause = stripQuotes(ifClause, CharPool.QUOTE);
161
162 ifClause = stripQuotes(ifClause, CharPool.APOSTROPHE);
163
164 if (ifClause.contains(StringPool.DOUBLE_SLASH) ||
165 ifClause.contains("")) {
166
167 return;
168 }
169
170 ifClause = stripRedundantParentheses(ifClause);
171
172 int level = 0;
173 int max = StringUtil.count(ifClause, StringPool.OPEN_PARENTHESIS);
174 int previousParenthesisPos = -1;
175
176 int[] levels = new int[max];
177
178 for (int i = 0; i < ifClause.length(); i++) {
179 char c = ifClause.charAt(i);
180
181 if ((c == CharPool.OPEN_PARENTHESIS) ||
182 (c == CharPool.CLOSE_PARENTHESIS)) {
183
184 if (previousParenthesisPos != -1) {
185 String s = ifClause.substring(
186 previousParenthesisPos + 1, i);
187
188 if (hasMissingParentheses(s)) {
189 processErrorMessage(
190 fileName,
191 "missing parentheses: " + fileName + " " +
192 lineCount);
193 }
194 }
195
196 previousParenthesisPos = i;
197
198 if (c == CharPool.OPEN_PARENTHESIS) {
199 levels[level] = i;
200
201 level += 1;
202 }
203 else {
204 int posOpenParenthesis = levels[level - 1];
205
206 if (level > 1) {
207 char nextChar = ifClause.charAt(i + 1);
208 char previousChar = ifClause.charAt(
209 posOpenParenthesis - 1);
210
211 if (!Character.isLetterOrDigit(nextChar) &&
212 (nextChar != CharPool.PERIOD) &&
213 !Character.isLetterOrDigit(previousChar)) {
214
215 String s = ifClause.substring(
216 posOpenParenthesis + 1, i);
217
218 if (hasRedundantParentheses(s)) {
219 processErrorMessage(
220 fileName,
221 "redundant parentheses: " + fileName + " " +
222 lineCount);
223 }
224 }
225
226 if ((previousChar == CharPool.OPEN_PARENTHESIS) &&
227 (nextChar == CharPool.CLOSE_PARENTHESIS)) {
228
229 processErrorMessage(
230 fileName,
231 "redundant parentheses: " + fileName + " " +
232 lineCount);
233 }
234 }
235
236 level -= 1;
237 }
238 }
239 }
240 }
241
242 protected void checkInefficientStringMethods(
243 String line, String fileName, int lineCount) {
244
245 if (mainReleaseVersion.equals(MAIN_RELEASE_VERSION_6_1_0)) {
246 return;
247 }
248
249 String methodName = "toLowerCase";
250
251 int pos = line.indexOf(".toLowerCase()");
252
253 if (pos == -1) {
254 methodName = "toUpperCase";
255
256 pos = line.indexOf(".toUpperCase()");
257 }
258
259 if ((pos == -1) && !line.contains("StringUtil.equalsIgnoreCase(")) {
260 methodName = "equalsIgnoreCase";
261
262 pos = line.indexOf(".equalsIgnoreCase(");
263 }
264
265 if (pos != -1) {
266 processErrorMessage(
267 fileName,
268 "Use StringUtil." + methodName + ": " + fileName + " " +
269 lineCount);
270 }
271 }
272
273 protected void checkLanguageKeys(
274 String fileName, String content, Pattern pattern)
275 throws IOException {
276
277 String fileExtension = fileUtil.getExtension(fileName);
278
279 if (!portalSource || fileExtension.equals("vm")) {
280 return;
281 }
282
283 if (_portalLanguageKeysProperties == null) {
284 _portalLanguageKeysProperties = new Properties();
285
286 ClassLoader classLoader =
287 BaseSourceProcessor.class.getClassLoader();
288
289 InputStream inputStream = classLoader.getResourceAsStream(
290 "content/Language.properties");
291
292 _portalLanguageKeysProperties.load(inputStream);
293 }
294
295 Matcher matcher = pattern.matcher(content);
296
297 while (matcher.find()) {
298 String[] languageKeys = getLanguageKeys(matcher);
299
300 for (String languageKey : languageKeys) {
301 if (Validator.isNumber(languageKey) ||
302 languageKey.endsWith(StringPool.DASH) ||
303 languageKey.endsWith(StringPool.OPEN_BRACKET) ||
304 languageKey.endsWith(StringPool.PERIOD) ||
305 languageKey.endsWith(StringPool.UNDERLINE) ||
306 languageKey.startsWith(StringPool.DASH) ||
307 languageKey.startsWith(StringPool.OPEN_BRACKET) ||
308 languageKey.startsWith(StringPool.OPEN_CURLY_BRACE) ||
309 languageKey.startsWith(StringPool.PERIOD) ||
310 languageKey.startsWith(StringPool.UNDERLINE)) {
311
312 continue;
313 }
314
315 if (!_portalLanguageKeysProperties.containsKey(languageKey)) {
316 processErrorMessage(
317 fileName,
318 "missing language key: " + languageKey +
319 StringPool.SPACE + fileName);
320 }
321 }
322 }
323 }
324
325 protected void checkStringBundler(
326 String line, String fileName, int lineCount) {
327
328 if ((!line.startsWith("sb.append(") && !line.contains("SB.append(")) ||
329 !line.endsWith(");")) {
330
331 return;
332 }
333
334 int pos = line.indexOf(".append(");
335
336 line = line.substring(pos + 8, line.length() - 2);
337
338 line = stripQuotes(line, CharPool.QUOTE);
339
340 if (!line.contains(" + ")) {
341 return;
342 }
343
344 String[] lineParts = StringUtil.split(line, " + ");
345
346 for (String linePart : lineParts) {
347 int closeParenthesesCount = StringUtil.count(
348 linePart, StringPool.CLOSE_PARENTHESIS);
349 int openParenthesesCount = StringUtil.count(
350 linePart, StringPool.OPEN_PARENTHESIS);
351
352 if (closeParenthesesCount != openParenthesesCount) {
353 return;
354 }
355
356 if (Validator.isNumber(linePart)) {
357 return;
358 }
359 }
360
361 processErrorMessage(fileName, "plus: " + fileName + " " + lineCount);
362 }
363
364 protected String fixCompatClassImports(File file, String content)
365 throws IOException {
366
367 String absolutePath = fileUtil.getAbsolutePath(file);
368
369 if (portalSource ||
370 !mainReleaseVersion.equals(MAIN_RELEASE_VERSION_6_1_0) ||
371 absolutePath.contains("/ext-") ||
372 absolutePath.contains("/portal-compat-shared/")) {
373
374 return content;
375 }
376
377 Map<String, String> compatClassNamesMap = getCompatClassNamesMap();
378
379 String newContent = content;
380
381 for (Map.Entry<String, String> entry : compatClassNamesMap.entrySet()) {
382 String compatClassName = entry.getKey();
383 String extendedClassName = entry.getValue();
384
385 Pattern pattern = Pattern.compile(extendedClassName + "\\W");
386
387 while (true) {
388 Matcher matcher = pattern.matcher(newContent);
389
390 if (!matcher.find()) {
391 break;
392 }
393
394 newContent =
395 newContent.substring(0, matcher.start()) + compatClassName +
396 newContent.substring(matcher.end() - 1);
397 }
398 }
399
400 return newContent;
401 }
402
403 protected String fixCopyright(
404 String content, String copyright, String oldCopyright, File file,
405 String fileName)
406 throws IOException {
407
408 if (fileName.endsWith(".vm")) {
409 return content;
410 }
411
412 if ((oldCopyright != null) && content.contains(oldCopyright)) {
413 content = StringUtil.replace(content, oldCopyright, copyright);
414
415 processErrorMessage(fileName, "old (c): " + fileName);
416 }
417
418 if (!content.contains(copyright)) {
419 String customCopyright = getCustomCopyright(file);
420
421 if (Validator.isNotNull(customCopyright)) {
422 copyright = customCopyright;
423 }
424
425 if (!content.contains(copyright)) {
426 processErrorMessage(fileName, "(c): " + fileName);
427 }
428 }
429
430 if (fileName.endsWith(".jsp") || fileName.endsWith(".jspf")) {
431 content = StringUtil.replace(
432 content, "<%\n" + copyright + "\n%>",
433 "<%--\n" + copyright + "\n--%>");
434 }
435
436 int x = content.indexOf("* Copyright (c) 2000-20");
437
438 if (x == -1) {
439 return content;
440 }
441
442 int y = copyright.indexOf("* Copyright (c) 2000-20");
443
444 if (y == -1) {
445 return content;
446 }
447
448 String contentCopyrightYear = content.substring(x, x + 25);
449 String copyrightYear = copyright.substring(y, y + 25);
450
451 return StringUtil.replace(content, contentCopyrightYear, copyrightYear);
452 }
453
454 protected String fixSessionKey(
455 String fileName, String content, Pattern pattern) {
456
457 if (mainReleaseVersion.equals(MAIN_RELEASE_VERSION_6_1_0)) {
458 return content;
459 }
460
461 Matcher matcher = pattern.matcher(content);
462
463 if (!matcher.find()) {
464 return content;
465 }
466
467 String newContent = content;
468
469 do {
470 String match = matcher.group();
471
472 String s = null;
473
474 if (pattern.equals(sessionKeyPattern)) {
475 s = StringPool.COMMA;
476 }
477 else if (pattern.equals(taglibSessionKeyPattern)) {
478 s = "key=";
479 }
480
481 int x = match.indexOf(s);
482
483 if (x == -1) {
484 continue;
485 }
486
487 x = x + s.length();
488
489 String substring = match.substring(x).trim();
490
491 String quote = StringPool.BLANK;
492
493 if (substring.startsWith(StringPool.APOSTROPHE)) {
494 quote = StringPool.APOSTROPHE;
495 }
496 else if (substring.startsWith(StringPool.QUOTE)) {
497 quote = StringPool.QUOTE;
498 }
499 else {
500 continue;
501 }
502
503 int y = match.indexOf(quote, x);
504 int z = match.indexOf(quote, y + 1);
505
506 if ((y == -1) || (z == -1)) {
507 continue;
508 }
509
510 String prefix = match.substring(0, y + 1);
511 String suffix = match.substring(z);
512 String oldKey = match.substring(y + 1, z);
513
514 boolean alphaNumericKey = true;
515
516 for (char c : oldKey.toCharArray()) {
517 if (!Validator.isChar(c) && !Validator.isDigit(c) &&
518 (c != CharPool.DASH) && (c != CharPool.UNDERLINE)) {
519
520 alphaNumericKey = false;
521 }
522 }
523
524 if (!alphaNumericKey) {
525 continue;
526 }
527
528 String newKey = TextFormatter.format(oldKey, TextFormatter.O);
529
530 newKey = TextFormatter.format(newKey, TextFormatter.M);
531
532 if (newKey.equals(oldKey)) {
533 continue;
534 }
535
536 String oldSub = prefix.concat(oldKey).concat(suffix);
537 String newSub = prefix.concat(newKey).concat(suffix);
538
539 newContent = StringUtil.replaceFirst(newContent, oldSub, newSub);
540 }
541 while (matcher.find());
542
543 return newContent;
544 }
545
546 protected abstract void format() throws Exception;
547
548 protected String format(String fileName) throws Exception {
549 return null;
550 }
551
552 protected Map<String, String> getCompatClassNamesMap() throws IOException {
553 if (_compatClassNamesMap != null) {
554 return _compatClassNamesMap;
555 }
556
557 Map<String, String> compatClassNamesMap = new HashMap<String, String>();
558
559 String[] includes = new String[] {
560 "**\\portal-compat-shared\\src\\com\\liferay\\compat\\**\\*.java"
561 };
562
563 String basedir = BASEDIR;
564
565 List<String> fileNames = new ArrayList<String>();
566
567 for (int i = 0; i < 3; i++) {
568 fileNames = getFileNames(basedir, new String[0], includes);
569
570 if (!fileNames.isEmpty()) {
571 break;
572 }
573
574 basedir = "../" + basedir;
575 }
576
577 for (String fileName : fileNames) {
578 File file = new File(basedir + fileName);
579
580 String content = fileUtil.read(file);
581
582 fileName = StringUtil.replace(
583 fileName, StringPool.BACK_SLASH, StringPool.SLASH);
584
585 fileName = StringUtil.replace(
586 fileName, StringPool.SLASH, StringPool.PERIOD);
587
588 int pos = fileName.indexOf("com.");
589
590 String compatClassName = fileName.substring(pos);
591
592 compatClassName = compatClassName.substring(
593 0, compatClassName.length() - 5);
594
595 String extendedClassName = StringUtil.replace(
596 compatClassName, "compat.", StringPool.BLANK);
597
598 if (content.contains("extends " + extendedClassName)) {
599 compatClassNamesMap.put(compatClassName, extendedClassName);
600 }
601 }
602
603 _compatClassNamesMap = compatClassNamesMap;
604
605 return _compatClassNamesMap;
606 }
607
608 protected String getCopyright() throws IOException {
609 if (Validator.isNotNull(_copyright)) {
610 return _copyright;
611 }
612
613 _copyright = fileUtil.read("copyright.txt");
614
615 if (Validator.isNull(_copyright)) {
616 _copyright = fileUtil.read("../copyright.txt");
617 }
618
619 if (Validator.isNull(_copyright)) {
620 _copyright = fileUtil.read("../../copyright.txt");
621 }
622
623 return _copyright;
624 }
625
626 protected String getCustomCopyright(File file) throws IOException {
627 String absolutePath = fileUtil.getAbsolutePath(file);
628
629 for (int x = absolutePath.length();;) {
630 x = absolutePath.lastIndexOf(StringPool.SLASH, x);
631
632 if (x == -1) {
633 break;
634 }
635
636 String copyright = fileUtil.read(
637 absolutePath.substring(0, x + 1) + "copyright.txt");
638
639 if (Validator.isNotNull(copyright)) {
640 return copyright;
641 }
642
643 x = x - 1;
644 }
645
646 return null;
647 }
648
649 protected Properties getExclusionsProperties(String fileName)
650 throws IOException {
651
652 InputStream inputStream = null;
653
654 int level = 0;
655
656 if (portalSource) {
657 ClassLoader classLoader =
658 BaseSourceProcessor.class.getClassLoader();
659
660 String sourceFormatterExclusions = System.getProperty(
661 "source-formatter-exclusions",
662 "com/liferay/portal/tools/dependencies/" + fileName);
663
664 URL url = classLoader.getResource(sourceFormatterExclusions);
665
666 if (url == null) {
667 return null;
668 }
669
670 inputStream = url.openStream();
671 }
672 else {
673 try {
674 inputStream = new FileInputStream(fileName);
675 }
676 catch (FileNotFoundException fnfe) {
677 }
678
679 if (inputStream == null) {
680 try {
681 inputStream = new FileInputStream("../" + fileName);
682
683 level = 1;
684 }
685 catch (FileNotFoundException fnfe) {
686 }
687 }
688
689 if (inputStream == null) {
690 try {
691 inputStream = new FileInputStream("../../" + fileName);
692
693 level = 2;
694 }
695 catch (FileNotFoundException fnfe) {
696 return null;
697 }
698 }
699 }
700
701 Properties properties = new Properties();
702
703 properties.load(inputStream);
704
705 inputStream.close();
706
707 if (level > 0) {
708 properties = stripTopLevelDirectories(properties, level);
709 }
710
711 return properties;
712 }
713
714 protected List<String> getFileNames(
715 String basedir, String[] excludes, String[] includes) {
716
717 DirectoryScanner directoryScanner = new DirectoryScanner();
718
719 directoryScanner.setBasedir(basedir);
720
721 excludes = ArrayUtil.append(
722 excludes, _excludes, new String[] {"**\\.git\\**", "**\\tmp\\**"});
723
724 if (portalSource) {
725 excludes = ArrayUtil.append(
726 excludes, new String[] {"**\\webapps\\**"});
727 }
728
729 directoryScanner.setExcludes(excludes);
730
731 directoryScanner.setIncludes(includes);
732
733 return sourceFormatterHelper.scanForFiles(directoryScanner);
734 }
735
736 protected List<String> getFileNames(String[] excludes, String[] includes) {
737 return getFileNames(BASEDIR, excludes, includes);
738 }
739
740 protected String[] getLanguageKeys(Matcher matcher) {
741 if (matcher.groupCount() > 0) {
742 String languageKey = matcher.group(1);
743
744 if (Validator.isNotNull(languageKey)) {
745 return new String[] {languageKey};
746 }
747 }
748
749 StringBundler sb = new StringBundler();
750
751 String match = matcher.group();
752
753 int count = 0;
754
755 for (int i = 0; i < match.length(); i++) {
756 char c = match.charAt(i);
757
758 switch (c) {
759 case CharPool.CLOSE_PARENTHESIS:
760 if (count <= 1) {
761 return new String[0];
762 }
763
764 count--;
765
766 break;
767
768 case CharPool.OPEN_PARENTHESIS:
769 count++;
770
771 break;
772
773 case CharPool.QUOTE:
774 if (count > 1) {
775 break;
776 }
777
778 while (i < match.length()) {
779 i++;
780
781 if (match.charAt(i) == CharPool.QUOTE) {
782 String languageKey = sb.toString();
783
784 if (match.startsWith("names")) {
785 return StringUtil.split(languageKey);
786 }
787 else {
788 return new String[] {languageKey};
789 }
790
791 }
792
793 sb.append(match.charAt(i));
794 }
795 }
796 }
797
798 return new String[0];
799 }
800
801 protected String getOldCopyright() throws IOException {
802 if (Validator.isNotNull(_oldCopyright)) {
803 return _oldCopyright;
804 }
805
806 _oldCopyright = fileUtil.read("old-copyright.txt");
807
808 if (Validator.isNull(_oldCopyright)) {
809 _oldCopyright = fileUtil.read("../old-copyright.txt");
810 }
811
812 if (Validator.isNull(_oldCopyright)) {
813 _oldCopyright = fileUtil.read("../../old-copyright.txt");
814 }
815
816 return _oldCopyright;
817 }
818
819 protected boolean hasMissingParentheses(String s) {
820 if (Validator.isNull(s)) {
821 return false;
822 }
823
824 boolean containsAndOrOperator = (s.contains("&&") || s.contains("||"));
825
826 boolean containsCompareOperator =
827 (s.contains(" == ") || s.contains(" != ") || s.contains(" < ") ||
828 s.contains(" > ") || s.contains(" =< ") || s.contains(" => ") ||
829 s.contains(" <= ") || s.contains(" >= "));
830
831 boolean containsMathOperator =
832 (s.contains(" = ") || s.contains(" - ") || s.contains(" + ") ||
833 s.contains(" & ") || s.contains(" % ") || s.contains(" * ") ||
834 s.contains(" / "));
835
836 if (containsCompareOperator &&
837 (containsAndOrOperator ||
838 (containsMathOperator && !s.contains(StringPool.OPEN_BRACKET)))) {
839
840 return true;
841 }
842 else {
843 return false;
844 }
845 }
846
847 protected boolean hasRedundantParentheses(String s) {
848 if (!s.contains("&&") && !s.contains("||")) {
849 for (int x = 0;;) {
850 x = s.indexOf(StringPool.CLOSE_PARENTHESIS);
851
852 if (x == -1) {
853 break;
854 }
855
856 int y = s.substring(0, x).lastIndexOf(
857 StringPool.OPEN_PARENTHESIS);
858
859 if (y == -1) {
860 break;
861 }
862
863 s = s.substring(0, y) + s.substring(x + 1);
864 }
865 }
866
867 if (Validator.isNotNull(s) && !s.contains(StringPool.SPACE)) {
868 return true;
869 }
870 else {
871 return false;
872 }
873 }
874
875 protected boolean isAutoFix() {
876 return _autoFix;
877 }
878
879 protected void processErrorMessage(String fileName, String message) {
880 _errorMessages.add(message);
881
882 if (_printErrors) {
883 sourceFormatterHelper.printError(fileName, message);
884 }
885 }
886
887 protected String replacePrimitiveWrapperInstantiation(
888 String fileName, String line, int lineCount) {
889
890 if (true) {
891 return line;
892 }
893
894 String newLine = StringUtil.replace(
895 line,
896 new String[] {
897 "new Boolean(", "new Byte(", "new Character(", "new Integer(",
898 "new Long(", "new Short("
899 },
900 new String[] {
901 "Boolean.valueOf(", "Byte.valueOf(", "Character.valueOf(",
902 "Integer.valueOf(", "Long.valueOf(", "Short.valueOf("
903 });
904
905 if (!line.equals(newLine)) {
906 processErrorMessage(
907 fileName, "> new Primitive(: " + fileName + " " + lineCount);
908 }
909
910 return newLine;
911 }
912
913 protected String stripQuotes(String s, char delimeter) {
914 boolean insideQuotes = false;
915
916 StringBundler sb = new StringBundler();
917
918 for (int i = 0; i < s.length(); i++) {
919 char c = s.charAt(i);
920
921 if (insideQuotes) {
922 if (c == delimeter) {
923 if ((c > 1) && (s.charAt(i - 1) == CharPool.BACK_SLASH) &&
924 (s.charAt(i - 2) != CharPool.BACK_SLASH)) {
925
926 continue;
927 }
928
929 insideQuotes = false;
930 }
931 }
932 else if (c == delimeter) {
933 insideQuotes = true;
934 }
935 else {
936 sb.append(c);
937 }
938 }
939
940 return sb.toString();
941 }
942
943 protected String stripRedundantParentheses(String s) {
944 for (int x = 0;;) {
945 x = s.indexOf(StringPool.OPEN_PARENTHESIS, x + 1);
946 int y = s.indexOf(StringPool.CLOSE_PARENTHESIS, x);
947
948 if ((x == -1) || (y == -1)) {
949 return s;
950 }
951
952 String linePart = s.substring(x + 1, y);
953
954 linePart = StringUtil.replace(
955 linePart, StringPool.COMMA, StringPool.BLANK);
956
957 if (Validator.isAlphanumericName(linePart) ||
958 Validator.isNull(linePart)) {
959
960 s = s.substring(0, x) + s.substring(y + 1);
961 }
962 }
963 }
964
965 protected Properties stripTopLevelDirectories(
966 Properties properties, int level)
967 throws IOException {
968
969 File dir = new File(".");
970
971 String dirName = dir.getCanonicalPath();
972
973 dirName = StringUtil.replace(
974 dirName, StringPool.BACK_SLASH, StringPool.SLASH);
975
976 int pos = dirName.length();
977
978 for (int i = 0; i < level; i++) {
979 pos = dirName.lastIndexOf(StringPool.SLASH, pos - 1);
980 }
981
982 String topLevelDirNames = dirName.substring(pos + 1) + StringPool.SLASH;
983
984 Properties newProperties = new Properties();
985
986 for (Map.Entry<Object, Object> entry : properties.entrySet()) {
987 String key = (String)entry.getKey();
988
989 if (!key.startsWith(topLevelDirNames)) {
990 continue;
991 }
992
993 key = StringUtil.replaceFirst(
994 key, topLevelDirNames, StringPool.BLANK);
995
996 String value = (String)entry.getValue();
997
998 newProperties.setProperty(key, value);
999 }
1000
1001 return newProperties;
1002 }
1003
1004 protected String trimContent(String content, boolean allowLeadingSpaces)
1005 throws IOException {
1006
1007 StringBundler sb = new StringBundler();
1008
1009 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
1010 new UnsyncStringReader(content));
1011
1012 String line = null;
1013
1014 while ((line = unsyncBufferedReader.readLine()) != null) {
1015 sb.append(trimLine(line, allowLeadingSpaces));
1016 sb.append("\n");
1017 }
1018
1019 unsyncBufferedReader.close();
1020
1021 content = sb.toString();
1022
1023 if (content.endsWith("\n")) {
1024 content = content.substring(0, content.length() - 1);
1025 }
1026
1027 return content;
1028 }
1029
1030 protected String trimLine(String line, boolean allowLeadingSpaces) {
1031 if (line.trim().length() == 0) {
1032 return StringPool.BLANK;
1033 }
1034
1035 line = StringUtil.trimTrailing(line);
1036
1037 if (allowLeadingSpaces || !line.startsWith(StringPool.SPACE) ||
1038 line.startsWith(" *")) {
1039
1040 return line;
1041 }
1042
1043 if (!line.startsWith(StringPool.FOUR_SPACES)) {
1044 while (line.startsWith(StringPool.SPACE)) {
1045 line = StringUtil.replaceFirst(
1046 line, StringPool.SPACE, StringPool.BLANK);
1047 }
1048 }
1049 else {
1050 int pos = 0;
1051
1052 String temp = line;
1053
1054 while (temp.startsWith(StringPool.FOUR_SPACES)) {
1055 line = StringUtil.replaceFirst(
1056 line, StringPool.FOUR_SPACES, StringPool.TAB);
1057
1058 pos++;
1059
1060 temp = line.substring(pos);
1061 }
1062 }
1063
1064 return line;
1065 }
1066
1067 protected static final String BASEDIR = "./";
1068
1069 protected static final String MAIN_RELEASE_VERSION_6_1_0 = "6.1.0";
1070
1071 protected static final String MAIN_RELEASE_VERSION_6_2_0 = "6.2.0";
1072
1073 protected static FileImpl fileUtil = FileImpl.getInstance();
1074 protected static Pattern languageKeyPattern = Pattern.compile(
1075 "LanguageUtil.(?:get|format)\\([^;%]+|Liferay.Language.get\\('([^']+)");
1076 protected static String mainReleaseVersion;
1077 protected static boolean portalSource;
1078 protected static SAXReaderImpl saxReaderUtil = SAXReaderImpl.getInstance();
1079 protected static Pattern sessionKeyPattern = Pattern.compile(
1080 "SessionErrors.(?:add|contains|get)\\([^;%&|!]+|".concat(
1081 "SessionMessages.(?:add|contains|get)\\([^;%&|!]+"),
1082 Pattern.MULTILINE);
1083 protected static SourceFormatterHelper sourceFormatterHelper;
1084 protected static Pattern taglibSessionKeyPattern = Pattern.compile(
1085 "<liferay-ui:error [^>]+>|<liferay-ui:success [^>]+>",
1086 Pattern.MULTILINE);
1087
1088 private void _init(
1089 boolean useProperties, boolean printErrors, boolean autoFix)
1090 throws Exception {
1091
1092 _errorMessages = new ArrayList<String>();
1093
1094 sourceFormatterHelper = new SourceFormatterHelper(useProperties);
1095
1096 sourceFormatterHelper.init();
1097
1098 if (_initialized) {
1099 return;
1100 }
1101
1102 _autoFix = autoFix;
1103
1104 _setVersion();
1105
1106 _excludes = StringUtil.split(
1107 GetterUtil.getString(
1108 System.getProperty("source.formatter.excludes")));
1109
1110 portalSource = _isPortalSource();
1111
1112 _printErrors = printErrors;
1113
1114 _initialized = true;
1115 }
1116
1117 private boolean _isPortalSource() {
1118 if (fileUtil.exists(BASEDIR + "portal-impl")) {
1119 return true;
1120 }
1121 else {
1122 return false;
1123 }
1124 }
1125
1126 private void _setVersion() throws Exception {
1127 String releaseInfoVersion = ReleaseInfo.getVersion();
1128
1129 if (releaseInfoVersion.startsWith("6.1")) {
1130 mainReleaseVersion = MAIN_RELEASE_VERSION_6_1_0;
1131 }
1132 else if (releaseInfoVersion.startsWith("6.2")) {
1133 mainReleaseVersion = MAIN_RELEASE_VERSION_6_2_0;
1134 }
1135 else {
1136 throw new Exception(
1137 "Invalid release information: " + ReleaseInfo.getVersion());
1138 }
1139 }
1140
1141 private static boolean _autoFix;
1142 private static Map<String, String> _compatClassNamesMap;
1143 private static String _copyright;
1144 private static List<String> _errorMessages = new ArrayList<String>();
1145 private static String[] _excludes;
1146 private static boolean _initialized;
1147 private static String _oldCopyright;
1148 private static Properties _portalLanguageKeysProperties;
1149 private static boolean _printErrors;
1150
1151 }