package org.netbeans.gradle.project.api.task; import java.util.regex.Pattern; import javax.annotation.Nonnull; import org.jtrim.utils.ExceptionHelper; /** * Defines a variable which might be replaced with a given string in Gradle * commands. Variables in strings take the form "${variable-name}" and their * name is case-sensitive. Variable names might only contain: alphanumerical * characters (English alphabet), dash ('-'), underscore ('_') and dot ('.') * and they must contain at least a single character. * <P> * The {@code equals} and {@code hashCode} methods of {@code TaskVariable} are * defined so that two {@code TaskVariable} instance equals, if and only, if * their {@link #getVariableName() name} equals (case-sensitive). * <P> * Instances of {@code TaskVariable} are immutable and as such are safe to be * accessed concurrently without any synchronization. * * @see GradleTaskVariableQuery */ public final class TaskVariable { private static final Pattern VARIABLE_NAME_PATTERN = Pattern.compile("[A-Za-z0-9\\-_\\.]+"); private final String variableName; /** * Creates a new {@code TaskVariable} with the given * {@link #getVariableName() name}. * * @param variableName the name of the variable to be replaced in strings. * The replacement constant will be "${variableName}". This argument * cannot be {@code null}, cannot be empty and may only contain characters * {@link #isValidVariableName(String) allowed for task variables}. * * @throws NullPointerException if the passed variable name is {@code null} * @throws IllegalArgumentException thrown if the variable name is invalid * * @see #isValidVariableName(String) */ public TaskVariable(@Nonnull String variableName) { ExceptionHelper.checkNotNullArgument(variableName, "variableName"); if (!VARIABLE_NAME_PATTERN.matcher(variableName).matches()) { throw new IllegalArgumentException("Variable name contains an invalid character: " + variableName); } this.variableName = variableName; } /** * Checks if the given variable name is appropriate to use or not. The name * is appropriate, if and only, if they only contain alphanumerical * characters (English alphabet), dash ('-'), underscore ('_') or dot ('.') * and they must contain at least a single character. * <P> * If this method returns {@code true}, then calling the constructor of * {@code TaskVariable} with the given name will not throw an exception. If * this method returns {@code false}, then calling the constructor of * {@code TaskVariable} with the given name is guaranteed to throw an * IllegalArgumentException. * * @param variableName the name of the variable to be verified. This * argument cannot be {@code null}. * @return {@code true} if this variable name is valid to use as a * {@code TaskVariable}, {@code false} otherwise * * @throws NullPointerException if the passed variable name is {@code null} */ public static boolean isValidVariableName(@Nonnull String variableName) { ExceptionHelper.checkNotNullArgument(variableName, "variableName"); return VARIABLE_NAME_PATTERN.matcher(variableName).matches(); } /** * Returns the name of the variable as specified at construction time. * * @return the name of the variable as specified at construction time. * This method never returns {@code null}. */ @Nonnull public String getVariableName() { return variableName; } /** * Returns the variable name as it needs to appear in strings to be * replaced. This method simply returns: * <P> * {@code "${" + getVariableName() + "}"}. * * @return the variable name as it needs to appear in strings to be * replaced. This method never returns {@code null}. */ @Nonnull public String getScriptReplaceConstant() { return "${" + variableName + "}"; } /** * {@inheritDoc } * * @return a hash code compatible with the {@code equals} method */ @Override public int hashCode() { return 85 + variableName.hashCode(); } /** * Checks if the specified object is a {@code TaskVariable} and has the * same {@link #getVariableName() name} as this {@code TaskVariable} or not. * <P> * This method will always return {@code false} if the specified object is * not an instance of {@code TaskVariable}. * * @param obj the object to be compared to this {@code TaskVariable}. This * argument can be {@code null}, in which case the return value is * {@code false}. * @return {@code true} if the specified object is a {@code TaskVariable} * and has the same {@link #getVariableName() name} as this * {@code TaskVariable}, {@code false} otherwise */ @Override public boolean equals(Object obj) { if (obj == null) return false; if (obj == this) return true; if (getClass() != obj.getClass()) return false; final TaskVariable other = (TaskVariable)obj; return this.variableName.equals(other.variableName); } }