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