com.meterware.httpunit.WebForm Maven / Gradle / Ivy
The newest version!
package com.meterware.httpunit;
/********************************************************************************************************************
* $Id: WebForm.java 952 2008-05-02 16:01:23Z wolfgang_fahl $
*
* Copyright (c) 2000-2008, Russell Gold
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
* to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
* THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*******************************************************************************************************************/
import com.meterware.httpunit.scripting.NamedDelegate;
import com.meterware.httpunit.scripting.ScriptableDelegate;
import com.meterware.httpunit.scripting.FormScriptable;
import com.meterware.httpunit.protocol.UploadFileSpec;
import com.meterware.httpunit.protocol.ParameterProcessor;
import java.io.IOException;
import java.io.File;
import java.net.URL;
import java.net.UnknownServiceException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import org.w3c.dom.Node;
import org.w3c.dom.html.HTMLFormElement;
import org.w3c.dom.html.HTMLCollection;
import org.xml.sax.SAXException;
/**
* This class represents a form in an HTML page. Users of this class may examine the parameters
* defined for the form, the structure of the form (as a DOM), or the text of the form. They
* may also create a {@link WebRequest} to simulate the submission of the form.
*
* @author Russell Gold
**/
public class WebForm extends WebRequestSource {
private static final FormParameter UNKNOWN_PARAMETER = new FormParameter();
private final static String[] NO_VALUES = new String[0];
private Button[] _buttons;
/** The submit buttons in this form. **/
private SubmitButton[] _submitButtons;
/** The character set in which the form will be submitted. **/
private String _characterSet;
private Vector _buttonVector;
private FormControl[] _presetParameters;
private ArrayList _presets;
private ElementRegistry _registry;
/** Predicate to match a link's name. **/
public final static HTMLElementPredicate MATCH_NAME;
private HTMLFormElement _domElement;
/**
* Submits this form using the web client from which it was originally obtained.
**/
public WebResponse submit() throws IOException, SAXException {
return submit( getDefaultButton() );
}
/**
* Submits this form using the web client from which it was originally obtained.
* Will usually return the result of that submission; however, if the submit button's 'onclick'
* or the form's 'onsubmit' event is triggered and
* inhibits the submission, will return the updated contents of the frame containing this form.
**/
public WebResponse submit( SubmitButton button ) throws IOException, SAXException {
WebResponse result=submit(button,0,0);
return result;
}
/**
* Submits this form using the web client from which it was originally obtained.
* Will usually return the result of that submission; however, if the submit button's 'onclick'
* or the form's 'onsubmit' event is triggered and
* inhibits the submission, will return the updated contents of the frame containing this form.
* @since 1.6
**/
public WebResponse submit( SubmitButton button, int x, int y ) throws IOException, SAXException {
WebResponse result=null;
if (button==null || button.doOnClickSequence(x, y)) {
result= doFormSubmit( button, x, y );
} else {
result=getCurrentFrameContents();
}
return result;
}
/**
* Submits this form using the web client from which it was originally obtained, ignoring any buttons defined for the form.
* @since 1.6
**/
public WebResponse submitNoButton() throws SAXException, IOException {
return submit( SubmitButton.createFakeSubmitButton( this /* fake */ ) );
}
protected WebResponse submitRequest( String event, WebRequest request ) throws IOException, SAXException {
try {
return super.submitRequest( event, request );
} catch (UnknownServiceException e) {
throw new UnsupportedActionException( "HttpUnit does not support " + request.getURL().getProtocol() + " URLs in form submissions" );
}
}
/**
* Submits the form without also invoking the button's "onclick" event.
*/
WebResponse doFormSubmit( SubmitButton button ) throws IOException, SAXException {
return submitRequest( getAttribute( "onsubmit" ), getRequest( button ) );
}
WebResponse doFormSubmit( SubmitButton button, int x, int y ) throws IOException, SAXException {
return submitRequest( getAttribute( "onsubmit" ), getRequest( button, x, y ) );
}
/**
* Returns the method defined for this form.
**/
public String getMethod() {
return getAttribute( "method", "GET" );
}
/**
* Returns the action defined for this form.
**/
public String getAction() {
return getDestination();
}
/**
* Returns true if a parameter with given name exists in this form.
**/
public boolean hasParameterNamed( String soughtName ) {
return getFormParameters().containsKey( soughtName );
}
/**
* Returns true if a parameter starting with a given name exists,
**/
public boolean hasParameterStartingWithPrefix( String prefix ) {
String[] names = getParameterNames();
for (int i = 0; i < names.length; i++) {
if (names[i].startsWith( prefix )) return true;
}
return false;
}
/**
* Returns an array containing all of the buttons defined for this form.
**/
public Button[] getButtons() {
if (_buttons == null) {
FormControl[] controls = getFormControls();
ArrayList buttonList = new ArrayList();
for (int i = 0; i < controls.length; i++) {
FormControl control = controls[ i ];
if (control instanceof Button) buttonList.add( control );
}
_buttons = (Button[]) buttonList.toArray( new Button[ buttonList.size() ] );
}
return _buttons;
}
public Button getButton( HTMLElementPredicate predicate, Object criteria ) {
Button[] buttons = getButtons();
for (int i = 0; i < buttons.length; i++) {
if (predicate.matchesCriteria( buttons[i], criteria )) return buttons[i];
}
return null;
}
/**
* Convenience method which returns the button with the specified ID.
*/
public Button getButtonWithID( String buttonID ) {
return getButton( Button.WITH_ID, buttonID );
}
/**
* Returns an array containing the submit buttons defined for this form.
**/
public SubmitButton[] getSubmitButtons() {
if (_submitButtons == null) {
Vector buttons = getSubmitButtonVector();
_submitButtons = new SubmitButton[ buttons.size() ];
buttons.copyInto( _submitButtons );
}
return _submitButtons;
}
/**
* Returns the submit button defined in this form with the specified name.
* If more than one such button exists, will return the first found.
* If no such button is found, will return null.
**/
public SubmitButton getSubmitButton( String name ) {
SubmitButton[] buttons = getSubmitButtons();
for (int i = 0; i < buttons.length; i++) {
if (buttons[i].getName().equals( name )) {
return buttons[i];
}
}
return null;
}
/**
* Returns the submit button defined in this form with the specified name and value.
* If more than one such button exists, will return the first found.
* If no such button is found, will return null.
**/
public SubmitButton getSubmitButton( String name, String value ) {
SubmitButton[] buttons = getSubmitButtons();
for (int i = 0; i < buttons.length; i++) {
if (buttons[i].getName().equals( name ) && buttons[i].getValue().equals( value )) {
return buttons[i];
}
}
return null;
}
/**
* Returns the submit button defined in this form with the specified ID.
* If more than one such button exists, will return the first found.
* If no such button is found, will return null.
**/
public SubmitButton getSubmitButtonWithID( String ID ) {
SubmitButton[] buttons = getSubmitButtons();
for (int i = 0; i < buttons.length; i++) {
if (buttons[i].getID().equals( ID )) {
return buttons[i];
}
}
return null;
}
/**
* Creates and returns a web request which will simulate the submission of this form with a button with the specified name and value.
**/
public WebRequest getRequest( String submitButtonName, String submitButtonValue ) {
SubmitButton sb = getSubmitButton( submitButtonName, submitButtonValue );
if (sb == null) throw new IllegalSubmitButtonException( submitButtonName, submitButtonValue );
return getRequest( sb );
}
/**
* Creates and returns a web request which will simulate the submission of this form with a button with the specified name.
**/
public WebRequest getRequest( String submitButtonName ) {
SubmitButton sb = getSubmitButton( submitButtonName );
if (sb == null) throw new IllegalSubmitButtonException( submitButtonName, "" );
return getRequest( sb );
}
/**
* Creates and returns a web request which will simulate the submission of this form by pressing the specified button.
* If the button is null, simulates the pressing of the default button.
**/
public WebRequest getRequest( SubmitButton button ) {
return getRequest( button, 0, 0 );
}
/**
* Creates and returns a web request which will simulate the submission of this form by pressing the specified button.
* If the button is null, simulates the pressing of the default button.
* @param button - the submitbutton to be pressed - may be null
* @param x - the x position
* @param y - the y position
**/
public WebRequest getRequest( SubmitButton button, int x, int y ) {
if (button == null)
button = getDefaultButton();
if (HttpUnitOptions.getParameterValuesValidated()) {
if (button == null) {
throw new IllegalUnnamedSubmitButtonException();
} else if (button.isFake()) {
// bypass checks
} else if (!getSubmitButtonVector().contains( button )) {
throw new IllegalSubmitButtonException( button );
} else if (!button.wasEnabled()) {
// this is too late for the check of isDisabled()
// onclick has already been done ...
// [ 1289151 ] Order of events in button.click() is wrong
button.throwDisabledException();
}
}
SubmitButton[] buttons = getSubmitButtons();
for (int i = 0; i < buttons.length; i++) {
buttons[i].setPressed( false );
}
button.setPressed( true );
if (getMethod().equalsIgnoreCase( "post" )) {
return new PostMethodWebRequest( this, button, x, y );
} else {
return new GetMethodWebRequest( this, WebRequest.newParameterHolder( this ), button, x, y );
}
}
/**
* Creates and returns a web request which includes the specified button. If no button is specified, will include
* the default button, if any. No parameter validation will be done on the returned request and no scripts
* will be run when it is submitted.
**/
public WebRequest newUnvalidatedRequest( SubmitButton button ) {
return newUnvalidatedRequest( button, 0, 0 );
}
/**
* Creates and returns a web request which includes the specified button and position. If no button is specified,
* will include the default button, if any. No parameter validation will be done on the returned request
* and no scripts will be run when it is submitted.
**/
public WebRequest newUnvalidatedRequest( SubmitButton button, int x, int y ) {
if (button == null) button = getDefaultButton();
SubmitButton[] buttons = getSubmitButtons();
for (int i = 0; i < buttons.length; i++) {
buttons[i].setPressed( false );
}
button.setPressed( true );
if (getMethod().equalsIgnoreCase( "post" )) {
return new PostMethodWebRequest( this, new UncheckedParameterHolder( this ), button, x, y );
} else {
return new GetMethodWebRequest( this, new UncheckedParameterHolder( this ), button, x, y );
}
}
private WebRequest getScriptedSubmitRequest() {
SubmitButton[] buttons = getSubmitButtons();
for (int i = 0; i < buttons.length; i++) {
buttons[i].setPressed( false );
}
if (getMethod().equalsIgnoreCase( "post" )) {
return new PostMethodWebRequest( this );
} else {
return new GetMethodWebRequest( this );
}
}
/**
* Returns the default value of the named parameter. If the parameter does not exist returns null.
**/
public String getParameterValue( String name ) {
String[] values = getParameterValues( name );
return values.length == 0 ? null : values[0];
}
/**
* Returns the displayed options defined for the specified parameter name.
**/
public String[] getOptions( String name ) {
return getParameter( name ).getOptions();
}
/**
* Returns the option values defined for the specified parameter name.
**/
public String[] getOptionValues( String name ) {
return getParameter( name ).getOptionValues();
}
/**
* Returns true if the named parameter accepts multiple values.
**/
public boolean isMultiValuedParameter( String name ) {
return getParameter( name ).isMultiValuedParameter();
}
/**
* Returns the number of text parameters in this form with the specified name.
**/
public int getNumTextParameters( String name ) {
return getParameter( name ).getNumTextParameters();
}
/**
* Returns true if the named parameter accepts free-form text.
**/
public boolean isTextParameter( String name ) {
return getParameter( name ).isTextParameter();
}
/**
* Returns true if this form is to be submitted using mime encoding (the default is URL encoding).
**/
public boolean isSubmitAsMime() {
return "multipart/form-data".equalsIgnoreCase( getAttribute( "enctype" ) );
}
public FormScriptable getScriptableObject() {
return (FormScriptable) getScriptingHandler();
}
/**
* Resets all parameters to their initial values.
*/
public void reset() {
if (handleEvent("onreset"))
resetControls();
}
private void resetControls() {
FormControl[] controls = getFormControls();
for (int i = 0; i < controls.length; i++) {
controls[i].reset();
}
}
public ScriptableDelegate newScriptable() {
return new Scriptable();
}
//---------------------------------- WebRequestSource methods --------------------------------
/**
* Returns the character set encoding for this form.
**/
public String getCharacterSet() {
return _characterSet;
}
/**
* Returns true if the named parameter accepts files for upload.
**/
public boolean isFileParameter( String name ) {
return getParameter( name ).isFileParameter();
}
/**
* Returns an array containing the names of the parameters defined for this form.
**/
public String[] getParameterNames() {
ArrayList parameterNames = new ArrayList( getFormParameters().keySet() );
return (String[]) parameterNames.toArray( new String[ parameterNames.size() ] );
}
/**
* Returns the multiple default values of the named parameter.
**/
public String[] getParameterValues( String name ) {
final FormParameter parameter = getParameter( name );
return parameter.getValues();
}
/**
* Returns true if the named parameter is read-only. If more than one control exists with the same name,
* will return true only if all such controls are read-only.
**/
public boolean isReadOnlyParameter( String name ) {
return getParameter( name ).isReadOnlyParameter();
}
/**
* Returns true if the named parameter is disabled. If more than one control exists with the same name,
* will return true only if all such controls are read-only.
**/
public boolean isDisabledParameter( String name ) {
return getParameter( name ).isDisabledParameter();
}
/**
* Returns true if the named parameter is hidden. If more than one control exists with the same name,
* will return true only if all such controls are hidden.
**/
public boolean isHiddenParameter( String name ) {
return getParameter( name ).isHiddenParameter();
}
/**
* Creates and returns a web request which will simulate the submission of this form with an unnamed submit button.
**/
public WebRequest getRequest() {
return getRequest( (SubmitButton) null );
}
/**
* Creates and returns a web request based on the current state of this form. No parameter validation will be done
* and there is no guarantee over the order of parameters transmitted.
*/
public WebRequest newUnvalidatedRequest() {
return newUnvalidatedRequest( null );
}
/**
* Records a parameter defined by including it in the destination URL. Ignores any parameters whose name matches
* a form control.
**/
protected void addPresetParameter( String name, String value ) {
FormControl[] formControls = getFormControls();
for (int i = 0; i < formControls.length; i++) {
if (formControls[i].getName().equals( name)) return;
}
_presets.add( new PresetFormParameter( this, name, value ) );
}
protected String getEmptyParameterValue() {
return null;
}
//---------------------------------- ParameterHolder methods --------------------------------
/**
* Specifies the position at which an image button (if any) was clicked.
**/
void selectImageButtonPosition( SubmitButton imageButton, int x, int y ) {
imageButton.setLocation( x, y );
}
/**
* Iterates through the fixed, predefined parameters in this holder, recording them in the supplied parameter processor.\
* These parameters always go on the URL, no matter what encoding method is used.
**/
void recordPredefinedParameters( ParameterProcessor processor ) throws IOException {
FormControl[] controls = getPresetParameters();
for (int i = 0; i < controls.length; i++) {
controls[i].addValues( processor, getCharacterSet() );
}
}
/**
* Iterates through the parameters in this holder, recording them in the supplied parameter processor.
**/
public void recordParameters( ParameterProcessor processor ) throws IOException {
FormControl[] controls = getFormControls();
for (int i = 0; i < controls.length; i++) {
controls[i].addValues( processor, getCharacterSet() );
}
}
/**
* Removes a parameter name from this collection.
**/
public void removeParameter( String name ) {
setParameter( name, NO_VALUES );
}
/**
* Sets the value of a parameter in this form.
* @param name - the name of the parameter
* @param value - the value of the parameter
**/
public void setParameter( String name, String value ) {
setParameter( name, new String[] { value } );
}
/**
* Sets the multiple values of a parameter in this form. This is generally used when there are multiple
* controls with the same name in the form.
*/
public void setParameter( String name, final String[] values ) {
FormParameter parameter = getParameter( name );
if (parameter == UNKNOWN_PARAMETER) throw new NoSuchParameterException( name );
if (parameter.isFileParameter()) {
throw new InvalidFileParameterException(name,values);
}
parameter.setValues( values );
}
/**
* Sets the multiple values of a file upload parameter in a web request.
**/
public void setParameter( String name, UploadFileSpec[] files ) {
FormParameter parameter = getParameter( name );
if ((parameter == null) || (!parameter.isFileParameter()))
throw new NoSuchParameterException( name );
parameter.setFiles( files );
}
/**
* Sets the single value of a file upload parameter in this form.
* A more convenient way to do this than using {@link #setParameter(String,com.meterware.httpunit.protocol.UploadFileSpec[])}
* @since 1.6
*/
public void setParameter( String name, File file ) {
setParameter( name, new UploadFileSpec[] { new UploadFileSpec( file ) } );
}
/**
* Toggles the value of the specified checkbox parameter.
* @param name the name of the checkbox parameter
* @throws IllegalArgumentException if the specified parameter is not a checkbox or there is more than one
* control with that name.
* @since 1.5.4
*/
public void toggleCheckbox( String name ) {
FormParameter parameter = getParameter( name );
if (parameter == null) throw new NoSuchParameterException( name );
parameter.toggleCheckbox();
}
/**
* Toggles the value of the specified checkbox parameter.
* @param name the name of the checkbox parameter
* @param value of the checkbox parameter
* @throws IllegalArgumentException if the specified parameter is not a checkbox or if there is no checkbox
* with the specified name and value.
* @since 1.6
*/
public void toggleCheckbox( String name, String value ) {
FormParameter parameter = getParameter( name );
if (parameter == null) throw new NoSuchParameterException( name );
parameter.toggleCheckbox( value );
}
/**
* Sets the value of the specified checkbox parameter.
* @param name the name of the checkbox parameter
* @param state the new state of the checkbox
* @throws IllegalArgumentException if the specified parameter is not a checkbox or there is more than one
* control with that name.
* @since 1.5.4
*/
public void setCheckbox( String name, boolean state ) {
FormParameter parameter = getParameter( name );
if (parameter == null) throw new NoSuchParameterException( name );
parameter.setValue( state );
}
/**
* Sets the value of the specified checkbox parameter.
* @param name the name of the checkbox parameter
* @param value of the checkbox parameter
* @param state the new state of the checkbox
* @throws IllegalArgumentException if the specified parameter is not a checkbox or if there is no checkbox
* with the specified name and value.
* @since 1.6
*/
public void setCheckbox( String name, String value, boolean state ) {
FormParameter parameter = getParameter( name );
if (parameter == null) throw new NoSuchParameterException( name );
parameter.setValue( value, state );
}
public class Scriptable extends HTMLElementScriptable implements NamedDelegate, FormScriptable {
public String getAction() { return WebForm.this.getAction(); }
public void setAction( String newAction ) { setDestination( newAction ); _presetParameters = null; }
public void submit() throws IOException, SAXException {
submitRequest( getScriptedSubmitRequest() );
}
public void reset() throws IOException, SAXException {
resetControls();
}
public String getName() {
return WebForm.this.getID().length() != 0 ? WebForm.this.getID() : WebForm.this.getName();
}
/**
* get the Object for the given propertyName
* @param propertyName - the name of the property to get
* @return the Object for the property
*/
public Object get( String propertyName ) {
if (propertyName.equals( "target" )) {
return getTarget();
} else if (propertyName.equals( "action" )) {
return getAction();
} else if (propertyName.equals( "length" )) {
return new Integer(getFormControls().length);
} else {
final FormParameter parameter = getParameter( propertyName );
if (parameter != UNKNOWN_PARAMETER) return parameter.getScriptableObject();
FormControl control = getControlWithID( propertyName );
return control == null ? super.get( propertyName ) : control.getScriptingHandler();
}
}
/**
* Sets the value of the named property. Will throw a runtime exception if the property does not exist or
* cannot accept the specified value.
* @param propertyName - the name of the property
* @param value - the new value
**/
public void set( String propertyName, Object value ) {
if (propertyName.equals( "target" )) {
setTargetAttribute( value.toString() );
} else if (propertyName.equals( "action" )) {
setAction( value.toString() );
} else if (value instanceof String) {
setParameterValue( propertyName, (String) value );
} else if (value instanceof Number) {
setParameterValue( propertyName, HttpUnitUtils.trimmedValue( (Number) value ) );
} else {
super.set( propertyName, value );
}
}
public void setParameterValue( String name, String value ) {
final Object scriptableObject = getParameter( name ).getScriptableObject();
if (scriptableObject instanceof ScriptableDelegate) {
((ScriptableDelegate) scriptableObject).set( "value", value );
} else if (scriptableObject instanceof ScriptableDelegate[]) {
((ScriptableDelegate[]) scriptableObject)[0].set( "value", value );
}
}
public ScriptableDelegate[] getElementDelegates() {
FormControl[] controls = getFormControls();
ScriptableDelegate[] result = new ScriptableDelegate[ controls.length ];
for (int i = 0; i < result.length; i++) {
result[i] = (ScriptableDelegate) controls[i].getScriptingHandler();
}
return result;
}
public ScriptableDelegate[] getElementsByTagName( String name ) throws SAXException {
return getDelegates( getHTMLPage().getElementsByTagName( getElement(), name ) );
}
Scriptable() {
super( WebForm.this );
}
}
//---------------------------------- package members --------------------------------
/**
* Contructs a web form given the URL of its source page and the DOM extracted
* from that page.
**/
WebForm( WebResponse response, URL baseURL, Node node, FrameSelector frame, String defaultTarget, String characterSet, ElementRegistry registry ) {
super( response, node, baseURL, "action", frame, defaultTarget );
_characterSet = characterSet;
_registry = registry;
_domElement = (HTMLFormElement) node;
}
/**
* Returns the form control which is part of this form with the specified ID.
*/
public FormControl getControlWithID( String id ) {
FormControl[] controls = getFormControls();
for (int i = 0; i < controls.length; i++) {
FormControl control = controls[i];
if (control.getID().equals(id)) return control;
}
return null;
}
//---------------------------------- private members --------------------------------
private SubmitButton getDefaultButton() {
if (getSubmitButtons().length == 1) {
return getSubmitButtons()[0];
} else {
return getSubmitButton( "" );
}
}
/**
* get the Vector of submit buttons - will always contain at least
* one button - if the original vector has none a faked submit button will be added
* @return a Vector with the submit buttons
*/
private Vector getSubmitButtonVector() {
if (_buttonVector == null) {
_buttonVector = new Vector();
FormControl[] controls = getFormControls();
for (int i = 0; i < controls.length; i++) {
FormControl control = controls[ i ];
if (control instanceof SubmitButton) {
SubmitButton sb=(SubmitButton)control;
sb.rememberEnableState();
_buttonVector.add( sb );
}
}
/**
* make sure that there is always at least one submit button
* if none is in the Vector add a faked one
*/
if (_buttonVector.isEmpty())
_buttonVector.addElement( SubmitButton.createFakeSubmitButton( this ) );
}
return _buttonVector;
}
private FormControl[] getPresetParameters() {
if (_presetParameters == null) {
_presets = new ArrayList();
loadDestinationParameters();
_presetParameters = (FormControl[]) _presets.toArray( new FormControl[ _presets.size() ] );
}
return _presetParameters;
}
FormControl newFormControl( Node child ) {
return FormControl.newFormParameter( this, child );
}
/**
* Returns an array of form parameter attributes for this form.
**/
private FormControl[] getFormControls() {
HTMLCollection controlElements = _domElement.getElements();
FormControl[] controls = new FormControl[ controlElements.getLength() ];
for (int i = 0; i < controls.length; i++) {
controls[i] = getControlForNode( controlElements.item( i ) );
}
return controls;
}
private FormControl getControlForNode( Node node ) {
if (_registry.hasNode( node )) {
return (FormControl) _registry.getRegisteredElement( node );
} else {
return (FormControl) _registry.registerElement( node, newFormControl( node ) );
}
}
/**
* get the form parameter with the given name
* @param name
* @return the form parameter with this name
*/
public FormParameter getParameter( String name ) {
final FormParameter parameter = ((FormParameter) getFormParameters().get( name ));
return parameter != null ? parameter : UNKNOWN_PARAMETER;
}
/**
* Returns a map of parameter name to form parameter objects. Each form parameter object represents the set of form
* controls with a particular name. Unnamed parameters are ignored.
*/
private Map getFormParameters() {
Map formParameters = new HashMap();
loadFormParameters( formParameters, getPresetParameters() );
loadFormParameters( formParameters, getFormControls() );
return formParameters;
}
private void loadFormParameters( Map formParameters, FormControl[] controls ) {
for (int i = 0; i < controls.length; i++) {
if (controls[i].getName().length() == 0) continue;
FormParameter parameter = (FormParameter) formParameters.get( controls[i].getName() );
if (parameter == null) {
parameter = new FormParameter();
formParameters.put( controls[i].getName(), parameter );
}
parameter.addControl( controls[i] );
}
}
static {
MATCH_NAME = new HTMLElementPredicate() {
public boolean matchesCriteria( Object htmlElement, Object criteria ) {
return HttpUnitUtils.matches( ((WebForm) htmlElement).getName(), (String) criteria );
}
};
}
//===========================---===== exception class NoSuchParameterException =========================================
/**
* This exception is thrown on an attempt to set a file parameter to a non file type
**/
class InvalidFileParameterException extends IllegalRequestParameterException {
/**
* construct a new InvalidFileParameterException for the given parameter name and value list
* @param parameterName
* @param values
*/
InvalidFileParameterException( String parameterName, String[] values ) {
_parameterName = parameterName;
_values=values;
}
/**
* get the message for this exception
*/
public String getMessage() {
String valueList="";
String delim="";
for (int i=0;i<_values.length;i++) {
valueList+=delim+"'"+_values[i]+"'";
delim=", ";
}
String msg="The file parameter with the name '"+_parameterName+"' must have type File but the string values "+valueList+" where supplied";
return msg;
}
private String _parameterName;
private String[] _values;
}
/**
* This exception is thrown on an attempt to set a parameter to a value not permitted to it by the form.
**/
class NoSuchParameterException extends IllegalRequestParameterException {
NoSuchParameterException( String parameterName ) {
_parameterName = parameterName;
}
public String getMessage() {
return "No parameter named '" + _parameterName + "' is defined in the form";
}
private String _parameterName;
}
//============================= exception class IllegalUnnamedSubmitButtonException ======================================
/**
* This exception is thrown on an attempt to define a form request with a button not defined on that form.
**/
class IllegalUnnamedSubmitButtonException extends IllegalRequestParameterException {
IllegalUnnamedSubmitButtonException() {
}
public String getMessage() {
return "This form has more than one submit button, none unnamed. You must specify the button to be used.";
}
}
//============================= exception class IllegalSubmitButtonException ======================================
/**
* This exception is thrown on an attempt to define a form request with a button not defined on that form.
**/
class IllegalSubmitButtonException extends IllegalRequestParameterException {
IllegalSubmitButtonException( SubmitButton button ) {
_name = button.getName();
_value = button.getValue();
}
IllegalSubmitButtonException( String name, String value ) {
_name = name;
_value = value;
}
public String getMessage() {
return "Specified submit button (name=\"" + _name + "\" value=\"" + _value + "\") not part of this form.";
}
private String _name;
private String _value;
}
//============================= exception class IllegalUnnamedSubmitButtonException ======================================
}
//========================================== class PresetFormParameter =================================================
class PresetFormParameter extends FormControl {
PresetFormParameter( WebForm form, String name, String value ) {
super( form );
_name = name;
_value = value;
}
/**
* Returns the name of this control..
**/
public String getName() {
return _name;
}
/**
* Returns true if this control is read-only.
**/
public boolean isReadOnly() {
return true;
}
/**
* Returns true if this control accepts free-form text.
**/
public boolean isTextControl() {
return true;
}
/**
* Remove any required values for this control from the list, throwing an exception if they are missing.
**/
void claimRequiredValues( List values ) {
if (_value != null) claimValueIsRequired( values, _value );
}
public String getType() {
return UNDEFINED_TYPE;
}
/**
* Returns the current value(s) associated with this control. These values will be transmitted to the server
* if the control is 'successful'.
**/
public String[] getValues() {
if (_values == null) _values = new String[] { _value };
return _values;
}
protected void addValues( ParameterProcessor processor, String characterSet ) throws IOException {
processor.addParameter( _name, _value, characterSet );
}
private String _name;
private String _value;
private String[] _values;
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy