/******************************************************************************* * Copyright (c) 2013 Rene Schneider, GEBIT Solutions GmbH and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package de.gebit.integrity.fixtures; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * Implementations of this class are used to provide an enumeration of all available arbitrary parameters for a fixture * class in Eclipse while test scripts are being edited. You must link implementations to their respective fixture * classes using {@link ArbitraryParameterFixtureLink}.<br> * <br> * Instances of this class must be instantiable using the default no-arg constructor. They will be instantiated inside * the Eclipse JVM. * * @author Rene Schneider - initial API and implementation * */ public interface ArbitraryParameterEnumerator { /** * Returns a list of valid parameters that will be added to the fixed parameter to any of the fixture methods in the * fixture class that this enumerator is connected to. <br \> * <br \> * This method will be called by the editor inside Eclipse; it is the counterpart of * {@link ArbitraryParameterFixture#defineArbitraryParameters(String, Map)}, thus it is expected to return the same * parameters. The name of the fixture method in question is provided, as well as all fixed parameters that have * been defined yet. <br \> * <br \> * The idea behind the arbitrary parameter mechanism is for this method to compute all available arbitrary params * with respect to the fixed parameters and the method being called. Note that this information is not used to * actually limit the parameters that may be entered by the user, but only for providing autocompletion and content * assist as well as automatic conversion of values. The user may still enter a parameter of any name, which will * then be passed to the fixture method without any value conversion. * * @param aFixtureMethodName * The name of the fixture method being called or entered * @param someFixedParameters * A map of fixed parameters and values * @param aNestedObjectPath * A path to the current position in a nested object (null if not in a nested object; this can be used to * optimize the amount of information to return) * @return A list with definitions of arbitrary parameters. */ List<ArbitraryParameterDefinition> defineArbitraryParameters(String aFixtureMethodName, Map<String, Object> someFixedParameters, List<String> aNestedObjectPath); /** * Returns a list of valid result names. This basically works like * {@link #defineArbitraryParameters(String, Map, boolean)}, but is used to determine named result identifiers. * * @param aFixtureMethodName * @param someFixedParameters * @param aNestedObjectPath * @return */ List<ArbitraryParameterDefinition> defineArbitraryResults(String aFixtureMethodName, Map<String, Object> someFixedParameters, List<String> aNestedObjectPath); /** * A container for the definition of one arbitrary parameter. * * @author Rene Schneider - initial API and implementation * */ public class ArbitraryParameterDefinition { /** * The name of the parameter. */ private String name; /** * The description which will appear next to the parameter name in the content assist window. This value is * optional and won't be used when * {@link ArbitraryParameterFixture#defineArbitraryParameters(String, Map, boolean)} was called during test * execution. */ private String description; /** * What to add after the parameter. Optional - if not present, a default is used (usually a colon in case of * parameters and an equals sign in case of results). This is ignored in case of tabletests and inside nested * objects! */ private ArbitraryParameterSuffix suffix; /** * Whether this is a parameter that shall contain a nested object. If this is set, the required brackets are * autocreated. */ private boolean nestedObjectParam; /** * Subdefinitions in case of nested objects/parameters. */ private List<ArbitraryParameterDefinition> subdefinitions = new ArrayList<ArbitraryParameterDefinition>(); /** * Creates a new instance. * * @param aName * The parameter name * @param aDescription * The description for content assist */ public ArbitraryParameterDefinition(String aName, String aDescription) { name = aName; description = aDescription; } /** * Creates a new instance. * * @param aName * The parameter name * @param aDescription * The description for content assist * @param aSuffix * What to add after the parameter. * @param anIsNestedObjectParamFlag * Whether this is a parameter that will contain a nested object. */ public ArbitraryParameterDefinition(String aName, String aDescription, ArbitraryParameterSuffix aSuffix, boolean anIsNestedObjectParamFlag) { name = aName; description = aDescription; suffix = aSuffix; nestedObjectParam = anIsNestedObjectParamFlag; } public String getName() { return name; } public String getDescription() { return description; } public ArbitraryParameterSuffix getSuffix() { return suffix; } public boolean isNestedObjectParam() { return nestedObjectParam; } public void setName(String aName) { this.name = aName; } public void setDescription(String aDescription) { this.description = aDescription; } public void setSuffix(ArbitraryParameterSuffix aSuffix) { this.suffix = aSuffix; } public void setNestedObjectParam(boolean aNestedObjectParam) { this.nestedObjectParam = aNestedObjectParam; } /** * Adds a subdefinition. * * @param aSubdefinition * the subdefinition to add */ public void addSubdefinition(ArbitraryParameterDefinition aSubdefinition) { subdefinitions.add(aSubdefinition); } public List<ArbitraryParameterDefinition> getSubdefinitions() { return subdefinitions; } /** * Checks whether this definition has any subdefinitions. * * @return true if subdefinitions are present */ public boolean hasSubdefinitions() { return subdefinitions.size() > 0; } /** * Searches a subdefinition by name. * * @param aName * the name to search for * @return the subdefinition or null if not found */ public ArbitraryParameterDefinition getSubdefinitionByName(String aName) { for (ArbitraryParameterDefinition tempSubdefinition : subdefinitions) { if (aName.equals(tempSubdefinition.getName())) { return tempSubdefinition; } } return null; } /** * Resolves a path of subdefinitions starting with the current definition (which must be the root of the path!). * * @param aPath * the path to follow * @return the subdefinition at the end of the path, or null if none was found */ public ArbitraryParameterDefinition getSubdefinitionByPath(List<String> aPath) { ArbitraryParameterDefinition tempDefinitionInFocus = null; for (String tempPathPart : aPath) { if (tempDefinitionInFocus == null) { if ((getName() == null && tempPathPart == null) || tempPathPart.equals(getName())) { tempDefinitionInFocus = this; } else { return null; } } else { tempDefinitionInFocus = tempDefinitionInFocus.getSubdefinitionByName(tempPathPart); if (tempDefinitionInFocus == null) { return null; } } } return tempDefinitionInFocus; } } /** * The suffix types that may follow a parameter name in a suggestion. * * * @author Rene Schneider - initial API and implementation * */ public enum ArbitraryParameterSuffix { /** * A colon. */ COLON(": "), /** * An equals sign. */ EQUALS(" = "), /** * A space. */ SPACE(" "); /** * Textual representation of the suffix. */ private String text; private ArbitraryParameterSuffix(String aText) { text = aText; } public String getText() { return text; } } }