/* * Sun Public License * * The contents of this file are subject to the Sun Public License Version * 1.0 (the "License"). You may not use this file except in compliance with * the License. A copy of the License is available at http://www.sun.com/ * * The Original Code is the SLAMD Distributed Load Generation Engine. * The Initial Developer of the Original Code is Neil A. Wilson. * Portions created by Neil A. Wilson are Copyright (C) 2004-2010. * Some preexisting portions Copyright (C) 2002-2006 Sun Microsystems, Inc. * All Rights Reserved. * * Contributor(s): Neil A. Wilson */ package com.slamd.scripting.engine; import com.slamd.job.JobClass; import com.slamd.stat.StatTracker; import com.slamd.scripting.general.BooleanLiteral; /** * This class defines a generic variable that may be defined in an LDAP script. * * * @author Neil A. Wilson */ public abstract class Variable implements Argument { // The name of the variable. private String name; /** * Creates a new variable with no name, to be used only when creating a * variable with <CODE>Class.newInstance()</CODE>, and only when * <CODE>setName()</CODE> is called after that to set the name. */ public Variable() { // No implementation required. } /** * Creates a generic variable with a name but no value. * * @param name The name to use for this variable. */ public Variable(String name) { this.name = name; } /** * Retrieves the name of the variable type for this variable. * * @return The name of the variable type for this variable. */ public abstract String getVariableTypeName(); /** * Sets the name of this variable. * * @param name The name to use for this variable. */ public void setName(String name) { this.name = name; } /** * Retrieves the name of this variable. * * @return The name of this variable. */ public String getName() { return name; } /** * Indicates whether the specified string may be used as a variable or method * identifier in a SLAMD script. All valid identifiers must start with an * alphabetic character and must contain only alphabetic characters, numeric * digits, or underscore characters. * * @param identifierName The name of the identifier for which to make the * determination. * * @return <CODE>true</CODE> if the provided name may be used as a valid * identifier, or <CODE>false</CODE> if not. */ public static boolean isValidIdentifier(String identifierName) { // We can't allow an empty identifier name. if ((identifierName == null) || (identifierName.length() == 0)) { return false; } // Convert the identifier name to all lowercase. identifierName = identifierName.toLowerCase(); // Make sure that the provided identifier name is not one of the reserved // words. if (ScriptParser.isReservedWord(identifierName)) { return false; } // Make sure that the provided identifier name is not one of the boolean // literal values. if (identifierName.equals(BooleanLiteral.BOOLEAN_TRUE_VALUE) || identifierName.equals(BooleanLiteral.BOOLEAN_FALSE_VALUE)) { return false; } // Convert the provided name to a character array for easier comparison. char[] nameChars = identifierName.toLowerCase().toCharArray(); // The first character must be alphabetic. if (! ((nameChars[0] >= 'a') && (nameChars[0] <= 'z'))) { return false; } // Now iterate through the remaining characters and check to make sure they // are alphabetic, numeric, or underscore characters. for (int i=1; i < nameChars.length; i++) { if (! (((nameChars[i] >= 'a') && (nameChars[i] <= 'z')) || ((nameChars[i] >= '0') && (nameChars[i] <= '9')) || (nameChars[i] == '_'))) { return false; } } // If we got here, then there doesn't seem to be anything wrong with it. return true; } /** * Retrieves a list of all methods defined for this variable. * * @return A list of all methods defined for this variable. */ public abstract Method[] getMethods(); /** * Indicates whether this variable type has a method with the specified name. * * @param methodName The name of the method. * * @return <CODE>true</CODE> if this variable has a method with the specified * name, or <CODE>false</CODE> if it does not. */ public abstract boolean hasMethod(String methodName); /** * Retrieves the method number for the method that has the specified name and * argument types, or -1 if there is no such method. * * @param methodName The name of the method. * @param argumentTypes The list of argument types for the method. * * @return The method number for the method that has the specified name and * argument types. */ public abstract int getMethodNumber(String methodName, String[] argumentTypes); /** * Retrieves the return type for the method with the specified name and * argument types. * * @param methodName The name of the method. * @param argumentTypes The set of argument types for the method. * * @return The return type for the method, or <CODE>null</CODE> if there is * no such method defined. */ public abstract String getReturnTypeForMethod(String methodName, String[] argumentTypes); /** * Executes the specified method, using the provided variables as arguments * to the method, and makes the return value available to the caller. * * @param lineNumber The line number of the script in which the method * call occurs. * @param methodNumber The method number of the method to execute. * @param arguments The set of arguments to use for the method. * * @return The value returned from the method, or <CODE>null</CODE> if it * does not return a value. * * @throws ScriptException If the specified method does not exist, or if a * problem occurs while attempting to execute it. */ public abstract Variable executeMethod(int lineNumber, int methodNumber, Argument[] arguments) throws ScriptException; /** * Retrieves the set of stat trackers that are maintained for this variable * type. Note that most variables should not maintain stat trackers -- only * those that perform a function for which it is worthwhile to report * statistics back to the SLAMD server. Also note that if this method is * implemented by a variable type, then the <CODE>startStatTrackers()</CODE> * and <CODE>stopStatTrackers()</CODE> methods must also be implemented to * make sure that they are handled properly. * * @return The set of stat trackers that are maintained for this variable * type. */ public StatTracker[] getStatTrackers() { return new StatTracker[0]; } /** * Notifies all the stat trackers associated with this variable type that they * should start collecting statistics. * * @param jobThread The job thread for which the statistics will be * gathered. */ public void startStatTrackers(JobClass jobThread) { return; } /** * Notifies all the stat trackers associated with this variable type that they * should start collecting statistics. */ public void stopStatTrackers() { return; } /** * Retrieves the name of the data type associated with this argument. * * @return The name of the data type associated with this argument. */ public String getArgumentType() { return getVariableTypeName(); } /** * Retrieves the value of this argument. * * @return The value of this argument. * * @throws ScriptException If a problem occurs while determining the value * of this argument. */ public Variable getArgumentValue() throws ScriptException { return this; } /** * Assigns the value of the provided argument to this variable. The value of * the provided argument must be of the same type as this variable. * * @param argument The argument whose value should be assigned to this * variable. * * @throws ScriptException If there is a problem while performing the * assignment. */ public abstract void assign(Argument argument) throws ScriptException; /** * Retrieves a string representation of this argument in a form appropriate * for inclusion in a script. * * @return A string representation of this argument in a form appropriate for * inclusion in a script. */ public String getArgumentAsString() { return name; } }