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.CharPool;
020 import com.liferay.portal.kernel.util.PropertiesUtil;
021 import com.liferay.portal.kernel.util.PropsKeys;
022 import com.liferay.portal.kernel.util.StringBundler;
023 import com.liferay.portal.kernel.util.StringPool;
024 import com.liferay.portal.kernel.util.StringUtil;
025 import com.liferay.portal.kernel.util.Validator;
026 import com.liferay.portal.kernel.xml.Document;
027 import com.liferay.portal.kernel.xml.Element;
028 import com.liferay.portal.tools.ComparableRoute;
029 import com.liferay.util.ContentUtil;
030
031 import java.io.File;
032
033 import java.util.ArrayList;
034 import java.util.Arrays;
035 import java.util.Collections;
036 import java.util.Comparator;
037 import java.util.List;
038 import java.util.Map;
039 import java.util.Properties;
040 import java.util.Set;
041 import java.util.TreeMap;
042 import java.util.TreeSet;
043 import java.util.regex.Matcher;
044 import java.util.regex.Pattern;
045
046
049 public class XMLSourceProcessor extends BaseSourceProcessor {
050
051 public static String formatXML(String content) {
052 String newContent = StringUtil.replace(content, "\"/>\n", "\" />\n");
053
054 while (true) {
055 Matcher matcher = _commentPattern1.matcher(newContent);
056
057 if (matcher.find()) {
058 newContent = StringUtil.replaceFirst(
059 newContent, ">\n", ">\n\n", matcher.start());
060
061 continue;
062 }
063
064 matcher = _commentPattern2.matcher(newContent);
065
066 if (!matcher.find()) {
067 break;
068 }
069
070 newContent = StringUtil.replaceFirst(
071 newContent, "-->\n", "-->\n\n", matcher.start());
072 }
073
074 return newContent;
075 }
076
077 protected void checkPoshiCharactersAfterDefinition(
078 String fileName, String content) {
079
080 if (content.contains("/definition>") &&
081 !content.endsWith("/definition>")) {
082
083 processErrorMessage(
084 fileName,
085 "Characters found after definition element: " + fileName);
086 }
087 }
088
089 protected void checkPoshiCharactersBeforeDefinition(
090 String fileName, String content) {
091
092 if (!content.startsWith("<definition")) {
093 processErrorMessage(
094 fileName,
095 "Characters found before definition element: " + fileName);
096 }
097 }
098
099 protected void checkServiceXMLExceptions(
100 String fileName, Element rootElement) {
101
102 Element exceptionsElement = rootElement.element("exceptions");
103
104 if (exceptionsElement == null) {
105 return;
106 }
107
108 List<Element> exceptionElements = exceptionsElement.elements(
109 "exception");
110
111 String previousException = StringPool.BLANK;
112
113 for (Element exceptionElement : exceptionElements) {
114 String exception = exceptionElement.getStringValue();
115
116 if (Validator.isNotNull(previousException) &&
117 (previousException.compareToIgnoreCase(exception) > 0)) {
118
119 processErrorMessage(
120 fileName, "sort: " + fileName + " " + exception);
121 }
122
123 previousException = exception;
124 }
125 }
126
127 protected void checkServiceXMLFinders(
128 String fileName, Element entityElement, String entityName)
129 throws Exception {
130
131 _columnNames = getColumnNames(fileName, entityName);
132
133 FinderElementComparator finderElementComparator =
134 new FinderElementComparator();
135
136 List<Element> finderElements = entityElement.elements("finder");
137
138 for (int i = 1; i < finderElements.size(); i++) {
139 Element finderElement = finderElements.get(i);
140 Element previousFinderElement = finderElements.get(i - 1);
141
142 if (finderElementComparator.compare(
143 previousFinderElement, finderElement) > 0) {
144
145 String finderName = finderElement.attributeValue("name");
146
147 processErrorMessage(
148 fileName,
149 "order: " + fileName + " " + entityName + " " + finderName);
150 }
151 }
152 }
153
154 protected void checkServiceXMLReferences(
155 String fileName, Element entityElement, String entityName) {
156
157 String previousReferenceEntity = StringPool.BLANK;
158 String previousReferencePackagePath = StringPool.BLANK;
159
160 List<Element> referenceElements = entityElement.elements("reference");
161
162 for (Element referenceElement : referenceElements) {
163 String referenceEntity = referenceElement.attributeValue("entity");
164 String referencePackagePath = referenceElement.attributeValue(
165 "package-path");
166
167 if (Validator.isNotNull(previousReferencePackagePath)) {
168 if ((previousReferencePackagePath.compareToIgnoreCase(
169 referencePackagePath) > 0) ||
170 (previousReferencePackagePath.equals(
171 referencePackagePath) &&
172 (previousReferenceEntity.compareToIgnoreCase(
173 referenceEntity) > 0))) {
174
175 processErrorMessage(
176 fileName,
177 "sort: " + fileName + " " + entityName + " " +
178 referenceEntity);
179 }
180 }
181
182 previousReferenceEntity = referenceEntity;
183 previousReferencePackagePath = referencePackagePath;
184 }
185 }
186
187 @Override
188 protected String doFormat(
189 File file, String fileName, String absolutePath, String content)
190 throws Exception {
191
192 if (isExcluded(_xmlExclusions, absolutePath)) {
193 return content;
194 }
195
196 String newContent = content;
197
198 if (!fileName.contains("/build")) {
199 newContent = trimContent(newContent, false);
200 }
201
202 if (fileName.contains("/build") && !fileName.contains("/tools/")) {
203 newContent = formatAntXML(fileName, newContent);
204 }
205 else if (fileName.contains("/custom-sql/")) {
206 formatCustomSQLXML(fileName, newContent);
207 }
208 else if (fileName.endsWith("structures.xml")) {
209 newContent = formatDDLStructuresXML(newContent);
210 }
211 else if (fileName.endsWith("routes.xml")) {
212 newContent = formatFriendlyURLRoutesXML(absolutePath, newContent);
213 }
214 else if (fileName.endsWith("/liferay-portlet.xml") ||
215 (portalSource &&
216 fileName.endsWith("/portlet-custom.xml")) ||
217 (!portalSource && fileName.endsWith("/portlet.xml"))) {
218
219 newContent = formatPortletXML(fileName, absolutePath, newContent);
220 }
221 else if (portalSource &&
222 (fileName.endsWith(".action") ||
223 fileName.endsWith(".function") ||
224 fileName.endsWith(".macro") ||
225 fileName.endsWith(".testcase") ||
226 fileName.endsWith(".testxml"))) {
227
228 newContent = formatPoshiXML(fileName, newContent);
229 }
230 else if (fileName.endsWith("/service.xml")) {
231 formatServiceXML(fileName, newContent);
232 }
233 else if (portalSource && fileName.endsWith("/struts-config.xml")) {
234 formatStrutsConfigXML(fileName, newContent);
235 }
236 else if (portalSource && fileName.endsWith("/tiles-defs.xml")) {
237 formatTilesDefsXML(fileName, newContent);
238 }
239 else if ((portalSource &&
240 fileName.endsWith(
241 "portal-web/docroot/WEB-INF/web.xml")) ||
242 (!portalSource && fileName.endsWith("/web.xml"))) {
243
244 newContent = formatWebXML(fileName, newContent);
245 }
246
247 return formatXML(newContent);
248 }
249
250 protected String fixAntXMLProjectName(String fileName, String content) {
251 int x = 0;
252
253 if (fileName.endsWith("-ext/build.xml")) {
254 if (fileName.startsWith("ext/")) {
255 x = 4;
256 }
257 }
258 else if (fileName.endsWith("-hook/build.xml")) {
259 if (fileName.startsWith("hooks/")) {
260 x = 6;
261 }
262 }
263 else if (fileName.endsWith("-layouttpl/build.xml")) {
264 if (fileName.startsWith("layouttpl/")) {
265 x = 10;
266 }
267 }
268 else if (fileName.endsWith("-portlet/build.xml")) {
269 if (fileName.startsWith("portlets/")) {
270 x = 9;
271 }
272 }
273 else if (fileName.endsWith("-theme/build.xml")) {
274 if (fileName.startsWith("themes/")) {
275 x = 7;
276 }
277 }
278 else if (fileName.endsWith("-web/build.xml") &&
279 !fileName.endsWith("/ext-web/build.xml")) {
280
281 if (fileName.startsWith("webs/")) {
282 x = 5;
283 }
284 }
285 else {
286 return content;
287 }
288
289 if (content.contains("<project>")) {
290 return content;
291 }
292
293 int y = fileName.indexOf("/", x);
294
295 String correctProjectElementText =
296 "<project name=\"" + fileName.substring(x, y) + "\"";
297
298 if (!content.contains(correctProjectElementText)) {
299 x = content.indexOf("<project name=\"");
300
301 y = content.indexOf("\"", x) + 1;
302 y = content.indexOf("\"", y) + 1;
303
304 content =
305 content.substring(0, x) + correctProjectElementText +
306 content.substring(y);
307
308 processErrorMessage(
309 fileName, fileName + " has an incorrect project name");
310 }
311
312 return content;
313 }
314
315 protected String fixPoshiXMLElementWithNoChild(String content) {
316 Matcher matcher = _poshiElementWithNoChildPattern.matcher(content);
317
318 while (matcher.find()) {
319 content = StringUtil.replace(content, matcher.group(), "\" />");
320 }
321
322 return content;
323 }
324
325 protected String fixPoshiXMLEndLines(String content) {
326 Matcher matcher = _poshiEndLinesPattern.matcher(content);
327
328 while (matcher.find()) {
329 String statement = matcher.group();
330
331 String newStatement = StringUtil.replace(
332 statement, matcher.group(), ">\n\n" + matcher.group(1));
333
334 content = StringUtil.replace(content, statement, newStatement);
335 }
336
337 return content;
338 }
339
340 protected String fixPoshiXMLEndLinesAfterClosingElement(String content) {
341 Matcher matcher = _poshiEndLinesAfterClosingElementPattern.matcher(
342 content);
343
344 while (matcher.find()) {
345 String statement = matcher.group();
346
347 String closingElementName = matcher.group(1);
348
349 if (StringUtil.equalsIgnoreCase("</and>", closingElementName) ||
350 StringUtil.equalsIgnoreCase("</elseif>", closingElementName) ||
351 StringUtil.equalsIgnoreCase("</not>", closingElementName) ||
352 StringUtil.equalsIgnoreCase("</or>", closingElementName) ||
353 StringUtil.equalsIgnoreCase("</then>", closingElementName)) {
354
355 String newStatement = StringUtil.replace(
356 statement, matcher.group(2), "\n");
357
358 content = StringUtil.replace(content, statement, newStatement);
359 }
360 else if (!StringUtil.equalsIgnoreCase(
361 "</var>", closingElementName)) {
362
363 String newStatement = StringUtil.replace(
364 statement, matcher.group(2), "\n\n");
365
366 content = StringUtil.replace(content, statement, newStatement);
367 }
368 }
369
370 return content;
371 }
372
373 protected String fixPoshiXMLEndLinesBeforeClosingElement(String content) {
374 Matcher matcher = _poshiEndLinesBeforeClosingElementPattern.matcher(
375 content);
376
377 while (matcher.find()) {
378 String statement = matcher.group();
379
380 String newStatement = StringUtil.replace(
381 statement, matcher.group(1), "\n");
382
383 content = StringUtil.replace(content, statement, newStatement);
384 }
385
386 return content;
387 }
388
389 protected String fixPoshiXMLNumberOfTabs(String content) {
390 Matcher matcher = _poshiTabsPattern.matcher(content);
391
392 int tabCount = 0;
393
394 boolean ignoredCdataBlock = false;
395 boolean ignoredCommentBlock = false;
396
397 while (matcher.find()) {
398 String statement = matcher.group();
399
400 Matcher quoteWithSlashMatcher = _poshiQuoteWithSlashPattern.matcher(
401 statement);
402
403 String fixedQuoteStatement = statement;
404
405 if (quoteWithSlashMatcher.find()) {
406 fixedQuoteStatement = StringUtil.replace(
407 statement, quoteWithSlashMatcher.group(), "\"\"");
408 }
409
410 Matcher closingTagMatcher = _poshiClosingTagPattern.matcher(
411 fixedQuoteStatement);
412 Matcher openingTagMatcher = _poshiOpeningTagPattern.matcher(
413 fixedQuoteStatement);
414 Matcher wholeTagMatcher = _poshiWholeTagPattern.matcher(
415 fixedQuoteStatement);
416
417 if (closingTagMatcher.find() && !openingTagMatcher.find() &&
418 !wholeTagMatcher.find() && !statement.contains("<!--") &&
419 !statement.contains("-->") &&
420 !statement.contains("<![CDATA[") &&
421 !statement.contains("]]>")) {
422
423 tabCount--;
424 }
425
426 if (statement.contains("]]>")) {
427 ignoredCdataBlock = false;
428 }
429 else if (statement.contains("<![CDATA[")) {
430 ignoredCdataBlock = true;
431 }
432
433 if (statement.contains("-->")) {
434 ignoredCommentBlock = false;
435 }
436 else if (statement.contains("<!--")) {
437 ignoredCommentBlock = true;
438 }
439
440 if (!ignoredCommentBlock && !ignoredCdataBlock) {
441 StringBundler sb = new StringBundler(tabCount + 1);
442
443 for (int i = 0; i < tabCount; i++) {
444 sb.append(StringPool.TAB);
445 }
446
447 sb.append(StringPool.LESS_THAN);
448
449 String replacement = sb.toString();
450
451 if (!replacement.equals(matcher.group(1))) {
452 String newStatement = StringUtil.replace(
453 statement, matcher.group(1), replacement);
454
455 return StringUtil.replaceFirst(
456 content, statement, newStatement, matcher.start());
457 }
458 }
459
460 if (openingTagMatcher.find() && !closingTagMatcher.find() &&
461 !wholeTagMatcher.find() && !statement.contains("<!--") &&
462 !statement.contains("-->") &&
463 !statement.contains("<![CDATA[") &&
464 !statement.contains("]]>")) {
465
466 tabCount++;
467 }
468 }
469
470 return content;
471 }
472
473 @Override
474 protected void format() throws Exception {
475 String[] excludes = new String[] {
476 "**\\.bnd\\**", "**\\.idea\\**", "**\\.ivy\\**",
477 "portal-impl\\**\\*.action", "portal-impl\\**\\*.function",
478 "portal-impl\\**\\*.macro", "portal-impl\\**\\*.testcase"
479 };
480
481 String[] includes = new String[] {
482 "**\\*.action","**\\*.function","**\\*.macro","**\\*.testcase",
483 "**\\*.xml"
484 };
485
486 _friendlyUrlRoutesSortExclusions = getPropertyList(
487 "friendly.url.routes.sort.excludes.files");
488 _numericalPortletNameElementExclusions = getPropertyList(
489 "numerical.portlet.name.element.excludes.files");
490 _xmlExclusions = getPropertyList("xml.excludes.files");
491
492 List<String> fileNames = getFileNames(excludes, includes);
493
494 for (String fileName : fileNames) {
495 format(fileName);
496 }
497 }
498
499 protected String formatAntXML(String fileName, String content)
500 throws Exception {
501
502 String newContent = trimContent(content, true);
503
504 newContent = fixAntXMLProjectName(fileName, newContent);
505
506 Document document = saxReaderUtil.read(newContent);
507
508 Element rootElement = document.getRootElement();
509
510 String previousName = StringPool.BLANK;
511
512 List<Element> targetElements = rootElement.elements("target");
513
514 for (Element targetElement : targetElements) {
515 String name = targetElement.attributeValue("name");
516
517 if (name.equals("Test")) {
518 name = StringUtil.toLowerCase(name);
519 }
520
521 if (name.compareTo(previousName) < -1) {
522 processErrorMessage(
523 fileName, fileName + " has an unordered target " + name);
524
525 break;
526 }
527
528 previousName = name;
529 }
530
531 return newContent;
532 }
533
534 protected void formatCustomSQLXML(String fileName, String content) {
535 Matcher matcher = _whereNotInSQLPattern.matcher(content);
536
537 if (!matcher.find()) {
538 return;
539 }
540
541 int x = content.lastIndexOf("<sql id=", matcher.start());
542
543 int y = content.indexOf(CharPool.QUOTE, x);
544
545 int z = content.indexOf(CharPool.QUOTE, y + 1);
546
547 processErrorMessage(
548 fileName,
549 "LPS-51315 Avoid using WHERE ... NOT IN: " + fileName + " " +
550 content.substring(y + 1, z));
551 }
552
553 protected String formatDDLStructuresXML(String content) throws Exception {
554 Document document = saxReaderUtil.read(content);
555
556 Element rootElement = document.getRootElement();
557
558 rootElement.sortAttributes(true);
559
560 rootElement.sortElementsByChildElement("structure", "name");
561
562 List<Element> structureElements = rootElement.elements("structure");
563
564 for (Element structureElement : structureElements) {
565 Element structureRootElement = structureElement.element("root");
566
567 structureRootElement.sortElementsByAttribute(
568 "dynamic-element", "name");
569
570 List<Element> dynamicElementElements =
571 structureRootElement.elements("dynamic-element");
572
573 for (Element dynamicElementElement : dynamicElementElements) {
574 Element metaDataElement = dynamicElementElement.element(
575 "meta-data");
576
577 metaDataElement.sortElementsByAttribute("entry", "name");
578 }
579 }
580
581 return document.formattedString();
582 }
583
584 protected String formatFriendlyURLRoutesXML(
585 String absolutePath, String content)
586 throws Exception {
587
588 if (isExcluded(_friendlyUrlRoutesSortExclusions, absolutePath)) {
589 return content;
590 }
591
592 Document document = saxReaderUtil.read(content);
593
594 Element rootElement = document.getRootElement();
595
596 List<ComparableRoute> comparableRoutes =
597 new ArrayList<ComparableRoute>();
598
599 for (Element routeElement : rootElement.elements("route")) {
600 String pattern = routeElement.elementText("pattern");
601
602 ComparableRoute comparableRoute = new ComparableRoute(pattern);
603
604 for (Element generatedParameterElement :
605 routeElement.elements("generated-parameter")) {
606
607 String name = generatedParameterElement.attributeValue("name");
608 String value = generatedParameterElement.getText();
609
610 comparableRoute.addGeneratedParameter(name, value);
611 }
612
613 for (Element ignoredParameterElement :
614 routeElement.elements("ignored-parameter")) {
615
616 String name = ignoredParameterElement.attributeValue("name");
617
618 comparableRoute.addIgnoredParameter(name);
619 }
620
621 for (Element implicitParameterElement :
622 routeElement.elements("implicit-parameter")) {
623
624 String name = implicitParameterElement.attributeValue("name");
625 String value = implicitParameterElement.getText();
626
627 comparableRoute.addImplicitParameter(name, value);
628 }
629
630 for (Element overriddenParameterElement :
631 routeElement.elements("overridden-parameter")) {
632
633 String name = overriddenParameterElement.attributeValue("name");
634 String value = overriddenParameterElement.getText();
635
636 comparableRoute.addOverriddenParameter(name, value);
637 }
638
639 comparableRoutes.add(comparableRoute);
640 }
641
642 Collections.sort(comparableRoutes);
643
644 String mainReleaseVersion = getMainReleaseVersion();
645
646 StringBundler sb = new StringBundler();
647
648 sb.append("<?xml version=\"1.0\"?>\n");
649 sb.append("<!DOCTYPE routes PUBLIC \"-
650 sb.append("Routes ");
651 sb.append(mainReleaseVersion);
652 sb.append("
653 sb.append("liferay-friendly-url-routes_");
654 sb.append(
655 StringUtil.replace(
656 mainReleaseVersion, StringPool.PERIOD, StringPool.UNDERLINE));
657 sb.append(".dtd\">\n\n<routes>\n");
658
659 for (ComparableRoute comparableRoute : comparableRoutes) {
660 sb.append("\t<route>\n");
661 sb.append("\t\t<pattern>");
662 sb.append(comparableRoute.getPattern());
663 sb.append("</pattern>\n");
664
665 Map<String, String> generatedParameters =
666 comparableRoute.getGeneratedParameters();
667
668 for (Map.Entry<String, String> entry :
669 generatedParameters.entrySet()) {
670
671 sb.append("\t\t<generated-parameter name=\"");
672 sb.append(entry.getKey());
673 sb.append("\">");
674 sb.append(entry.getValue());
675 sb.append("</generated-parameter>\n");
676 }
677
678 Set<String> ignoredParameters =
679 comparableRoute.getIgnoredParameters();
680
681 for (String entry : ignoredParameters) {
682 sb.append("\t\t<ignored-parameter name=\"");
683 sb.append(entry);
684 sb.append("\" />\n");
685 }
686
687 Map<String, String> implicitParameters =
688 comparableRoute.getImplicitParameters();
689
690 for (Map.Entry<String, String> entry :
691 implicitParameters.entrySet()) {
692
693 sb.append("\t\t<implicit-parameter name=\"");
694 sb.append(entry.getKey());
695 sb.append("\">");
696 sb.append(entry.getValue());
697 sb.append("</implicit-parameter>\n");
698 }
699
700 Map<String, String> overriddenParameters =
701 comparableRoute.getOverriddenParameters();
702
703 for (Map.Entry<String, String> entry :
704 overriddenParameters.entrySet()) {
705
706 sb.append("\t\t<overridden-parameter name=\"");
707 sb.append(entry.getKey());
708 sb.append("\">");
709 sb.append(entry.getValue());
710 sb.append("</overridden-parameter>\n");
711 }
712
713 sb.append("\t</route>\n");
714 }
715
716 sb.append("</routes>");
717
718 return sb.toString();
719 }
720
721 protected String formatPortletXML(
722 String fileName, String absolutePath, String content)
723 throws Exception {
724
725 Document document = saxReaderUtil.read(content);
726
727 Element rootElement = document.getRootElement();
728
729 rootElement.sortAttributes(true);
730
731 boolean checkNumericalPortletNameElement = !isExcluded(
732 _numericalPortletNameElementExclusions, absolutePath);
733
734 List<Element> portletElements = rootElement.elements("portlet");
735
736 for (Element portletElement : portletElements) {
737 if (checkNumericalPortletNameElement) {
738 Element portletNameElement = portletElement.element(
739 "portlet-name");
740
741 String portletNameText = portletNameElement.getText();
742
743 if (!Validator.isNumber(portletNameText)) {
744 processErrorMessage(
745 fileName,
746 fileName +
747 " contains a nonstandard portlet-name element " +
748 portletNameText);
749 }
750 }
751
752 if (fileName.endsWith("/liferay-portlet.xml")) {
753 continue;
754 }
755
756 portletElement.sortElementsByChildElement("init-param", "name");
757
758 Element portletPreferencesElement = portletElement.element(
759 "portlet-preferences");
760
761 if (portletPreferencesElement != null) {
762 portletPreferencesElement.sortElementsByChildElement(
763 "preference", "name");
764 }
765 }
766
767 return document.formattedString();
768 }
769
770 protected String formatPoshiXML(String fileName, String content)
771 throws Exception {
772
773 checkPoshiCharactersAfterDefinition(fileName, content);
774 checkPoshiCharactersBeforeDefinition(fileName, content);
775
776 content = sortPoshiAttributes(fileName, content);
777
778 content = sortPoshiCommands(content);
779
780 content = sortPoshiVariables(content);
781
782 content = fixPoshiXMLElementWithNoChild(content);
783
784 content = fixPoshiXMLEndLinesAfterClosingElement(content);
785
786 content = fixPoshiXMLEndLinesBeforeClosingElement(content);
787
788 content = fixPoshiXMLEndLines(content);
789
790 return fixPoshiXMLNumberOfTabs(content);
791 }
792
793 protected void formatServiceXML(String fileName, String content)
794 throws Exception {
795
796 Document document = saxReaderUtil.read(content);
797
798 Element rootElement = document.getRootElement();
799
800 List<Element> entityElements = rootElement.elements("entity");
801
802 String previousEntityName = StringPool.BLANK;
803
804 for (Element entityElement : entityElements) {
805 String entityName = entityElement.attributeValue("name");
806
807 if (Validator.isNotNull(previousEntityName) &&
808 (previousEntityName.compareToIgnoreCase(entityName) > 0)) {
809
810 processErrorMessage(
811 fileName, "sort: " + fileName + " " + entityName);
812 }
813
814 checkServiceXMLFinders(fileName, entityElement, entityName);
815 checkServiceXMLReferences(fileName, entityElement, entityName);
816
817 previousEntityName = entityName;
818 }
819
820 checkServiceXMLExceptions(fileName, rootElement);
821 }
822
823 protected void formatStrutsConfigXML(String fileName, String content)
824 throws Exception {
825
826 Document document = saxReaderUtil.read(content);
827
828 Element rootElement = document.getRootElement();
829
830 Element actionMappingsElement = rootElement.element("action-mappings");
831
832 List<Element> actionElements = actionMappingsElement.elements("action");
833
834 String previousPath = StringPool.BLANK;
835
836 for (Element actionElement : actionElements) {
837 String path = actionElement.attributeValue("path");
838
839 if (Validator.isNotNull(previousPath) &&
840 (previousPath.compareTo(path) > 0) &&
841 (!previousPath.startsWith("/portal/") ||
842 path.startsWith("/portal/"))) {
843
844 processErrorMessage(fileName, "sort: " + fileName + " " + path);
845 }
846
847 previousPath = path;
848 }
849 }
850
851 protected void formatTilesDefsXML(String fileName, String content)
852 throws Exception {
853
854 Document document = saxReaderUtil.read(content);
855
856 Element rootElement = document.getRootElement();
857
858 List<Element> definitionElements = rootElement.elements("definition");
859
860 String previousName = StringPool.BLANK;
861
862 for (Element definitionElement : definitionElements) {
863 String name = definitionElement.attributeValue("name");
864
865 if (Validator.isNotNull(previousName) &&
866 (previousName.compareTo(name) > 0) &&
867 !previousName.equals("portlet")) {
868
869 processErrorMessage(fileName, "sort: " + fileName + " " + name);
870 }
871
872 previousName = name;
873 }
874 }
875
876 protected String formatWebXML(String fileName, String content)
877 throws Exception {
878
879 if (!portalSource) {
880 String webXML = ContentUtil.get(
881 "com/liferay/portal/deploy/dependencies/web.xml");
882
883 if (content.equals(webXML)) {
884 processErrorMessage(fileName, fileName);
885 }
886
887 return content;
888 }
889
890 Properties properties = new Properties();
891
892 String propertiesContent = fileUtil.read(
893 BASEDIR + "portal-impl/src/portal.properties");
894
895 PropertiesUtil.load(properties, propertiesContent);
896
897 String[] locales = StringUtil.split(
898 properties.getProperty(PropsKeys.LOCALES));
899
900 Arrays.sort(locales);
901
902 Set<String> urlPatterns = new TreeSet<String>();
903
904 for (String locale : locales) {
905 int pos = locale.indexOf(StringPool.UNDERLINE);
906
907 String languageCode = locale.substring(0, pos);
908
909 urlPatterns.add(languageCode);
910 urlPatterns.add(locale);
911 }
912
913 StringBundler sb = new StringBundler(6 * urlPatterns.size());
914
915 for (String urlPattern : urlPatterns) {
916 sb.append("\t<servlet-mapping>\n");
917 sb.append("\t\t<servlet-name>I18n Servlet</servlet-name>\n");
918 sb.append("\t\t<url-pattern>/");
919 sb.append(urlPattern);
920 sb.append("