001: package net.matuschek.html;
002:
003: /*************************************************
004: Copyright (c) 2001/2002 by Daniel Matuschek
005: **************************************************/
006:
007: import java.net.MalformedURLException;
008: import java.net.URL;
009: import java.util.Vector;
010:
011: import net.matuschek.http.ExtendedURL;
012: import net.matuschek.http.HttpConstants;
013:
014: import org.apache.log4j.Category;
015:
016: import org.w3c.dom.Element;
017: import org.w3c.dom.NodeList;
018:
019: /**
020: * This class fills out form fields by predefined values
021: *
022: * @author Daniel Matuschek
023: * @version $Id: FormFiller.java,v 1.9 2003/01/30 14:54:51 oliver_schmidt Exp $
024: */
025: public class FormFiller {
026:
027: /**
028: * Form Handlers
029: * @link aggregation
030: * @associates <{FormHandler}>
031: */
032: private Vector formHandlers = null;
033:
034: /** Log4J category for logging purposes */
035: private Category log;
036:
037: /**
038: * Basic initialization
039: */
040: public FormFiller() {
041: log = Category.getInstance(getClass().getName());
042: }
043:
044: /**
045: * Initializes the form filler with a given list of form handlers
046: *
047: * @param formHandlers a Vector containing FormHandler objects
048: */
049: public FormFiller(Vector formHandler) {
050: this ();
051: this .formHandlers = formHandler;
052: }
053:
054: /**
055: * Sets the list of form handlers
056: * @param formHandlers a Vector containing FormHandler objects
057: */
058: public void setFormHandlers(Vector formHandlers) {
059: this .formHandlers = formHandlers;
060: }
061:
062: /**
063: * Gets the list of form handlers
064: * @return a Vector containing FormHandler objects
065: */
066: public Vector getFormHandlers() {
067: return this .formHandlers;
068: }
069:
070: /**
071: * Tries to fill the given form with values
072: *
073: * @param baseURL the URL of the form itself. needed for relative adressing
074: * @param form a element node containing a DOM description of a form
075: * (e.g. from a DOM parser or HTML Tidy)
076: *
077: * @return a form filled with values or null, if no form handler was found
078: */
079: public ExtendedURL fillForm(URL baseURL, Element form) {
080: ExtendedURL eurl = new ExtendedURL();
081: String formURL = form.getAttribute("action");
082: String type = form.getAttribute("method");
083: FormHandler handler;
084: URL absoluteFormURL = null;
085:
086: try {
087: absoluteFormURL = new URL(baseURL, formURL);
088: } catch (MalformedURLException e) {
089: log.info("MalformedURLException in fillForm(): "
090: + e.getMessage());
091: }
092:
093: if (!form.getNodeName().equals("form")) {
094: log.error("not a form !");
095: return null;
096: }
097:
098: handler = getFormHandler(absoluteFormURL.toString());
099: if (handler == null) {
100: log.debug("found no form handler for URL " + formURL);
101: return null;
102: }
103:
104: if (type.equalsIgnoreCase("get")) {
105: eurl.setRequestMethod(HttpConstants.GET);
106: } else if (type.equalsIgnoreCase("post")) {
107: eurl.setRequestMethod(HttpConstants.POST);
108: } else if (type.equals("")) {
109: // workaround for sites that have no "action" attribute
110: // in their forms, like Google :-(
111: eurl.setRequestMethod(HttpConstants.GET);
112: } else {
113: log.debug("method " + type + " unknown");
114: return null;
115: }
116:
117: try {
118: eurl.setURL(absoluteFormURL);
119: } catch (Exception e) {
120: log.debug("error calculating URL: " + e.getMessage());
121: }
122:
123: // clear the old data in this form handler
124: handler.clearValues();
125:
126: // okay, now fill the form fields ...
127: collectInputFields(form, handler);
128: eurl.setParams(handler.getParamString());
129:
130: return eurl;
131: }
132:
133: /**
134: * Get
135: */
136: private void collectInputFields(Element element, FormHandler fh) {
137: // this should not happen !
138: if (element == null) {
139: log.error("got a null element");
140: return;
141: }
142:
143: if (element.getNodeName().equals("input")) {
144:
145: String type = element.getAttribute("type").toLowerCase();
146: String name = element.getAttribute("name");
147: String value = element.getAttribute("value");
148:
149: // ignore reset tags
150: if (!type.equals("reset")) {
151:
152: // must have a name
153: if ((name != null) && (!name.equals(""))) {
154:
155: // must have a value
156: if ((value != null) && (!value.equals(""))) {
157:
158: // add this value to the form handler
159: fh.addValue(name, value);
160:
161: }
162:
163: }
164:
165: }
166:
167: }
168:
169: // recursive travel through all childs
170: NodeList childs = element.getChildNodes();
171:
172: for (int i = 0; i < childs.getLength(); i++) {
173: if (childs.item(i) instanceof Element) {
174: collectInputFields((Element) childs.item(i), fh);
175: }
176: }
177:
178: }
179:
180: /**
181: * Gets a form handler for a given URL
182: * @param u an URL
183: * @return a FormHandler object, if there is a registered FormHandler
184: * for this URL, null otherwise
185: */
186: protected FormHandler getFormHandler(String url) {
187: if (url == null) {
188: return null;
189: }
190:
191: if (formHandlers == null) {
192: return null;
193: }
194:
195: for (int i = 0; i < formHandlers.size(); i++) {
196: FormHandler fh = (FormHandler) formHandlers.elementAt(i);
197: if (fh.getUrl().toString().equals(url)) {
198: return fh;
199: }
200: }
201:
202: return null;
203: }
204:
205: }
|