001: /*
002: * Created on Nov 11, 2005
003: */
004: package uk.org.ponder.rsf.processor;
005:
006: import java.util.HashMap;
007: import java.util.Iterator;
008: import java.util.List;
009: import java.util.Map;
010:
011: import uk.org.ponder.arrayutil.ArrayUtil;
012: import uk.org.ponder.rsf.request.EarlyRequestParser;
013: import uk.org.ponder.rsf.request.FossilizedConverter;
014: import uk.org.ponder.rsf.request.RenderSystemDecoder;
015: import uk.org.ponder.rsf.request.RequestSubmittedValueCache;
016: import uk.org.ponder.rsf.request.SVESorter;
017: import uk.org.ponder.rsf.request.SubmittedValueEntry;
018: import uk.org.ponder.util.Logger;
019:
020: /**
021: * A request-scope bean whose job is to determine the (topologically sorted) set
022: * of submitted request submitted values for this POST request. If this is a
023: * RENDER request, returns an empty list, or any RSVC queued as a result of
024: * error state for this view.
025: *
026: * @author Antranig Basman (antranig@caret.cam.ac.uk)
027: *
028: */
029: public class PostDecoder {
030: private FossilizedConverter fossilizedconverter;
031: private RenderSystemDecoder rendersystemdecoder;
032: private Map requestparams;
033: private String requesttype;
034: private Map normalizedrequest;
035: private RequestSubmittedValueCache requestrsvc;
036:
037: public void setFossilizedConverter(
038: FossilizedConverter fossilizedconverter) {
039: this .fossilizedconverter = fossilizedconverter;
040: }
041:
042: public void setRenderSystemDecoder(
043: RenderSystemDecoder rendersystemdecoder) {
044: this .rendersystemdecoder = rendersystemdecoder;
045: }
046:
047: public void setRequestMap(Map requestparams) {
048: this .requestparams = requestparams;
049: }
050:
051: public void setRequestType(String requesttype) {
052: this .requesttype = requesttype;
053: }
054:
055: public void init() {
056: normalizedrequest = new HashMap();
057: normalizedrequest.putAll(requestparams);
058: rendersystemdecoder.normalizeRequestMap(normalizedrequest);
059: }
060:
061: private static void fuseStrings(SubmittedValueEntry existing,
062: SubmittedValueEntry sve) {
063: if (existing.isEL)
064: return; // avoid having to optimise PFS client
065: if (existing.newvalue instanceof String) {
066: existing.newvalue = new String[] {
067: (String) existing.newvalue, (String) sve.newvalue };
068: } else {
069: existing.newvalue = ArrayUtil.append(
070: (Object[]) existing.newvalue, sve.newvalue);
071: }
072: }
073:
074: // This method is expected to be called by accreteRSVC
075: public void parseRequest(RequestSubmittedValueCache rsvc) {
076: // Firstly acquire all non-component ("pure") bindings
077: for (Iterator keyit = normalizedrequest.keySet().iterator(); keyit
078: .hasNext();) {
079: String key = (String) keyit.next();
080: String[] values = (String[]) normalizedrequest.get(key);
081: Logger.log.info("PostInit: key " + key + " value "
082: + values[0]);
083: if (fossilizedconverter.isNonComponentBinding(key)) {
084: for (int i = 0; i < values.length; ++i) {
085: // EL binding key is fixed, there may be many values
086: try {
087: SubmittedValueEntry sve = fossilizedconverter
088: .parseBinding(key, values[i]);
089: SubmittedValueEntry existing = rsvc
090: .byPath(sve.valuebinding);
091: if (existing != null
092: && existing.componentid == null) {
093: fuseStrings(existing, sve);
094: } else {
095: rsvc.addEntry(sve);
096: }
097: Logger.log
098: .info("Discovered noncomponent binding for "
099: + sve.valuebinding
100: + " rvalue "
101: + sve.newvalue);
102: } catch (Exception e) {
103: Logger.log.warn("Error parsing binding key "
104: + key + " value " + values[i], e);
105: }
106: }
107: }
108: // Secondly assess whether this was a component fossilised binding.
109: else if (fossilizedconverter.isFossilisedBinding(key)
110: && values.length > 0) {
111: SubmittedValueEntry sve = fossilizedconverter
112: .parseFossil(key, values[0]);
113:
114: // Grab dependent values which we can now deduce may be in the request
115: String[] newvalue = (String[]) normalizedrequest
116: .get(sve.componentid);
117: sve.newvalue = newvalue;
118: fossilizedconverter.fixupNewValue(sve,
119: rendersystemdecoder, key, values[0]);
120:
121: String[] reshaper = (String[]) normalizedrequest
122: .get(fossilizedconverter
123: .getReshaperKey(sve.componentid));
124: if (reshaper != null) {
125: sve.reshaperbinding = reshaper[0];
126: }
127:
128: Logger.log.info("Discovered fossilised binding for "
129: + sve.valuebinding + " for component "
130: + sve.componentid + " with old value "
131: + sve.oldvalue);
132: rsvc.addEntry(sve);
133: }
134: }
135: }
136:
137: public RequestSubmittedValueCache getRequestRSVC() {
138: if (requestrsvc == null) {
139: requestrsvc = new RequestSubmittedValueCache();
140: if (requesttype.equals(EarlyRequestParser.ACTION_REQUEST)) {
141: RequestSubmittedValueCache newvalues = new RequestSubmittedValueCache();
142: parseRequest(newvalues);
143: // Topologically sort the fresh values (which may be arbitrarily
144: // disordered through passing the request) in order of intrinsic
145: // dependency.
146: SVESorter sorter = new SVESorter(newvalues);
147: List sorted = sorter.getSortedRSVC();
148:
149: for (int i = 0; i < sorted.size(); ++i) {
150: requestrsvc.addEntry((SubmittedValueEntry) sorted
151: .get(i));
152: }
153: }
154: }
155: return requestrsvc;
156: }
157:
158: public Map getNormalizedRequest() {
159: return normalizedrequest;
160: }
161:
162: public static String decodeAction(Map normalizedrequest) {
163: String[] actionmethods = (String[]) normalizedrequest
164: .get(SubmittedValueEntry.FAST_TRACK_ACTION);
165: if (actionmethods != null) {
166: String actionmethod = actionmethods[0];
167: // actionmethod = BeanUtil.stripEL(actionmethod);
168: return actionmethod;
169: }
170: return null;
171: }
172:
173: public static String decodeSubmittingControl(Map normalized) {
174: // This SHOULD be set if an RSF submitting response is required
175: String[] array = (String[]) normalized
176: .get(SubmittedValueEntry.SUBMITTING_CONTROL);
177: return array == null ? null : array[0];
178: }
179:
180: }
|