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