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.ByteArrayInputStream;
037 import java.io.File;
038 import java.io.InputStream;
039
040 import java.util.ArrayList;
041 import java.util.HashMap;
042 import java.util.HashSet;
043 import java.util.List;
044 import java.util.Map;
045 import java.util.Properties;
046 import java.util.Set;
047 import java.util.TreeSet;
048 import java.util.regex.Matcher;
049 import java.util.regex.Pattern;
050
051 import javax.xml.xpath.XPath;
052 import javax.xml.xpath.XPathFactory;
053
054 import org.apache.commons.lang.StringEscapeUtils;
055
056
059 public class SeleniumBuilderFileUtil {
060
061 public SeleniumBuilderFileUtil(String baseDirName, String projectDirName) {
062 _baseDirName = baseDirName;
063
064 Properties properties = new Properties();
065
066 try {
067 String content = FileUtil.read(projectDirName + "/test.properties");
068
069 InputStream inputStream = new ByteArrayInputStream(
070 content.getBytes());
071
072 properties.load(inputStream);
073 }
074 catch (Exception e) {
075 e.printStackTrace();
076 }
077
078 _componentNames = ListUtil.fromArray(
079 StringUtil.split(properties.getProperty("component.names")));
080 _testcaseAvailablePropertyNames = ListUtil.fromArray(
081 StringUtil.split(
082 properties.getProperty("testcase.available.property.names")));
083 _testrayAvailableComponentNames = ListUtil.fromArray(
084 StringUtil.split(
085 properties.getProperty("testray.available.component.names")));
086 }
087
088 public String escapeHtml(String input) {
089 return StringEscapeUtils.escapeHtml(input);
090 }
091
092 public String escapeJava(String input) {
093 return StringEscapeUtils.escapeJava(input);
094 }
095
096 public List<Element> getAllChildElements(
097 Element element, String elementName) {
098
099 List<Element> allChildElements = new ArrayList<Element>();
100
101 List<Element> childElements = element.elements();
102
103 if (childElements.isEmpty()) {
104 return allChildElements;
105 }
106
107 for (Element childElement : childElements) {
108 String childElementName = childElement.getName();
109
110 if (childElementName.equals(elementName)) {
111 allChildElements.add(childElement);
112 }
113
114 allChildElements.addAll(
115 getAllChildElements(childElement, elementName));
116 }
117
118 return allChildElements;
119 }
120
121 public String getBaseDirName() {
122 return _baseDirName;
123 }
124
125 public Set<String> getChildElementAttributeValues(
126 Element element, String attributeName) {
127
128 Set<String> childElementAttributeValues = new TreeSet<String>();
129
130 List<Element> childElements = element.elements();
131
132 if (childElements.isEmpty()) {
133 return childElementAttributeValues;
134 }
135
136 for (Element childElement : childElements) {
137 String childElementName = childElement.attributeValue(
138 attributeName);
139
140 if (childElementName != null) {
141 int x = childElementName.lastIndexOf(StringPool.POUND);
142
143 if (x != -1) {
144 childElementAttributeValues.add(
145 childElementName.substring(0, x));
146 }
147 }
148
149 childElementAttributeValues.addAll(
150 getChildElementAttributeValues(childElement, attributeName));
151 }
152
153 return childElementAttributeValues;
154 }
155
156 public Set<String> getChildElementLineNumbers(Element element) {
157 Set<String> childElementLineNumbers = new TreeSet<String>();
158
159 List<Element> childElements = element.elements();
160
161 if (childElements.isEmpty()) {
162 return childElementLineNumbers;
163 }
164
165 for (Element childElement : childElements) {
166 String childElementLineNumber = childElement.attributeValue(
167 "line-number");
168
169 if (childElementLineNumber != null) {
170 childElementLineNumbers.add(childElementLineNumber);
171 }
172
173 childElementLineNumbers.addAll(
174 getChildElementLineNumbers(childElement));
175 }
176
177 return childElementLineNumbers;
178 }
179
180 public String getClassName(String fileName) {
181 String classSuffix = getClassSuffix(fileName);
182
183 return getClassName(fileName, classSuffix);
184 }
185
186 public String getClassName(String fileName, String classSuffix) {
187 return
188 getPackageName(fileName) + "." +
189 getSimpleClassName(fileName, classSuffix);
190 }
191
192 public String getClassSimpleClassName(String className) {
193 int x = className.lastIndexOf(CharPool.PERIOD);
194
195 return className.substring(x + 1);
196 }
197
198 public String getClassSuffix(String fileName) {
199 int x = fileName.indexOf(CharPool.PERIOD);
200
201 String classSuffix = StringUtil.upperCaseFirstLetter(
202 fileName.substring(x + 1));
203
204 if (classSuffix.equals("Testcase")) {
205 classSuffix = "TestCase";
206 }
207
208 return classSuffix;
209 }
210
211 public List<String> getComponentNames() {
212 return _componentNames;
213 }
214
215 public String getHTMLFileName(String fileName) {
216 String javaFileName = getJavaFileName(fileName);
217
218 return StringUtil.replace(javaFileName, ".java", ".html");
219 }
220
221 public String getJavaFileName(String fileName) {
222 String classSuffix = getClassSuffix(fileName);
223
224 return getJavaFileName(fileName, classSuffix);
225 }
226
227 public String getJavaFileName(String fileName, String classSuffix) {
228 return
229 getPackagePath(fileName) + "/" +
230 getSimpleClassName(fileName, classSuffix) + ".java";
231 }
232
233 public int getLocatorCount(Element rootElement) {
234 String xml = rootElement.asXML();
235
236 for (int i = 1;; i++) {
237 if (xml.contains("${locator" + i + "}")) {
238 continue;
239 }
240
241 if (i > 1) {
242 i--;
243 }
244
245 return i;
246 }
247 }
248
249 public String getName(String fileName) {
250 int x = fileName.lastIndexOf(StringPool.SLASH);
251 int y = fileName.lastIndexOf(CharPool.PERIOD);
252
253 return fileName.substring(x + 1, y);
254 }
255
256 public String getNormalizedContent(String fileName) throws Exception {
257 String content = readFile(fileName);
258
259 if (fileName.endsWith(".path")) {
260 int x = content.indexOf("<tbody>");
261 int y = content.indexOf("</tbody>");
262
263 if ((x == -1) || (y == -1)) {
264 throwValidationException(1002, fileName, "tbody");
265 }
266
267 String pathTbody = content.substring(x, y + 8);
268
269 Map<String, Object> context = new HashMap<String, Object>();
270
271 context.put("pathName", getName(fileName));
272 context.put("pathTbody", pathTbody);
273
274 String newContent = processTemplate("path_xml.ftl", context);
275
276 if (!content.equals(newContent)) {
277 content = newContent;
278
279 writeFile(getBaseDirName(), fileName, newContent, false);
280 }
281 }
282
283 StringBundler sb = new StringBundler();
284
285 int lineNumber = 1;
286
287 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
288 new UnsyncStringReader(content));
289
290 String line = null;
291
292 while ((line = unsyncBufferedReader.readLine()) != null) {
293 Matcher matcher = _tagPattern.matcher(line);
294
295 if (matcher.find()) {
296 for (String reservedTag : _reservedTags) {
297 if (line.contains("<" + reservedTag)) {
298 line = StringUtil.replace(
299 line, matcher.group(),
300 matcher.group() + " line-number=\"" + lineNumber +
301 "\"");
302
303 break;
304 }
305 }
306 }
307
308 sb.append(line);
309
310 lineNumber++;
311 }
312
313 content = sb.toString();
314
315 if (content != null) {
316 content = content.trim();
317 content = StringUtil.replace(content, "\n", "");
318 content = StringUtil.replace(content, "\r\n", "");
319 content = StringUtil.replace(content, "\t", " ");
320 content = content.replaceAll(" +", " ");
321 }
322
323 return content;
324 }
325
326 public String getObjectName(String name) {
327 return StringUtil.upperCaseFirstLetter(name);
328 }
329
330 public String getPackageName(String fileName) {
331 String packagePath = getPackagePath(fileName);
332
333 return StringUtil.replace(
334 packagePath, StringPool.SLASH, StringPool.PERIOD);
335 }
336
337 public String getPackagePath(String fileName) {
338 int x = fileName.lastIndexOf(StringPool.SLASH);
339
340 return fileName.substring(0, x);
341 }
342
343 public String getReturnType(String name) {
344 if (name.startsWith("Is")) {
345 return "boolean";
346 }
347
348 return "void";
349 }
350
351 public Element getRootElement(String fileName) throws Exception {
352 String content = getNormalizedContent(fileName);
353
354 try {
355 Document document = SAXReaderUtil.read(content, true);
356
357 Element rootElement = document.getRootElement();
358
359 validate(fileName, rootElement);
360
361 return rootElement;
362 }
363 catch (DocumentException de) {
364 throwValidationException(1007, fileName, de);
365 }
366
367 return null;
368 }
369
370 public String getSimpleClassName(String fileName) {
371 String classSuffix = getClassSuffix(fileName);
372
373 return getSimpleClassName(fileName, classSuffix);
374 }
375
376 public String getSimpleClassName(String fileName, String classSuffix) {
377 return getName(fileName) + classSuffix;
378 }
379
380 public String getVariableName(String name) {
381 return TextFormatter.format(name, TextFormatter.I);
382 }
383
384 public String normalizeFileName(String fileName) {
385 return StringUtil.replace(
386 fileName, StringPool.BACK_SLASH, StringPool.SLASH);
387 }
388
389 public String readFile(String fileName) throws Exception {
390 return FileUtil.read(getBaseDirName() + "/" + fileName);
391 }
392
393 public void writeFile(String fileName, String content, boolean format)
394 throws Exception {
395
396 writeFile(getBaseDirName() + "-generated", fileName, content, format);
397 }
398
399 public void writeFile(
400 String baseDirName, String fileName, String content, boolean format)
401 throws Exception {
402
403 File file = new File(baseDirName + "/" + fileName);
404
405 if (format) {
406 ServiceBuilder.writeFile(file, content);
407 }
408 else {
409 System.out.println("Writing " + file);
410
411 FileUtil.write(file, content);
412 }
413 }
414
415 protected String processTemplate(String name, Map<String, Object> context)
416 throws Exception {
417
418 return StringUtil.strip(
419 FreeMarkerUtil.process(_TPL_ROOT + name, context), '\r');
420 }
421
422 protected void throwValidationException(int errorCode, String fileName) {
423 throwValidationException(
424 errorCode, fileName, null, null, null, null, null);
425 }
426
427 protected void throwValidationException(
428 int errorCode, String fileName, Element element) {
429
430 throwValidationException(
431 errorCode, fileName, element, null, null, null, null);
432 }
433
434 protected void throwValidationException(
435 int errorCode, String fileName, Element element, String string1) {
436
437 throwValidationException(
438 errorCode, fileName, element, null, string1, null, null);
439 }
440
441 protected void throwValidationException(
442 int errorCode, String fileName, Element element, String string1,
443 String string2) {
444
445 throwValidationException(
446 errorCode, fileName, element, null, string1, string2, null);
447 }
448
449 protected void throwValidationException(
450 int errorCode, String fileName, Element element, String[] array) {
451
452 throwValidationException(
453 errorCode, fileName, element, array, null, null, null);
454 }
455
456 protected void throwValidationException(
457 int errorCode, String fileName, Element element, String[] array,
458 String string1) {
459
460 throwValidationException(
461 errorCode, fileName, element, array, string1, null, null);
462 }
463
464 protected void throwValidationException(
465 int errorCode, String fileName, Element element, String[] array,
466 String string1, String string2, Exception e) {
467
468 String prefix = "Error " + errorCode + ": ";
469 String suffix = fileName;
470
471 if (element != null) {
472 suffix += ":" + element.attributeValue("line-number");
473 }
474
475 if (errorCode == 1000) {
476 throw new IllegalArgumentException(
477 prefix + "Invalid root element in " + suffix);
478 }
479 else if (errorCode == 1001) {
480 throw new IllegalArgumentException(
481 prefix + "Missing (" + StringUtil.merge(array, "|") +
482 ") child element in " + suffix);
483 }
484 else if (errorCode == 1002) {
485 throw new IllegalArgumentException(
486 prefix + "Invalid " + string1 + " element in " + suffix);
487 }
488 else if (errorCode == 1003) {
489 throw new IllegalArgumentException(
490 prefix + "Missing " + string1 + " attribute in " + suffix);
491 }
492 else if (errorCode == 1004) {
493 throw new IllegalArgumentException(
494 prefix + "Missing (" + StringUtil.merge(array, "|") +
495 ") attribute in " + suffix);
496 }
497 else if (errorCode == 1005) {
498 throw new IllegalArgumentException(
499 prefix + "Invalid " + string1 + " attribute in " + suffix);
500 }
501 else if (errorCode == 1006) {
502 throw new IllegalArgumentException(
503 prefix + "Invalid " + string1 + " attribute value in " +
504 suffix);
505 }
506 else if (errorCode == 1007) {
507 throw new IllegalArgumentException(
508 prefix + "Poorly formed XML in " + suffix, e);
509 }
510 else if (errorCode == 1008) {
511 throw new IllegalArgumentException(
512 prefix + "Duplicate file name " + string1 + " at " + suffix);
513 }
514 else if (errorCode == 1009) {
515 throw new IllegalArgumentException(
516 prefix + "Duplicate command name " + string1 + " at " + suffix);
517 }
518 else if (errorCode == 1010) {
519 throw new IllegalArgumentException(
520 prefix + "Invalid locator-key " + string1 + " at " + suffix);
521 }
522 else if (errorCode == 1011) {
523 throw new IllegalArgumentException(
524 prefix + "Invalid " + string1 + " name " + string2 + " at " +
525 suffix);
526 }
527 else if (errorCode == 1012) {
528 throw new IllegalArgumentException(
529 prefix + "Invalid " + string1 + " command " + string2 + " at " +
530 suffix);
531 }
532 else if (errorCode == 1013) {
533 throw new IllegalArgumentException(
534 prefix + "Invalid method " + string1 + " at " + suffix);
535 }
536 else if (errorCode == 1014) {
537 throw new IllegalArgumentException(
538 prefix + "Invalid path " + string1 + " at " + suffix);
539 }
540 else if (errorCode == 1015) {
541 throw new IllegalArgumentException(
542 prefix + "Poorly formed test case command " + string1 + " at " +
543 suffix);
544 }
545 else if (errorCode == 1016) {
546 throw new IllegalArgumentException(
547 prefix + "Invalid " + string1 + " attribute value " + string2 +
548 " in " + suffix);
549 }
550 else if (errorCode == 1017) {
551 throw new IllegalArgumentException(
552 prefix + "Description '" + string1 +
553 "' must end with a '.' in " + suffix);
554 }
555 else if (errorCode == 1018) {
556 throw new IllegalArgumentException(
557 prefix + "Missing (" + StringUtil.merge(array, "|") +
558 ") in attribute " + string1 + " at " + suffix);
559 }
560 else if (errorCode == 2000) {
561 throw new IllegalArgumentException(
562 prefix + "Too many child elements in the " + string1 +
563 " element in " + suffix);
564 }
565 else if (errorCode == 2001) {
566 throw new IllegalArgumentException(
567 prefix + "Action command " + string1 +
568 " does not match a function name at " + suffix);
569 }
570 else if (errorCode == 2002) {
571 throw new IllegalArgumentException(
572 prefix + "Missing matching " + string1 + ".path for " + suffix);
573 }
574 else if (errorCode == 2003) {
575 throw new IllegalArgumentException(
576 prefix + "Illegal XPath " + string1 + " in " + suffix);
577 }
578 else if (errorCode == 2004) {
579 throw new IllegalArgumentException(
580 prefix + "Description '" + string1 +
581 "' must title convention in " + suffix);
582 }
583 else if (errorCode == 3001) {
584 throw new IllegalArgumentException(
585 prefix + "The property '" + string1 +
586 "' has an invalid component name '" + string2 + "' in " +
587 suffix);
588 }
589 else if (errorCode == 3002) {
590 throw new IllegalArgumentException(
591 prefix + "Missing property '" + string1 + "' for " + suffix);
592 }
593 else if (errorCode == 3003) {
594 throw new IllegalArgumentException(
595 prefix + "Invalid property " + string1 + " at " + suffix);
596 }
597 else {
598 throw new IllegalArgumentException(prefix + suffix);
599 }
600 }
601
602 protected void throwValidationException(
603 int errorCode, String fileName, Exception e) {
604
605 throwValidationException(
606 errorCode, fileName, null, null, null, null, e);
607 }
608
609 protected void throwValidationException(
610 int errorCode, String fileName, String string1) {
611
612 throwValidationException(
613 errorCode, fileName, null, null, string1, null, null);
614 }
615
616 protected void validate(String fileName, Element rootElement)
617 throws Exception {
618
619 if (fileName.endsWith(".action")) {
620 validateActionDocument(fileName, rootElement);
621 }
622 else if (fileName.endsWith(".function")) {
623 validateFunctionDocument(fileName, rootElement);
624 }
625 else if (fileName.endsWith(".macro")) {
626 validateMacroDocument(fileName, rootElement);
627 }
628 else if (fileName.endsWith(".path")) {
629 validatePathDocument(fileName, rootElement);
630 }
631 else if (fileName.endsWith(".testcase")) {
632 validateTestCaseDocument(fileName, rootElement);
633 }
634 }
635
636 protected void validateActionCommandElement(
637 String fileName, Element commandElement,
638 String[] allowedBlockChildElementNames,
639 String[] allowedExecuteAttributeNames,
640 String[] allowedExecuteChildElementNames) {
641
642 List<Element> elements = commandElement.elements();
643
644 if (elements.isEmpty()) {
645 throwValidationException(
646 1001, fileName, commandElement,
647 new String[] {"case", "default"});
648 }
649
650 for (Element element : elements) {
651 List<Element> descriptionElements = element.elements("description");
652
653 String elementName = element.getName();
654
655 if (descriptionElements.size() > 1) {
656 throwValidationException(
657 2000, fileName, descriptionElements.get(1), elementName);
658 }
659
660 List<Element> executeChildElements = element.elements("execute");
661
662 if (executeChildElements.size() > 1) {
663 throwValidationException(
664 2000, fileName, executeChildElements.get(1), elementName);
665 }
666
667 if (elementName.equals("case")) {
668 List<Attribute> attributes = element.attributes();
669
670 boolean hasNeededAttributeName = false;
671
672 for (Attribute attribute : attributes) {
673 String attributeName = attribute.getName();
674
675 if (attributeName.equals("comparator")) {
676 String attributeValue = attribute.getValue();
677
678 if (!attributeValue.equals("contains") &&
679 !attributeValue.equals("endsWith") &&
680 !attributeValue.equals("equals") &&
681 !attributeValue.equals("startsWith")) {
682
683 throwValidationException(
684 1006, fileName, element, attributeName);
685 }
686 }
687 else if (attributeName.equals("locator1") ||
688 attributeName.equals("locator2") ||
689 attributeName.equals("locator-key1") ||
690 attributeName.equals("locator-key2") ||
691 attributeName.equals("value1") ||
692 attributeName.equals("value2")) {
693
694 String attributeValue = attribute.getValue();
695
696 if (Validator.isNull(attributeValue)) {
697 throwValidationException(
698 1006, fileName, element, attributeName);
699 }
700
701 hasNeededAttributeName = true;
702 }
703
704 if (!attributeName.equals("comparator") &&
705 !attributeName.equals("line-number") &&
706 !attributeName.equals("locator1") &&
707 !attributeName.equals("locator2") &&
708 !attributeName.equals("locator-key1") &&
709 !attributeName.equals("locator-key2") &&
710 !attributeName.equals("value1") &&
711 !attributeName.equals("value2")) {
712
713 throwValidationException(
714 1005, fileName, element, attributeName);
715 }
716
717 if (attributeName.equals("locator") ||
718 attributeName.equals("locator-key") ||
719 attributeName.equals("value")) {
720
721 throwValidationException(
722 1005, fileName, element, attributeName);
723 }
724 }
725
726 if (!hasNeededAttributeName) {
727 throwValidationException(
728 1004, fileName, element,
729 new String[] {"locator1", "locator-key1", "value1"});
730 }
731
732 validateBlockElement(
733 fileName, element, new String[] {"execute"},
734 new String[] {"function"}, new String[0], new String[0]);
735 }
736 else if (elementName.equals("default")) {
737 List<Attribute> attributes = element.attributes();
738
739 if (attributes.size() != 1) {
740 Attribute attribute = attributes.get(1);
741
742 String attributeName = attribute.getName();
743
744 throwValidationException(
745 1005, fileName, element, attributeName);
746 }
747
748 validateBlockElement(
749 fileName, element, new String[] {"description", "execute"},
750 new String[] {"function"}, new String[0], new String[0]);
751 }
752 else {
753 throwValidationException(1002, fileName, element, elementName);
754 }
755 }
756 }
757
758 protected void validateActionDocument(
759 String fileName, Element rootElement) {
760
761 if (!Validator.equals(rootElement.getName(), "definition")) {
762 throwValidationException(1000, fileName, rootElement);
763 }
764
765 List<Element> elements = rootElement.elements();
766
767 if (elements.isEmpty()) {
768 throwValidationException(
769 1001, fileName, rootElement, new String[] {"command"});
770 }
771
772 for (Element element : elements) {
773 String elementName = element.getName();
774
775 if (elementName.equals("command")) {
776 String attributeValue = element.attributeValue("name");
777
778 if (attributeValue == null) {
779 throwValidationException(1003, fileName, element, "name");
780 }
781 else if (Validator.isNull(attributeValue)) {
782 throwValidationException(1006, fileName, element, "name");
783 }
784
785 validateActionCommandElement(
786 fileName, element, new String[] {"execute"},
787 new String[] {"function"}, new String[0]);
788 }
789 else {
790 throwValidationException(1002, fileName, element, elementName);
791 }
792 }
793 }
794
795 protected void validateBlockElement(
796 String fileName, Element commandElement,
797 String[] allowedBlockChildElementNames,
798 String[] allowedExecuteAttributeNames,
799 String[] allowedExecuteChildElementNames,
800 String[] allowedIfConditionElementNames) {
801
802 List<Element> elements = commandElement.elements();
803
804 if (elements.isEmpty()) {
805 throwValidationException(
806 1001, fileName, commandElement, allowedBlockChildElementNames);
807 }
808
809 for (Element element : elements) {
810 String elementName = element.getName();
811
812 if (!ArrayUtil.contains(
813 allowedBlockChildElementNames, elementName)) {
814
815 throwValidationException(1002, fileName, element, elementName);
816 }
817
818 if (elementName.equals("description")) {
819 validateSimpleElement(
820 fileName, element, new String[] {"message"});
821
822 String message = element.attributeValue("message");
823
824 if (!message.endsWith(".")) {
825 throwValidationException(
826 1017, fileName, commandElement, message);
827 }
828 }
829 else if (elementName.equals("echo") || elementName.equals("fail")) {
830 validateSimpleElement(
831 fileName, element, new String[] {"message"});
832 }
833 else if (elementName.equals("execute")) {
834 validateExecuteElement(
835 fileName, element, allowedExecuteAttributeNames, ".+",
836 allowedExecuteChildElementNames);
837 }
838 else if (elementName.equals("for")) {
839 validateForElement(
840 fileName, element, new String[] {"list", "param"},
841 allowedBlockChildElementNames, allowedExecuteAttributeNames,
842 allowedExecuteChildElementNames,
843 allowedIfConditionElementNames);
844 }
845 else if (elementName.equals("if") || elementName.equals("while")) {
846 validateIfElement(
847 fileName, element, allowedBlockChildElementNames,
848 allowedExecuteAttributeNames,
849 allowedExecuteChildElementNames,
850 allowedIfConditionElementNames);
851 }
852 else if (elementName.equals("property")) {
853 validatePropertyElement(fileName, element);
854 }
855 else if (elementName.equals("take-screenshot")) {
856 validateSimpleElement(fileName, element, new String[0]);
857 }
858 else if (elementName.equals("var")) {
859 validateVarElement(fileName, element);
860 }
861 else {
862 throwValidationException(1002, fileName, element, elementName);
863 }
864 }
865 }
866
867 protected void validateExecuteElement(
868 String fileName, Element executeElement,
869 String[] allowedExecuteAttributeNames,
870 String allowedExecuteAttributeValuesRegex,
871 String[] allowedExecuteChildElementNames) {
872
873 boolean hasAllowedAttributeName = false;
874
875 List<Attribute> attributes = executeElement.attributes();
876
877 for (Attribute attribute : attributes) {
878 String attributeName = attribute.getName();
879
880 if (ArrayUtil.contains(
881 allowedExecuteAttributeNames, attributeName)) {
882
883 hasAllowedAttributeName = true;
884
885 break;
886 }
887 }
888
889 if (!hasAllowedAttributeName) {
890 throwValidationException(
891 1004, fileName, executeElement, allowedExecuteAttributeNames);
892 }
893
894 String action = executeElement.attributeValue("action");
895 String function = executeElement.attributeValue("function");
896 String macro = executeElement.attributeValue("macro");
897 String selenium = executeElement.attributeValue("selenium");
898 String testCase = executeElement.attributeValue("test-case");
899 String testCaseCommand = executeElement.attributeValue(
900 "test-case-command");
901 String testClass = executeElement.attributeValue("test-class");
902
903 if (action != null) {
904 if (Validator.isNull(action) ||
905 !action.matches(allowedExecuteAttributeValuesRegex)) {
906
907 throwValidationException(
908 1006, fileName, executeElement, "action");
909 }
910
911 for (Attribute attribute : attributes) {
912 String attributeName = attribute.getName();
913
914 if (!attributeName.equals("action") &&
915 !attributeName.equals("line-number") &&
916 !attributeName.equals("locator1") &&
917 !attributeName.equals("locator2") &&
918 !attributeName.equals("locator-key1") &&
919 !attributeName.equals("locator-key2") &&
920 !attributeName.equals("value1") &&
921 !attributeName.equals("value2")) {
922
923 throwValidationException(
924 1005, fileName, executeElement, attributeName);
925 }
926
927 if (attributeName.equals("locator") ||
928 attributeName.equals("locator-key") ||
929 attributeName.equals("value")) {
930
931 throwValidationException(
932 1005, fileName, executeElement, attributeName);
933 }
934
935 String attributeValue = attribute.getValue();
936
937 if (attributeName.equals("value1") &&
938 attributeValue.contains("move-file")) {
939
940 if (!attributeValue.contains("-Dfile") ||
941 !attributeValue.contains("-Dtofile")) {
942
943 throwValidationException(
944 1018, fileName, executeElement,
945 new String[] {"-Dfile", "-Dtofile"}, "value1");
946 }
947 }
948 }
949 }
950 else if (function != null) {
951 if (Validator.isNull(function) ||
952 !function.matches(allowedExecuteAttributeValuesRegex)) {
953
954 throwValidationException(
955 1006, fileName, executeElement, "function");
956 }
957
958 for (Attribute attribute : attributes) {
959 String attributeName = attribute.getName();
960
961 if (!attributeName.equals("function") &&
962 !attributeName.equals("ignore-javascript-error") &&
963 !attributeName.equals("line-number") &&
964 !attributeName.startsWith("locator") &&
965 !attributeName.startsWith("value")) {
966
967 throwValidationException(
968 1005, fileName, executeElement, attributeName);
969 }
970
971 if (attributeName.equals("locator") ||
972 attributeName.equals("value")) {
973
974 throwValidationException(
975 1005, fileName, executeElement, attributeName);
976 }
977 }
978 }
979 else if (macro != null) {
980 if (Validator.isNull(macro) ||
981 !macro.matches(allowedExecuteAttributeValuesRegex)) {
982
983 throwValidationException(
984 1006, fileName, executeElement, "macro");
985 }
986
987 for (Attribute attribute : attributes) {
988 String attributeName = attribute.getName();
989
990 if (!attributeName.equals("macro") &&
991 !attributeName.equals("line-number")) {
992
993 throwValidationException(
994 1005, fileName, executeElement, attributeName);
995 }
996 }
997 }
998 else if (selenium != null) {
999 if (Validator.isNull(selenium) ||
1000 !selenium.matches(allowedExecuteAttributeValuesRegex)) {
1001
1002 throwValidationException(
1003 1006, fileName, executeElement, "selenium");
1004 }
1005
1006 for (Attribute attribute : attributes) {
1007 String attributeName = attribute.getName();
1008
1009 if (!attributeName.equals("argument1") &&
1010 !attributeName.equals("argument2") &&
1011 !attributeName.equals("line-number") &&
1012 !attributeName.equals("selenium")) {
1013
1014 throwValidationException(
1015 1005, fileName, executeElement, attributeName);
1016 }
1017 }
1018 }
1019 else if (testCase != null) {
1020 if (Validator.isNull(testCase) ||
1021 !testCase.matches(allowedExecuteAttributeValuesRegex)) {
1022
1023 throwValidationException(
1024 1006, fileName, executeElement, "test-case");
1025 }
1026
1027 if (testCase.contains("#")) {
1028 int x = testCase.lastIndexOf("#");
1029
1030 if (x == -1) {
1031 throwValidationException(
1032 1015, fileName, executeElement, testCaseCommand);
1033 }
1034
1035 String testCaseName = testCase.substring(0, x);
1036
1037 String testCaseCommandName = testCase.substring(x + 1);
1038
1039 if (Validator.isNull(testCaseCommandName) ||
1040 Validator.isNull(testCaseName) ||
1041 !testCaseName.equals("super")) {
1042
1043 throwValidationException(
1044 1015, fileName, executeElement, testCase);
1045 }
1046 }
1047 else {
1048 throwValidationException(
1049 1015, fileName, executeElement, testCase);
1050 }
1051
1052 for (Attribute attribute : attributes) {
1053 String attributeName = attribute.getName();
1054
1055 if (!attributeName.equals("line-number") &&
1056 !attributeName.equals("test-case")) {
1057
1058 throwValidationException(
1059 1005, fileName, executeElement, attributeName);
1060 }
1061 }
1062 }
1063 else if (testCaseCommand != null) {
1064 if (Validator.isNull(testCaseCommand) ||
1065 !testCaseCommand.matches(allowedExecuteAttributeValuesRegex)) {
1066
1067 throwValidationException(
1068 1006, fileName, executeElement, "test-case-command");
1069 }
1070
1071 if (testCaseCommand.contains("#")) {
1072 int x = testCaseCommand.lastIndexOf("#");
1073
1074 String testCaseName = testCaseCommand.substring(0, x);
1075
1076 String testCaseCommandName = testCaseCommand.substring(x + 1);
1077
1078 if (Validator.isNull(testCaseCommandName) ||
1079 Validator.isNull(testCaseName)) {
1080
1081 throwValidationException(
1082 1015, fileName, executeElement, testCaseCommand);
1083 }
1084 }
1085 else {
1086 throwValidationException(
1087 1015, fileName, executeElement, testCaseCommand);
1088 }
1089
1090 for (Attribute attribute : attributes) {
1091 String attributeName = attribute.getName();
1092
1093 if (!attributeName.equals("line-number") &&
1094 !attributeName.equals("test-case-command")) {
1095
1096 throwValidationException(
1097 1005, fileName, executeElement, attributeName);
1098 }
1099 }
1100 }
1101 else if (testClass != null) {
1102 if (Validator.isNull(testClass) ||
1103 !testClass.matches(allowedExecuteAttributeValuesRegex)) {
1104
1105 throwValidationException(
1106 1006, fileName, executeElement, "test-class");
1107 }
1108
1109 for (Attribute attribute : attributes) {
1110 String attributeName = attribute.getName();
1111
1112 if (!attributeName.equals("line-number") &&
1113 !attributeName.equals("test-class")) {
1114
1115 throwValidationException(
1116 1005, fileName, executeElement, attributeName);
1117 }
1118 }
1119 }
1120 else {
1121 throwValidationException(0, fileName);
1122 }
1123
1124 List<Element> elements = executeElement.elements();
1125
1126 if (allowedExecuteChildElementNames.length == 0) {
1127 if (!elements.isEmpty()) {
1128 Element element = elements.get(0);
1129
1130 String elementName = element.getName();
1131
1132 throwValidationException(1002, fileName, element, elementName);
1133 }
1134 }
1135 else {
1136 String executeElementName = executeElement.getName();
1137
1138 for (Element element : elements) {
1139 String elementName = element.getName();
1140
1141 if (executeElementName.equals("condition")) {
1142 throwValidationException(
1143 1002, fileName, element, elementName);
1144 }
1145
1146 if (elementName.equals("var")) {
1147 validateVarElement(fileName, element);
1148 }
1149 else {
1150 throwValidationException(
1151 1002, fileName, element, elementName);
1152 }
1153 }
1154 }
1155 }
1156
1157 protected void validateForElement(
1158 String fileName, Element forElement, String[] neededAttributes,
1159 String[] allowedBlockChildElementNames,
1160 String[] allowedExecuteAttributeNames,
1161 String[] allowedExecuteChildElementNames,
1162 String[] allowedIfConditionElementNames) {
1163
1164 Map<String, Boolean> hasNeededAttributes =
1165 new HashMap<String, Boolean>();
1166
1167 for (String neededAttribute : neededAttributes) {
1168 hasNeededAttributes.put(neededAttribute, false);
1169 }
1170
1171 List<Attribute> attributes = forElement.attributes();
1172
1173 for (Attribute attribute : attributes) {
1174 String attributeName = attribute.getName();
1175 String attributeValue = attribute.getValue();
1176
1177 if (!_allowedNullAttributes.contains(attributeName) &&
1178 Validator.isNull(attributeValue)) {
1179
1180 throwValidationException(
1181 1006, fileName, forElement, attributeName);
1182 }
1183
1184 if (hasNeededAttributes.containsKey(attributeName)) {
1185 hasNeededAttributes.put(attributeName, true);
1186 }
1187
1188 if (!attributeName.equals("line-number") &&
1189 !hasNeededAttributes.containsKey(attributeName)) {
1190
1191 throwValidationException(
1192 1005, fileName, forElement, attributeName);
1193 }
1194 }
1195
1196 for (String neededAttribute : neededAttributes) {
1197 if (!hasNeededAttributes.get(neededAttribute)) {
1198 throwValidationException(
1199 1004, fileName, forElement, neededAttributes);
1200 }
1201 }
1202
1203 validateBlockElement(
1204 fileName, forElement, allowedBlockChildElementNames,
1205 allowedExecuteAttributeNames, allowedExecuteChildElementNames,
1206 allowedIfConditionElementNames);
1207 }
1208
1209 protected void validateFunctionDocument(
1210 String fileName, Element rootElement) {
1211
1212 if (!Validator.equals(rootElement.getName(), "definition")) {
1213 throwValidationException(1000, fileName, rootElement);
1214 }
1215
1216 List<Element> elements = rootElement.elements();
1217
1218 if (elements.isEmpty()) {
1219 throwValidationException(
1220 1001, fileName, rootElement, new String[] {"command"});
1221 }
1222
1223 for (Element element : elements) {
1224 String elementName = element.getName();
1225
1226 if (elementName.equals("command")) {
1227 String attributeValue = element.attributeValue("name");
1228
1229 if (attributeValue == null) {
1230 throwValidationException(1003, fileName, element, "name");
1231 }
1232 else if (Validator.isNull(attributeValue)) {
1233 throwValidationException(1006, fileName, element, "name");
1234 }
1235
1236 validateBlockElement(
1237 fileName, element, new String[] {"execute", "if"},
1238 new String[] {"function", "selenium"}, new String[0],
1239 new String[] {"condition"});
1240 }
1241 else {
1242 throwValidationException(1002, fileName, element, elementName);
1243 }
1244 }
1245 }
1246
1247 protected void validateIfElement(
1248 String fileName, Element ifElement,
1249 String[] allowedBlockChildElementNames,
1250 String[] allowedExecuteAttributeNames,
1251 String[] allowedExecuteChildElementNames,
1252 String[] allowedIfConditionElementNames) {
1253
1254 List<Element> elements = ifElement.elements();
1255
1256 Set<String> elementNames = new HashSet<String>();
1257
1258 boolean hasAllowedIfConditionElementNames = false;
1259
1260 for (Element element : elements) {
1261 String elementName = element.getName();
1262
1263 elementNames.add(elementName);
1264
1265 if (ArrayUtil.contains(
1266 allowedIfConditionElementNames, elementName)) {
1267
1268 hasAllowedIfConditionElementNames = true;
1269 }
1270
1271 String ifElementName = ifElement.getName();
1272
1273 if (elementName.equals("and") || elementName.equals("not") ||
1274 elementName.equals("or")) {
1275
1276 validateIfElement(
1277 fileName, element, allowedBlockChildElementNames,
1278 allowedExecuteAttributeNames,
1279 allowedExecuteChildElementNames,
1280 allowedIfConditionElementNames);
1281 }
1282 else if (elementName.equals("condition")) {
1283 validateExecuteElement(
1284 fileName, element, allowedExecuteAttributeNames,
1285 ".*(is|Is).+", allowedExecuteChildElementNames);
1286 }
1287 else if (elementName.equals("contains")) {
1288 validateSimpleElement(
1289 fileName, element, new String[] {"string", "substring"});
1290 }
1291 else if (elementName.equals("else")) {
1292 if (ifElementName.equals("while")) {
1293 throwValidationException(
1294 1002, fileName, element, elementName);
1295 }
1296
1297 validateBlockElement(
1298 fileName, element, allowedBlockChildElementNames,
1299 allowedExecuteAttributeNames,
1300 allowedExecuteChildElementNames,
1301 allowedIfConditionElementNames);
1302 }
1303 else if (elementName.equals("elseif")) {
1304 if (ifElementName.equals("while")) {
1305 throwValidationException(
1306 1002, fileName, element, elementName);
1307 }
1308
1309 validateIfElement(
1310 fileName, element, allowedBlockChildElementNames,
1311 allowedExecuteAttributeNames,
1312 allowedExecuteChildElementNames,
1313 allowedIfConditionElementNames);
1314 }
1315 else if (elementName.equals("equals")) {
1316 validateSimpleElement(
1317 fileName, element, new String[] {"arg1", "arg2"});
1318 }
1319 else if (elementName.equals("isset")) {
1320 validateSimpleElement(fileName, element, new String[] {"var"});
1321 }
1322 else if (elementName.equals("then")) {
1323 validateBlockElement(
1324 fileName, element, allowedBlockChildElementNames,
1325 allowedExecuteAttributeNames,
1326 allowedExecuteChildElementNames,
1327 allowedIfConditionElementNames);
1328 }
1329 else {
1330 throwValidationException(1002, fileName, element, elementName);
1331 }
1332 }
1333
1334 if (!hasAllowedIfConditionElementNames) {
1335 throwValidationException(
1336 1001, fileName, ifElement, allowedIfConditionElementNames);
1337 }
1338
1339 if (Validator.equals(ifElement.getName(), "and") ||
1340 Validator.equals(ifElement.getName(), "not") ||
1341 Validator.equals(ifElement.getName(), "or")) {
1342
1343 return;
1344 }
1345
1346 if (!elementNames.contains("then")) {
1347 throwValidationException(
1348 1001, fileName, ifElement, new String[] {"then"});
1349 }
1350 }
1351
1352 protected void validateMacroDocument(String fileName, Element rootElement) {
1353 if (!Validator.equals(rootElement.getName(), "definition")) {
1354 throwValidationException(1000, fileName, rootElement);
1355 }
1356
1357 List<Element> elements = rootElement.elements();
1358
1359 String extendsName = rootElement.attributeValue("extends");
1360
1361 if (elements.isEmpty() && (extendsName == null)) {
1362 throwValidationException(
1363 1001, fileName, rootElement, new String[] {"command", "var"});
1364 }
1365 else if (extendsName != null) {
1366 if (Validator.isNull(extendsName)) {
1367 throwValidationException(
1368 1006, fileName, rootElement, "extends");
1369 }
1370 }
1371
1372 for (Element element : elements) {
1373 String elementName = element.getName();
1374
1375 if (elementName.equals("command")) {
1376 String attributeValue = element.attributeValue("name");
1377
1378 if (attributeValue == null) {
1379 throwValidationException(1003, fileName, element, "name");
1380 }
1381 else if (Validator.isNull(attributeValue)) {
1382 throwValidationException(1006, fileName, element, "name");
1383 }
1384
1385 validateBlockElement(
1386 fileName, element,
1387 new String[] {
1388 "description", "echo", "execute", "fail", "for", "if",
1389 "take-screenshot", "var", "while",
1390 },
1391 new String[] {"action", "macro"}, new String[] {"var"},
1392 new String[] {
1393 "and", "condition", "contains", "equals", "isset",
1394 "not", "or"
1395 });
1396 }
1397 else if (elementName.equals("var")) {
1398 validateVarElement(fileName, element);
1399 }
1400 else {
1401 throwValidationException(1002, fileName, element, elementName);
1402 }
1403 }
1404 }
1405
1406 protected void validatePathDocument(String fileName, Element rootElement) {
1407 Element headElement = rootElement.element("head");
1408
1409 Element titleElement = headElement.element("title");
1410
1411 String title = titleElement.getText();
1412
1413 int x = fileName.lastIndexOf(StringPool.SLASH);
1414 int y = fileName.lastIndexOf(CharPool.PERIOD);
1415
1416 String shortFileName = fileName.substring(x + 1, y);
1417
1418 if ((title == null) || !shortFileName.equals(title)) {
1419 throwValidationException(0, fileName);
1420 }
1421
1422 Element bodyElement = rootElement.element("body");
1423
1424 Element tableElement = bodyElement.element("table");
1425
1426 Element theadElement = tableElement.element("thead");
1427
1428 Element trElement = theadElement.element("tr");
1429
1430 Element tdElement = trElement.element("td");
1431
1432 String tdText = tdElement.getText();
1433
1434 if ((tdText == null) || !shortFileName.equals(tdText)) {
1435 throwValidationException(0, fileName);
1436 }
1437
1438 Element tbodyElement = tableElement.element("tbody");
1439
1440 List<Element> elements = tbodyElement.elements();
1441
1442 for (Element element : elements) {
1443 String elementName = element.getName();
1444
1445 if (elementName.equals("tr")) {
1446 validatePathTrElement(fileName, element);
1447 }
1448 else {
1449 throwValidationException(1002, fileName, element, elementName);
1450 }
1451 }
1452 }
1453
1454 protected void validatePathTrElement(String fileName, Element trElement) {
1455 List<Element> elements = trElement.elements();
1456
1457 for (Element element : elements) {
1458 String elementName = element.getName();
1459
1460 if (!elementName.equals("td")) {
1461 throwValidationException(1002, fileName, element, elementName);
1462 }
1463 }
1464
1465 if (elements.size() < 3) {
1466 throwValidationException(
1467 1001, fileName, trElement, new String[] {"td"});
1468 }
1469
1470 if (elements.size() > 3) {
1471 Element element = elements.get(3);
1472
1473 String elementName = element.getName();
1474
1475 throwValidationException(1002, fileName, element, elementName);
1476 }
1477
1478 Element locatorElement = elements.get(1);
1479
1480 String locator = locatorElement.getText();
1481
1482 locator = locator.replace("${","");
1483 locator = locator.replace("}","");
1484 locator = locator.replace("/-/","/");
1485
1486 if (locator.endsWith("/")) {
1487 locator = locator.substring(0, locator.length() - 1);
1488 }
1489
1490 if (!locator.equals("") && !locator.startsWith("link=") &&
1491 !locator.startsWith("title=") && !locator.contains(".png")) {
1492
1493 try {
1494 XPathFactory xPathFactory = XPathFactory.newInstance();
1495
1496 XPath xPath = xPathFactory.newXPath();
1497
1498 xPath.compile(locator);
1499 }
1500 catch (Exception e) {
1501 throwValidationException(2003, fileName, locator);
1502 }
1503 }
1504
1505 Element keyElement = elements.get(0);
1506
1507 String key = keyElement.getText();
1508
1509 Element descriptionElement = elements.get(2);
1510
1511 String description = descriptionElement.getText();
1512
1513 if (!key.equals("") && !key.equals("EXTEND_ACTION_PATH") &&
1514 !key.equals("PAGE_NAME") && !description.equals("")) {
1515
1516 if (description.endsWith(".")) {
1517 throwValidationException(2004, fileName, description);
1518 }
1519
1520 Matcher statmentMatcher = _pathTrElementStatementPattern.matcher(
1521 description);
1522
1523 if (!statmentMatcher.find()) {
1524 throwValidationException(2004, fileName, description);
1525 }
1526
1527 Matcher wordMatcher1 = _pathTrElementWordPattern1.matcher(
1528 description);
1529
1530 while (wordMatcher1.find()) {
1531 String word = wordMatcher1.group();
1532
1533 if (word.equals("a") || word.equals("and") ||
1534 word.equals("as") || word.equals("at") ||
1535 word.equals("by") || word.equals("for") ||
1536 word.equals("from") || word.equals("in") ||
1537 word.equals("of") || word.equals("the") ||
1538 word.equals("to")) {
1539
1540 continue;
1541 }
1542
1543 Matcher wordMatcher2 = _pathTrElementWordPattern2.matcher(word);
1544
1545 if (!wordMatcher2.find()) {
1546 throwValidationException(2004, fileName, description);
1547 }
1548 }
1549 }
1550 }
1551
1552 protected void validatePropertyElement(
1553 String fileName, Element propertyElement) {
1554
1555 List<Attribute> attributes = propertyElement.attributes();
1556
1557 String propertyName = propertyElement.attributeValue("name");
1558
1559 if (!_testcaseAvailablePropertyNames.contains(propertyName)) {
1560 throwValidationException(
1561 3003, fileName, propertyElement, propertyName);
1562 }
1563
1564 if (propertyName.equals("ignore.errors")) {
1565 String propertyDelimiter = propertyElement.attributeValue(
1566 "delimiter");
1567
1568 String propertyValue = propertyElement.attributeValue("value");
1569
1570 if (propertyDelimiter != null) {
1571 if (!propertyValue.contains(propertyDelimiter)) {
1572 throwValidationException(
1573 1006, fileName, propertyElement, "delimiter");
1574 }
1575 }
1576
1577 if (Validator.isNull(propertyValue)) {
1578 throwValidationException(
1579 1006, fileName, propertyElement, "value");
1580 }
1581 }
1582
1583 for (Attribute attribute : attributes) {
1584 String attributeName = attribute.getName();
1585
1586 if (attributeName.equals("delimiter") &&
1587 propertyName.equals("ignore.errors")) {
1588
1589 continue;
1590 }
1591 else if (attributeName.equals("line-number") ||
1592 attributeName.equals("name") ||
1593 attributeName.equals("value")) {
1594
1595 continue;
1596 }
1597 else {
1598 throwValidationException(
1599 1005, fileName, propertyElement, attributeName);
1600 }
1601 }
1602 }
1603
1604 protected void validateSimpleElement(
1605 String fileName, Element element, String[] neededAttributes) {
1606
1607 Map<String, Boolean> hasNeededAttributes =
1608 new HashMap<String, Boolean>();
1609
1610 for (String neededAttribute : neededAttributes) {
1611 hasNeededAttributes.put(neededAttribute, false);
1612 }
1613
1614 List<Attribute> attributes = element.attributes();
1615
1616 for (Attribute attribute : attributes) {
1617 String attributeName = attribute.getName();
1618 String attributeValue = attribute.getValue();
1619
1620 if (!_allowedNullAttributes.contains(attributeName) &&
1621 Validator.isNull(attributeValue)) {
1622
1623 throwValidationException(
1624 1006, fileName, element, attributeName);
1625 }
1626
1627 if (hasNeededAttributes.containsKey(attributeName)) {
1628 hasNeededAttributes.put(attributeName, true);
1629 }
1630
1631 if (!attributeName.equals("line-number") &&
1632 !hasNeededAttributes.containsKey(attributeName)) {
1633
1634 throwValidationException(
1635 1005, fileName, element, attributeName);
1636 }
1637 }
1638
1639 for (String neededAttribute : neededAttributes) {
1640 if (!hasNeededAttributes.get(neededAttribute)) {
1641 throwValidationException(
1642 1004, fileName, element, neededAttributes);
1643 }
1644 }
1645
1646 List<Element> childElements = element.elements();
1647
1648 if (!childElements.isEmpty()) {
1649 Element childElement = childElements.get(0);
1650
1651 String childElementName = childElement.getName();
1652
1653 throwValidationException(
1654 1002, fileName, childElement, childElementName);
1655 }
1656 }
1657
1658 protected void validateTestCaseDocument(
1659 String fileName, Element rootElement) {
1660
1661 if (!Validator.equals(rootElement.getName(), "definition")) {
1662 throwValidationException(1000, fileName, rootElement);
1663 }
1664
1665 String extendedTestCase = rootElement.attributeValue("extends");
1666
1667 if (extendedTestCase != null) {
1668 if (Validator.isNull(extendedTestCase)) {
1669 throwValidationException(
1670 1006, fileName, rootElement, "extends");
1671 }
1672 }
1673
1674 String componentName = rootElement.attributeValue("component-name");
1675
1676 if (componentName == null) {
1677 throwValidationException(
1678 1003, fileName, rootElement, "component-name");
1679 }
1680
1681 if ((componentName != null) &&
1682 !_componentNames.contains(componentName)) {
1683
1684 throwValidationException(
1685 1006, fileName, rootElement, "component-name");
1686 }
1687
1688 List<Element> elements = rootElement.elements();
1689
1690 if (Validator.isNull(extendedTestCase)) {
1691 if (elements.isEmpty()) {
1692 throwValidationException(
1693 1001, fileName, rootElement, new String[] {"command"});
1694 }
1695 }
1696
1697 for (Element element : elements) {
1698 String elementName = element.getName();
1699
1700 if (elementName.equals("command")) {
1701 String attributeValue = element.attributeValue("name");
1702
1703 if (attributeValue == null) {
1704 throwValidationException(1003, fileName, element, "name");
1705 }
1706 else if (Validator.isNull(attributeValue)) {
1707 throwValidationException(1006, fileName, element, "name");
1708 }
1709
1710 String priorityValue = element.attributeValue("priority");
1711
1712 if (priorityValue == null) {
1713 throwValidationException(
1714 1003, fileName, element, "priority");
1715 }
1716 else if (!(priorityValue.equals("1") ||
1717 priorityValue.equals("2") ||
1718 priorityValue.equals("3") ||
1719 priorityValue.equals("4") ||
1720 priorityValue.equals("5"))) {
1721
1722 throwValidationException(
1723 1006, fileName, element, "priority");
1724 }
1725
1726 validateBlockElement(
1727 fileName, element,
1728 new String[] {
1729 "description", "echo", "execute", "fail", "for", "if",
1730 "property", "take-screenshot", "var", "while"
1731 },
1732 new String[] {"action", "macro", "test-case"},
1733 new String[] {"var"},
1734 new String[] {
1735 "and", "condition", "contains", "equals", "isset",
1736 "not", "or"
1737 });
1738 }
1739 else if (elementName.equals("property")) {
1740 validatePropertyElement(fileName, element);
1741 }
1742 else if (elementName.equals("set-up") ||
1743 elementName.equals("tear-down")) {
1744
1745 List<Attribute> attributes = element.attributes();
1746
1747 for (Attribute attribute : attributes) {
1748 String attributeName = attribute.getName();
1749
1750 if (!attributeName.equals("line-number")) {
1751 throwValidationException(
1752 1005, fileName, element, attributeName);
1753 }
1754 }
1755
1756 validateBlockElement(
1757 fileName, element,
1758 new String[] {
1759 "description", "echo", "execute", "fail", "if",
1760 "take-screenshot", "var", "while"
1761 },
1762 new String[] {"action", "macro", "test-case"},
1763 new String[] {"var"},
1764 new String[] {
1765 "and", "condition", "contains", "equals", "isset",
1766 "not", "or"
1767 });
1768 }
1769 else if (elementName.equals("var")) {
1770 validateVarElement(fileName, element);
1771 }
1772 else {
1773 throwValidationException(1002, fileName, element, elementName);
1774 }
1775 }
1776
1777 elements = getAllChildElements(rootElement, "property");
1778
1779 for (Element element : elements) {
1780 String name = element.attributeValue("name");
1781 String value = element.attributeValue("value");
1782
1783 if (name.equals("testray.component.names")) {
1784 List<String> testrayComponentNames = ListUtil.fromArray(
1785 StringUtil.split(value));
1786
1787 for (String testrayComponentName : testrayComponentNames) {
1788 if (!_testrayAvailableComponentNames.contains(
1789 testrayComponentName)) {
1790
1791 throwValidationException(
1792 3001, fileName, element, name,
1793 testrayComponentName);
1794 }
1795 }
1796 }
1797 else if (name.equals("testray.main.component.name")) {
1798 if (!_testrayAvailableComponentNames.contains(value)) {
1799 throwValidationException(
1800 3001, fileName, element, name, value);
1801 }
1802 }
1803 }
1804
1805 elements = rootElement.elements("property");
1806
1807 boolean rootTestrayMainComponentNameFound = false;
1808
1809 for (Element element : elements) {
1810 String name = element.attributeValue("name");
1811
1812 if (name.equals("testray.main.component.name")) {
1813 rootTestrayMainComponentNameFound = true;
1814
1815 break;
1816 }
1817 }
1818
1819 if (!rootTestrayMainComponentNameFound) {
1820 elements = rootElement.elements("command");
1821
1822 for (Element element : elements) {
1823 List<Element> propertyElements = getAllChildElements(
1824 element, "property");
1825
1826 boolean commandTestrayMainComponentNameFound = false;
1827
1828 for (Element propertyElement : propertyElements) {
1829 String propertyName = propertyElement.attributeValue(
1830 "name");
1831
1832 if (propertyName.equals("testray.main.component.name")) {
1833 commandTestrayMainComponentNameFound = true;
1834
1835 break;
1836 }
1837 }
1838
1839 if (!commandTestrayMainComponentNameFound) {
1840 throwValidationException(
1841 3002, fileName, element, "testray.main.component.name");
1842 }
1843 }
1844 }
1845 }
1846
1847 protected void validateVarElement(String fileName, Element element) {
1848 List<Attribute> attributes = element.attributes();
1849
1850 Map<String, String> attributeMap = new HashMap<String, String>();
1851
1852 for (Attribute attribute : attributes) {
1853 String attributeName = attribute.getName();
1854 String attributeValue = attribute.getValue();
1855
1856 if (!attributeName.equals("value") &&
1857 Validator.isNull(attributeValue)) {
1858
1859 throwValidationException(
1860 1006, fileName, element, attributeName);
1861 }
1862
1863 if (!_allowedVarAttributes.contains(attributeName)) {
1864 throwValidationException(
1865 1005, fileName, element, attributeName);
1866 }
1867
1868 attributeMap.put(attributeName, attributeValue);
1869 }
1870
1871 if (!attributeMap.containsKey("name")) {
1872 throwValidationException(
1873 1004, fileName, element, new String[] {"name"});
1874 }
1875 else {
1876 String nameValue = attributeMap.get("name");
1877
1878 if (Validator.isNull(nameValue)) {
1879 throwValidationException(1006, fileName, element, "name");
1880 }
1881 }
1882
1883 if (attributeMap.containsKey("locator")) {
1884 String[] disallowedAttributes = {"locator-key", "path", "value"};
1885
1886 for (String disallowedAttribute : disallowedAttributes) {
1887 if (attributeMap.containsKey(disallowedAttribute)) {
1888 throwValidationException(
1889 1005, fileName, element, disallowedAttribute);
1890 }
1891 }
1892 }
1893 else if (attributeMap.containsKey("locator-key") &&
1894 attributeMap.containsKey("path")) {
1895
1896 if (attributeMap.containsKey("value")) {
1897 throwValidationException(1005, fileName, element, "value");
1898 }
1899 }
1900 else if (attributeMap.containsKey("locator-key")) {
1901 throwValidationException(
1902 1004, fileName, element, new String [] {"path"});
1903 }
1904 else if (attributeMap.containsKey("path")) {
1905 throwValidationException(
1906 1004, fileName, element, new String [] {"locator-key"});
1907 }
1908
1909 String varText = element.getText();
1910
1911 if (attributeMap.containsKey("locator") ||
1912 attributeMap.containsKey("locator-key") ||
1913 attributeMap.containsKey("path")) {
1914
1915 if (!Validator.isNull(varText)) {
1916 throwValidationException(1005, fileName, element, "value");
1917 }
1918 }
1919
1920 if (attributeMap.containsKey("method")) {
1921 String methodValue = attributeMap.get("method");
1922
1923 if (!methodValue.startsWith("MathUtil") &&
1924 !methodValue.startsWith("selenium") &&
1925 !methodValue.startsWith("StringUtil")) {
1926
1927 throwValidationException(1005, fileName, element, "method");
1928 }
1929
1930 if (!methodValue.contains("#")) {
1931 throwValidationException(1005, fileName, element, "method");
1932 }
1933 }
1934
1935 if (!attributeMap.containsKey("property-value") &&
1936 !attributeMap.containsKey("value") && Validator.isNull(varText)) {
1937
1938 if (!attributeMap.containsKey("group") &&
1939 !attributeMap.containsKey("input") &&
1940 !attributeMap.containsKey("locator") &&
1941 !attributeMap.containsKey("locator-key") &&
1942 !attributeMap.containsKey("method") &&
1943 !attributeMap.containsKey("path") &&
1944 !attributeMap.containsKey("pattern")) {
1945
1946 throwValidationException(
1947 1004, fileName, element, new String [] {"value"});
1948 }
1949 }
1950 else {
1951 String varValue = attributeMap.get("value");
1952
1953 if (Validator.isNull(varValue)) {
1954 varValue = varText;
1955 }
1956
1957 Matcher matcher = _varElementPattern.matcher(varValue);
1958
1959 while (matcher.find()) {
1960 String statement = matcher.group(1);
1961
1962 Matcher statementMatcher = _varElementStatementPattern.matcher(
1963 statement);
1964
1965 if (statementMatcher.find()) {
1966 String operand = statementMatcher.group(1);
1967
1968 String method = statementMatcher.group(2);
1969
1970 if (operand.equals("") || method.equals("")) {
1971 throwValidationException(
1972 1006, fileName, element, "value");
1973 }
1974
1975 if (!_methodNames.contains(method)) {
1976 throwValidationException(
1977 1013, fileName, element, method);
1978 }
1979 }
1980 }
1981 }
1982
1983 List<Element> childElements = element.elements();
1984
1985 if (!childElements.isEmpty()) {
1986 Element childElement = childElements.get(0);
1987
1988 String childElementName = childElement.getName();
1989
1990 throwValidationException(
1991 1002, fileName, childElement, childElementName);
1992 }
1993 }
1994
1995 private static final String _TPL_ROOT =
1996 "com/liferay/portal/tools/seleniumbuilder/dependencies/";
1997
1998 private static List<String> _allowedNullAttributes = ListUtil.fromArray(
1999 new String[] {
2000 "arg1", "arg2", "delimiter", "message", "string", "substring",
2001 "value"
2002 });
2003 private static List<String> _allowedVarAttributes = ListUtil.fromArray(
2004 new String[] {
2005 "attribute", "group", "input", "line-number", "locator",
2006 "locator-key", "method", "name", "path", "pattern",
2007 "property-value", "value"
2008 });
2009 private static List<String> _componentNames;
2010 private static List<String> _methodNames = ListUtil.fromArray(
2011 new String[] {
2012 "getFirstNumber", "getIPAddress", "increment", "length",
2013 "lowercase", "replace", "uppercase"
2014 });
2015 private static List<String> _reservedTags = ListUtil.fromArray(
2016 new String[] {
2017 "and", "case", "command", "condition", "contains", "default",
2018 "definition", "delimiter", "description", "echo", "else", "elseif",
2019 "equals", "execute", "fail", "for", "if", "isset", "not", "or",
2020 "property", "set-up", "take-screenshot", "td", "tear-down", "then",
2021 "tr", "while", "var"
2022 });
2023 private static List<String> _testcaseAvailablePropertyNames;
2024 private static List<String> _testrayAvailableComponentNames;
2025
2026 private String _baseDirName;
2027 private Pattern _pathTrElementStatementPattern = Pattern.compile(
2028 "[A-Z0-9].*");
2029 private Pattern _pathTrElementWordPattern1 = Pattern.compile(
2030 "[A-Za-z0-9\\-]+");
2031 private Pattern _pathTrElementWordPattern2 = Pattern.compile(
2032 "[A-Z0-9][A-Za-z0-9\\-]*");
2033 private Pattern _tagPattern = Pattern.compile("<[a-z\\-]+");
2034 private Pattern _varElementPattern = Pattern.compile("\\$\\{([^\\}]*?)\\}");
2035 private Pattern _varElementStatementPattern = Pattern.compile(
2036 "(.*)\\?(.*)\\(([^\\)]*?)\\)");
2037
2038 }