Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright Technophobia Ltd 2012
*
* This file is part of Substeps.
*
* Substeps is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Substeps is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Substeps. If not, see .
*/
package com.technophobia.substeps.model;
import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import com.technophobia.substeps.model.exception.DuplicateStepImplementationException;
import com.technophobia.substeps.model.exception.StepImplementationException;
import com.technophobia.substeps.model.exception.UnimplementedStepException;
import com.technophobia.substeps.runner.syntax.DefaultSyntaxErrorReporter;
import com.technophobia.substeps.runner.syntax.SyntaxErrorReporter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.*;
import java.util.Map.Entry;
import java.util.regex.PatternSyntaxException;
/**
* @author imoore
*/
public class Syntax {
private static final Logger log = LoggerFactory.getLogger(Syntax.class);
// These two will always be populated
private final Map> stepImplementationMap = new HashMap>();
private final Map> stepImplementationsUsageMap = new HashMap>();
// this is the map of substeps - Define: blah blah and might not be populated
private PatternMap subStepsMap = null;
private boolean strict;
private boolean failOnDuplicateStepImplementations = true;
private String[] nonStrictKeywordPrecedence;
private final SyntaxErrorReporter syntaxErrorReporter;
public Syntax() {
this(new DefaultSyntaxErrorReporter());
}
public Syntax(final SyntaxErrorReporter syntaxErrorReporter) {
this.syntaxErrorReporter = syntaxErrorReporter;
}
public Map> getStepImplementationMap() {
return this.stepImplementationMap;
}
public List getStepImplementations() {
// build a list of the impls in the order of the annotations
final List allImpls = new ArrayList();
final List sortedAnnotations = new ArrayList();
sortedAnnotations.addAll(this.stepImplementationMap.keySet());
Collections.sort(sortedAnnotations);
// get all the PatternMaps for each annotation:
for (final String annotation : sortedAnnotations) {
final PatternMap patternMap = this.stepImplementationMap.get(annotation);
if (patternMap != null) {
for (final StepImplementation impl : patternMap.values()) {
allImpls.add(impl);
}
}
}
return allImpls;
}
private PatternMap getPatternMapForAnnotation(final String keyWord) {
return this.stepImplementationMap.get(keyWord);
}
public void setSubStepsMap(final PatternMap loadSubSteps) {
this.subStepsMap = loadSubSteps;
}
public PatternMap getSubStepsMap() {
return this.subStepsMap;
}
public List getSortedRootSubSteps() {
final List sortedList = new ArrayList();
// this can be null if no substeps files are provided - this is legit behaviour..
if (this.subStepsMap != null) {
final Collection rootSubSteps = this.subStepsMap.values();
sortedList.addAll(rootSubSteps);
Collections.sort(sortedList, ParentStep.PARENT_STEP_COMPARATOR);
}
return sortedList;
}
public void addStepImplementation(final StepImplementation impl) {
stepImplementationsUsageMap.put(impl, new ArrayList());
PatternMap patternMap = this.stepImplementationMap.get(impl.getKeyword());
if (patternMap == null) {
patternMap = new PatternMap();
this.stepImplementationMap.put(impl.getKeyword(), patternMap);
}
final String pattern = impl.getValue();
if (!patternMap.containsPattern(pattern)) {
try {
patternMap.put(pattern, impl);
} catch (final PatternSyntaxException e) {
log.warn("Invalid step implementation pattern: " + e.getMessage() + "\n" + impl.getClass() + "."
+ impl.getMethod() + " will not be added to the syntax");
}
} else {
final StepImplementation implAlreadyGot = patternMap.getValueForPattern(pattern);
if (!implAlreadyGot.getMethod().equals(impl.getMethod())) {
final StepImplementationException ex = new DuplicateStepImplementationException(pattern,
patternMap.getValueForPattern(pattern), impl);
this.syntaxErrorReporter.reportStepImplError(ex);
if (this.failOnDuplicateStepImplementations) {
throw ex;
}
} else {
// this is the same - no need to make a fuss, just ignore it
}
}
}
public void setStrict(final boolean strict, final String[] nonStrictKeywordPrecedence) {
this.strict = strict;
this.nonStrictKeywordPrecedence = nonStrictKeywordPrecedence;
if (!strict && (this.nonStrictKeywordPrecedence == null || this.nonStrictKeywordPrecedence.length == 0)) {
throw new IllegalArgumentException(
"Please provide a keyword precedence in parameter nonStrictKeywordPrecedence to use when running in non strict mode");
}
}
public void setFailOnDuplicateStepImplementations(final boolean failOnDuplicateStepImplementations) {
this.failOnDuplicateStepImplementations = failOnDuplicateStepImplementations;
}
public List getStepImplementations(final String keyword, final String parameterLine,
final File source, final int lineNumber) {
return getStepImplementationsInternal(keyword, parameterLine, false, source, lineNumber);
}
public List checkForStepImplementations(final String keyword, final String parameterLine,
final File source, final int lineNumber) {
return getStepImplementationsInternal(keyword, parameterLine, true, source, lineNumber);
}
private List getStepImplementationsInternal(final String keyword, final String parameterLine,
final boolean okNotTofindAnything, final File source, final int lineNumber) {
List list = getStrictStepimplementation(keyword, parameterLine, okNotTofindAnything,
source, lineNumber);
if (!this.strict
&& ((list == null && okNotTofindAnything) || (!okNotTofindAnything && list != null && list.isEmpty()))) {
// look for an alternative, iterate through the
// nonStrictKeywordPrecedence until we get what we want
for (final String altKeyword : this.nonStrictKeywordPrecedence) {
// don't use the same keyword again
if (altKeyword.compareToIgnoreCase(keyword) != 0) {
final List altStepImplementations = getStrictStepimplementation(altKeyword,
parameterLine.replaceFirst(keyword, altKeyword), okNotTofindAnything, source, lineNumber);
if (altStepImplementations != null && !altStepImplementations.isEmpty()) {
// found an alternative, bail immediately
list = new ArrayList(Collections2.transform(altStepImplementations,
new CloneStepImplementationsWithNewKeywordFunction(keyword)));
break;
}
}
}
}
if (list != null) {
for (final StepImplementation s : list) {
stepImplementationsUsageMap.get(s).add(new StepImplementationUsage(parameterLine, source, lineNumber));
}
}
return list;
}
private List getStrictStepimplementation(final String keyword, final String parameterLine,
final boolean okNotTofindAnything, final File source, final int lineNumber) {
List list = null;
final PatternMap pMap = getPatternMapForAnnotation(keyword);
if (pMap != null) {
list = pMap.get(parameterLine);
} else if (!okNotTofindAnything) {
throw new UnimplementedStepException(parameterLine, source, lineNumber);
}
return list;
}
private static final class CloneStepImplementationsWithNewKeywordFunction implements
Function {
private final String keyword;
public CloneStepImplementationsWithNewKeywordFunction(final String keyword) {
this.keyword = keyword;
}
@Override
public StepImplementation apply(final StepImplementation stepImplementation) {
return stepImplementation != null ? stepImplementation.cloneWithKeyword(this.keyword) : null;
}
}
/**
* @return the strict
*/
public boolean isStrict() {
return this.strict;
}
/**
* @return the nonStrictKeywordPrecedence
*/
public String[] getNonStrictKeywordPrecedence() {
return this.nonStrictKeywordPrecedence;
}
public List getUncalledStepImplementations() {
final List uncalled = new ArrayList();
final Set>> entrySet = stepImplementationsUsageMap
.entrySet();
for (final Entry> e : entrySet) {
if (e.getValue().isEmpty()) {
uncalled.add(e.getKey());
}
}
return uncalled;
}
}