/*
* 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.parameter;
import java.util.ArrayList;
import java.util.StringTokenizer;
import com.slamd.common.Constants;
/**
* This class defines a parameter that may contain multiple lines of text. Each
* line may be treated as an individual string.
*
*
* @author Neil A. Wilson
*/
public class MultiLineTextParameter
extends Parameter
{
// The number of columns that will be visible in the text area used to
// retrieve the value of the parameter.
private int visibleColumns = 30;
// The number of rows that will be visible in the text area used to retrieve
// the value of the parameter.
private int visibleRows = 5;
// The lines of text associated with this parameter
private String[] lines;
/**
* Creates a new instance of the Parameter to be used when decoding values
* transported over the network, and should not be used by jobs to create
* parameters. If any initialization is needed that will not be covered by
* calls to the <CODE>setName</CODE>, <CODE>setDisplayName</CODE>,
* <CODE>setDescription</CODE>, or <CODE>setValueFromString</CODE>, then it
* should be done here.
*/
public MultiLineTextParameter()
{
super();
// Create an empty set of lines.
lines = new String[0];
}
/**
* Creates a new multi-line text parameter with the specified name. The
* display name will be the same as the name, it will not have a description
* or set of lines, and it will not be required.
*
* @param name The name to use for this parameter.
*/
public MultiLineTextParameter(String name)
{
this(name, name, null, new String[0], false);
}
/**
* Creates a new multi-line text parameter with the specified name and
* required/optional indicator. The display name will be the same as the
* name, and it will not have a description or set of lines.
*
* @param name The name to use for this parameter.
* @param isRequired Indicates whether this parameter is required to have a
* value.
*/
public MultiLineTextParameter(String name, boolean isRequired)
{
this(name, name, null, new String[0], isRequired);
}
/**
* Creates a new multi-line text parameter with the specified name and set of
* lines. The display name will be the same as the name, it will not have a
* description, and it will not be required.
*
* @param name The name to use for this parameter.
* @param lines The set of lines associated with this parameter.
*/
public MultiLineTextParameter(String name, String[] lines)
{
this(name, name, null, lines, false);
}
/**
* Creates a new multi-line text parameter with the specified name, set of
* lines, and required/optional indicator. The display name will be the same
* as the name and it will not have a description.
*
* @param name The name to use for this parameter.
* @param lines The set of lines associated with this parameter.
* @param isRequired Indicates whether this parameter is required to have a
* value.
*/
public MultiLineTextParameter(String name, String[] lines, boolean isRequired)
{
this(name, name, null, lines, isRequired);
}
/**
* Creates a new multi-line parameter with the specified name and display
* name. It will not have a description or set of lines, and it will not be
* required.
*
* @param name The name to use for this parameter.
* @param displayName The display name to use for this parameter.
*/
public MultiLineTextParameter(String name, String displayName)
{
this(name, displayName, null, new String[0], false);
}
/**
* Creates a new multi-line parameter with the specified name, display name,
* and required/optional indicator. It will not have a description or set of
* lines.
*
* @param name The name to use for this parameter.
* @param displayName The display name to use for this parameter.
* @param isRequired Indicates whether this parameter is required to have a
* value.
*/
public MultiLineTextParameter(String name, String displayName,
boolean isRequired)
{
this(name, displayName, null, new String[0], isRequired);
}
/**
* Creates a new multi-line parameter with the specified name, display name,
* and set of lines. It will not have a description, and it will not be
* required.
*
* @param name The name to use for this parameter.
* @param displayName The display name to use for this parameter.
* @param lines The set of lines associated with this parameter.
*/
public MultiLineTextParameter(String name, String displayName, String[] lines)
{
this(name, displayName, null, lines, false);
}
/**
* Creates a new multi-line parameter with the specified name, display name,
* set of lines, and required/optional indicator. It will not have a
* description.
*
* @param name The name to use for this parameter.
* @param displayName The display name to use for this parameter.
* @param lines The set of lines associated with this parameter.
* @param isRequired Indicates whether this parameter is required to have a
* value.
*/
public MultiLineTextParameter(String name, String displayName, String[] lines,
boolean isRequired)
{
this(name, displayName, null, lines, isRequired);
}
/**
* Creates a new multi-line parameter with the specified name, display name,
* description, and set of lines. It will not be required.
*
* @param name The name to use for this parameter.
* @param displayName The display name to use for this parameter.
* @param description The description to use for this parameter.
* @param lines The set of lines associated with this parameter.
*/
public MultiLineTextParameter(String name, String displayName,
String description, String[] lines)
{
this(name, displayName, description, lines, false);
}
/**
* Creates a new multi-line parameter with the specified name, display name,
* description, set of lines, and required/optional indicator.
*
* @param name The name to use for this parameter.
* @param displayName The display name to use for this parameter.
* @param description The description to use for this parameter.
* @param lines The set of lines associated with this parameter.
* @param isRequired Indicates whether this parameter is required to have a
* value.
*/
public MultiLineTextParameter(String name, String displayName,
String description, String[] lines,
boolean isRequired)
{
super(name, displayName, description, isRequired, lines);
this.lines = lines;
}
/**
* Retrieves the set of lines associated with this parameter.
*
* @return The set of lines associated with this parameter.
*/
public String[] getLines()
{
if (lines == null)
{
return new String[0];
}
return lines;
}
/**
* Retrieves the set of non-blank lines associated with this parameter.
*
* @return The set of non-blank lines associated with this parameter.
*/
public String[] getNonBlankLines()
{
if (lines == null)
{
return new String[0];
}
ArrayList<String> lineList = new ArrayList<String>(lines.length);
for (int i=0; i < lines.length; i++)
{
if (lines[i].length() > 0)
{
lineList.add(lines[i]);
}
}
String[] nonBlankLines = new String[lineList.size()];
lineList.toArray(nonBlankLines);
return nonBlankLines;
}
/**
* Breaks up a single string containing line breaks into an array of strings
* separated into lines.
*
* @param multilineText The text to be broken up by line.
*
* @return An array of strings representing the lines in the text provided.
*/
public static String[] breakString(String multilineText)
{
// First, check to see if this text includes actual line breaks.
ArrayList<String> stringList = new ArrayList<String>();
StringTokenizer tokenizer = new StringTokenizer(multilineText, "\n\r");
while (tokenizer.hasMoreTokens())
{
String line = tokenizer.nextToken();
// See if this line itself has any occurrences of the string "\n", which
// will also be interpreted as line breaks (for the benefit of the
// standalone client).
int breakPos = 0;
int startPos = 0;
if (line.contains("\\n"))
{
while ((breakPos = line.indexOf("\\n", startPos)) >= 0)
{
if (breakPos == 0)
{
stringList.add("");
}
else
{
// If it wasn't "\\n", then treat it as a line break.
if (line.charAt(breakPos-1) != '\\')
{
stringList.add(line.substring(startPos, breakPos));
}
else
{
// If it was "\\n", then convert it to "\n".
stringList.add(line.substring(startPos, breakPos) + 'n');
}
}
startPos = breakPos + 2;
}
stringList.add(line.substring(startPos));
}
else
{
stringList.add(line);
}
}
// Next, check to see if it contains the "\n" character, which will also be
// interpreted as a line break, provided that the backslash is not itself
// escaped.
String[] stringArray = new String[stringList.size()];
stringList.toArray(stringArray);
return stringArray;
}
/**
* Retrieves the value for this parameter.
*
* @return The value for this parameter.
*/
@Override()
public String[] getValue()
{
if ((lines == null) || (lines.length == 0))
{
return null;
}
else
{
return lines;
}
}
/**
* Specifies the value to use for this parameter. The provided value must
* either be an array of strings or a single string with line breaks.
*
* @param value The value to use for this parameter.
*
* @throws InvalidValueException If the provided value is of an invalid type
* or if there is no value and the parameter
* is required.
*/
@Override()
public void setValue(Object value)
throws InvalidValueException
{
String invalidReason = getInvalidReason(value);
if (invalidReason != null)
{
throw new InvalidValueException(invalidReason);
}
if (value instanceof String[])
{
this.lines = (String[]) value;
this.value = lines;
}
else if (value instanceof String)
{
this.lines = breakString((String) value);
this.value = lines;
}
}
/**
* Sets the value for this parameter from the information in the provided
* parameter. Note that the provided parameter must be of the same type
* as this parameter or no action will be taken.
*
* @param parameter The parameter from which to take the value for this
* parameter.
*/
@Override()
public void setValueFrom(Parameter parameter)
{
if ((parameter != null) && (parameter instanceof MultiLineTextParameter))
{
MultiLineTextParameter mltp = (MultiLineTextParameter) parameter;
this.value = mltp.value;
this.lines = mltp.lines;
}
}
/**
* Retrieves the number of rows that will be visible when setting the value
* through the HTML interface.
*
* @return The number of rows that will be visible when setting the value
* through the HTML interface.
*/
public int getVisibleRows()
{
return visibleRows;
}
/**
* Specifies the number of rows that will be visible when setting the value
* through the HTML interface.
*
* @param visibleRows The number of rows that will be visible when setting
* the value through the HTML interface.
*/
public void setVisibleRows(int visibleRows)
{
if (visibleRows > 0)
{
this.visibleRows = visibleRows;
}
}
/**
* Retrieves the number of columns that will be visible when setting the value
* through the HTML interface.
*
* @return The number of columns that will be visible when setting the value
* through the HTML interface.
*/
public int getVisibleColumns()
{
return visibleColumns;
}
/**
* Specifies the number of columns that will be visible when setting the value
* through the HTML interface.
*
* @param visibleColumns The number of columns that will be visible when
* setting the value through the HTML interface.
*/
public void setVisibleColumns(int visibleColumns)
{
if (visibleColumns > 0)
{
this.visibleColumns = visibleColumns;
}
}
/**
* Retrieves the value of this parameter as a single string (containing line
* breaks).
*
* @return The value of this parameter as a single string.
*/
@Override()
public String getValueString()
{
if ((lines == null) || (lines.length == 0))
{
return "";
}
else
{
StringBuilder returnBuffer = new StringBuilder(lines[0]);
for (int i=1; i < lines.length; i++)
{
returnBuffer.append(Constants.EOL);
returnBuffer.append(lines[i]);
}
return returnBuffer.toString();
}
}
/**
* Specifies the value to use for this parameter from the provided String.
* Note that no validation is performed with this method.
*
* @param valueString The string representation of the value to use for this
* parameter.
*
* @throws InvalidValueException If the provided value cannot be used to
* provide a value for this parameter.
*/
@Override()
public void setValueFromString(String valueString)
throws InvalidValueException
{
lines = breakString(valueString);
value = lines;
}
/**
* Retrieves the reason that the specified value is not valid.
*
* @param value The value for which to make the determination.
*
* @return The reason that the value is not valid, or <CODE>null</CODE> if it
* is valid.
*/
@Override()
public String getInvalidReason(Object value)
{
if (value == null)
{
if (isRequired)
{
return "No value specified for required parameter";
}
else
{
return null;
}
}
else if (value instanceof String[])
{
String[] valueArr = (String[]) value;
if (isRequired && (valueArr.length == 0))
{
return "No value specified for required parameter";
}
else
{
return null;
}
}
else if (value instanceof String)
{
String[] valueArr = breakString((String) value);
if (isRequired && (valueArr.length == 0))
{
return "No value specified for required parameter";
}
else
{
return null;
}
}
else
{
return (value.getClass().getName() + " is not a supported multi-line " +
"text object type");
}
}
/**
* Retrieves the value in a form that may be displayed to the end user.
*
* @return The value in a form that may be displayed to the end user.
*/
@Override()
public String getDisplayValue()
{
if ((lines == null) || (lines.length == 0))
{
return "";
}
else
{
StringBuilder returnBuffer = new StringBuilder(lines[0]);
for (int i=1; i < lines.length; i++)
{
returnBuffer.append(Constants.EOL);
returnBuffer.append(lines[i]);
}
return returnBuffer.toString();
}
}
/**
* Retrieves the value in a form that may be displayed to the end user as part
* of an HTML document.
*
* @return The value in a form that may be displayed to the end user as part
* of an HTML document.
*/
@Override()
public String getHTMLDisplayValue()
{
if ((lines == null) || (lines.length == 0))
{
return "";
}
else
{
StringBuilder returnBuffer = new StringBuilder();
returnBuffer.append(Constants.makeHTMLSafe(lines[0]));
for (int i=1; i < lines.length; i++)
{
returnBuffer.append("<BR>");
returnBuffer.append(Constants.EOL);
returnBuffer.append(Constants.makeHTMLSafe(lines[i]));
}
return returnBuffer.toString();
}
}
/**
* Retrieves a string of text that can be used to request a value for this
* parameter using an HTML form. Note that this should just be for the input
* field itself and should not use the display name or have any special marker
* to indicate whether the value is required or not, as those are to be added
* by whatever is generating the HTML page.
*
* @param prefix The prefix that should be placed in front of the parameter
* name as the name of the form element.
*
* @return A string of text that can be used to request a value for this
* parameter using an HTML form.
*/
@Override()
public String getHTMLInputForm(String prefix)
{
String returnStr = "<TEXTAREA NAME=\"" + prefix + name + "\" ROWS=\"" +
visibleRows + "\" COLS=\"" + visibleColumns + "\">" +
getValueString() + "</TEXTAREA>";
return returnStr;
}
/**
* Specifies the value of this parameter based on the provided text that would
* be returned from posting an HTML form.
*
* @param values The set of values for this parameter contained in the
* servlet request.
*
* @throws InvalidValueException If the specified value is not acceptable
* for this parameter.
*/
@Override()
public void htmlInputFormToValue(String[] values)
throws InvalidValueException
{
if ((values == null) || (values.length == 0))
{
setValue(null);
}
else
{
setValue(breakString(values[0]));
}
}
/**
* Retrieves a string representation of the content that should be included in
* an HTML form in which this parameter should be provided as a hidden
* element.
*
* @param prefix The prefix to use for the parameter name.
*
* @return A string representation of this parameter as a hidden element in
* an HTML form.
*/
@Override()
public String generateHidden(String prefix)
{
if ((lines == null) || (lines.length == 0))
{
return "";
}
StringBuilder buffer = new StringBuilder();
for (int i=0; i < lines.length; i++)
{
buffer.append(lines[i] + '\n');
}
return "<INPUT TYPE=\"HIDDEN\" NAME=\"" + prefix + name +
"\" VALUE=\"" + buffer.toString() + "\">";
}
/**
* Creates a clone of this parameter.
*
* @return A clone of this parameter.
*/
@Override()
public MultiLineTextParameter clone()
{
MultiLineTextParameter mltp = new MultiLineTextParameter(name, displayName,
description, lines,
isRequired);
mltp.visibleRows = visibleRows;
mltp.visibleColumns = visibleColumns;
mltp.setSensitive(isSensitive());
return mltp;
}
}