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