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.ListUtil;
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.kernel.xml.Attribute;
030 import com.liferay.portal.kernel.xml.Document;
031 import com.liferay.portal.kernel.xml.DocumentException;
032 import com.liferay.portal.kernel.xml.Element;
033 import com.liferay.portal.kernel.xml.SAXReaderUtil;
034 import com.liferay.portal.tools.servicebuilder.ServiceBuilder;
035
036 import java.io.File;
037
038 import java.util.ArrayList;
039 import java.util.HashMap;
040 import java.util.HashSet;
041 import java.util.List;
042 import java.util.Map;
043 import java.util.Set;
044 import java.util.TreeSet;
045 import java.util.regex.Matcher;
046 import java.util.regex.Pattern;
047
048
051 public class SeleniumBuilderFileUtil {
052
053 public SeleniumBuilderFileUtil(String baseDir) {
054 _baseDir = baseDir;
055 }
056
057 public List<Element> getAllChildElements(
058 Element element, String elementName) {
059
060 List<Element> allChildElements = new ArrayList<Element>();
061
062 List<Element> childElements = element.elements();
063
064 if (childElements.isEmpty()) {
065 return allChildElements;
066 }
067
068 for (Element childElement : childElements) {
069 String childElementName = childElement.getName();
070
071 if (childElementName.equals(elementName)) {
072 allChildElements.add(childElement);
073 }
074
075 allChildElements.addAll(
076 getAllChildElements(childElement, elementName));
077 }
078
079 return allChildElements;
080 }
081
082 public String getBaseDir() {
083 return _baseDir;
084 }
085
086 public Set<String> getChildElementAttributeValues(
087 Element element, String attributeName) {
088
089 Set<String> childElementAttributeValues = new TreeSet<String>();
090
091 List<Element> childElements = element.elements();
092
093 if (childElements.isEmpty()) {
094 return childElementAttributeValues;
095 }
096
097 for (Element childElement : childElements) {
098 String childElementName = childElement.attributeValue(
099 attributeName);
100
101 if (childElementName != null) {
102 int x = childElementName.lastIndexOf(StringPool.POUND);
103
104 if (x != -1) {
105 childElementAttributeValues.add(
106 childElementName.substring(0, x));
107 }
108 }
109
110 childElementAttributeValues.addAll(
111 getChildElementAttributeValues(childElement, attributeName));
112 }
113
114 return childElementAttributeValues;
115 }
116
117 public String getClassName(String fileName) {
118 String classSuffix = getClassSuffix(fileName);
119
120 return getClassName(fileName, classSuffix);
121 }
122
123 public String getClassName(String fileName, String classSuffix) {
124 return
125 getPackageName(fileName) + "." +
126 getSimpleClassName(fileName, classSuffix);
127 }
128
129 public String getClassSimpleClassName(String className) {
130 int x = className.lastIndexOf(CharPool.PERIOD);
131
132 return className.substring(x + 1);
133 }
134
135 public String getClassSuffix(String fileName) {
136 int x = fileName.indexOf(CharPool.PERIOD);
137
138 String classSuffix = StringUtil.upperCaseFirstLetter(
139 fileName.substring(x + 1));
140
141 if (classSuffix.equals("Testcase")) {
142 classSuffix = "TestCase";
143 }
144 else if (classSuffix.equals("Testsuite")) {
145 classSuffix = "TestSuite";
146 }
147
148 return classSuffix;
149 }
150
151 public String getHTMLFileName(String fileName) {
152 String javaFileName = getJavaFileName(fileName);
153
154 return StringUtil.replace(javaFileName, ".java", ".html");
155 }
156
157 public String getJavaFileName(String fileName) {
158 String classSuffix = getClassSuffix(fileName);
159
160 return getJavaFileName(fileName, classSuffix);
161 }
162
163 public String getJavaFileName(String fileName, String classSuffix) {
164 return
165 getPackagePath(fileName) + "/" +
166 getSimpleClassName(fileName, classSuffix) + ".java";
167 }
168
169 public int getLocatorCount(Element rootElement) {
170 String xml = rootElement.asXML();
171
172 for (int i = 1;; i++) {
173 if (xml.contains("${locator" + i + "}")) {
174 continue;
175 }
176
177 if (i > 1) {
178 i--;
179 }
180
181 return i;
182 }
183 }
184
185 public String getName(String fileName) {
186 int x = fileName.lastIndexOf(StringPool.SLASH);
187 int y = fileName.lastIndexOf(CharPool.PERIOD);
188
189 return fileName.substring(x + 1, y);
190 }
191
192 public String getNormalizedContent(String fileName) throws Exception {
193 String content = readFile(fileName);
194
195 if (fileName.endsWith(".path")) {
196 int x = content.indexOf("<tbody>");
197 int y = content.indexOf("</tbody>");
198
199 if ((x == -1) || (y == -1)) {
200 throwValidationException(1002, fileName, "tbody");
201 }
202
203 String pathTbody = content.substring(x, y + 8);
204
205 Map<String, Object> context = new HashMap<String, Object>();
206
207 context.put("pathName", getName(fileName));
208 context.put("pathTbody", pathTbody);
209
210 String newContent = processTemplate("path_xml.ftl", context);
211
212 if (!content.equals(newContent)) {
213 content = newContent;
214
215 writeFile(getBaseDir(), fileName, newContent, false);
216 }
217 }
218
219 StringBundler sb = new StringBundler();
220
221 int lineNumber = 1;
222
223 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
224 new UnsyncStringReader(content));
225
226 String line = null;
227
228 while ((line = unsyncBufferedReader.readLine()) != null) {
229 Pattern pattern = Pattern.compile("<[a-z\\-]+");
230
231 Matcher matcher = pattern.matcher(line);
232
233 if (matcher.find()) {
234 for (String reservedTag : _reservedTags) {
235 if (line.contains("<" + reservedTag)) {
236 line = StringUtil.replace(
237 line, matcher.group(),
238 matcher.group() + " line-number=\"" + lineNumber +
239 "\"");
240
241 break;
242 }
243 }
244 }
245
246 sb.append(line);
247
248 lineNumber++;
249 }
250
251 content = sb.toString();
252
253 if (content != null) {
254 content = content.trim();
255 content = StringUtil.replace(content, "\n", "");
256 content = StringUtil.replace(content, "\r\n", "");
257 content = StringUtil.replace(content, "\t", " ");
258 content = content.replaceAll(" +", " ");
259 }
260
261 return content;
262 }
263
264 public String getObjectName(String name) {
265 return StringUtil.upperCaseFirstLetter(name);
266 }
267
268 public String getPackageName(String fileName) {
269 String packagePath = getPackagePath(fileName);
270
271 return StringUtil.replace(
272 packagePath, StringPool.SLASH, StringPool.PERIOD);
273 }
274
275 public String getPackagePath(String fileName) {
276 int x = fileName.lastIndexOf(StringPool.SLASH);
277
278 return fileName.substring(0, x);
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 == 1013) {
463 throw new IllegalArgumentException(
464 prefix + "Invalid method " + string1 + " at " + suffix);
465 }
466 else if (errorCode == 1014) {
467 throw new IllegalArgumentException(
468 prefix + "Invalid path " + string1 + " at " + suffix);
469 }
470 else if (errorCode == 1015) {
471 throw new IllegalArgumentException(
472 prefix + "Poorly formed test case command " + string1 + " at " +
473 suffix);
474 }
475 else if (errorCode == 1016) {
476 throw new IllegalArgumentException(
477 prefix + "Invalid " + string1 + " attribute value " + string2 +
478 " in " + suffix);
479 }
480 else if (errorCode == 2000) {
481 throw new IllegalArgumentException(
482 prefix + "Too many child elements in the " + string1 +
483 " element in " + suffix);
484 }
485 else if (errorCode == 2001) {
486 throw new IllegalArgumentException(
487 prefix + "Action command " + string1 +
488 " does not match a function name at " + suffix);
489 }
490 else if (errorCode == 2002) {
491 throw new IllegalArgumentException(
492 prefix + "Missing matching " + string1 + ".path for " + suffix);
493 }
494 else {
495 throw new IllegalArgumentException(prefix + suffix);
496 }
497 }
498
499 protected void throwValidationException(
500 int errorCode, String fileName, Exception e) {
501
502 throwValidationException(
503 errorCode, fileName, null, null, null, null, e);
504 }
505
506 protected void throwValidationException(
507 int errorCode, String fileName, String string1) {
508
509 throwValidationException(
510 errorCode, fileName, null, null, string1, null, null);
511 }
512
513 protected void validate(String fileName, Element rootElement)
514 throws Exception {
515
516 if (fileName.endsWith(".action")) {
517 validateActionDocument(fileName, rootElement);
518 }
519 else if (fileName.endsWith(".function")) {
520 validateFunctionDocument(fileName, rootElement);
521 }
522 else if (fileName.endsWith(".macro")) {
523 validateMacroDocument(fileName, rootElement);
524 }
525 else if (fileName.endsWith(".path")) {
526 validatePathDocument(fileName, rootElement);
527 }
528 else if (fileName.endsWith(".testcase")) {
529 validateTestCaseDocument(fileName, rootElement);
530 }
531 else if (fileName.endsWith(".testsuite")) {
532 validateTestSuiteDocument(fileName, rootElement);
533 }
534 }
535
536 protected void validateActionCommandElement(
537 String fileName, Element commandElement,
538 String[] allowedBlockChildElementNames,
539 String[] allowedExecuteAttributeNames,
540 String[] allowedExecuteChildElementNames) {
541
542 List<Element> elements = commandElement.elements();
543
544 if (elements.isEmpty()) {
545 throwValidationException(
546 1001, fileName, commandElement,
547 new String[] {"case", "default"});
548 }
549
550 for (Element element : elements) {
551 List<Element> childElements = element.elements();
552
553 String elementName = element.getName();
554
555 if (childElements.size() > 1) {
556 throwValidationException(
557 2000, fileName, childElements.get(1), elementName);
558 }
559
560 if (elementName.equals("case")) {
561 List<Attribute> attributes = element.attributes();
562
563 boolean hasNeededAttributeName = false;
564
565 for (Attribute attribute : attributes) {
566 String attributeName = attribute.getName();
567
568 if (attributeName.equals("comparator")) {
569 String attributeValue = attribute.getValue();
570
571 if (!attributeValue.equals("contains") &&
572 !attributeValue.equals("endsWith") &&
573 !attributeValue.equals("equals") &&
574 !attributeValue.equals("startsWith")) {
575
576 throwValidationException(
577 1006, fileName, element, attributeName);
578 }
579 }
580 else if (attributeName.startsWith("locator") ||
581 attributeName.startsWith("locator-key")) {
582
583 String attributeValue = attribute.getValue();
584
585 if (Validator.isNull(attributeValue)) {
586 throwValidationException(
587 1006, fileName, element, attributeName);
588 }
589
590 hasNeededAttributeName = true;
591 }
592
593 if (!attributeName.equals("comparator") &&
594 !attributeName.equals("line-number") &&
595 !attributeName.startsWith("locator") &&
596 !attributeName.startsWith("locator-key")) {
597
598 throwValidationException(
599 1005, fileName, element, attributeName);
600 }
601
602 if (attributeName.equals("locator") ||
603 attributeName.equals("locator-key")) {
604
605 throwValidationException(
606 1005, fileName, element, attributeName);
607 }
608 }
609
610 if (!hasNeededAttributeName) {
611 throwValidationException(
612 1004, fileName, element,
613 new String[] {"locator1", "locator-key1"});
614 }
615
616 validateBlockElement(
617 fileName, element, new String[] {"execute"},
618 new String[] {"function"}, new String[0], new String[0]);
619 }
620 else if (elementName.equals("default")) {
621 List<Attribute> attributes = element.attributes();
622
623 if (attributes.size() != 1) {
624 Attribute attribute = attributes.get(1);
625
626 String attributeName = attribute.getName();
627
628 throwValidationException(
629 1005, fileName, element, attributeName);
630 }
631
632 validateBlockElement(
633 fileName, element, new String[] {"execute"},
634 new String[] {"function"}, new String[0], new String[0]);
635 }
636 else {
637 throwValidationException(1002, fileName, element, elementName);
638 }
639 }
640 }
641
642 protected void validateActionDocument(
643 String fileName, Element rootElement) {
644
645 if (!Validator.equals(rootElement.getName(), "definition")) {
646 throwValidationException(1000, fileName, rootElement);
647 }
648
649 List<Element> elements = rootElement.elements();
650
651 if (elements.isEmpty()) {
652 throwValidationException(
653 1001, fileName, rootElement, new String[] {"command"});
654 }
655
656 for (Element element : elements) {
657 String elementName = element.getName();
658
659 if (elementName.equals("command")) {
660 String attributeValue = element.attributeValue("name");
661
662 if (attributeValue == null) {
663 throwValidationException(1003, fileName, element, "name");
664 }
665 else if (Validator.isNull(attributeValue)) {
666 throwValidationException(1006, fileName, element, "name");
667 }
668
669 validateActionCommandElement(
670 fileName, element, new String[] {"execute"},
671 new String[] {"function"}, new String[0]);
672 }
673 else {
674 throwValidationException(1002, fileName, element, elementName);
675 }
676 }
677 }
678
679 protected void validateBlockElement(
680 String fileName, Element commandElement,
681 String[] allowedBlockChildElementNames,
682 String[] allowedExecuteAttributeNames,
683 String[] allowedExecuteChildElementNames,
684 String[] allowedIfConditionElementNames) {
685
686 List<Element> elements = commandElement.elements();
687
688 if (elements.isEmpty()) {
689 throwValidationException(
690 1001, fileName, commandElement, allowedBlockChildElementNames);
691 }
692
693 for (Element element : elements) {
694 String elementName = element.getName();
695
696 if (!ArrayUtil.contains(
697 allowedBlockChildElementNames, elementName)) {
698
699 throwValidationException(1002, fileName, element, elementName);
700 }
701
702 if (elementName.equals("echo") || elementName.equals("fail")) {
703 validateSimpleElement(
704 fileName, element, new String[] {"message"});
705 }
706 else if (elementName.equals("execute")) {
707 validateExecuteElement(
708 fileName, element, allowedExecuteAttributeNames, ".+",
709 allowedExecuteChildElementNames);
710 }
711 else if (elementName.equals("if")) {
712 validateIfElement(
713 fileName, element, allowedBlockChildElementNames,
714 allowedExecuteAttributeNames,
715 allowedExecuteChildElementNames,
716 allowedIfConditionElementNames);
717 }
718 else if (elementName.equals("var")) {
719 validateVarElement(fileName, element);
720 }
721 else if (elementName.equals("while")) {
722 validateWhileElement(
723 fileName, element, allowedBlockChildElementNames,
724 allowedExecuteAttributeNames,
725 allowedExecuteChildElementNames,
726 allowedIfConditionElementNames);
727 }
728 else {
729 throwValidationException(1002, fileName, element, elementName);
730 }
731 }
732 }
733
734 protected void validateExecuteElement(
735 String fileName, Element executeElement,
736 String[] allowedExecuteAttributeNames,
737 String allowedExecuteAttributeValuesRegex,
738 String[] allowedExecuteChildElementNames) {
739
740 boolean hasAllowedAttributeName = false;
741
742 List<Attribute> attributes = executeElement.attributes();
743
744 for (Attribute attribute : attributes) {
745 String attributeName = attribute.getName();
746
747 if (ArrayUtil.contains(
748 allowedExecuteAttributeNames, attributeName)) {
749
750 hasAllowedAttributeName = true;
751
752 break;
753 }
754 }
755
756 if (!hasAllowedAttributeName) {
757 throwValidationException(
758 1004, fileName, executeElement, allowedExecuteAttributeNames);
759 }
760
761 String action = executeElement.attributeValue("action");
762 String function = executeElement.attributeValue("function");
763 String macro = executeElement.attributeValue("macro");
764 String selenium = executeElement.attributeValue("selenium");
765 String testCase = executeElement.attributeValue("test-case");
766 String testCaseCommand = executeElement.attributeValue(
767 "test-case-command");
768 String testClass = executeElement.attributeValue("test-class");
769 String testSuite = executeElement.attributeValue("test-suite");
770
771 if (action != null) {
772 if (Validator.isNull(action) ||
773 !action.matches(allowedExecuteAttributeValuesRegex)) {
774
775 throwValidationException(
776 1006, fileName, executeElement, "action");
777 }
778
779 for (Attribute attribute : attributes) {
780 String attributeName = attribute.getName();
781
782 if (!attributeName.equals("action") &&
783 !attributeName.equals("line-number") &&
784 !attributeName.startsWith("locator") &&
785 !attributeName.startsWith("locator-key") &&
786 !attributeName.startsWith("value")) {
787
788 throwValidationException(
789 1005, fileName, executeElement, attributeName);
790 }
791
792 if (attributeName.equals("locator") ||
793 attributeName.equals("locator-key") ||
794 attributeName.equals("value")) {
795
796 throwValidationException(
797 1005, fileName, executeElement, attributeName);
798 }
799 }
800 }
801 else if (function != null) {
802 if (Validator.isNull(function) ||
803 !function.matches(allowedExecuteAttributeValuesRegex)) {
804
805 throwValidationException(
806 1006, fileName, executeElement, "function");
807 }
808
809 for (Attribute attribute : attributes) {
810 String attributeName = attribute.getName();
811
812 if (!attributeName.equals("function") &&
813 !attributeName.equals("line-number") &&
814 !attributeName.startsWith("locator") &&
815 !attributeName.startsWith("value")) {
816
817 throwValidationException(
818 1005, fileName, executeElement, attributeName);
819 }
820
821 if (attributeName.equals("locator") ||
822 attributeName.equals("value")) {
823
824 throwValidationException(
825 1005, fileName, executeElement, attributeName);
826 }
827 }
828 }
829 else if (macro != null) {
830 if (Validator.isNull(macro) ||
831 !macro.matches(allowedExecuteAttributeValuesRegex)) {
832
833 throwValidationException(
834 1006, fileName, executeElement, "macro");
835 }
836
837 for (Attribute attribute : attributes) {
838 String attributeName = attribute.getName();
839
840 if (!attributeName.equals("macro") &&
841 !attributeName.equals("line-number")) {
842
843 throwValidationException(
844 1005, fileName, executeElement, attributeName);
845 }
846 }
847 }
848 else if (selenium != null) {
849 if (Validator.isNull(selenium) ||
850 !selenium.matches(allowedExecuteAttributeValuesRegex)) {
851
852 throwValidationException(
853 1006, fileName, executeElement, "selenium");
854 }
855
856 for (Attribute attribute : attributes) {
857 String attributeName = attribute.getName();
858
859 if (!attributeName.equals("argument1") &&
860 !attributeName.equals("argument2") &&
861 !attributeName.equals("line-number") &&
862 !attributeName.equals("selenium")) {
863
864 throwValidationException(
865 1005, fileName, executeElement, attributeName);
866 }
867 }
868 }
869 else if (testCase != null) {
870 if (Validator.isNull(testCase) ||
871 !testCase.matches(allowedExecuteAttributeValuesRegex)) {
872
873 throwValidationException(
874 1006, fileName, executeElement, "test-case");
875 }
876
877 for (Attribute attribute : attributes) {
878 String attributeName = attribute.getName();
879
880 if (!attributeName.equals("line-number") &&
881 !attributeName.equals("test-case")) {
882
883 throwValidationException(
884 1005, fileName, executeElement, attributeName);
885 }
886 }
887 }
888 else if (testCaseCommand != null) {
889 if (Validator.isNull(testCaseCommand) ||
890 !testCaseCommand.matches(allowedExecuteAttributeValuesRegex)) {
891
892 throwValidationException(
893 1006, fileName, executeElement, "test-case-command");
894 }
895
896 if (testCaseCommand.contains("#")) {
897 int x = testCaseCommand.lastIndexOf("#");
898
899 String testCaseName = testCaseCommand.substring(0, x);
900
901 String testCaseCommandName = testCaseCommand.substring(x + 1);
902
903 if (Validator.isNull(testCaseCommandName) ||
904 Validator.isNull(testCaseName)) {
905
906 throwValidationException(
907 1015, fileName, executeElement, testCaseCommand);
908 }
909 }
910 else {
911 throwValidationException(
912 1015, fileName, executeElement, testCaseCommand);
913 }
914
915 for (Attribute attribute : attributes) {
916 String attributeName = attribute.getName();
917
918 if (!attributeName.equals("line-number") &&
919 !attributeName.equals("test-case-command")) {
920
921 throwValidationException(
922 1005, fileName, executeElement, attributeName);
923 }
924 }
925 }
926 else if (testClass != null) {
927 if (Validator.isNull(testClass) ||
928 !testClass.matches(allowedExecuteAttributeValuesRegex)) {
929
930 throwValidationException(
931 1006, fileName, executeElement, "test-class");
932 }
933
934 for (Attribute attribute : attributes) {
935 String attributeName = attribute.getName();
936
937 if (!attributeName.equals("line-number") &&
938 !attributeName.equals("test-class")) {
939
940 throwValidationException(
941 1005, fileName, executeElement, attributeName);
942 }
943 }
944 }
945 else if (testSuite != null) {
946 if (Validator.isNull(testSuite) ||
947 !testSuite.matches(allowedExecuteAttributeValuesRegex)) {
948
949 throwValidationException(
950 1006, fileName, executeElement, "test-suite");
951 }
952
953 for (Attribute attribute : attributes) {
954 String attributeName = attribute.getName();
955
956 if (!attributeName.equals("line-number") &&
957 !attributeName.equals("test-suite")) {
958
959 throwValidationException(
960 1005, fileName, executeElement, attributeName);
961 }
962 }
963 }
964 else {
965 throwValidationException(0, fileName);
966 }
967
968 List<Element> elements = executeElement.elements();
969
970 if (allowedExecuteChildElementNames.length == 0) {
971 if (!elements.isEmpty()) {
972 Element element = elements.get(0);
973
974 String elementName = element.getName();
975
976 throwValidationException(1002, fileName, element, elementName);
977 }
978 }
979 else {
980 String executeElementName = executeElement.getName();
981
982 for (Element element : elements) {
983 String elementName = element.getName();
984
985 if (executeElementName.equals("condition")) {
986 throwValidationException(
987 1002, fileName, element, elementName);
988 }
989
990 if (elementName.equals("var")) {
991 validateVarElement(fileName, element);
992 }
993 else {
994 throwValidationException(
995 1002, fileName, element, elementName);
996 }
997 }
998 }
999 }
1000
1001 protected void validateFunctionDocument(
1002 String fileName, Element rootElement) {
1003
1004 if (!Validator.equals(rootElement.getName(), "definition")) {
1005 throwValidationException(1000, fileName, rootElement);
1006 }
1007
1008 List<Element> elements = rootElement.elements();
1009
1010 if (elements.isEmpty()) {
1011 throwValidationException(
1012 1001, fileName, rootElement, new String[] {"command"});
1013 }
1014
1015 for (Element element : elements) {
1016 String elementName = element.getName();
1017
1018 if (elementName.equals("command")) {
1019 String attributeValue = element.attributeValue("name");
1020
1021 if (attributeValue == null) {
1022 throwValidationException(1003, fileName, element, "name");
1023 }
1024 else if (Validator.isNull(attributeValue)) {
1025 throwValidationException(1006, fileName, element, "name");
1026 }
1027
1028 validateBlockElement(
1029 fileName, element, new String[] {"execute", "if"},
1030 new String[] {"function", "selenium"}, new String[0],
1031 new String[] {"condition"});
1032 }
1033 else {
1034 throwValidationException(1002, fileName, element, elementName);
1035 }
1036 }
1037 }
1038
1039 protected void validateIfElement(
1040 String fileName, Element ifElement,
1041 String[] allowedBlockChildElementNames,
1042 String[] allowedExecuteAttributeNames,
1043 String[] allowedExecuteChildElementNames,
1044 String[] allowedIfConditionElementNames) {
1045
1046 List<Element> elements = ifElement.elements();
1047
1048 Set<String> elementNames = new HashSet<String>();
1049
1050 boolean hasAllowedIfConditionElementNames = false;
1051
1052 for (Element element : elements) {
1053 String elementName = element.getName();
1054
1055 elementNames.add(elementName);
1056
1057 if (ArrayUtil.contains(
1058 allowedIfConditionElementNames, elementName)) {
1059
1060 hasAllowedIfConditionElementNames = true;
1061 }
1062
1063 if (elementName.equals("condition")) {
1064 validateExecuteElement(
1065 fileName, element, allowedExecuteAttributeNames,
1066 ".*(is|Is).+", allowedExecuteChildElementNames);
1067 }
1068 else if (elementName.equals("contains")) {
1069 validateSimpleElement(
1070 fileName, element, new String[] {"string", "substring"});
1071 }
1072 else if (elementName.equals("else") || elementName.equals("then")) {
1073 validateBlockElement(
1074 fileName, element, allowedBlockChildElementNames,
1075 allowedExecuteAttributeNames,
1076 allowedExecuteChildElementNames,
1077 allowedIfConditionElementNames);
1078 }
1079 else if (elementName.equals("elseif")) {
1080 validateIfElement(
1081 fileName, element, allowedBlockChildElementNames,
1082 allowedExecuteAttributeNames,
1083 allowedExecuteChildElementNames,
1084 allowedIfConditionElementNames);
1085 }
1086 else if (elementName.equals("equals")) {
1087 validateSimpleElement(
1088 fileName, element, new String[] {"arg1", "arg2"});
1089 }
1090 else if (elementName.equals("isset")) {
1091 validateSimpleElement(fileName, element, new String[] {"var"});
1092 }
1093 else if (elementName.equals("not")) {
1094 validateIfElement(
1095 fileName, element, allowedBlockChildElementNames,
1096 allowedExecuteAttributeNames,
1097 allowedExecuteChildElementNames,
1098 allowedIfConditionElementNames);
1099 }
1100 else {
1101 throwValidationException(1002, fileName, element, elementName);
1102 }
1103 }
1104
1105 if (!hasAllowedIfConditionElementNames) {
1106 throwValidationException(
1107 1001, fileName, ifElement, allowedIfConditionElementNames);
1108 }
1109
1110 if (ifElement.getName() == "not") {
1111 return;
1112 }
1113
1114 if (!elementNames.contains("then")) {
1115 throwValidationException(
1116 1001, fileName, ifElement, new String[] {"then"});
1117 }
1118 }
1119
1120 protected void validateMacroDocument(String fileName, Element rootElement) {
1121 if (!Validator.equals(rootElement.getName(), "definition")) {
1122 throwValidationException(1000, fileName, rootElement);
1123 }
1124
1125 List<Element> elements = rootElement.elements();
1126
1127 if (elements.isEmpty()) {
1128 throwValidationException(
1129 1001, fileName, rootElement, new String[] {"command", "var"});
1130 }
1131
1132 for (Element element : elements) {
1133 String elementName = element.getName();
1134
1135 if (elementName.equals("command")) {
1136 String attributeValue = element.attributeValue("name");
1137
1138 if (attributeValue == null) {
1139 throwValidationException(1003, fileName, element, "name");
1140 }
1141 else if (Validator.isNull(attributeValue)) {
1142 throwValidationException(1006, fileName, element, "name");
1143 }
1144
1145 validateBlockElement(
1146 fileName, element,
1147 new String[] {
1148 "echo", "execute", "fail", "if", "var","while"
1149 },
1150 new String[] {"action", "macro"}, new String[] {"var"},
1151 new String[] {
1152 "condition", "contains", "equals", "isset", "not"});
1153 }
1154 else if (elementName.equals("var")) {
1155 validateVarElement(fileName, element);
1156 }
1157 else {
1158 throwValidationException(1002, fileName, element, elementName);
1159 }
1160 }
1161 }
1162
1163 protected void validatePathDocument(String fileName, Element rootElement) {
1164 Element headElement = rootElement.element("head");
1165
1166 Element titleElement = headElement.element("title");
1167
1168 String title = titleElement.getText();
1169
1170 int x = fileName.lastIndexOf(StringPool.SLASH);
1171 int y = fileName.lastIndexOf(CharPool.PERIOD);
1172
1173 String shortFileName = fileName.substring(x + 1, y);
1174
1175 if ((title == null) || !shortFileName.equals(title)) {
1176 throwValidationException(0, fileName);
1177 }
1178
1179 Element bodyElement = rootElement.element("body");
1180
1181 Element tableElement = bodyElement.element("table");
1182
1183 Element theadElement = tableElement.element("thead");
1184
1185 Element trElement = theadElement.element("tr");
1186
1187 Element tdElement = trElement.element("td");
1188
1189 String tdText = tdElement.getText();
1190
1191 if ((tdText == null) || !shortFileName.equals(tdText)) {
1192 throwValidationException(0, fileName);
1193 }
1194
1195 Element tbodyElement = tableElement.element("tbody");
1196
1197 List<Element> elements = tbodyElement.elements();
1198
1199 for (Element element : elements) {
1200 String elementName = element.getName();
1201
1202 if (elementName.equals("tr")) {
1203 validatePathTrElement(fileName, element);
1204 }
1205 else {
1206 throwValidationException(1002, fileName, element, elementName);
1207 }
1208 }
1209 }
1210
1211 protected void validatePathTrElement(String fileName, Element trElement) {
1212 List<Element> elements = trElement.elements();
1213
1214 for (Element element : elements) {
1215 String elementName = element.getName();
1216
1217 if (!elementName.equals("td")) {
1218 throwValidationException(1002, fileName, element, elementName);
1219 }
1220 }
1221
1222 if (elements.size() < 3) {
1223 throwValidationException(
1224 1001, fileName, trElement, new String[] {"td"});
1225 }
1226
1227 if (elements.size() > 3) {
1228 Element element = elements.get(3);
1229
1230 String elementName = element.getName();
1231
1232 throwValidationException(1002, fileName, element, elementName);
1233 }
1234 }
1235
1236 protected void validateSimpleElement(
1237 String fileName, Element element, String[] neededAttributes) {
1238
1239 Map<String, Boolean> hasNeededAttributes =
1240 new HashMap<String, Boolean>();
1241
1242 for (String neededAttribute : neededAttributes) {
1243 hasNeededAttributes.put(neededAttribute, false);
1244 }
1245
1246 List<Attribute> attributes = element.attributes();
1247
1248 for (Attribute attribute : attributes) {
1249 String attributeName = attribute.getName();
1250 String attributeValue = attribute.getValue();
1251
1252 if (Validator.isNull(attributeValue)) {
1253 throwValidationException(
1254 1006, fileName, element, attributeName);
1255 }
1256
1257 if (hasNeededAttributes.containsKey(attributeName)) {
1258 hasNeededAttributes.put(attributeName, true);
1259 }
1260
1261 if (!attributeName.equals("line-number") &&
1262 !hasNeededAttributes.containsKey(attributeName)) {
1263
1264 throwValidationException(
1265 1005, fileName, element, attributeName);
1266 }
1267 }
1268
1269 for (String neededAttribute : neededAttributes) {
1270 if (!hasNeededAttributes.get(neededAttribute)) {
1271 throwValidationException(
1272 1004, fileName, element, neededAttributes);
1273 }
1274 }
1275
1276 List<Element> childElements = element.elements();
1277
1278 if (!childElements.isEmpty()) {
1279 Element childElement = childElements.get(0);
1280
1281 String childElementName = childElement.getName();
1282
1283 throwValidationException(
1284 1002, fileName, childElement, childElementName);
1285 }
1286 }
1287
1288 protected void validateTestCaseDocument(
1289 String fileName, Element rootElement) {
1290
1291 if (!Validator.equals(rootElement.getName(), "definition")) {
1292 throwValidationException(1000, fileName, rootElement);
1293 }
1294
1295 List<Element> elements = rootElement.elements();
1296
1297 if (elements.isEmpty()) {
1298 throwValidationException(
1299 1001, fileName, rootElement, new String[] {"command"});
1300 }
1301
1302 for (Element element : elements) {
1303 String elementName = element.getName();
1304
1305 if (elementName.equals("command")) {
1306 String attributeValue = element.attributeValue("name");
1307
1308 if (attributeValue == null) {
1309 throwValidationException(1003, fileName, element, "name");
1310 }
1311 else if (Validator.isNull(attributeValue)) {
1312 throwValidationException(1006, fileName, element, "name");
1313 }
1314
1315 validateBlockElement(
1316 fileName, element, new String[] {"execute", "var"},
1317 new String[] {"action", "macro"}, new String[] {"var"},
1318 new String[0]);
1319 }
1320 else if (elementName.equals("set-up") ||
1321 elementName.equals("tear-down")) {
1322
1323 List<Attribute> attributes = element.attributes();
1324
1325 for (Attribute attribute : attributes) {
1326 String attributeName = attribute.getName();
1327
1328 if (!attributeName.equals("line-number")) {
1329 throwValidationException(
1330 1005, fileName, element, attributeName);
1331 }
1332 }
1333
1334 validateBlockElement(
1335 fileName, element, new String[] {"execute", "var"},
1336 new String[] {"action", "macro"}, new String[] {"var"},
1337 new String[0]);
1338 }
1339 else if (elementName.equals("var")) {
1340 validateVarElement(fileName, element);
1341 }
1342 else {
1343 throwValidationException(1002, fileName, element, elementName);
1344 }
1345 }
1346 }
1347
1348 protected void validateTestSuiteDocument(
1349 String fileName, Element rootElement) {
1350
1351 if (!Validator.equals(rootElement.getName(), "definition")) {
1352 throwValidationException(1000, fileName, rootElement);
1353 }
1354
1355 List<Element> elements = rootElement.elements();
1356
1357 if (elements.isEmpty()) {
1358 throwValidationException(
1359 1001, fileName, rootElement, new String[] {"execute"});
1360 }
1361
1362 for (Element element : elements) {
1363 String elementName = element.getName();
1364
1365 if (elementName.equals("execute")) {
1366 validateExecuteElement(
1367 fileName, element,
1368 new String[] {
1369 "test-case", "test-case-command", "test-class",
1370 "test-suite"
1371 },
1372 ".+", new String[0]);
1373 }
1374 else {
1375 throwValidationException(1002, fileName, element, elementName);
1376 }
1377 }
1378 }
1379
1380 protected void validateVarElement(String fileName, Element element) {
1381 List<Attribute> attributes = element.attributes();
1382
1383 Map<String, String> attributeMap = new HashMap<String, String>();
1384
1385 for (Attribute attribute : attributes) {
1386 String attributeName = attribute.getName();
1387 String attributeValue = attribute.getValue();
1388
1389 if (!attributeName.equals("value") &&
1390 Validator.isNull(attributeValue)) {
1391
1392 throwValidationException(
1393 1006, fileName, element, attributeName);
1394 }
1395
1396 if (!_allowedVarAttributes.contains(attributeName)) {
1397 throwValidationException(
1398 1005, fileName, element, attributeName);
1399 }
1400
1401 attributeMap.put(attributeName, attributeValue);
1402 }
1403
1404 if (!attributeMap.containsKey("name")) {
1405 throwValidationException(
1406 1004, fileName, element, new String[] {"name"});
1407 }
1408 else {
1409 String nameValue = attributeMap.get("name");
1410
1411 if (Validator.isNull(nameValue)) {
1412 throwValidationException(1006, fileName, element, "name");
1413 }
1414 }
1415
1416 String varText = element.getText();
1417
1418 if (Validator.isNull(varText) &&
1419 !attributeMap.containsKey("locator-key") &&
1420 !attributeMap.containsKey("path") &&
1421 !attributeMap.containsKey("value")) {
1422
1423 throwValidationException(
1424 1004, fileName, element, new String [] {"value"});
1425 }
1426
1427 if (!attributeMap.containsKey("value")) {
1428 String locatorKeyValue = attributeMap.get("locator-key");
1429 String pathValue = attributeMap.get("path");
1430
1431 if (Validator.isNull(locatorKeyValue) &&
1432 Validator.isNotNull(pathValue)) {
1433
1434 throwValidationException(
1435 1004, fileName, element, new String [] {"locator-key"});
1436 }
1437
1438 if (Validator.isNotNull(locatorKeyValue) &&
1439 Validator.isNull(pathValue)) {
1440
1441 throwValidationException(
1442 1004, fileName, element, new String [] {"path"});
1443 }
1444 }
1445 else {
1446 String varValue = attributeMap.get("value");
1447
1448 Pattern pattern = Pattern.compile("\\$\\{([^\\}]*?)\\}");
1449
1450 Matcher matcher = pattern.matcher(varValue);
1451
1452 while (matcher.find()) {
1453 String statement = matcher.group(1);
1454
1455 Pattern statementPattern = Pattern.compile(
1456 "(.*)\\?(.*)\\(([^\\)]*?)\\)");
1457
1458 Matcher statementMatcher = statementPattern.matcher(statement);
1459
1460 if (statementMatcher.find()) {
1461 String operand = statementMatcher.group(1);
1462
1463 String method = statementMatcher.group(2);
1464
1465 if (operand.equals("") || method.equals("")) {
1466 throwValidationException(
1467 1006, fileName, element, "value");
1468 }
1469
1470 if (!_methodNames.contains(method)) {
1471 throwValidationException(
1472 1013, fileName, element, method);
1473 }
1474 }
1475 else {
1476 if (statement.matches(".*[\\?\\(\\)\\}\\{].*")) {
1477 throwValidationException(
1478 1006, fileName, element, "value");
1479 }
1480 }
1481 }
1482 }
1483
1484 List<Element> childElements = element.elements();
1485
1486 if (!childElements.isEmpty()) {
1487 Element childElement = childElements.get(0);
1488
1489 String childElementName = childElement.getName();
1490
1491 throwValidationException(
1492 1002, fileName, childElement, childElementName);
1493 }
1494 }
1495
1496 protected void validateWhileElement(
1497 String fileName, Element whileElement,
1498 String[] allowedBlockChildElementNames,
1499 String[] allowedExecuteAttributeNames,
1500 String[] allowedExecuteChildElementNames,
1501 String[] allowedIfConditionElementNames) {
1502
1503 List<Element> elements = whileElement.elements();
1504
1505 Set<String> elementNames = new HashSet<String>();
1506
1507 for (Element element : elements) {
1508 String elementName = element.getName();
1509
1510 elementNames.add(elementName);
1511
1512 if (elementName.equals("condition")) {
1513 validateExecuteElement(
1514 fileName, element, allowedExecuteAttributeNames,
1515 ".*(is|Is).+", allowedExecuteChildElementNames);
1516 }
1517 else if (elementName.equals("then")) {
1518 validateBlockElement(
1519 fileName, element, allowedBlockChildElementNames,
1520 allowedExecuteAttributeNames,
1521 allowedExecuteChildElementNames,
1522 allowedIfConditionElementNames);
1523 }
1524 else {
1525 throwValidationException(1002, fileName, element, elementName);
1526 }
1527 }
1528
1529 if (!elementNames.contains("condition") ||
1530 !elementNames.contains("then")) {
1531
1532 throwValidationException(
1533 1001, fileName, whileElement,
1534 new String[] {"condition", "then"});
1535 }
1536 }
1537
1538 private static final String _TPL_ROOT =
1539 "com/liferay/portal/tools/seleniumbuilder/dependencies/";
1540
1541 private static List<String> _allowedVarAttributes = ListUtil.fromArray(
1542 new String[] {"line-number", "locator-key", "name", "path", "value"});
1543 private static List<String> _methodNames = ListUtil.fromArray(
1544 new String[] {"increment", "length", "lowercase", "replace"});
1545 private static List<String> _reservedTags = ListUtil.fromArray(
1546 new String[] {
1547 "case", "command", "condition", "contains", "default", "definition",
1548 "echo", "else", "elseif", "equals", "execute", "fail", "if",
1549 "isset", "not", "set-up", "td", "tear-down", "then", "tr", "while",
1550 "var"
1551 });
1552
1553 private String _baseDir;
1554
1555 }