001    /**
002     * Copyright (c) 2000-present 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.kernel.util.StringPool;
018    import com.liferay.portal.kernel.util.StringUtil;
019    import com.liferay.portal.kernel.util.Validator;
020    import com.liferay.portal.kernel.xml.Attribute;
021    import com.liferay.portal.kernel.xml.Element;
022    
023    import java.util.HashMap;
024    import java.util.HashSet;
025    import java.util.List;
026    import java.util.Map;
027    import java.util.Set;
028    import java.util.TreeSet;
029    import java.util.regex.Matcher;
030    import java.util.regex.Pattern;
031    
032    import org.apache.tools.ant.DirectoryScanner;
033    
034    /**
035     * @author Michael Hashimoto
036     */
037    public class SeleniumBuilderContext {
038    
039            public SeleniumBuilderContext(
040                            SeleniumBuilderFileUtil seleniumBuilderFileUtil)
041                    throws Exception {
042    
043                    this(
044                            seleniumBuilderFileUtil,
045                            "com/liferay/portalweb/portal/util/liferayselenium/");
046            }
047    
048            public SeleniumBuilderContext(
049                            SeleniumBuilderFileUtil seleniumBuilderFileUtil,
050                            String liferaySeleniumDirName)
051                    throws Exception {
052    
053                    _seleniumBuilderFileUtil = seleniumBuilderFileUtil;
054    
055                    DirectoryScanner directoryScanner = new DirectoryScanner();
056    
057                    directoryScanner.setBasedir(seleniumBuilderFileUtil.getBaseDirName());
058                    directoryScanner.setIncludes(
059                            new String[] {
060                                    "**\\*.action", "**\\*.function", "**\\*.macro", "**\\*.path",
061                                    "**\\*.testcase"
062                            });
063    
064                    directoryScanner.scan();
065    
066                    String[] fileNames = directoryScanner.getIncludedFiles();
067    
068                    for (String fileName : fileNames) {
069                            addFile(fileName);
070                    }
071    
072                    String[] seleniumFileNames = {
073                            liferaySeleniumDirName + "LiferaySelenium.java",
074                            liferaySeleniumDirName + "SeleniumWrapper.java"
075                    };
076    
077                    for (String seleniumFileName : seleniumFileNames) {
078                            String content = _seleniumBuilderFileUtil.getNormalizedContent(
079                                    seleniumFileName);
080    
081                            Matcher matcher = _pattern.matcher(content);
082    
083                            while (matcher.find()) {
084                                    String methodSignature = matcher.group();
085    
086                                    int x = methodSignature.indexOf(" ", 7);
087                                    int y = methodSignature.indexOf("(");
088    
089                                    String seleniumCommandName = methodSignature.substring(
090                                            x + 1, y);
091    
092                                    int count = 0;
093    
094                                    int z = methodSignature.indexOf(")");
095    
096                                    String parameters = methodSignature.substring(y + 1, z);
097    
098                                    if (!parameters.equals("")) {
099                                            count = StringUtil.count(parameters, ",") + 1;
100                                    }
101    
102                                    _seleniumParameterCounts.put(seleniumCommandName, count);
103                            }
104                    }
105    
106                    _seleniumParameterCounts.put("open", 1);
107            }
108    
109            public void addFile(String fileName) throws Exception {
110                    fileName = _normalizeFileName(fileName);
111    
112                    if (fileName.endsWith(".action")) {
113                            String actionName = _getName(fileName);
114    
115                            if (_actionFileNames.containsKey(actionName)) {
116                                    _seleniumBuilderFileUtil.throwValidationException(
117                                            1008, fileName, actionName);
118                            }
119    
120                            _actionFileNames.put(actionName, fileName);
121    
122                            _actionNames.add(actionName);
123    
124                            _actionRootElements.put(actionName, _getRootElement(fileName));
125                    }
126                    else if (fileName.endsWith(".function")) {
127                            String functionName = _getName(fileName);
128    
129                            _functionClassNames.put(functionName, _getClassName(fileName));
130    
131                            _functionFileNames.put(functionName, fileName);
132    
133                            _functionJavaFileNames.put(
134                                    functionName, _getJavaFileName(fileName));
135    
136                            Element rootElement = _getRootElement(fileName);
137    
138                            _functionLocatorCounts.put(
139                                    functionName, _getLocatorCount(rootElement));
140    
141                            if (_functionNames.contains(functionName)) {
142                                    _seleniumBuilderFileUtil.throwValidationException(
143                                            1008, fileName, functionName);
144                            }
145    
146                            _functionNames.add(functionName);
147    
148                            _functionPackageNames.put(functionName, _getPackageName(fileName));
149    
150                            _functionReturnTypes.put(
151                                    functionName, _getReturnType(functionName));
152    
153                            _functionRootElements.put(functionName, rootElement);
154    
155                            _functionSimpleClassNames.put(
156                                    functionName, _getSimpleClassName(fileName));
157                    }
158                    else if (fileName.endsWith(".macro")) {
159                            String macroName = _getName(fileName);
160    
161                            _macroClassNames.put(macroName, _getClassName(fileName));
162    
163                            _macroFileNames.put(macroName, fileName);
164    
165                            _macroJavaFileNames.put(macroName, _getJavaFileName(fileName));
166    
167                            if (_macroNames.contains(macroName)) {
168                                    _seleniumBuilderFileUtil.throwValidationException(
169                                            1008, fileName, macroName);
170                            }
171    
172                            _macroNames.add(macroName);
173    
174                            _macroPackageNames.put(macroName, _getPackageName(fileName));
175    
176                            _macroSimpleClassNames.put(
177                                    macroName, _getSimpleClassName(fileName));
178    
179                            _macroRootElements.put(macroName, _getRootElement(fileName));
180                    }
181                    else if (fileName.endsWith(".path")) {
182                            String pathName = _getName(fileName);
183    
184                            _actionClassNames.put(pathName, _getClassName(fileName, "Action"));
185    
186                            _actionJavaFileNames.put(
187                                    pathName, _getJavaFileName(fileName, "Action"));
188    
189                            _actionNames.add(pathName);
190    
191                            _actionPackageNames.put(pathName, _getPackageName(fileName));
192    
193                            _actionSimpleClassNames.put(
194                                    pathName, _getSimpleClassName(fileName, "Action"));
195    
196                            _pathClassNames.put(pathName, _getClassName(fileName));
197    
198                            _pathFileNames.put(pathName, fileName);
199    
200                            _pathJavaFileNames.put(pathName, _getJavaFileName(fileName));
201    
202                            if (_pathNames.contains(pathName)) {
203                                    _seleniumBuilderFileUtil.throwValidationException(
204                                            1008, fileName, pathName);
205                            }
206    
207                            _pathNames.add(pathName);
208    
209                            _pathPackageNames.put(pathName, _getPackageName(fileName));
210    
211                            _pathRootElements.put(pathName, _getRootElement(fileName));
212    
213                            _pathSimpleClassNames.put(pathName, _getSimpleClassName(fileName));
214                    }
215                    else if (fileName.endsWith(".testcase")) {
216                            String testCaseName = _getName(fileName);
217    
218                            _testCaseClassNames.put(testCaseName, _getClassName(fileName));
219    
220                            Element rootElement = _getRootElement(fileName);
221    
222                            _testCaseCommandNames.put(
223                                    testCaseName, _getTestCaseCommandNames(rootElement));
224    
225                            _testCaseFileNames.put(testCaseName, fileName);
226    
227                            _testCaseHTMLFileNames.put(
228                                    testCaseName, _getHTMLFileName(fileName));
229    
230                            _testCaseJavaFileNames.put(
231                                    testCaseName, _getJavaFileName(fileName));
232    
233                            if (_testCaseNames.contains(testCaseName)) {
234                                    _seleniumBuilderFileUtil.throwValidationException(
235                                            1008, fileName, testCaseName);
236                            }
237    
238                            _testCaseNames.add(testCaseName);
239    
240                            _testCasePackageNames.put(testCaseName, _getPackageName(fileName));
241    
242                            _testCaseRootElements.put(testCaseName, rootElement);
243    
244                            _testCaseSimpleClassNames.put(
245                                    testCaseName, _getSimpleClassName(fileName));
246                    }
247                    else {
248                            throw new IllegalArgumentException("Invalid file " + fileName);
249                    }
250            }
251    
252            public String getActionClassName(String actionName) {
253                    return _actionClassNames.get(actionName);
254            }
255    
256            public String getActionFileName(String actionName) {
257                    return _actionFileNames.get(actionName);
258            }
259    
260            public String getActionJavaFileName(String actionName) {
261                    return _actionJavaFileNames.get(actionName);
262            }
263    
264            public Set<String> getActionNames() {
265                    return _actionNames;
266            }
267    
268            public String getActionPackageName(String actionName) {
269                    return _actionPackageNames.get(actionName);
270            }
271    
272            public Element getActionRootElement(String actionName) {
273                    return _actionRootElements.get(actionName);
274            }
275    
276            public String getActionSimpleClassName(String actionName) {
277                    return _actionSimpleClassNames.get(actionName);
278            }
279    
280            public String getFunctionClassName(String functionName) {
281                    return _functionClassNames.get(functionName);
282            }
283    
284            public String getFunctionFileName(String functionName) {
285                    return _functionFileNames.get(functionName);
286            }
287    
288            public String getFunctionJavaFileName(String functionName) {
289                    return _functionJavaFileNames.get(functionName);
290            }
291    
292            public int getFunctionLocatorCount(String functionName) {
293                    return _functionLocatorCounts.get(functionName);
294            }
295    
296            public Set<String> getFunctionNames() {
297                    return _functionNames;
298            }
299    
300            public String getFunctionPackageName(String functionName) {
301                    return _functionPackageNames.get(functionName);
302            }
303    
304            public String getFunctionReturnType(String functionName) {
305                    return _functionReturnTypes.get(functionName);
306            }
307    
308            public Element getFunctionRootElement(String functionName) {
309                    return _functionRootElements.get(functionName);
310            }
311    
312            public String getFunctionSimpleClassName(String functionName) {
313                    return _functionSimpleClassNames.get(functionName);
314            }
315    
316            public String getMacroClassName(String macroName) {
317                    return _macroClassNames.get(macroName);
318            }
319    
320            public Set<Element> getMacroCommandElements(String macroName) {
321                    Set<Element> commandElementsSet = new HashSet<Element>();
322    
323                    Element macroRootElement = getMacroRootElement(macroName);
324    
325                    List<Element> macroCommandElements = macroRootElement.elements(
326                            "command");
327    
328                    String extendsName = macroRootElement.attributeValue("extends");
329    
330                    if (extendsName != null) {
331                            Element extendsRootElement = getMacroRootElement(extendsName);
332    
333                            List<Element> extendsCommandElements = extendsRootElement.elements(
334                                    "command");
335    
336                            Set<String> commandNames = getMacroCommandNames(macroName);
337    
338                            for (String commandName : commandNames) {
339                                    boolean macroElementFound = false;
340    
341                                    for (Element macroCommandElement : macroCommandElements) {
342                                            String macroCommandName =
343                                                    macroCommandElement.attributeValue("name");
344    
345                                            if (commandName.equals(macroCommandName)) {
346                                                    commandElementsSet.add(macroCommandElement);
347    
348                                                    macroElementFound = true;
349    
350                                                    break;
351                                            }
352                                    }
353    
354                                    if (macroElementFound) {
355                                            continue;
356                                    }
357    
358                                    for (Element extendsCommandElement : extendsCommandElements) {
359                                            String extendsCommandName =
360                                                    extendsCommandElement.attributeValue("name");
361    
362                                            if (commandName.equals(extendsCommandName)) {
363                                                    commandElementsSet.add(extendsCommandElement);
364    
365                                                    break;
366                                            }
367                                    }
368                            }
369                    }
370                    else {
371                            commandElementsSet.addAll(macroCommandElements);
372                    }
373    
374                    return commandElementsSet;
375            }
376    
377            public Set<String> getMacroCommandNames(String macroName) {
378                    Set<String> commandNames = new TreeSet<String>();
379    
380                    Element macroRootElement = getMacroRootElement(macroName);
381    
382                    List<Element> macroCommandElements = macroRootElement.elements(
383                            "command");
384    
385                    for (Element macroCommandElement : macroCommandElements) {
386                            commandNames.add(macroCommandElement.attributeValue("name"));
387                    }
388    
389                    String extendsName = macroRootElement.attributeValue("extends");
390    
391                    if (extendsName != null) {
392                            Element extendsRootElement = getMacroRootElement(extendsName);
393    
394                            List<Element> extendsCommandElements = extendsRootElement.elements(
395                                    "command");
396    
397                            for (Element extendsCommandElement : extendsCommandElements) {
398                                    commandNames.add(extendsCommandElement.attributeValue("name"));
399                            }
400                    }
401    
402                    return commandNames;
403            }
404    
405            public String getMacroFileName(String macroName) {
406                    return _macroFileNames.get(macroName);
407            }
408    
409            public String getMacroJavaFileName(String macroName) {
410                    return _macroJavaFileNames.get(macroName);
411            }
412    
413            public Set<String> getMacroNames() {
414                    return _macroNames;
415            }
416    
417            public String getMacroPackageName(String macroName) {
418                    return _macroPackageNames.get(macroName);
419            }
420    
421            public Element getMacroRootElement(String macroName) {
422                    return _macroRootElements.get(macroName);
423            }
424    
425            public String getMacroSimpleClassName(String macroName) {
426                    return _macroSimpleClassNames.get(macroName);
427            }
428    
429            public String getPath(Element rootElement, String locatorKey) {
430                    String pathName = "";
431    
432                    Element bodyElement = rootElement.element("body");
433    
434                    Element tableElement = bodyElement.element("table");
435    
436                    Element tbodyElement = tableElement.element("tbody");
437    
438                    List<Element> trElements = tbodyElement.elements();
439    
440                    for (Element trElement : trElements) {
441                            List<Element> tdElements = trElement.elements("td");
442    
443                            Element pathLocatorElement = tdElements.get(1);
444    
445                            Element pathLocatorKeyElement = tdElements.get(0);
446    
447                            String pathLocatorKey = pathLocatorKeyElement.getText();
448    
449                            if (pathLocatorKey.equals(locatorKey)) {
450                                    return pathLocatorElement.getText();
451                            }
452    
453                            if (pathLocatorKey.equals("EXTEND_ACTION_PATH")) {
454                                    pathName = pathLocatorElement.getText();
455                            }
456                    }
457    
458                    if (Validator.isNotNull(pathName)) {
459                            Element pathRootElement = getPathRootElement(pathName);
460    
461                            return getPath(pathRootElement, locatorKey);
462                    }
463    
464                    return locatorKey;
465            }
466    
467            public String getPathClassName(String pathName) {
468                    return _pathClassNames.get(pathName);
469            }
470    
471            public String getPathFileName(String pathName) {
472                    return _pathFileNames.get(pathName);
473            }
474    
475            public String getPathJavaFileName(String pathName) {
476                    return _pathJavaFileNames.get(pathName);
477            }
478    
479            public Set<String> getPathLocatorKeys(Element rootElement) {
480                    Set<String> pathLocatorKeys = new HashSet<String>();
481    
482                    Element bodyElement = rootElement.element("body");
483    
484                    Element tableElement = bodyElement.element("table");
485    
486                    Element tbodyElement = tableElement.element("tbody");
487    
488                    List<Element> trElements = tbodyElement.elements();
489    
490                    for (Element trElement : trElements) {
491                            List<Element> tdElements = trElement.elements("td");
492    
493                            Element pathLocatorKeyElement = tdElements.get(0);
494    
495                            String pathLocatorKey = pathLocatorKeyElement.getText();
496    
497                            if (pathLocatorKey.equals("EXTEND_ACTION_PATH")) {
498                                    Element pathLocatorElement = tdElements.get(1);
499    
500                                    String pathName = pathLocatorElement.getText();
501    
502                                    Element pathRootElement = getPathRootElement(pathName);
503    
504                                    pathLocatorKeys.addAll(getPathLocatorKeys(pathRootElement));
505                            }
506                            else {
507                                    pathLocatorKeys.add(pathLocatorKey);
508                            }
509                    }
510    
511                    return pathLocatorKeys;
512            }
513    
514            public Set<String> getPathNames() {
515                    return _pathNames;
516            }
517    
518            public String getPathPackageName(String pathName) {
519                    return _pathPackageNames.get(pathName);
520            }
521    
522            public Element getPathRootElement(String pathName) {
523                    return _pathRootElements.get(pathName);
524            }
525    
526            public String getPathSimpleClassName(String pathName) {
527                    return _pathSimpleClassNames.get(pathName);
528            }
529    
530            public int getSeleniumParameterCount(String seleniumCommandName) {
531                    return _seleniumParameterCounts.get(seleniumCommandName);
532            }
533    
534            public String getTestCaseClassName(String testCaseName) {
535                    return _testCaseClassNames.get(testCaseName);
536            }
537    
538            public Set<String> getTestCaseCommandNames(String testCaseName) {
539                    Element testCaseRootElement = getTestCaseRootElement(testCaseName);
540    
541                    String extendedTestCaseName = testCaseRootElement.attributeValue(
542                            "extends");
543    
544                    if (extendedTestCaseName != null) {
545                            Set<String> extendedTestCaseCommandNames =
546                                    _testCaseCommandNames.get(extendedTestCaseName);
547    
548                            Set<String> currentTestCaseCommandNames = _testCaseCommandNames.get(
549                                    testCaseName);
550    
551                            currentTestCaseCommandNames.addAll(extendedTestCaseCommandNames);
552    
553                            return currentTestCaseCommandNames;
554                    }
555                    else {
556                            return _testCaseCommandNames.get(testCaseName);
557                    }
558            }
559    
560            public String getTestCaseFileName(String testCaseName) {
561                    return _testCaseFileNames.get(testCaseName);
562            }
563    
564            public String getTestCaseHTMLFileName(String testCaseName) {
565                    return _testCaseHTMLFileNames.get(testCaseName);
566            }
567    
568            public String getTestCaseJavaFileName(String testCaseName) {
569                    return _testCaseJavaFileNames.get(testCaseName);
570            }
571    
572            public Set<String> getTestCaseNames() {
573                    return _testCaseNames;
574            }
575    
576            public String getTestCasePackageName(String testCaseName) {
577                    return _testCasePackageNames.get(testCaseName);
578            }
579    
580            public Element getTestCaseRootElement(String testCaseName) {
581                    return _testCaseRootElements.get(testCaseName);
582            }
583    
584            public String getTestCaseSimpleClassName(String testCaseName) {
585                    return _testCaseSimpleClassNames.get(testCaseName);
586            }
587    
588            public void validateActionElements(String actionName) {
589                    String actionFileName = getActionFileName(actionName);
590    
591                    Element rootElement = getActionRootElement(actionName);
592    
593                    if (rootElement == null) {
594                            return;
595                    }
596    
597                    if (!_pathNames.contains(actionName)) {
598                            _seleniumBuilderFileUtil.throwValidationException(
599                                    2002, actionFileName, actionName);
600                    }
601    
602                    List<Element> caseElements =
603                            _seleniumBuilderFileUtil.getAllChildElements(rootElement, "case");
604    
605                    for (Element caseElement : caseElements) {
606                            _validateLocatorKeyElement(actionFileName, actionName, caseElement);
607                    }
608    
609                    List<Element> commandElements =
610                            _seleniumBuilderFileUtil.getAllChildElements(
611                                    rootElement, "command");
612    
613                    Set<String> commandElementNames = new HashSet<String>();
614    
615                    for (Element commandElement : commandElements) {
616                            String commandName = commandElement.attributeValue("name");
617    
618                            if (commandElementNames.contains(commandName)) {
619                                    _seleniumBuilderFileUtil.throwValidationException(
620                                            1009, actionFileName, commandElement, commandName);
621                            }
622    
623                            commandElementNames.add(commandName);
624    
625                            if (!_isFunctionName(commandName)) {
626                                    _seleniumBuilderFileUtil.throwValidationException(
627                                            2001, actionFileName, commandElement, commandName);
628                            }
629                    }
630    
631                    List<Element> executeElements =
632                            _seleniumBuilderFileUtil.getAllChildElements(
633                                    rootElement, "execute");
634    
635                    for (Element executeElement : executeElements) {
636                            _validateFunctionElement(actionFileName, executeElement);
637                    }
638            }
639    
640            public void validateElements(String fileName) {
641                    String name = _getName(fileName);
642    
643                    if (fileName.endsWith(".action")) {
644                            validateActionElements(name);
645                    }
646                    else if (fileName.endsWith(".function")) {
647                            validateFunctionElements(name);
648                    }
649                    else if (fileName.endsWith(".macro")) {
650                            validateMacroElements(name);
651                    }
652                    else if (fileName.endsWith(".testcase")) {
653                            validateTestCaseElements(name);
654                    }
655            }
656    
657            public void validateFunctionElements(String functionName) {
658                    Element rootElement = getFunctionRootElement(functionName);
659    
660                    if (rootElement == null) {
661                            return;
662                    }
663    
664                    String functionFileName = getFunctionFileName(functionName);
665    
666                    List<Element> commandElements =
667                            _seleniumBuilderFileUtil.getAllChildElements(
668                                    rootElement, "command");
669    
670                    Set<String> commandElementNames = new HashSet<String>();
671    
672                    for (Element commandElement : commandElements) {
673                            String commandName = commandElement.attributeValue("name");
674    
675                            if (commandElementNames.contains(commandName)) {
676                                    _seleniumBuilderFileUtil.throwValidationException(
677                                            1009, functionFileName, commandElement, commandName);
678                            }
679                            else {
680                                    commandElementNames.add(commandName);
681                            }
682                    }
683    
684                    List<Element> conditionAndExecuteElements =
685                            _seleniumBuilderFileUtil.getAllChildElements(
686                                    rootElement, "condition");
687    
688                    conditionAndExecuteElements.addAll(
689                            _seleniumBuilderFileUtil.getAllChildElements(
690                                    rootElement, "execute"));
691    
692                    for (Element conditionAndExecuteElement : conditionAndExecuteElements) {
693                            String function = conditionAndExecuteElement.attributeValue(
694                                    "function");
695                            String selenium = conditionAndExecuteElement.attributeValue(
696                                    "selenium");
697    
698                            if (function != null) {
699                                    _validateFunctionElement(
700                                            functionFileName, conditionAndExecuteElement);
701                            }
702                            else if (selenium != null) {
703                                    _validateSeleniumElement(
704                                            functionFileName, conditionAndExecuteElement);
705                            }
706                    }
707            }
708    
709            public void validateMacroElements(String macroName) {
710                    Element rootElement = getMacroRootElement(macroName);
711    
712                    if (rootElement == null) {
713                            return;
714                    }
715    
716                    String macroFileName = getMacroFileName(macroName);
717    
718                    String extendsName = rootElement.attributeValue("extends");
719    
720                    if (extendsName != null) {
721                            if (!_macroNames.contains(extendsName)) {
722                                    _seleniumBuilderFileUtil.throwValidationException(
723                                            1006, macroFileName, rootElement, "extends");
724                            }
725    
726                            if (macroName.equals(extendsName)) {
727                                    _seleniumBuilderFileUtil.throwValidationException(
728                                            1006, macroFileName, rootElement, "extends");
729                            }
730    
731                            Element extendsRootElement = getMacroRootElement(extendsName);
732    
733                            if (extendsRootElement.attributeValue("extends") != null) {
734                                    _seleniumBuilderFileUtil.throwValidationException(
735                                            1006, macroFileName, rootElement, "extends");
736                            }
737                    }
738    
739                    validateVarElements(rootElement, macroFileName);
740    
741                    List<Element> commandElements =
742                            _seleniumBuilderFileUtil.getAllChildElements(
743                                    rootElement, "command");
744    
745                    Set<String> commandElementNames = new HashSet<String>();
746    
747                    for (Element commandElement : commandElements) {
748                            String commandName = commandElement.attributeValue("name");
749    
750                            if (commandElementNames.contains(commandName)) {
751                                    _seleniumBuilderFileUtil.throwValidationException(
752                                            1009, macroFileName, commandElement, commandName);
753                            }
754                            else {
755                                    commandElementNames.add(commandName);
756                            }
757                    }
758    
759                    List<Element> conditionAndExecuteElements =
760                            _seleniumBuilderFileUtil.getAllChildElements(
761                                    rootElement, "condition");
762    
763                    conditionAndExecuteElements.addAll(
764                            _seleniumBuilderFileUtil.getAllChildElements(
765                                    rootElement, "execute"));
766    
767                    for (Element conditionAndExecuteElement : conditionAndExecuteElements) {
768                            String action = conditionAndExecuteElement.attributeValue("action");
769                            String macro = conditionAndExecuteElement.attributeValue("macro");
770    
771                            if (action != null) {
772                                    _validateActionElement(
773                                            macroFileName, conditionAndExecuteElement);
774                            }
775                            else if (macro != null) {
776                                    _validateMacroElement(
777                                            macroFileName, conditionAndExecuteElement);
778                            }
779                    }
780            }
781    
782            public void validateTestCaseElements(String testCaseName) {
783                    Element rootElement = getTestCaseRootElement(testCaseName);
784    
785                    if (rootElement == null) {
786                            return;
787                    }
788    
789                    String testCaseFileName = getTestCaseFileName(testCaseName);
790    
791                    String extendedTestCase = rootElement.attributeValue("extends");
792    
793                    if (extendedTestCase != null) {
794                            if (!_testCaseNames.contains(extendedTestCase) ||
795                                    testCaseName.equals(extendedTestCase)) {
796    
797                                    _seleniumBuilderFileUtil.throwValidationException(
798                                            1006, testCaseFileName, rootElement, "extends");
799                            }
800                    }
801    
802                    validateVarElements(rootElement, testCaseFileName);
803    
804                    List<Element> commandElements =
805                            _seleniumBuilderFileUtil.getAllChildElements(
806                                    rootElement, "command");
807    
808                    Set<String> commandElementNames = new HashSet<String>();
809    
810                    for (Element commandElement : commandElements) {
811                            String commandName = commandElement.attributeValue("name");
812    
813                            if (commandElementNames.contains(commandName)) {
814                                    _seleniumBuilderFileUtil.throwValidationException(
815                                            1009, testCaseFileName, commandElement, commandName);
816                            }
817                            else {
818                                    commandElementNames.add(commandName);
819                            }
820                    }
821    
822                    List<Element> executeElements =
823                            _seleniumBuilderFileUtil.getAllChildElements(
824                                    rootElement, "execute");
825    
826                    for (Element executeElement : executeElements) {
827                            String action = executeElement.attributeValue("action");
828                            String macro = executeElement.attributeValue("macro");
829                            String testCase = executeElement.attributeValue("test-case");
830    
831                            if (action != null) {
832                                    _validateActionElement(testCaseFileName, executeElement);
833                            }
834                            else if (macro != null) {
835                                    _validateMacroElement(testCaseFileName, executeElement);
836                            }
837                            else if (testCase != null) {
838                                    _validateTestCaseElement(
839                                            testCaseFileName, executeElement, rootElement);
840                            }
841                    }
842            }
843    
844            public void validateVarElements(Element rootElement, String fileName) {
845                    List<Element> varElements =
846                            _seleniumBuilderFileUtil.getAllChildElements(rootElement, "var");
847    
848                    for (Element varElement : varElements) {
849                            String varLocatorKey = varElement.attributeValue("locator-key");
850                            String varPath = varElement.attributeValue("path");
851    
852                            if (Validator.isNotNull(varLocatorKey) &&
853                                    Validator.isNotNull(varPath)) {
854    
855                                    if (!_pathRootElements.containsKey(varPath)) {
856                                            _seleniumBuilderFileUtil.throwValidationException(
857                                                    1014, fileName, varElement, varPath);
858                                    }
859    
860                                    if (!_isValidLocatorKey(varPath, null, varLocatorKey)) {
861                                            _seleniumBuilderFileUtil.throwValidationException(
862                                                    1010, fileName, varElement, varLocatorKey);
863                                    }
864                            }
865                    }
866            }
867    
868            private String _getClassName(String fileName) {
869                    return _seleniumBuilderFileUtil.getClassName(fileName);
870            }
871    
872            private String _getClassName(String fileName, String classSuffix) {
873                    return _seleniumBuilderFileUtil.getClassName(fileName, classSuffix);
874            }
875    
876            private String _getHTMLFileName(String fileName) {
877                    return _seleniumBuilderFileUtil.getHTMLFileName(fileName);
878            }
879    
880            private String _getJavaFileName(String fileName) {
881                    return _seleniumBuilderFileUtil.getJavaFileName(fileName);
882            }
883    
884            private String _getJavaFileName(String fileName, String classSuffix) {
885                    return _seleniumBuilderFileUtil.getJavaFileName(fileName, classSuffix);
886            }
887    
888            private int _getLocatorCount(Element rootElement) throws Exception {
889                    return _seleniumBuilderFileUtil.getLocatorCount(rootElement);
890            }
891    
892            private String _getName(String fileName) {
893                    return _seleniumBuilderFileUtil.getName(fileName);
894            }
895    
896            private String _getPackageName(String fileName) {
897                    return _seleniumBuilderFileUtil.getPackageName(fileName);
898            }
899    
900            private String _getReturnType(String name) throws Exception {
901                    return _seleniumBuilderFileUtil.getReturnType(name);
902            }
903    
904            private Element _getRootElement(String fileName) throws Exception {
905                    return _seleniumBuilderFileUtil.getRootElement(fileName);
906            }
907    
908            private String _getSimpleClassName(String fileName) {
909                    return _seleniumBuilderFileUtil.getSimpleClassName(fileName);
910            }
911    
912            private String _getSimpleClassName(String fileName, String classSuffix) {
913                    return _seleniumBuilderFileUtil.getSimpleClassName(
914                            fileName, classSuffix);
915            }
916    
917            private Set<String> _getTestCaseCommandNames(Element rootElement) {
918                    List<Element> commandElements =
919                            _seleniumBuilderFileUtil.getAllChildElements(
920                                    rootElement, "command");
921    
922                    Set<String> commandNames = new TreeSet<String>();
923    
924                    for (Element commandElement : commandElements) {
925                            commandNames.add(commandElement.attributeValue("name"));
926                    }
927    
928                    return commandNames;
929            }
930    
931            private boolean _isActionName(String name) {
932                    for (String actionName : _actionNames) {
933                            if (actionName.equals(name)) {
934                                    return true;
935                            }
936                    }
937    
938                    return false;
939            }
940    
941            private boolean _isFunctionCommand(String name, String command) {
942                    if (!_isFunctionName(name)) {
943                            return false;
944                    }
945    
946                    Element rootElement = getFunctionRootElement(name);
947    
948                    List<Element> commandElements =
949                            _seleniumBuilderFileUtil.getAllChildElements(
950                                    rootElement, "command");
951    
952                    for (Element commandElement : commandElements) {
953                            String commandName = commandElement.attributeValue("name");
954    
955                            if (commandName.equals(command)) {
956                                    return true;
957                            }
958                    }
959    
960                    return false;
961            }
962    
963            private boolean _isFunctionName(String name) {
964                    for (String functionName : _functionNames) {
965                            if (functionName.equals(StringUtil.upperCaseFirstLetter(name))) {
966                                    return true;
967                            }
968                    }
969    
970                    return false;
971            }
972    
973            private boolean _isMacroCommand(String name, String command) {
974                    if (!_isMacroName(name)) {
975                            return false;
976                    }
977    
978                    Set<Element> commandElements = getMacroCommandElements(name);
979    
980                    for (Element commandElement : commandElements) {
981                            String commandName = commandElement.attributeValue("name");
982    
983                            if (commandName.equals(command)) {
984                                    return true;
985                            }
986                    }
987    
988                    return false;
989            }
990    
991            private boolean _isMacroName(String name) {
992                    for (String macroName : _macroNames) {
993                            if (macroName.equals(name)) {
994                                    return true;
995                            }
996                    }
997    
998                    return false;
999            }
1000    
1001            private boolean _isSeleniumCommand(String command) {
1002                    if (_seleniumParameterCounts.containsKey(command)) {
1003                            return true;
1004                    }
1005    
1006                    return false;
1007            }
1008    
1009            private boolean _isValidLocatorKey(
1010                    String actionName, String caseComparator, String locatorKey) {
1011    
1012                    Element pathRootElement = getPathRootElement(actionName);
1013    
1014                    Set<String> pathLocatorKeys = getPathLocatorKeys(pathRootElement);
1015    
1016                    String[] partialKeys = {};
1017    
1018                    if (locatorKey.contains("${") && locatorKey.contains("}")) {
1019                            caseComparator = "partial";
1020    
1021                            partialKeys = locatorKey.split("\\$\\{[^}]*?\\}");
1022                    }
1023    
1024                    for (String pathLocatorKey : pathLocatorKeys) {
1025                            if (caseComparator == null) {
1026                                    if (pathLocatorKey.equals(locatorKey)) {
1027                                            return true;
1028                                    }
1029                            }
1030                            else {
1031                                    if (caseComparator.equals("contains") &&
1032                                            pathLocatorKey.contains(locatorKey)) {
1033    
1034                                            return true;
1035                                    }
1036                                    else if (caseComparator.equals("endsWith") &&
1037                                                     pathLocatorKey.endsWith(locatorKey)) {
1038    
1039                                            return true;
1040                                    }
1041                                    else if (caseComparator.equals("partial")) {
1042                                            boolean containsAll = true;
1043    
1044                                            for (String s : partialKeys) {
1045                                                    if (!pathLocatorKey.contains(s)) {
1046                                                            containsAll = false;
1047                                                    }
1048                                            }
1049    
1050                                            if (containsAll) {
1051                                                    return true;
1052                                            }
1053                                    }
1054                                    else if (caseComparator.equals("startsWith") &&
1055                                                     pathLocatorKey.startsWith(locatorKey)) {
1056    
1057                                            return true;
1058                                    }
1059                            }
1060                    }
1061    
1062                    return false;
1063            }
1064    
1065            private String _normalizeFileName(String fileName) {
1066                    return _seleniumBuilderFileUtil.normalizeFileName(fileName);
1067            }
1068    
1069            private void _validateActionElement(String fileName, Element element) {
1070                    String action = element.attributeValue("action");
1071    
1072                    int x = action.indexOf(StringPool.POUND);
1073    
1074                    if (x == -1) {
1075                            _seleniumBuilderFileUtil.throwValidationException(
1076                                    1006, fileName, element, "action");
1077                    }
1078    
1079                    String actionName = action.substring(0, x);
1080    
1081                    if (!_isActionName(actionName)) {
1082                            _seleniumBuilderFileUtil.throwValidationException(
1083                                    1011, fileName, element, "action", actionName);
1084                    }
1085    
1086                    String actionCommand = action.substring(x + 1);
1087    
1088                    if (!_isFunctionName(actionCommand)) {
1089                            _seleniumBuilderFileUtil.throwValidationException(
1090                                    1012, fileName, element, "action", actionCommand);
1091                    }
1092    
1093                    _validateLocatorKeyElement(fileName, actionName, element);
1094            }
1095    
1096            private void _validateFunctionElement(String fileName, Element element) {
1097                    String function = element.attributeValue("function");
1098    
1099                    int x = function.indexOf(StringPool.POUND);
1100    
1101                    if (x == -1) {
1102                            _seleniumBuilderFileUtil.throwValidationException(
1103                                    1006, fileName, element, "function");
1104                    }
1105    
1106                    String functionName = function.substring(0, x);
1107    
1108                    if (!_isFunctionName(functionName)) {
1109                            _seleniumBuilderFileUtil.throwValidationException(
1110                                    1011, fileName, element, "function", functionName);
1111                    }
1112    
1113                    String functionCommand = function.substring(x + 1);
1114    
1115                    if (!_isFunctionCommand(functionName, functionCommand)) {
1116                            _seleniumBuilderFileUtil.throwValidationException(
1117                                    1012, fileName, element, "function", functionCommand);
1118                    }
1119            }
1120    
1121            private void _validateLocatorKeyElement(
1122                    String fileName, String actionName, Element element) {
1123    
1124                    String comparator = element.attributeValue("comparator");
1125    
1126                    List<Attribute> attributes = element.attributes();
1127    
1128                    for (Attribute attribute : attributes) {
1129                            String attributeName = attribute.getName();
1130    
1131                            if (attributeName.startsWith("locator-key")) {
1132                                    String attributeValue = attribute.getValue();
1133    
1134                                    if (!_isValidLocatorKey(
1135                                                    actionName, comparator, attributeValue)) {
1136    
1137                                            _seleniumBuilderFileUtil.throwValidationException(
1138                                                    1010, fileName, element, attributeValue);
1139                                    }
1140                            }
1141                    }
1142            }
1143    
1144            private void _validateMacroElement(String fileName, Element element) {
1145                    String macro = element.attributeValue("macro");
1146    
1147                    int x = macro.indexOf(StringPool.POUND);
1148    
1149                    if (x == -1) {
1150                            _seleniumBuilderFileUtil.throwValidationException(
1151                                    1006, fileName, element, "macro");
1152                    }
1153    
1154                    String macroName = macro.substring(0, x);
1155    
1156                    if (!_isMacroName(macroName)) {
1157                            _seleniumBuilderFileUtil.throwValidationException(
1158                                    1011, fileName, element, "macro", macroName);
1159                    }
1160    
1161                    String macroCommand = macro.substring(x + 1);
1162    
1163                    if (!_isMacroCommand(macroName, macroCommand)) {
1164                            _seleniumBuilderFileUtil.throwValidationException(
1165                                    1012, fileName, element, "macro", macroCommand);
1166                    }
1167            }
1168    
1169            private void _validateSeleniumElement(String fileName, Element element) {
1170                    String selenium = element.attributeValue("selenium");
1171    
1172                    if (!_isSeleniumCommand(selenium)) {
1173                            _seleniumBuilderFileUtil.throwValidationException(
1174                                    1012, fileName, element, "selenium", selenium);
1175                    }
1176            }
1177    
1178            private void _validateTestCaseElement(
1179                    String fileName, Element element, Element rootElement) {
1180    
1181                    String testCase = element.attributeValue("test-case");
1182    
1183                    int x = testCase.indexOf(StringPool.POUND);
1184    
1185                    String testCaseCommand = testCase.substring(x + 1);
1186    
1187                    String extendedTestCase = rootElement.attributeValue("extends");
1188    
1189                    if (extendedTestCase != null) {
1190                            Element extendedTestCaseRootElement = getTestCaseRootElement(
1191                                    extendedTestCase);
1192    
1193                            if (testCaseCommand.equals("set-up")) {
1194                                    Element extendedTestCaseSetUpElement =
1195                                            extendedTestCaseRootElement.element("set-up");
1196    
1197                                    if (extendedTestCaseSetUpElement == null) {
1198                                            _seleniumBuilderFileUtil.throwValidationException(
1199                                                    1006, fileName, element, "test-case");
1200                                    }
1201                            }
1202                            else if (testCaseCommand.equals("tear-down")) {
1203                                    Element extendedTestCaseTearDownElement =
1204                                            extendedTestCaseRootElement.element("tear-down");
1205    
1206                                    if (extendedTestCaseTearDownElement == null) {
1207                                            _seleniumBuilderFileUtil.throwValidationException(
1208                                                    1006, fileName, element, "test-case");
1209                                    }
1210                            }
1211                            else {
1212                                    Set<String> extendedTestCaseCommandNames =
1213                                            _testCaseCommandNames.get(extendedTestCase);
1214    
1215                                    if (!extendedTestCaseCommandNames.contains(testCaseCommand)) {
1216                                            _seleniumBuilderFileUtil.throwValidationException(
1217                                                    1006, fileName, element, "test-case");
1218                                    }
1219                            }
1220                    }
1221                    else {
1222                            _seleniumBuilderFileUtil.throwValidationException(
1223                                    1004, fileName, rootElement, new String[] {"extends"});
1224                    }
1225            }
1226    
1227            private static final Pattern _pattern = Pattern.compile(
1228                    "public [a-z]* [A-Za-z0-9_]*\\(.*?\\)");
1229    
1230            private final Map<String, String> _actionClassNames =
1231                    new HashMap<String, String>();
1232            private final Map<String, String> _actionFileNames =
1233                    new HashMap<String, String>();
1234            private final Map<String, String> _actionJavaFileNames =
1235                    new HashMap<String, String>();
1236            private final Set<String> _actionNames = new HashSet<String>();
1237            private final Map<String, String> _actionPackageNames =
1238                    new HashMap<String, String>();
1239            private final Map<String, Element> _actionRootElements =
1240                    new HashMap<String, Element>();
1241            private final Map<String, String> _actionSimpleClassNames =
1242                    new HashMap<String, String>();
1243            private final Map<String, String> _functionClassNames =
1244                    new HashMap<String, String>();
1245            private final Map<String, String> _functionFileNames =
1246                    new HashMap<String, String>();
1247            private final Map<String, String> _functionJavaFileNames =
1248                    new HashMap<String, String>();
1249            private final Map<String, Integer> _functionLocatorCounts =
1250                    new HashMap<String, Integer>();
1251            private final Set<String> _functionNames = new HashSet<String>();
1252            private final Map<String, String> _functionPackageNames =
1253                    new HashMap<String, String>();
1254            private final Map<String, String> _functionReturnTypes =
1255                    new HashMap<String, String>();
1256            private final Map<String, Element> _functionRootElements =
1257                    new HashMap<String, Element>();
1258            private final Map<String, String> _functionSimpleClassNames =
1259                    new HashMap<String, String>();
1260            private final Map<String, String> _macroClassNames =
1261                    new HashMap<String, String>();
1262            private final Map<String, String> _macroFileNames =
1263                    new HashMap<String, String>();
1264            private final Map<String, String> _macroJavaFileNames =
1265                    new HashMap<String, String>();
1266            private final Set<String> _macroNames = new HashSet<String>();
1267            private final Map<String, String> _macroPackageNames =
1268                    new HashMap<String, String>();
1269            private final Map<String, Element> _macroRootElements =
1270                    new HashMap<String, Element>();
1271            private final Map<String, String> _macroSimpleClassNames =
1272                    new HashMap<String, String>();
1273            private final Map<String, String> _pathClassNames =
1274                    new HashMap<String, String>();
1275            private final Map<String, String> _pathFileNames =
1276                    new HashMap<String, String>();
1277            private final Map<String, String> _pathJavaFileNames =
1278                    new HashMap<String, String>();
1279            private final Set<String> _pathNames = new HashSet<String>();
1280            private final Map<String, String> _pathPackageNames =
1281                    new HashMap<String, String>();
1282            private final Map<String, Element> _pathRootElements =
1283                    new HashMap<String, Element>();
1284            private final Map<String, String> _pathSimpleClassNames =
1285                    new HashMap<String, String>();
1286            private final SeleniumBuilderFileUtil _seleniumBuilderFileUtil;
1287            private final Map<String, Integer> _seleniumParameterCounts =
1288                    new HashMap<String, Integer>();
1289            private final Map<String, String> _testCaseClassNames =
1290                    new HashMap<String, String>();
1291            private final Map<String, Set<String>> _testCaseCommandNames =
1292                    new HashMap<String, Set<String>>();
1293            private final Map<String, String> _testCaseFileNames =
1294                    new HashMap<String, String>();
1295            private final Map<String, String> _testCaseHTMLFileNames =
1296                    new HashMap<String, String>();
1297            private final Map<String, String> _testCaseJavaFileNames =
1298                    new HashMap<String, String>();
1299            private final Set<String> _testCaseNames = new HashSet<String>();
1300            private final Map<String, String> _testCasePackageNames =
1301                    new HashMap<String, String>();
1302            private final Map<String, Element> _testCaseRootElements =
1303                    new HashMap<String, Element>();
1304            private final Map<String, String> _testCaseSimpleClassNames =
1305                    new HashMap<String, String>();
1306    
1307    }