001: /*
002: * Created on Nov 2, 2005
003: */
004: package uk.org.ponder.rsf.componentprocessor;
005:
006: import java.util.Iterator;
007: import java.util.Map;
008:
009: import uk.org.ponder.rsf.components.ParameterList;
010: import uk.org.ponder.rsf.components.UIBound;
011: import uk.org.ponder.rsf.components.UICommand;
012: import uk.org.ponder.rsf.components.UIComponent;
013: import uk.org.ponder.rsf.components.UIForm;
014: import uk.org.ponder.rsf.request.EarlyRequestParser;
015: import uk.org.ponder.rsf.view.View;
016: import uk.org.ponder.rsf.view.ViewReceiver;
017: import uk.org.ponder.rsf.viewstate.InternalURLRewriter;
018: import uk.org.ponder.rsf.viewstate.URLRewriter;
019: import uk.org.ponder.rsf.viewstate.ViewParamUtil;
020: import uk.org.ponder.rsf.viewstate.ViewParameters;
021: import uk.org.ponder.rsf.viewstate.ViewStateHandler;
022: import uk.org.ponder.stringutil.StringSet;
023: import uk.org.ponder.util.Logger;
024: import uk.org.ponder.util.UniversalRuntimeException;
025:
026: /**
027: * The basic FormFixer implementation, with responsibilities for i) setting form
028: * submission URL to current view URL ii) Folding form children up into parent,
029: * leaving it as a leaf in the tree, iii) registering submitting nested UIBound
030: * components into the FormModel. Point iii) must have ALREADY been set up by
031: * having the <code>submittingcontrols</code> field of UIForm filled in
032: * (possibly by ContainmentFormChildFixer)
033: *
034: * @author Antranig Basman (antranig@caret.cam.ac.uk)
035: */
036: // WHY do we treat forms in this strange way? Because we WOULD like IKAT to be
037: // form-agnostic, and also form nesting is not a "given" for WAP &c.
038: public class DefaultFormFixer implements ComponentProcessor,
039: ViewReceiver {
040: private ViewParameters viewparams;
041: private ViewStateHandler viewstatehandler;
042: private View view;
043: private ParameterList outgoingparams;
044: private URLRewriter urlrewriter;
045: private InternalURLRewriter inturlrewriter;
046:
047: public void setViewParameters(ViewParameters viewparams) {
048: this .viewparams = viewparams;
049: }
050:
051: public void setViewStateHandler(ViewStateHandler viewstatehandler) {
052: this .viewstatehandler = viewstatehandler;
053: }
054:
055: public void setView(View view) {
056: this .view = view;
057: }
058:
059: public void setOutgoingParams(ParameterList outgoingparams) {
060: this .outgoingparams = outgoingparams;
061: }
062:
063: public void setURLRewriter(URLRewriter urlrewriter) {
064: this .urlrewriter = urlrewriter;
065: }
066:
067: public void setInternalURLRewriter(
068: InternalURLRewriter inturlrewriter) {
069: this .inturlrewriter = inturlrewriter;
070: }
071:
072: public void processComponent(UIComponent toprocesso) {
073: if (!(toprocesso instanceof UIForm))
074: return;
075: UIForm toprocess = (UIForm) toprocesso;
076:
077: StringSet submittingnames = new StringSet();
078:
079: // Check that anything registered so far as submitting exists and is
080: // valid.
081: for (int i = 0; i < toprocess.submittingcontrols.size(); ++i) {
082: String childid = toprocess.submittingcontrols.stringAt(i);
083: UIComponent child = view.getComponent(childid);
084: if (!(child instanceof UIBound)
085: && !(child instanceof UICommand)) {
086: throw UniversalRuntimeException
087: .accumulate(
088: new IllegalArgumentException(),
089: "Component with ID "
090: + childid
091: + " listed as submitting child of form "
092: + toprocess.getFullID()
093: + " is not valid (non-Command, non-Bound or "
094: + "non-existent)");
095: }
096: if (child instanceof UIBound) {
097: UIBound boundchild = (UIBound) child;
098: if (boundchild.submittingname == null
099: && boundchild.willinput) {
100: Logger.log.warn("Submitting name for "
101: + boundchild.getFullID()
102: + " not set by previous fixup");
103: boundchild.submittingname = boundchild.getFullID();
104: }
105: submittingnames.add(boundchild.submittingname);
106: }
107: // formmodel.registerChild(toprocess, (UIBound) child);
108: }
109: // if the user has filled in targetURL, simply let it stand.
110: if (toprocess.targetURL == null) {
111: // form will submit to current URL if none other specified
112: if (toprocess.viewparams == null) {
113: toprocess.viewparams = viewparams.copyBase();
114: if (viewparams.endflow == null) {
115: toprocess.viewparams.flowtoken = viewparams.flowtoken;
116: }
117: toprocess.viewparams.errortoken = null;
118: }
119: Map attrmap = viewstatehandler
120: .getAttrMap(toprocess.viewparams);
121: // remove any URL keys for which there exist controls for a GET form
122: if (toprocess.type
123: .equals(EarlyRequestParser.RENDER_REQUEST)) {
124: for (Iterator keyit = attrmap.keySet().iterator(); keyit
125: .hasNext();) {
126: String key = (String) keyit.next();
127: if (submittingnames.contains(key)) {
128: keyit.remove();
129: }
130: }
131: String fullURL = viewstatehandler
132: .getFullURL(toprocess.viewparams);
133: int qpos = fullURL.indexOf('?');
134: if (qpos != -1)
135: fullURL = fullURL.substring(0, qpos);
136: toprocess.targetURL = fullURL;
137: } else {
138: toprocess.targetURL = viewstatehandler
139: .getActionURL(toprocess.viewparams);
140: }
141: toprocess.parameters.addAll(ViewParamUtil
142: .mapToParamList(attrmap));
143: toprocess.parameters.addAll(outgoingparams);
144: } else {
145: // We worry that in general IBUP processing is non-idempotent, but
146: // I think we can depend on fixups occuring only once...
147: toprocess.targetURL = toprocess.type
148: .equals(EarlyRequestParser.RENDER_REQUEST) ? inturlrewriter
149: .rewriteRenderURL(toprocess.targetURL)
150: : inturlrewriter
151: .rewriteActionURL(toprocess.targetURL);
152: }
153: }
154:
155: }
|