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 if (attributeName.equals("value1") &&
950 attributeValue.contains("replace-file")) {
951
952 if (!attributeValue.contains("-Dfile") ||
953 !attributeValue.contains("-Dtoken") ||
954 !attributeValue.contains("-Dvalue")) {
955
956 throwValidationException(
957 1018, fileName, executeElement,
958 new String[] {"-Dfile", "-Dtoken", "-Dvalue"},
959 "value1");
960 }
961 }
962 }
963 }
964 else if (function != null) {
965 if (Validator.isNull(function) ||
966 !function.matches(allowedExecuteAttributeValuesRegex)) {
967
968 throwValidationException(
969 1006, fileName, executeElement, "function");
970 }
971
972 for (Attribute attribute : attributes) {
973 String attributeName = attribute.getName();
974
975 if (!attributeName.equals("function") &&
976 !attributeName.equals("ignore-javascript-error") &&
977 !attributeName.equals("line-number") &&
978 !attributeName.startsWith("locator") &&
979 !attributeName.startsWith("value")) {
980
981 throwValidationException(
982 1005, fileName, executeElement, attributeName);
983 }
984
985 if (attributeName.equals("locator") ||
986 attributeName.equals("value")) {
987
988 throwValidationException(
989 1005, fileName, executeElement, attributeName);
990 }
991 }
992 }
993 else if (macro != null) {
994 if (Validator.isNull(macro) ||
995 !macro.matches(allowedExecuteAttributeValuesRegex)) {
996
997 throwValidationException(
998 1006, fileName, executeElement, "macro");
999 }
1000
1001 for (Attribute attribute : attributes) {
1002 String attributeName = attribute.getName();
1003
1004 if (!attributeName.equals("macro") &&
1005 !attributeName.equals("line-number")) {
1006
1007 throwValidationException(
1008 1005, fileName, executeElement, attributeName);
1009 }
1010 }
1011 }
1012 else if (selenium != null) {
1013 if (Validator.isNull(selenium) ||
1014 !selenium.matches(allowedExecuteAttributeValuesRegex)) {
1015
1016 throwValidationException(
1017 1006, fileName, executeElement, "selenium");
1018 }
1019
1020 for (Attribute attribute : attributes) {
1021 String attributeName = attribute.getName();
1022
1023 if (!attributeName.equals("argument1") &&
1024 !attributeName.equals("argument2") &&
1025 !attributeName.equals("line-number") &&
1026 !attributeName.equals("selenium")) {
1027
1028 throwValidationException(
1029 1005, fileName, executeElement, attributeName);
1030 }
1031 }
1032 }
1033 else if (testCase != null) {
1034 if (Validator.isNull(testCase) ||
1035 !testCase.matches(allowedExecuteAttributeValuesRegex)) {
1036
1037 throwValidationException(
1038 1006, fileName, executeElement, "test-case");
1039 }
1040
1041 if (testCase.contains("#")) {
1042 int x = testCase.lastIndexOf("#");
1043
1044 if (x == -1) {
1045 throwValidationException(
1046 1015, fileName, executeElement, testCaseCommand);
1047 }
1048
1049 String testCaseName = testCase.substring(0, x);
1050
1051 String testCaseCommandName = testCase.substring(x + 1);
1052
1053 if (Validator.isNull(testCaseCommandName) ||
1054 Validator.isNull(testCaseName) ||
1055 !testCaseName.equals("super")) {
1056
1057 throwValidationException(
1058 1015, fileName, executeElement, testCase);
1059 }
1060 }
1061 else {
1062 throwValidationException(
1063 1015, fileName, executeElement, testCase);
1064 }
1065
1066 for (Attribute attribute : attributes) {
1067 String attributeName = attribute.getName();
1068
1069 if (!attributeName.equals("line-number") &&
1070 !attributeName.equals("test-case")) {
1071
1072 throwValidationException(
1073 1005, fileName, executeElement, attributeName);
1074 }
1075 }
1076 }
1077 else if (testCaseCommand != null) {
1078 if (Validator.isNull(testCaseCommand) ||
1079 !testCaseCommand.matches(allowedExecuteAttributeValuesRegex)) {
1080
1081 throwValidationException(
1082 1006, fileName, executeElement, "test-case-command");
1083 }
1084
1085 if (testCaseCommand.contains("#")) {
1086 int x = testCaseCommand.lastIndexOf("#");
1087
1088 String testCaseName = testCaseCommand.substring(0, x);
1089
1090 String testCaseCommandName = testCaseCommand.substring(x + 1);
1091
1092 if (Validator.isNull(testCaseCommandName) ||
1093 Validator.isNull(testCaseName)) {
1094
1095 throwValidationException(
1096 1015, fileName, executeElement, testCaseCommand);
1097 }
1098 }
1099 else {
1100 throwValidationException(
1101 1015, fileName, executeElement, testCaseCommand);
1102 }
1103
1104 for (Attribute attribute : attributes) {
1105 String attributeName = attribute.getName();
1106
1107 if (!attributeName.equals("line-number") &&
1108 !attributeName.equals("test-case-command")) {
1109
1110 throwValidationException(
1111 1005, fileName, executeElement, attributeName);
1112 }
1113 }
1114 }
1115 else if (testClass != null) {
1116 if (Validator.isNull(testClass) ||
1117 !testClass.matches(allowedExecuteAttributeValuesRegex)) {
1118
1119 throwValidationException(
1120 1006, fileName, executeElement, "test-class");
1121 }
1122
1123 for (Attribute attribute : attributes) {
1124 String attributeName = attribute.getName();
1125
1126 if (!attributeName.equals("line-number") &&
1127 !attributeName.equals("test-class")) {
1128
1129 throwValidationException(
1130 1005, fileName, executeElement, attributeName);
1131 }
1132 }
1133 }
1134 else {
1135 throwValidationException(0, fileName);
1136 }
1137
1138 List<Element> elements = executeElement.elements();
1139
1140 if (allowedExecuteChildElementNames.length == 0) {
1141 if (!elements.isEmpty()) {
1142 Element element = elements.get(0);
1143
1144 String elementName = element.getName();
1145
1146 throwValidationException(1002, fileName, element, elementName);
1147 }
1148 }
1149 else {
1150 String executeElementName = executeElement.getName();
1151
1152 for (Element element : elements) {
1153 String elementName = element.getName();
1154
1155 if (executeElementName.equals("condition")) {
1156 throwValidationException(
1157 1002, fileName, element, elementName);
1158 }
1159
1160 if (elementName.equals("var")) {
1161 validateVarElement(fileName, element);
1162 }
1163 else {
1164 throwValidationException(
1165 1002, fileName, element, elementName);
1166 }
1167 }
1168 }
1169 }
1170
1171 protected void validateForElement(
1172 String fileName, Element forElement, String[] neededAttributes,
1173 String[] allowedBlockChildElementNames,
1174 String[] allowedExecuteAttributeNames,
1175 String[] allowedExecuteChildElementNames,
1176 String[] allowedIfConditionElementNames) {
1177
1178 Map<String, Boolean> hasNeededAttributes =
1179 new HashMap<String, Boolean>();
1180
1181 for (String neededAttribute : neededAttributes) {
1182 hasNeededAttributes.put(neededAttribute, false);
1183 }
1184
1185 List<Attribute> attributes = forElement.attributes();
1186
1187 for (Attribute attribute : attributes) {
1188 String attributeName = attribute.getName();
1189 String attributeValue = attribute.getValue();
1190
1191 if (!_allowedNullAttributes.contains(attributeName) &&
1192 Validator.isNull(attributeValue)) {
1193
1194 throwValidationException(
1195 1006, fileName, forElement, attributeName);
1196 }
1197
1198 if (hasNeededAttributes.containsKey(attributeName)) {
1199 hasNeededAttributes.put(attributeName, true);
1200 }
1201
1202 if (!attributeName.equals("line-number") &&
1203 !hasNeededAttributes.containsKey(attributeName)) {
1204
1205 throwValidationException(
1206 1005, fileName, forElement, attributeName);
1207 }
1208 }
1209
1210 for (String neededAttribute : neededAttributes) {
1211 if (!hasNeededAttributes.get(neededAttribute)) {
1212 throwValidationException(
1213 1004, fileName, forElement, neededAttributes);
1214 }
1215 }
1216
1217 validateBlockElement(
1218 fileName, forElement, allowedBlockChildElementNames,
1219 allowedExecuteAttributeNames, allowedExecuteChildElementNames,
1220 allowedIfConditionElementNames);
1221 }
1222
1223 protected void validateFunctionDocument(
1224 String fileName, Element rootElement) {
1225
1226 if (!Validator.equals(rootElement.getName(), "definition")) {
1227 throwValidationException(1000, fileName, rootElement);
1228 }
1229
1230 List<Element> elements = rootElement.elements();
1231
1232 if (elements.isEmpty()) {
1233 throwValidationException(
1234 1001, fileName, rootElement, new String[] {"command"});
1235 }
1236
1237 for (Element element : elements) {
1238 String elementName = element.getName();
1239
1240 if (elementName.equals("command")) {
1241 String attributeValue = element.attributeValue("name");
1242
1243 if (attributeValue == null) {
1244 throwValidationException(1003, fileName, element, "name");
1245 }
1246 else if (Validator.isNull(attributeValue)) {
1247 throwValidationException(1006, fileName, element, "name");
1248 }
1249
1250 validateBlockElement(
1251 fileName, element, new String[] {"execute", "if"},
1252 new String[] {"function", "selenium"}, new String[0],
1253 new String[] {"condition"});
1254 }
1255 else {
1256 throwValidationException(1002, fileName, element, elementName);
1257 }
1258 }
1259 }
1260
1261 protected void validateIfElement(
1262 String fileName, Element ifElement,
1263 String[] allowedBlockChildElementNames,
1264 String[] allowedExecuteAttributeNames,
1265 String[] allowedExecuteChildElementNames,
1266 String[] allowedIfConditionElementNames) {
1267
1268 List<Element> elements = ifElement.elements();
1269
1270 Set<String> elementNames = new HashSet<String>();
1271
1272 boolean hasAllowedIfConditionElementNames = false;
1273
1274 for (Element element : elements) {
1275 String elementName = element.getName();
1276
1277 elementNames.add(elementName);
1278
1279 if (ArrayUtil.contains(
1280 allowedIfConditionElementNames, elementName)) {
1281
1282 hasAllowedIfConditionElementNames = true;
1283 }
1284
1285 String ifElementName = ifElement.getName();
1286
1287 if (elementName.equals("and") || elementName.equals("not") ||
1288 elementName.equals("or")) {
1289
1290 validateIfElement(
1291 fileName, element, allowedBlockChildElementNames,
1292 allowedExecuteAttributeNames,
1293 allowedExecuteChildElementNames,
1294 allowedIfConditionElementNames);
1295 }
1296 else if (elementName.equals("condition")) {
1297 validateExecuteElement(
1298 fileName, element, allowedExecuteAttributeNames,
1299 ".*(is|Is).+", allowedExecuteChildElementNames);
1300 }
1301 else if (elementName.equals("contains")) {
1302 validateSimpleElement(
1303 fileName, element, new String[] {"string", "substring"});
1304 }
1305 else if (elementName.equals("else")) {
1306 if (ifElementName.equals("while")) {
1307 throwValidationException(
1308 1002, fileName, element, elementName);
1309 }
1310
1311 validateBlockElement(
1312 fileName, element, allowedBlockChildElementNames,
1313 allowedExecuteAttributeNames,
1314 allowedExecuteChildElementNames,
1315 allowedIfConditionElementNames);
1316 }
1317 else if (elementName.equals("elseif")) {
1318 if (ifElementName.equals("while")) {
1319 throwValidationException(
1320 1002, fileName, element, elementName);
1321 }
1322
1323 validateIfElement(
1324 fileName, element, allowedBlockChildElementNames,
1325 allowedExecuteAttributeNames,
1326 allowedExecuteChildElementNames,
1327 allowedIfConditionElementNames);
1328 }
1329 else if (elementName.equals("equals")) {
1330 validateSimpleElement(
1331 fileName, element, new String[] {"arg1", "arg2"});
1332 }
1333 else if (elementName.equals("isset")) {
1334 validateSimpleElement(fileName, element, new String[] {"var"});
1335 }
1336 else if (elementName.equals("then")) {
1337 validateBlockElement(
1338 fileName, element, allowedBlockChildElementNames,
1339 allowedExecuteAttributeNames,
1340 allowedExecuteChildElementNames,
1341 allowedIfConditionElementNames);
1342 }
1343 else {
1344 throwValidationException(1002, fileName, element, elementName);
1345 }
1346 }
1347
1348 if (!hasAllowedIfConditionElementNames) {
1349 throwValidationException(
1350 1001, fileName, ifElement, allowedIfConditionElementNames);
1351 }
1352
1353 if (Validator.equals(ifElement.getName(), "and") ||
1354 Validator.equals(ifElement.getName(), "not") ||
1355 Validator.equals(ifElement.getName(), "or")) {
1356
1357 return;
1358 }
1359
1360 if (!elementNames.contains("then")) {
1361 throwValidationException(
1362 1001, fileName, ifElement, new String[] {"then"});
1363 }
1364 }
1365
1366 protected void validateMacroDocument(String fileName, Element rootElement) {
1367 if (!Validator.equals(rootElement.getName(), "definition")) {
1368 throwValidationException(1000, fileName, rootElement);
1369 }
1370
1371 List<Element> elements = rootElement.elements();
1372
1373 String extendsName = rootElement.attributeValue("extends");
1374
1375 if (elements.isEmpty() && (extendsName == null)) {
1376 throwValidationException(
1377 1001, fileName, rootElement, new String[] {"command", "var"});
1378 }
1379 else if (extendsName != null) {
1380 if (Validator.isNull(extendsName)) {
1381 throwValidationException(
1382 1006, fileName, rootElement, "extends");
1383 }
1384 }
1385
1386 for (Element element : elements) {
1387 String elementName = element.getName();
1388
1389 if (elementName.equals("command")) {
1390 String attributeValue = element.attributeValue("name");
1391
1392 if (attributeValue == null) {
1393 throwValidationException(1003, fileName, element, "name");
1394 }
1395 else if (Validator.isNull(attributeValue)) {
1396 throwValidationException(1006, fileName, element, "name");
1397 }
1398
1399 validateBlockElement(
1400 fileName, element,
1401 new String[] {
1402 "description", "echo", "execute", "fail", "for", "if",
1403 "take-screenshot", "var", "while",
1404 },
1405 new String[] {"action", "function", "macro"},
1406 new String[] {"var"},
1407 new String[] {
1408 "and", "condition", "contains", "equals", "isset",
1409 "not", "or"
1410 });
1411 }
1412 else if (elementName.equals("var")) {
1413 validateVarElement(fileName, element);
1414 }
1415 else {
1416 throwValidationException(1002, fileName, element, elementName);
1417 }
1418 }
1419 }
1420
1421 protected void validatePathDocument(String fileName, Element rootElement) {
1422 Element headElement = rootElement.element("head");
1423
1424 Element titleElement = headElement.element("title");
1425
1426 String title = titleElement.getText();
1427
1428 int x = fileName.lastIndexOf(StringPool.SLASH);
1429 int y = fileName.lastIndexOf(CharPool.PERIOD);
1430
1431 String shortFileName = fileName.substring(x + 1, y);
1432
1433 if ((title == null) || !shortFileName.equals(title)) {
1434 throwValidationException(0, fileName);
1435 }
1436
1437 Element bodyElement = rootElement.element("body");
1438
1439 Element tableElement = bodyElement.element("table");
1440
1441 Element theadElement = tableElement.element("thead");
1442
1443 Element trElement = theadElement.element("tr");
1444
1445 Element tdElement = trElement.element("td");
1446
1447 String tdText = tdElement.getText();
1448
1449 if ((tdText == null) || !shortFileName.equals(tdText)) {
1450 throwValidationException(0, fileName);
1451 }
1452
1453 Element tbodyElement = tableElement.element("tbody");
1454
1455 List<Element> elements = tbodyElement.elements();
1456
1457 for (Element element : elements) {
1458 String elementName = element.getName();
1459
1460 if (elementName.equals("tr")) {
1461 validatePathTrElement(fileName, element);
1462 }
1463 else {
1464 throwValidationException(1002, fileName, element, elementName);
1465 }
1466 }
1467 }
1468
1469 protected void validatePathTrElement(String fileName, Element trElement) {
1470 List<Element> elements = trElement.elements();
1471
1472 for (Element element : elements) {
1473 String elementName = element.getName();
1474
1475 if (!elementName.equals("td")) {
1476 throwValidationException(1002, fileName, element, elementName);
1477 }
1478 }
1479
1480 if (elements.size() < 3) {
1481 throwValidationException(
1482 1001, fileName, trElement, new String[] {"td"});
1483 }
1484
1485 if (elements.size() > 3) {
1486 Element element = elements.get(3);
1487
1488 String elementName = element.getName();
1489
1490 throwValidationException(1002, fileName, element, elementName);
1491 }
1492
1493 Element locatorElement = elements.get(1);
1494
1495 String locator = locatorElement.getText();
1496
1497 locator = locator.replace("${","");
1498 locator = locator.replace("}","");
1499 locator = locator.replace("/-/","/");
1500
1501 if (locator.endsWith("/")) {
1502 locator = locator.substring(0, locator.length() - 1);
1503 }
1504
1505 if (!locator.equals("") && !locator.startsWith("link=") &&
1506 !locator.startsWith("title=") && !locator.contains(".png")) {
1507
1508 try {
1509 XPathFactory xPathFactory = XPathFactory.newInstance();
1510
1511 XPath xPath = xPathFactory.newXPath();
1512
1513 xPath.compile(locator);
1514 }
1515 catch (Exception e) {
1516 throwValidationException(2003, fileName, locator);
1517 }
1518 }
1519
1520 Element keyElement = elements.get(0);
1521
1522 String key = keyElement.getText();
1523
1524 Element descriptionElement = elements.get(2);
1525
1526 String description = descriptionElement.getText();
1527
1528 if (!key.equals("") && !key.equals("EXTEND_ACTION_PATH") &&
1529 !key.equals("PAGE_NAME") && !description.equals("")) {
1530
1531 if (description.endsWith(".")) {
1532 throwValidationException(2004, fileName, description);
1533 }
1534
1535 Matcher statmentMatcher = _pathTrElementStatementPattern.matcher(
1536 description);
1537
1538 if (!statmentMatcher.find()) {
1539 throwValidationException(2004, fileName, description);
1540 }
1541
1542 Matcher wordMatcher1 = _pathTrElementWordPattern1.matcher(
1543 description);
1544
1545 while (wordMatcher1.find()) {
1546 String word = wordMatcher1.group();
1547
1548 if (word.equals("a") || word.equals("and") ||
1549 word.equals("as") || word.equals("at") ||
1550 word.equals("by") || word.equals("for") ||
1551 word.equals("from") || word.equals("in") ||
1552 word.equals("of") || word.equals("the") ||
1553 word.equals("to")) {
1554
1555 continue;
1556 }
1557
1558 Matcher wordMatcher2 = _pathTrElementWordPattern2.matcher(word);
1559
1560 if (!wordMatcher2.find()) {
1561 throwValidationException(2004, fileName, description);
1562 }
1563 }
1564 }
1565 }
1566
1567 protected void validatePropertyElement(
1568 String fileName, Element propertyElement) {
1569
1570 List<Attribute> attributes = propertyElement.attributes();
1571
1572 String propertyName = propertyElement.attributeValue("name");
1573
1574 if (!_testcaseAvailablePropertyNames.contains(propertyName)) {
1575 throwValidationException(
1576 3003, fileName, propertyElement, propertyName);
1577 }
1578
1579 if (propertyName.equals("ignore.errors")) {
1580 String propertyDelimiter = propertyElement.attributeValue(
1581 "delimiter");
1582
1583 String propertyValue = propertyElement.attributeValue("value");
1584
1585 if (propertyDelimiter != null) {
1586 if (!propertyValue.contains(propertyDelimiter)) {
1587 throwValidationException(
1588 1006, fileName, propertyElement, "delimiter");
1589 }
1590 }
1591
1592 if (Validator.isNull(propertyValue)) {
1593 throwValidationException(
1594 1006, fileName, propertyElement, "value");
1595 }
1596 }
1597
1598 for (Attribute attribute : attributes) {
1599 String attributeName = attribute.getName();
1600
1601 if (attributeName.equals("delimiter") &&
1602 propertyName.equals("ignore.errors")) {
1603
1604 continue;
1605 }
1606 else if (attributeName.equals("line-number") ||
1607 attributeName.equals("name") ||
1608 attributeName.equals("value")) {
1609
1610 continue;
1611 }
1612 else {
1613 throwValidationException(
1614 1005, fileName, propertyElement, attributeName);
1615 }
1616 }
1617 }
1618
1619 protected void validateSimpleElement(
1620 String fileName, Element element, String[] neededAttributes) {
1621
1622 Map<String, Boolean> hasNeededAttributes =
1623 new HashMap<String, Boolean>();
1624
1625 for (String neededAttribute : neededAttributes) {
1626 hasNeededAttributes.put(neededAttribute, false);
1627 }
1628
1629 List<Attribute> attributes = element.attributes();
1630
1631 for (Attribute attribute : attributes) {
1632 String attributeName = attribute.getName();
1633 String attributeValue = attribute.getValue();
1634
1635 if (!_allowedNullAttributes.contains(attributeName) &&
1636 Validator.isNull(attributeValue)) {
1637
1638 throwValidationException(
1639 1006, fileName, element, attributeName);
1640 }
1641
1642 if (hasNeededAttributes.containsKey(attributeName)) {
1643 hasNeededAttributes.put(attributeName, true);
1644 }
1645
1646 if (!attributeName.equals("line-number") &&
1647 !hasNeededAttributes.containsKey(attributeName)) {
1648
1649 throwValidationException(
1650 1005, fileName, element, attributeName);
1651 }
1652 }
1653
1654 for (String neededAttribute : neededAttributes) {
1655 if (!hasNeededAttributes.get(neededAttribute)) {
1656 throwValidationException(
1657 1004, fileName, element, neededAttributes);
1658 }
1659 }
1660
1661 List<Element> childElements = element.elements();
1662
1663 if (!childElements.isEmpty()) {
1664 Element childElement = childElements.get(0);
1665
1666 String childElementName = childElement.getName();
1667
1668 throwValidationException(
1669 1002, fileName, childElement, childElementName);
1670 }
1671 }
1672
1673 protected void validateTestCaseDocument(
1674 String fileName, Element rootElement) {
1675
1676 if (!Validator.equals(rootElement.getName(), "definition")) {
1677 throwValidationException(1000, fileName, rootElement);
1678 }
1679
1680 String extendedTestCase = rootElement.attributeValue("extends");
1681
1682 if (extendedTestCase != null) {
1683 if (Validator.isNull(extendedTestCase)) {
1684 throwValidationException(
1685 1006, fileName, rootElement, "extends");
1686 }
1687 }
1688
1689 String componentName = rootElement.attributeValue("component-name");
1690
1691 if (componentName == null) {
1692 throwValidationException(
1693 1003, fileName, rootElement, "component-name");
1694 }
1695
1696 if ((componentName != null) &&
1697 !_componentNames.contains(componentName)) {
1698
1699 throwValidationException(
1700 1006, fileName, rootElement, "component-name");
1701 }
1702
1703 List<Element> elements = rootElement.elements();
1704
1705 if (Validator.isNull(extendedTestCase)) {
1706 if (elements.isEmpty()) {
1707 throwValidationException(
1708 1001, fileName, rootElement, new String[] {"command"});
1709 }
1710 }
1711
1712 for (Element element : elements) {
1713 String elementName = element.getName();
1714
1715 if (elementName.equals("command")) {
1716 String attributeValue = element.attributeValue("name");
1717
1718 if (attributeValue == null) {
1719 throwValidationException(1003, fileName, element, "name");
1720 }
1721 else if (Validator.isNull(attributeValue)) {
1722 throwValidationException(1006, fileName, element, "name");
1723 }
1724
1725 String priorityValue = element.attributeValue("priority");
1726
1727 if (priorityValue == null) {
1728 throwValidationException(
1729 1003, fileName, element, "priority");
1730 }
1731 else if (!(priorityValue.equals("1") ||
1732 priorityValue.equals("2") ||
1733 priorityValue.equals("3") ||
1734 priorityValue.equals("4") ||
1735 priorityValue.equals("5"))) {
1736
1737 throwValidationException(
1738 1006, fileName, element, "priority");
1739 }
1740
1741 validateBlockElement(
1742 fileName, element,
1743 new String[] {
1744 "description", "echo", "execute", "fail", "for", "if",
1745 "property", "take-screenshot", "var", "while"
1746 },
1747 new String[] {"action", "function", "macro", "test-case"},
1748 new String[] {"var"},
1749 new String[] {
1750 "and", "condition", "contains", "equals", "isset",
1751 "not", "or"
1752 });
1753 }
1754 else if (elementName.equals("property")) {
1755 validatePropertyElement(fileName, element);
1756 }
1757 else if (elementName.equals("set-up") ||
1758 elementName.equals("tear-down")) {
1759
1760 List<Attribute> attributes = element.attributes();
1761
1762 for (Attribute attribute : attributes) {
1763 String attributeName = attribute.getName();
1764
1765 if (!attributeName.equals("line-number")) {
1766 throwValidationException(
1767 1005, fileName, element, attributeName);
1768 }
1769 }
1770
1771 validateBlockElement(
1772 fileName, element,
1773 new String[] {
1774 "description", "echo", "execute", "fail", "if",
1775 "take-screenshot", "var", "while"
1776 },
1777 new String[] {"action", "function", "macro", "test-case"},
1778 new String[] {"var"},
1779 new String[] {
1780 "and", "condition", "contains", "equals", "isset",
1781 "not", "or"
1782 });
1783 }
1784 else if (elementName.equals("var")) {
1785 validateVarElement(fileName, element);
1786 }
1787 else {
1788 throwValidationException(1002, fileName, element, elementName);
1789 }
1790 }
1791
1792 elements = getAllChildElements(rootElement, "property");
1793
1794 for (Element element : elements) {
1795 String name = element.attributeValue("name");
1796 String value = element.attributeValue("value");
1797
1798 if (name.equals("testray.component.names")) {
1799 List<String> testrayComponentNames = ListUtil.fromArray(
1800 StringUtil.split(value));
1801
1802 for (String testrayComponentName : testrayComponentNames) {
1803 if (!_testrayAvailableComponentNames.contains(
1804 testrayComponentName)) {
1805
1806 throwValidationException(
1807 3001, fileName, element, name,
1808 testrayComponentName);
1809 }
1810 }
1811 }
1812 else if (name.equals("testray.main.component.name")) {
1813 if (!_testrayAvailableComponentNames.contains(value)) {
1814 throwValidationException(
1815 3001, fileName, element, name, value);
1816 }
1817 }
1818 }
1819
1820 elements = rootElement.elements("property");
1821
1822 boolean rootTestrayMainComponentNameFound = false;
1823
1824 for (Element element : elements) {
1825 String name = element.attributeValue("name");
1826
1827 if (name.equals("testray.main.component.name")) {
1828 rootTestrayMainComponentNameFound = true;
1829
1830 break;
1831 }
1832 }
1833
1834 if (!rootTestrayMainComponentNameFound) {
1835 elements = rootElement.elements("command");
1836
1837 for (Element element : elements) {
1838 List<Element> propertyElements = getAllChildElements(
1839 element, "property");
1840
1841 boolean commandTestrayMainComponentNameFound = false;
1842
1843 for (Element propertyElement : propertyElements) {
1844 String propertyName = propertyElement.attributeValue(
1845 "name");
1846
1847 if (propertyName.equals("testray.main.component.name")) {
1848 commandTestrayMainComponentNameFound = true;
1849
1850 break;
1851 }
1852 }
1853
1854 if (!commandTestrayMainComponentNameFound) {
1855 throwValidationException(
1856 3002, fileName, element, "testray.main.component.name");
1857 }
1858 }
1859 }
1860 }
1861
1862 protected void validateVarElement(String fileName, Element element) {
1863 List<Attribute> attributes = element.attributes();
1864
1865 Map<String, String> attributeMap = new HashMap<String, String>();
1866
1867 for (Attribute attribute : attributes) {
1868 String attributeName = attribute.getName();
1869 String attributeValue = attribute.getValue();
1870
1871 if (!attributeName.equals("value") &&
1872 Validator.isNull(attributeValue)) {
1873
1874 throwValidationException(
1875 1006, fileName, element, attributeName);
1876 }
1877
1878 if (!_allowedVarAttributes.contains(attributeName)) {
1879 throwValidationException(
1880 1005, fileName, element, attributeName);
1881 }
1882
1883 attributeMap.put(attributeName, attributeValue);
1884 }
1885
1886 if (!attributeMap.containsKey("name")) {
1887 throwValidationException(
1888 1004, fileName, element, new String[] {"name"});
1889 }
1890 else {
1891 String nameValue = attributeMap.get("name");
1892
1893 if (Validator.isNull(nameValue)) {
1894 throwValidationException(1006, fileName, element, "name");
1895 }
1896 }
1897
1898 if (attributeMap.containsKey("locator")) {
1899 String[] disallowedAttributes = {"locator-key", "path", "value"};
1900
1901 for (String disallowedAttribute : disallowedAttributes) {
1902 if (attributeMap.containsKey(disallowedAttribute)) {
1903 throwValidationException(
1904 1005, fileName, element, disallowedAttribute);
1905 }
1906 }
1907 }
1908 else if (attributeMap.containsKey("locator-key") &&
1909 attributeMap.containsKey("path")) {
1910
1911 if (attributeMap.containsKey("value")) {
1912 throwValidationException(1005, fileName, element, "value");
1913 }
1914 }
1915 else if (attributeMap.containsKey("locator-key")) {
1916 throwValidationException(
1917 1004, fileName, element, new String [] {"path"});
1918 }
1919 else if (attributeMap.containsKey("path")) {
1920 throwValidationException(
1921 1004, fileName, element, new String [] {"locator-key"});
1922 }
1923
1924 String varText = element.getText();
1925
1926 if (attributeMap.containsKey("locator") ||
1927 attributeMap.containsKey("locator-key") ||
1928 attributeMap.containsKey("path")) {
1929
1930 if (!Validator.isNull(varText)) {
1931 throwValidationException(1005, fileName, element, "value");
1932 }
1933 }
1934
1935 if (attributeMap.containsKey("method")) {
1936 String methodValue = attributeMap.get("method");
1937
1938 if (!methodValue.startsWith("MathUtil") &&
1939 !methodValue.startsWith("selenium") &&
1940 !methodValue.startsWith("StringUtil")) {
1941
1942 throwValidationException(1005, fileName, element, "method");
1943 }
1944
1945 if (!methodValue.contains("#")) {
1946 throwValidationException(1005, fileName, element, "method");
1947 }
1948 }
1949
1950 if (!attributeMap.containsKey("property-value") &&
1951 !attributeMap.containsKey("value") && Validator.isNull(varText)) {
1952
1953 if (!attributeMap.containsKey("group") &&
1954 !attributeMap.containsKey("input") &&
1955 !attributeMap.containsKey("locator") &&
1956 !attributeMap.containsKey("locator-key") &&
1957 !attributeMap.containsKey("method") &&
1958 !attributeMap.containsKey("path") &&
1959 !attributeMap.containsKey("pattern")) {
1960
1961 throwValidationException(
1962 1004, fileName, element, new String [] {"value"});
1963 }
1964 }
1965 else {
1966 String varValue = attributeMap.get("value");
1967
1968 if (Validator.isNull(varValue)) {
1969 varValue = varText;
1970 }
1971
1972 Matcher matcher = _varElementPattern.matcher(varValue);
1973
1974 while (matcher.find()) {
1975 String statement = matcher.group(1);
1976
1977 Matcher statementMatcher = _varElementStatementPattern.matcher(
1978 statement);
1979
1980 if (statementMatcher.find()) {
1981 String operand = statementMatcher.group(1);
1982
1983 String method = statementMatcher.group(2);
1984
1985 if (operand.equals("") || method.equals("")) {
1986 throwValidationException(
1987 1006, fileName, element, "value");
1988 }
1989
1990 if (!_methodNames.contains(method)) {
1991 throwValidationException(
1992 1013, fileName, element, method);
1993 }
1994 }
1995 }
1996 }
1997
1998 List<Element> childElements = element.elements();
1999
2000 if (!childElements.isEmpty()) {
2001 Element childElement = childElements.get(0);
2002
2003 String childElementName = childElement.getName();
2004
2005 throwValidationException(
2006 1002, fileName, childElement, childElementName);
2007 }
2008 }
2009
2010 private static final String _TPL_ROOT =
2011 "com/liferay/portal/tools/seleniumbuilder/dependencies/";
2012
2013 private static List<String> _allowedNullAttributes = ListUtil.fromArray(
2014 new String[] {
2015 "arg1", "arg2", "delimiter", "message", "string", "substring",
2016 "value"
2017 });
2018 private static List<String> _allowedVarAttributes = ListUtil.fromArray(
2019 new String[] {
2020 "attribute", "group", "input", "line-number", "locator",
2021 "locator-key", "method", "name", "path", "pattern",
2022 "property-value", "value"
2023 });
2024 private static List<String> _componentNames;
2025 private static List<String> _methodNames = ListUtil.fromArray(
2026 new String[] {
2027 "getFirstNumber", "getIPAddress", "increment", "length",
2028 "lowercase", "replace", "uppercase"
2029 });
2030 private static List<String> _reservedTags = ListUtil.fromArray(
2031 new String[] {
2032 "and", "case", "command", "condition", "contains", "default",
2033 "definition", "delimiter", "description", "echo", "else", "elseif",
2034 "equals", "execute", "fail", "for", "if", "isset", "not", "or",
2035 "property", "set-up", "take-screenshot", "td", "tear-down", "then",
2036 "tr", "while", "var"
2037 });
2038 private static List<String> _testcaseAvailablePropertyNames;
2039 private static List<String> _testrayAvailableComponentNames;
2040
2041 private String _baseDirName;
2042 private Pattern _pathTrElementStatementPattern = Pattern.compile(
2043 "[A-Z0-9].*");
2044 private Pattern _pathTrElementWordPattern1 = Pattern.compile(
2045 "[A-Za-z0-9\\-]+");
2046 private Pattern _pathTrElementWordPattern2 = Pattern.compile(
2047 "[A-Z0-9][A-Za-z0-9\\-]*");
2048 private Pattern _tagPattern = Pattern.compile("<[a-z\\-]+");
2049 private Pattern _varElementPattern = Pattern.compile("\\$\\{([^\\}]*?)\\}");
2050 private Pattern _varElementStatementPattern = Pattern.compile(
2051 "(.*)\\?(.*)\\(([^\\)]*?)\\)");
2052
2053 }