001
014
015 package com.liferay.portal.tools.seleniumbuilder;
016
017 import com.liferay.portal.freemarker.FreeMarkerUtil;
018 import com.liferay.portal.kernel.io.unsync.UnsyncBufferedReader;
019 import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
020 import com.liferay.portal.kernel.util.ArrayUtil;
021 import com.liferay.portal.kernel.util.CharPool;
022 import com.liferay.portal.kernel.util.FileUtil;
023 import com.liferay.portal.kernel.util.StringBundler;
024 import com.liferay.portal.kernel.util.StringPool;
025 import com.liferay.portal.kernel.util.StringUtil;
026 import com.liferay.portal.kernel.util.TextFormatter;
027 import com.liferay.portal.kernel.util.Validator;
028 import com.liferay.portal.kernel.xml.Attribute;
029 import com.liferay.portal.kernel.xml.Document;
030 import com.liferay.portal.kernel.xml.DocumentException;
031 import com.liferay.portal.kernel.xml.Element;
032 import com.liferay.portal.kernel.xml.SAXReaderUtil;
033 import com.liferay.portal.tools.servicebuilder.ServiceBuilder;
034
035 import java.io.File;
036
037 import java.util.ArrayList;
038 import java.util.HashMap;
039 import java.util.HashSet;
040 import java.util.List;
041 import java.util.Map;
042 import java.util.Set;
043 import java.util.TreeSet;
044 import java.util.regex.Matcher;
045 import java.util.regex.Pattern;
046
047
050 public class SeleniumBuilderFileUtil {
051
052 public SeleniumBuilderFileUtil(String baseDir) {
053 _baseDir = baseDir;
054 }
055
056 public List<Element> getAllChildElements(
057 Element element, String elementName) {
058
059 List<Element> allChildElements = new ArrayList<Element>();
060
061 List<Element> childElements = element.elements();
062
063 if (childElements.isEmpty()) {
064 return allChildElements;
065 }
066
067 for (Element childElement : childElements) {
068 String childElementName = childElement.getName();
069
070 if (childElementName.equals(elementName)) {
071 allChildElements.add(childElement);
072 }
073
074 allChildElements.addAll(
075 getAllChildElements(childElement, elementName));
076 }
077
078 return allChildElements;
079 }
080
081 public String getBaseDir() {
082 return _baseDir;
083 }
084
085 public Set<String> getChildElementAttributeValues(
086 Element element, String attributeName) {
087
088 Set<String> childElementAttributeValues = new TreeSet<String>();
089
090 List<Element> childElements = element.elements();
091
092 if (childElements.isEmpty()) {
093 return childElementAttributeValues;
094 }
095
096 for (Element childElement : childElements) {
097 String childElementName = childElement.attributeValue(
098 attributeName);
099
100 if (childElementName != null) {
101 int x = childElementName.lastIndexOf(StringPool.POUND);
102
103 if (x != -1) {
104 childElementAttributeValues.add(
105 childElementName.substring(0, x));
106 }
107 }
108
109 childElementAttributeValues.addAll(
110 getChildElementAttributeValues(childElement, attributeName));
111 }
112
113 return childElementAttributeValues;
114 }
115
116 public String getClassName(String fileName) {
117 String classSuffix = getClassSuffix(fileName);
118
119 return getClassName(fileName, classSuffix);
120 }
121
122 public String getClassName(String fileName, String classSuffix) {
123 return
124 getPackageName(fileName) + "." +
125 getSimpleClassName(fileName, classSuffix);
126 }
127
128 public String getClassSuffix(String fileName) {
129 int x = fileName.indexOf(CharPool.PERIOD);
130
131 String classSuffix = StringUtil.upperCaseFirstLetter(
132 fileName.substring(x + 1));
133
134 if (classSuffix.equals("Testcase")) {
135 classSuffix = "TestCase";
136 }
137 else if (classSuffix.equals("Testsuite")) {
138 classSuffix = "TestSuite";
139 }
140
141 return classSuffix;
142 }
143
144 public String getJavaFileName(String fileName) {
145 String classSuffix = getClassSuffix(fileName);
146
147 return getJavaFileName(fileName, classSuffix);
148 }
149
150 public String getJavaFileName(String fileName, String classSuffix) {
151 return
152 getPackagePath(fileName) + "/" +
153 getSimpleClassName(fileName, classSuffix) + ".java";
154 }
155
156 public int getLocatorCount(Element rootElement) {
157 String xml = rootElement.asXML();
158
159 for (int i = 1;; i++) {
160 if (xml.contains("${locator" + i + "}")) {
161 continue;
162 }
163
164 if (i > 1) {
165 i--;
166 }
167
168 return i;
169 }
170 }
171
172 public String getName(String fileName) {
173 int x = fileName.lastIndexOf(StringPool.SLASH);
174 int y = fileName.lastIndexOf(CharPool.PERIOD);
175
176 return fileName.substring(x + 1, y);
177 }
178
179 public String getNormalizedContent(String fileName) throws Exception {
180 String content = readFile(fileName);
181
182 if (fileName.endsWith(".path")) {
183 int x = content.indexOf("<tbody>");
184 int y = content.indexOf("</tbody>");
185
186 if ((x == -1) || (y == -1)) {
187 throwValidationException(1002, fileName, "tbody");
188 }
189
190 String pathTbody = content.substring(x, y + 8);
191
192 Map<String, Object> context = new HashMap<String, Object>();
193
194 context.put("pathName", getName(fileName));
195 context.put("pathTbody", pathTbody);
196
197 String newContent = processTemplate("path_xml.ftl", context);
198
199 if (!content.equals(newContent)) {
200 content = newContent;
201
202 writeFile(getBaseDir(), fileName, newContent, false);
203 }
204 }
205
206 StringBundler sb = new StringBundler();
207
208 int lineNumber = 1;
209
210 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
211 new UnsyncStringReader(content));
212
213 String line = null;
214
215 while ((line = unsyncBufferedReader.readLine()) != null) {
216 Pattern pattern = Pattern.compile("<[a-z\\-]+");
217
218 Matcher matcher = pattern.matcher(line);
219
220 if (matcher.find()) {
221 line = StringUtil.replace(
222 line, matcher.group(),
223 matcher.group() + " line-number=\"" + lineNumber + "\"");
224 }
225
226 sb.append(line);
227
228 lineNumber++;
229 }
230
231 content = sb.toString();
232
233 if (content != null) {
234 content = content.trim();
235 content = StringUtil.replace(content, "\n", "");
236 content = StringUtil.replace(content, "\r\n", "");
237 content = StringUtil.replace(content, "\t", " ");
238 content = content.replaceAll(" +", " ");
239 }
240
241 return content;
242 }
243
244 public String getObjectName(String name) {
245 return StringUtil.upperCaseFirstLetter(name);
246 }
247
248 public String getPackageName(String fileName) {
249 String packagePath = getPackagePath(fileName);
250
251 return StringUtil.replace(
252 packagePath, StringPool.SLASH, StringPool.PERIOD);
253 }
254
255 public String getPackagePath(String fileName) {
256 int x = fileName.lastIndexOf(StringPool.SLASH);
257
258 return fileName.substring(0, x);
259 }
260
261 public Set<String> getPathLocatorKeys(Element rootElement) {
262 Set<String> pathLocatorKeys = new HashSet<String>();
263
264 Element bodyElement = rootElement.element("body");
265
266 Element tableElement = bodyElement.element("table");
267
268 Element tbodyElement = tableElement.element("tbody");
269
270 List<Element> trElements = tbodyElement.elements();
271
272 for (Element trElement : trElements) {
273 Element tdElement = trElement.element("td");
274
275 pathLocatorKeys.add(tdElement.getText());
276 }
277
278 return pathLocatorKeys;
279 }
280
281 public String getReturnType(String name) {
282 if (name.startsWith("Is")) {
283 return "boolean";
284 }
285
286 return "void";
287 }
288
289 public Element getRootElement(String fileName) throws Exception {
290 String content = getNormalizedContent(fileName);
291
292 try {
293 Document document = SAXReaderUtil.read(content, true);
294
295 Element rootElement = document.getRootElement();
296
297 validate(fileName, rootElement);
298
299 return rootElement;
300 }
301 catch (DocumentException de) {
302 throwValidationException(1007, fileName, de);
303 }
304
305 return null;
306 }
307
308 public String getSimpleClassName(String fileName) {
309 String classSuffix = getClassSuffix(fileName);
310
311 return getSimpleClassName(fileName, classSuffix);
312 }
313
314 public String getSimpleClassName(String fileName, String classSuffix) {
315 return getName(fileName) + classSuffix;
316 }
317
318 public String getVariableName(String name) {
319 return TextFormatter.format(name, TextFormatter.I);
320 }
321
322 public String normalizeFileName(String fileName) {
323 return StringUtil.replace(
324 fileName, StringPool.BACK_SLASH, StringPool.SLASH);
325 }
326
327 public String readFile(String fileName) throws Exception {
328 return FileUtil.read(getBaseDir() + "/" + fileName);
329 }
330
331 public void writeFile(String fileName, String content, boolean format)
332 throws Exception {
333
334 writeFile(getBaseDir() + "-generated", fileName, content, format);
335 }
336
337 public void writeFile(
338 String baseDir, String fileName, String content, boolean format)
339 throws Exception {
340
341 File file = new File(baseDir + "/" + fileName);
342
343 if (format) {
344 ServiceBuilder.writeFile(file, content);
345 }
346 else {
347 System.out.println("Writing " + file);
348
349 FileUtil.write(file, content);
350 }
351 }
352
353 protected String processTemplate(String name, Map<String, Object> context)
354 throws Exception {
355
356 return StringUtil.strip(
357 FreeMarkerUtil.process(_TPL_ROOT + name, context), '\r');
358 }
359
360 protected void throwValidationException(int errorCode, String fileName) {
361 throwValidationException(
362 errorCode, fileName, null, null, null, null, null);
363 }
364
365 protected void throwValidationException(
366 int errorCode, String fileName, Element element) {
367
368 throwValidationException(
369 errorCode, fileName, element, null, null, null, null);
370 }
371
372 protected void throwValidationException(
373 int errorCode, String fileName, Element element, String string1) {
374
375 throwValidationException(
376 errorCode, fileName, element, null, string1, null, null);
377 }
378
379 protected void throwValidationException(
380 int errorCode, String fileName, Element element, String string1,
381 String string2) {
382
383 throwValidationException(
384 errorCode, fileName, element, null, string1, string2, null);
385 }
386
387 protected void throwValidationException(
388 int errorCode, String fileName, Element element, String[] array) {
389
390 throwValidationException(
391 errorCode, fileName, element, array, null, null, null);
392 }
393
394 protected void throwValidationException(
395 int errorCode, String fileName, Element element, String[] array,
396 String string1, String string2, Exception e) {
397
398 String prefix = "Error " + errorCode + ": ";
399 String suffix = fileName;
400
401 if (element != null) {
402 suffix += ":" + element.attributeValue("line-number");
403 }
404
405 if (errorCode == 1000) {
406 throw new IllegalArgumentException(
407 prefix + "Invalid root element in " + suffix);
408 }
409 else if (errorCode == 1001) {
410 throw new IllegalArgumentException(
411 prefix + "Missing (" + StringUtil.merge(array, "|") +
412 ") child element in " + suffix);
413 }
414 else if (errorCode == 1002) {
415 throw new IllegalArgumentException(
416 prefix + "Invalid " + string1 + " element in " + suffix);
417 }
418 else if (errorCode == 1003) {
419 throw new IllegalArgumentException(
420 prefix + "Missing " + string1 + " attribute in " + suffix);
421 }
422 else if (errorCode == 1004) {
423 throw new IllegalArgumentException(
424 prefix + "Missing (" + StringUtil.merge(array, "|") +
425 ") attribute in " + suffix);
426 }
427 else if (errorCode == 1005) {
428 throw new IllegalArgumentException(
429 prefix + "Invalid " + string1 + " attribute in " + suffix);
430 }
431 else if (errorCode == 1006) {
432 throw new IllegalArgumentException(
433 prefix + "Invalid " + string1 + " attribute value in " +
434 suffix);
435 }
436 else if (errorCode == 1007) {
437 throw new IllegalArgumentException(
438 prefix + "Poorly formed XML in " + suffix, e);
439 }
440 else if (errorCode == 1008) {
441 throw new IllegalArgumentException(
442 prefix + "Duplicate file name " + string1 + " at " + suffix);
443 }
444 else if (errorCode == 1009) {
445 throw new IllegalArgumentException(
446 prefix + "Duplicate command name " + string1 + " at " + suffix);
447 }
448 else if (errorCode == 1010) {
449 throw new IllegalArgumentException(
450 prefix + "Invalid locator-key " + string1 + " at " + suffix);
451 }
452 else if (errorCode == 1011) {
453 throw new IllegalArgumentException(
454 prefix + "Invalid " + string1 + " name " + string2 + " at " +
455 suffix);
456 }
457 else if (errorCode == 1012) {
458 throw new IllegalArgumentException(
459 prefix + "Invalid " + string1 + " command " + string2 + " at " +
460 suffix);
461 }
462 else if (errorCode == 2000) {
463 throw new IllegalArgumentException(
464 prefix + "Too many child elements in the " + string1 +
465 " element in " + suffix);
466 }
467 else if (errorCode == 2001) {
468 throw new IllegalArgumentException(
469 prefix + "Action command " + string1 +
470 " does not match a function name at " + suffix);
471 }
472 else if (errorCode == 2002) {
473 throw new IllegalArgumentException(
474 prefix + "Missing matching " + string1 + ".path for " + suffix);
475 }
476 else {
477 throw new IllegalArgumentException(prefix + suffix);
478 }
479 }
480
481 protected void throwValidationException(
482 int errorCode, String fileName, Exception e) {
483
484 throwValidationException(
485 errorCode, fileName, null, null, null, null, e);
486 }
487
488 protected void throwValidationException(
489 int errorCode, String fileName, String string1) {
490
491 throwValidationException(
492 errorCode, fileName, null, null, string1, null, null);
493 }
494
495 protected void validate(String fileName, Element rootElement)
496 throws Exception {
497
498 if (fileName.endsWith(".action")) {
499 validateActionDocument(fileName, rootElement);
500 }
501 else if (fileName.endsWith(".function")) {
502 validateFunctionDocument(fileName, rootElement);
503 }
504 else if (fileName.endsWith(".macro")) {
505 validateMacroDocument(fileName, rootElement);
506 }
507 else if (fileName.endsWith(".path")) {
508 validatePathDocument(fileName, rootElement);
509 }
510 else if (fileName.endsWith(".testcase")) {
511 validateTestCaseDocument(fileName, rootElement);
512 }
513 else if (fileName.endsWith(".testsuite")) {
514 validateTestSuiteDocument(fileName, rootElement);
515 }
516 }
517
518 protected void validateActionCommandElement(
519 String fileName, Element commandElement,
520 String[] allowedBlockChildElementNames,
521 String[] allowedExecuteAttributeNames,
522 String[] allowedExecuteChildElementNames) {
523
524 List<Element> elements = commandElement.elements();
525
526 if (elements.isEmpty()) {
527 throwValidationException(
528 1001, fileName, commandElement,
529 new String[] {"case", "default"});
530 }
531
532 for (Element element : elements) {
533 List<Element> childElements = element.elements();
534
535 String elementName = element.getName();
536
537 if (childElements.size() > 1) {
538 throwValidationException(
539 2000, fileName, childElements.get(1), elementName);
540 }
541
542 if (elementName.equals("case")) {
543 List<Attribute> attributes = element.attributes();
544
545 boolean hasNeededAttributeName = false;
546
547 for (Attribute attribute : attributes) {
548 String attributeName = attribute.getName();
549
550 if (attributeName.equals("comparator")) {
551 String attributeValue = attribute.getValue();
552
553 if (!attributeValue.equals("contains") &&
554 !attributeValue.equals("endsWith") &&
555 !attributeValue.equals("equals") &&
556 !attributeValue.equals("startsWith")) {
557
558 throwValidationException(
559 1006, fileName, element, attributeName);
560 }
561 }
562 else if (attributeName.startsWith("locator") ||
563 attributeName.startsWith("locator-key")) {
564
565 String attributeValue = attribute.getValue();
566
567 if (Validator.isNull(attributeValue)) {
568 throwValidationException(
569 1006, fileName, element, attributeName);
570 }
571
572 hasNeededAttributeName = true;
573 }
574
575 if (!attributeName.equals("comparator") &&
576 !attributeName.equals("line-number") &&
577 !attributeName.startsWith("locator") &&
578 !attributeName.startsWith("locator-key")) {
579
580 throwValidationException(
581 1005, fileName, element, attributeName);
582 }
583
584 if (attributeName.equals("locator") ||
585 attributeName.equals("locator-key")) {
586
587 throwValidationException(
588 1005, fileName, element, attributeName);
589 }
590 }
591
592 if (!hasNeededAttributeName) {
593 throwValidationException(
594 1004, fileName, element,
595 new String[] {"locator1", "locator-key1"});
596 }
597
598 validateBlockElement(
599 fileName, element, new String[] {"execute"},
600 new String[] {"function"}, new String[0], new String[0]);
601 }
602 else if (elementName.equals("default")) {
603 List<Attribute> attributes = element.attributes();
604
605 if (attributes.size() != 1) {
606 Attribute attribute = attributes.get(1);
607
608 String attributeName = attribute.getName();
609
610 throwValidationException(
611 1005, fileName, element, attributeName);
612 }
613
614 validateBlockElement(
615 fileName, element, new String[] {"execute"},
616 new String[] {"function"}, new String[0], new String[0]);
617 }
618 else {
619 throwValidationException(1002, fileName, element, elementName);
620 }
621 }
622 }
623
624 protected void validateActionDocument(
625 String fileName, Element rootElement) {
626
627 if (!Validator.equals(rootElement.getName(), "definition")) {
628 throwValidationException(1000, fileName, rootElement);
629 }
630
631 List<Element> elements = rootElement.elements();
632
633 if (elements.isEmpty()) {
634 throwValidationException(
635 1001, fileName, rootElement, new String[] {"command"});
636 }
637
638 for (Element element : elements) {
639 String elementName = element.getName();
640
641 if (elementName.equals("command")) {
642 String attributeValue = element.attributeValue("name");
643
644 if (attributeValue == null) {
645 throwValidationException(1003, fileName, element, "name");
646 }
647 else if (Validator.isNull(attributeValue)) {
648 throwValidationException(1006, fileName, element, "name");
649 }
650
651 validateActionCommandElement(
652 fileName, element, new String[] {"execute"},
653 new String[] {"function"}, new String[0]);
654 }
655 else {
656 throwValidationException(1002, fileName, element, elementName);
657 }
658 }
659 }
660
661 protected void validateBlockElement(
662 String fileName, Element commandElement,
663 String[] allowedBlockChildElementNames,
664 String[] allowedExecuteAttributeNames,
665 String[] allowedExecuteChildElementNames,
666 String[] allowedIfConditionElementNames) {
667
668 List<Element> elements = commandElement.elements();
669
670 if (elements.isEmpty()) {
671 throwValidationException(
672 1001, fileName, commandElement, allowedBlockChildElementNames);
673 }
674
675 for (Element element : elements) {
676 String elementName = element.getName();
677
678 if (!ArrayUtil.contains(
679 allowedBlockChildElementNames, elementName)) {
680
681 throwValidationException(1002, fileName, element, elementName);
682 }
683
684 if (elementName.equals("echo") || elementName.equals("fail")) {
685 validateSimpleElement(
686 fileName, element, new String[] {"message"});
687 }
688 else if (elementName.equals("execute")) {
689 validateExecuteElement(
690 fileName, element, allowedExecuteAttributeNames, ".+",
691 allowedExecuteChildElementNames);
692 }
693 else if (elementName.equals("if")) {
694 validateIfElement(
695 fileName, element, allowedBlockChildElementNames,
696 allowedExecuteAttributeNames,
697 allowedExecuteChildElementNames,
698 allowedIfConditionElementNames);
699 }
700 else if (elementName.equals("var")) {
701 validateSimpleElement(
702 fileName, element, new String[] {"name", "value"});
703 }
704 else if (elementName.equals("while")) {
705 validateWhileElement(
706 fileName, element, allowedBlockChildElementNames,
707 allowedExecuteAttributeNames,
708 allowedExecuteChildElementNames,
709 allowedIfConditionElementNames);
710 }
711 else {
712 throwValidationException(1002, fileName, element, elementName);
713 }
714 }
715 }
716
717 protected void validateExecuteElement(
718 String fileName, Element executeElement,
719 String[] allowedExecuteAttributeNames,
720 String allowedExecuteAttributeValuesRegex,
721 String[] allowedExecuteChildElementNames) {
722
723 boolean hasAllowedAttributeName = false;
724
725 List<Attribute> attributes = executeElement.attributes();
726
727 for (Attribute attribute : attributes) {
728 String attributeName = attribute.getName();
729
730 if (ArrayUtil.contains(
731 allowedExecuteAttributeNames, attributeName)) {
732
733 hasAllowedAttributeName = true;
734
735 break;
736 }
737 }
738
739 if (!hasAllowedAttributeName) {
740 throwValidationException(
741 1004, fileName, executeElement, allowedExecuteAttributeNames);
742 }
743
744 String action = executeElement.attributeValue("action");
745 String function = executeElement.attributeValue("function");
746 String macro = executeElement.attributeValue("macro");
747 String selenium = executeElement.attributeValue("selenium");
748 String testCase = executeElement.attributeValue("test-case");
749 String testSuite = executeElement.attributeValue("test-suite");
750
751 if (action != null) {
752 if (Validator.isNull(action) ||
753 !action.matches(allowedExecuteAttributeValuesRegex)) {
754
755 throwValidationException(
756 1006, fileName, executeElement, "action");
757 }
758
759 for (Attribute attribute : attributes) {
760 String attributeName = attribute.getName();
761
762 if (!attributeName.equals("action") &&
763 !attributeName.equals("line-number") &&
764 !attributeName.startsWith("locator") &&
765 !attributeName.startsWith("locator-key") &&
766 !attributeName.startsWith("value")) {
767
768 throwValidationException(
769 1005, fileName, executeElement, attributeName);
770 }
771
772 if (attributeName.equals("locator") ||
773 attributeName.equals("locator-key") ||
774 attributeName.equals("value")) {
775
776 throwValidationException(
777 1005, fileName, executeElement, attributeName);
778 }
779 }
780 }
781 else if (function != null) {
782 if (Validator.isNull(function) ||
783 !function.matches(allowedExecuteAttributeValuesRegex)) {
784
785 throwValidationException(
786 1006, fileName, executeElement, "function");
787 }
788
789 for (Attribute attribute : attributes) {
790 String attributeName = attribute.getName();
791
792 if (!attributeName.equals("function") &&
793 !attributeName.equals("line-number") &&
794 !attributeName.startsWith("locator") &&
795 !attributeName.startsWith("value")) {
796
797 throwValidationException(
798 1005, fileName, executeElement, attributeName);
799 }
800
801 if (attributeName.equals("locator") ||
802 attributeName.equals("value")) {
803
804 throwValidationException(
805 1005, fileName, executeElement, attributeName);
806 }
807 }
808 }
809 else if (macro != null) {
810 if (Validator.isNull(macro) ||
811 !macro.matches(allowedExecuteAttributeValuesRegex)) {
812
813 throwValidationException(
814 1006, fileName, executeElement, "macro");
815 }
816
817 for (Attribute attribute : attributes) {
818 String attributeName = attribute.getName();
819
820 if (!attributeName.equals("macro") &&
821 !attributeName.equals("line-number")) {
822
823 throwValidationException(
824 1005, fileName, executeElement, attributeName);
825 }
826 }
827 }
828 else if (selenium != null) {
829 if (Validator.isNull(selenium) ||
830 !selenium.matches(allowedExecuteAttributeValuesRegex)) {
831
832 throwValidationException(
833 1006, fileName, executeElement, "selenium");
834 }
835
836 for (Attribute attribute : attributes) {
837 String attributeName = attribute.getName();
838
839 if (!attributeName.equals("argument1") &&
840 !attributeName.equals("argument2") &&
841 !attributeName.equals("line-number") &&
842 !attributeName.equals("selenium")) {
843
844 throwValidationException(
845 1005, fileName, executeElement, attributeName);
846 }
847 }
848 }
849 else if (testCase != null) {
850 if (Validator.isNull(testCase) ||
851 !testCase.matches(allowedExecuteAttributeValuesRegex)) {
852
853 throwValidationException(
854 1006, fileName, executeElement, "test-case");
855 }
856
857 for (Attribute attribute : attributes) {
858 String attributeName = attribute.getName();
859
860 if (!attributeName.equals("line-number") &&
861 !attributeName.equals("test-case")) {
862
863 throwValidationException(
864 1005, fileName, executeElement, attributeName);
865 }
866 }
867 }
868 else if (testSuite != null) {
869 if (Validator.isNull(testSuite) ||
870 !testSuite.matches(allowedExecuteAttributeValuesRegex)) {
871
872 throwValidationException(
873 1006, fileName, executeElement, "test-suite");
874 }
875
876 for (Attribute attribute : attributes) {
877 String attributeName = attribute.getName();
878
879 if (!attributeName.equals("line-number") &&
880 !attributeName.equals("test-suite")) {
881
882 throwValidationException(
883 1005, fileName, executeElement, attributeName);
884 }
885 }
886 }
887 else {
888 throwValidationException(0, fileName);
889 }
890
891 List<Element> elements = executeElement.elements();
892
893 if (allowedExecuteChildElementNames.length == 0) {
894 if (!elements.isEmpty()) {
895 Element element = elements.get(0);
896
897 String elementName = element.getName();
898
899 throwValidationException(1002, fileName, element, elementName);
900 }
901 }
902 else {
903 String executeElementName = executeElement.getName();
904
905 for (Element element : elements) {
906 String elementName = element.getName();
907
908 if (executeElementName.equals("condition")) {
909 throwValidationException(
910 1002, fileName, element, elementName);
911 }
912
913 if (elementName.equals("var")) {
914 validateSimpleElement(
915 fileName, element, new String[] {"name", "value"});
916 }
917 else {
918 throwValidationException(
919 1002, fileName, element, elementName);
920 }
921 }
922 }
923 }
924
925 protected void validateFunctionDocument(
926 String fileName, Element rootElement) {
927
928 if (!Validator.equals(rootElement.getName(), "definition")) {
929 throwValidationException(1000, fileName, rootElement);
930 }
931
932 List<Element> elements = rootElement.elements();
933
934 if (elements.isEmpty()) {
935 throwValidationException(
936 1001, fileName, rootElement, new String[] {"command"});
937 }
938
939 for (Element element : elements) {
940 String elementName = element.getName();
941
942 if (elementName.equals("command")) {
943 String attributeValue = element.attributeValue("name");
944
945 if (attributeValue == null) {
946 throwValidationException(1003, fileName, element, "name");
947 }
948 else if (Validator.isNull(attributeValue)) {
949 throwValidationException(1006, fileName, element, "name");
950 }
951
952 validateBlockElement(
953 fileName, element, new String[] {"execute", "if"},
954 new String[] {"function", "selenium"}, new String[0],
955 new String[] {"condition"});
956 }
957 else {
958 throwValidationException(1002, fileName, element, elementName);
959 }
960 }
961 }
962
963 protected void validateIfElement(
964 String fileName, Element ifElement,
965 String[] allowedBlockChildElementNames,
966 String[] allowedExecuteAttributeNames,
967 String[] allowedExecuteChildElementNames,
968 String[] allowedIfConditionElementNames) {
969
970 List<Element> elements = ifElement.elements();
971
972 Set<String> elementNames = new HashSet<String>();
973
974 boolean hasAllowedIfConditionElementNames = false;
975
976 for (Element element : elements) {
977 String elementName = element.getName();
978
979 elementNames.add(elementName);
980
981 if (ArrayUtil.contains(
982 allowedIfConditionElementNames, elementName)) {
983
984 hasAllowedIfConditionElementNames = true;
985 }
986
987 if (elementName.equals("condition")) {
988 validateExecuteElement(
989 fileName, element, allowedExecuteAttributeNames,
990 ".*(is|Is).+", allowedExecuteChildElementNames);
991 }
992 else if (elementName.equals("contains")) {
993 validateSimpleElement(
994 fileName, element, new String[] {"string", "substring"});
995 }
996 else if (elementName.equals("else") || elementName.equals("then")) {
997 validateBlockElement(
998 fileName, element, allowedBlockChildElementNames,
999 allowedExecuteAttributeNames,
1000 allowedExecuteChildElementNames,
1001 allowedIfConditionElementNames);
1002 }
1003 else if (elementName.equals("elseif")) {
1004 validateIfElement(
1005 fileName, element, allowedBlockChildElementNames,
1006 allowedExecuteAttributeNames,
1007 allowedExecuteChildElementNames,
1008 allowedIfConditionElementNames);
1009 }
1010 else if (elementName.equals("equals")) {
1011 validateSimpleElement(
1012 fileName, element, new String[] {"arg1", "arg2"});
1013 }
1014 else if (elementName.equals("isset")) {
1015 validateSimpleElement(fileName, element, new String[] {"var"});
1016 }
1017 else {
1018 throwValidationException(1002, fileName, element, elementName);
1019 }
1020 }
1021
1022 if (!hasAllowedIfConditionElementNames) {
1023 throwValidationException(
1024 1001, fileName, ifElement, allowedIfConditionElementNames);
1025 }
1026
1027 if (!elementNames.contains("then")) {
1028 throwValidationException(
1029 1001, fileName, ifElement, new String[] {"then"});
1030 }
1031 }
1032
1033 protected void validateMacroDocument(String fileName, Element rootElement) {
1034 if (!Validator.equals(rootElement.getName(), "definition")) {
1035 throwValidationException(1000, fileName, rootElement);
1036 }
1037
1038 List<Element> elements = rootElement.elements();
1039
1040 if (elements.isEmpty()) {
1041 throwValidationException(
1042 1001, fileName, rootElement, new String[] {"command", "var"});
1043 }
1044
1045 for (Element element : elements) {
1046 String elementName = element.getName();
1047
1048 if (elementName.equals("command")) {
1049 String attributeValue = element.attributeValue("name");
1050
1051 if (attributeValue == null) {
1052 throwValidationException(1003, fileName, element, "name");
1053 }
1054 else if (Validator.isNull(attributeValue)) {
1055 throwValidationException(1006, fileName, element, "name");
1056 }
1057
1058 validateBlockElement(
1059 fileName, element,
1060 new String[] {
1061 "echo", "execute", "fail", "if", "var","while"
1062 },
1063 new String[] {"action", "macro"}, new String[] {"var"},
1064 new String[] {"condition", "contains", "equals", "isset"});
1065 }
1066 else if (elementName.equals("var")) {
1067 validateSimpleElement(
1068 fileName, element, new String[] {"name", "value"});
1069 }
1070 else {
1071 throwValidationException(1002, fileName, element, elementName);
1072 }
1073 }
1074 }
1075
1076 protected void validatePathDocument(String fileName, Element rootElement) {
1077 Element headElement = rootElement.element("head");
1078
1079 Element titleElement = headElement.element("title");
1080
1081 String title = titleElement.getText();
1082
1083 int x = fileName.lastIndexOf(StringPool.SLASH);
1084 int y = fileName.lastIndexOf(CharPool.PERIOD);
1085
1086 String shortFileName = fileName.substring(x + 1, y);
1087
1088 if ((title == null) || !shortFileName.equals(title)) {
1089 throwValidationException(0, fileName);
1090 }
1091
1092 Element bodyElement = rootElement.element("body");
1093
1094 Element tableElement = bodyElement.element("table");
1095
1096 Element theadElement = tableElement.element("thead");
1097
1098 Element trElement = theadElement.element("tr");
1099
1100 Element tdElement = trElement.element("td");
1101
1102 String tdText = tdElement.getText();
1103
1104 if ((tdText == null) || !shortFileName.equals(tdText)) {
1105 throwValidationException(0, fileName);
1106 }
1107
1108 Element tbodyElement = tableElement.element("tbody");
1109
1110 List<Element> elements = tbodyElement.elements();
1111
1112 for (Element element : elements) {
1113 String elementName = element.getName();
1114
1115 if (elementName.equals("tr")) {
1116 validatePathTrElement(fileName, element);
1117 }
1118 else {
1119 throwValidationException(1002, fileName, element, elementName);
1120 }
1121 }
1122 }
1123
1124 protected void validatePathTrElement(String fileName, Element trElement) {
1125 List<Element> elements = trElement.elements();
1126
1127 for (Element element : elements) {
1128 String elementName = element.getName();
1129
1130 if (!elementName.equals("td")) {
1131 throwValidationException(1002, fileName, element, elementName);
1132 }
1133 }
1134
1135 if (elements.size() < 3) {
1136 throwValidationException(
1137 1001, fileName, trElement, new String[] {"td"});
1138 }
1139
1140 if (elements.size() > 3) {
1141 Element element = elements.get(3);
1142
1143 String elementName = element.getName();
1144
1145 throwValidationException(1002, fileName, element, elementName);
1146 }
1147 }
1148
1149 protected void validateSimpleElement(
1150 String fileName, Element element, String[] neededAttributes) {
1151
1152 Map<String, Boolean> hasNeededAttributes =
1153 new HashMap<String, Boolean>();
1154
1155 for (String neededAttribute : neededAttributes) {
1156 hasNeededAttributes.put(neededAttribute, false);
1157 }
1158
1159 List<Attribute> attributes = element.attributes();
1160
1161 for (Attribute attribute : attributes) {
1162 String attributeName = attribute.getName();
1163 String attributeValue = attribute.getValue();
1164
1165 if (Validator.isNull(attributeValue)) {
1166 throwValidationException(
1167 1006, fileName, element, attributeName);
1168 }
1169
1170 if (hasNeededAttributes.containsKey(attributeName)) {
1171 hasNeededAttributes.put(attributeName, true);
1172 }
1173
1174 if (!attributeName.equals("line-number") &&
1175 !hasNeededAttributes.containsKey(attributeName)) {
1176
1177 throwValidationException(
1178 1005, fileName, element, attributeName);
1179 }
1180 }
1181
1182 for (String neededAttribute : neededAttributes) {
1183 if (!hasNeededAttributes.get(neededAttribute)) {
1184 throwValidationException(
1185 1004, fileName, element, neededAttributes);
1186 }
1187 }
1188
1189 List<Element> childElements = element.elements();
1190
1191 if (!childElements.isEmpty()) {
1192 Element childElement = childElements.get(0);
1193
1194 String childElementName = childElement.getName();
1195
1196 throwValidationException(
1197 1002, fileName, childElement, childElementName);
1198 }
1199 }
1200
1201 protected void validateTestCaseDocument(
1202 String fileName, Element rootElement) {
1203
1204 if (!Validator.equals(rootElement.getName(), "definition")) {
1205 throwValidationException(1000, fileName, rootElement);
1206 }
1207
1208 List<Element> elements = rootElement.elements();
1209
1210 if (elements.isEmpty()) {
1211 throwValidationException(
1212 1001, fileName, rootElement, new String[] {"command"});
1213 }
1214
1215 for (Element element : elements) {
1216 String elementName = element.getName();
1217
1218 if (elementName.equals("command")) {
1219 String attributeValue = element.attributeValue("name");
1220
1221 if (attributeValue == null) {
1222 throwValidationException(1003, fileName, element, "name");
1223 }
1224 else if (Validator.isNull(attributeValue)) {
1225 throwValidationException(1006, fileName, element, "name");
1226 }
1227
1228 validateBlockElement(
1229 fileName, element, new String[] {"execute", "var"},
1230 new String[] {"action", "macro"}, new String[] {"var"},
1231 new String[0]);
1232 }
1233 else if (elementName.equals("set-up") ||
1234 elementName.equals("tear-down")) {
1235
1236 List<Attribute> attributes = element.attributes();
1237
1238 for (Attribute attribute : attributes) {
1239 String attributeName = attribute.getName();
1240
1241 if (!attributeName.equals("line-number")) {
1242 throwValidationException(
1243 1005, fileName, element, attributeName);
1244 }
1245 }
1246
1247 validateBlockElement(
1248 fileName, element, new String[] {"execute", "var"},
1249 new String[] {"action", "macro"}, new String[] {"var"},
1250 new String[0]);
1251 }
1252 else if (elementName.equals("var")) {
1253 validateSimpleElement(
1254 fileName, element, new String[] {"name", "value"});
1255 }
1256 else {
1257 throwValidationException(1002, fileName, element, elementName);
1258 }
1259 }
1260 }
1261
1262 protected void validateTestSuiteDocument(
1263 String fileName, Element rootElement) {
1264
1265 if (!Validator.equals(rootElement.getName(), "definition")) {
1266 throwValidationException(1000, fileName, rootElement);
1267 }
1268
1269 List<Element> elements = rootElement.elements();
1270
1271 if (elements.isEmpty()) {
1272 throwValidationException(
1273 1001, fileName, rootElement, new String[] {"execute"});
1274 }
1275
1276 for (Element element : elements) {
1277 String elementName = element.getName();
1278
1279 if (elementName.equals("execute")) {
1280 validateExecuteElement(
1281 fileName, element, new String[] {"test-case", "test-suite"},
1282 ".+", new String[0]);
1283 }
1284 else {
1285 throwValidationException(1002, fileName, element, elementName);
1286 }
1287 }
1288 }
1289
1290 protected void validateWhileElement(
1291 String fileName, Element whileElement,
1292 String[] allowedBlockChildElementNames,
1293 String[] allowedExecuteAttributeNames,
1294 String[] allowedExecuteChildElementNames,
1295 String[] allowedIfConditionElementNames) {
1296
1297 List<Element> elements = whileElement.elements();
1298
1299 Set<String> elementNames = new HashSet<String>();
1300
1301 for (Element element : elements) {
1302 String elementName = element.getName();
1303
1304 elementNames.add(elementName);
1305
1306 if (elementName.equals("condition")) {
1307 validateExecuteElement(
1308 fileName, element, allowedExecuteAttributeNames,
1309 ".*(is|Is).+", allowedExecuteChildElementNames);
1310 }
1311 else if (elementName.equals("then")) {
1312 validateBlockElement(
1313 fileName, element, allowedBlockChildElementNames,
1314 allowedExecuteAttributeNames,
1315 allowedExecuteChildElementNames,
1316 allowedIfConditionElementNames);
1317 }
1318 else {
1319 throwValidationException(1002, fileName, element, elementName);
1320 }
1321 }
1322
1323 if (!elementNames.contains("condition") ||
1324 !elementNames.contains("then")) {
1325
1326 throwValidationException(
1327 1001, fileName, whileElement,
1328 new String[] {"condition", "then"});
1329 }
1330 }
1331
1332 private static final String _TPL_ROOT =
1333 "com/liferay/portal/tools/seleniumbuilder/dependencies/";
1334
1335 private String _baseDir;
1336
1337 }