package net.matuschek.html;
/*************************************************
Copyright (c) 2001/2002 by Daniel Matuschek
**************************************************/
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Vector;
import net.matuschek.http.ExtendedURL;
import net.matuschek.http.HttpConstants;
import org.apache.log4j.Category;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
/**
* This class fills out form fields by predefined values
*
* @author Daniel Matuschek
* @version $Id: FormFiller.java,v 1.9 2003/01/30 14:54:51 oliver_schmidt Exp $
*/
public class FormFiller {
/**
* Form Handlers
* @link aggregation
* @associates <{FormHandler}>
*/
private Vector formHandlers = null;
/** Log4J category for logging purposes */
private Category log;
/**
* Basic initialization
*/
public FormFiller() {
log = Category.getInstance(getClass().getName());
}
/**
* Initializes the form filler with a given list of form handlers
*
* @param formHandlers a Vector containing FormHandler objects
*/
public FormFiller(Vector formHandler) {
this();
this.formHandlers = formHandler;
}
/**
* Sets the list of form handlers
* @param formHandlers a Vector containing FormHandler objects
*/
public void setFormHandlers(Vector formHandlers) {
this.formHandlers = formHandlers;
}
/**
* Gets the list of form handlers
* @return a Vector containing FormHandler objects
*/
public Vector getFormHandlers() {
return this.formHandlers;
}
/**
* Tries to fill the given form with values
*
* @param baseURL the URL of the form itself. needed for relative adressing
* @param form a element node containing a DOM description of a form
* (e.g. from a DOM parser or HTML Tidy)
*
* @return a form filled with values or null, if no form handler was found
*/
public ExtendedURL fillForm(URL baseURL, Element form) {
ExtendedURL eurl = new ExtendedURL();
String formURL = form.getAttribute("action");
String type = form.getAttribute("method");
FormHandler handler;
URL absoluteFormURL = null;
try {
absoluteFormURL = new URL(baseURL, formURL);
} catch( MalformedURLException e) {
log.info("MalformedURLException in fillForm(): "+e.getMessage());
}
if (! form.getNodeName().equals("form")) {
log.error("not a form !");
return null;
}
handler = getFormHandler(absoluteFormURL.toString());
if (handler == null) {
log.debug("found no form handler for URL "+formURL);
return null;
}
if (type.equalsIgnoreCase("get")) {
eurl.setRequestMethod(HttpConstants.GET);
} else if (type.equalsIgnoreCase("post")) {
eurl.setRequestMethod(HttpConstants.POST);
} else if (type.equals("")) {
// workaround for sites that have no "action" attribute
// in their forms, like Google :-(
eurl.setRequestMethod(HttpConstants.GET);
} else {
log.debug("method "+type+" unknown");
return null;
}
try {
eurl.setURL(absoluteFormURL);
} catch (Exception e) {
log.debug("error calculating URL: "+e.getMessage());
}
// clear the old data in this form handler
handler.clearValues();
// okay, now fill the form fields ...
collectInputFields(form, handler);
eurl.setParams(handler.getParamString());
return eurl;
}
/**
* Get
*/
private void collectInputFields(Element element, FormHandler fh) {
// this should not happen !
if (element==null) {
log.error("got a null element");
return;
}
if (element.getNodeName().equals("input")) {
String type = element.getAttribute("type").toLowerCase();
String name = element.getAttribute("name");
String value = element.getAttribute("value");
// ignore reset tags
if (! type.equals("reset")) {
// must have a name
if ((name != null) && (! name.equals(""))) {
// must have a value
if ((value != null) && (! value.equals(""))) {
// add this value to the form handler
fh.addValue(name, value);
}
}
}
}
// recursive travel through all childs
NodeList childs = element.getChildNodes();
for (int i=0; i<childs.getLength(); i++) {
if (childs.item(i) instanceof Element) {
collectInputFields((Element)childs.item(i),fh);
}
}
}
/**
* Gets a form handler for a given URL
* @param u an URL
* @return a FormHandler object, if there is a registered FormHandler
* for this URL, null otherwise
*/
protected FormHandler getFormHandler(String url) {
if (url == null) {
return null;
}
if (formHandlers == null) {
return null;
}
for (int i=0; i<formHandlers.size(); i++) {
FormHandler fh = (FormHandler)formHandlers.elementAt(i);
if (fh.getUrl().toString().equals(url)) {
return fh;
}
}
return null;
}
}