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