001: /*
002: * Created on 16 Jul 2007
003: */
004: package uk.org.ponder.rsf.swf.support;
005:
006: import java.util.HashMap;
007: import java.util.Iterator;
008: import java.util.Map;
009:
010: import uk.org.ponder.beanutil.BeanModelAlterer;
011: import uk.org.ponder.rsf.swf.viewparams.SWFViewParams;
012: import uk.org.ponder.rsf.viewstate.CoreViewParamsCodec;
013: import uk.org.ponder.rsf.viewstate.RawURLState;
014: import uk.org.ponder.rsf.viewstate.StaticViewIDInferrer;
015: import uk.org.ponder.rsf.viewstate.ViewIDInferrer;
016: import uk.org.ponder.rsf.viewstate.ViewParamUtil;
017: import uk.org.ponder.rsf.viewstate.ViewParameters;
018: import uk.org.ponder.rsf.viewstate.ViewParamsCodec;
019: import uk.org.ponder.rsf.viewstate.ViewParamsMapInfo;
020: import uk.org.ponder.rsf.viewstate.ViewParamsRegistry;
021:
022: public class SWFViewParamsCodec implements ViewParamsCodec {
023:
024: public boolean isSupported(ViewParameters viewparams) {
025: return viewparams instanceof SWFViewParams;
026: }
027:
028: private CoreViewParamsCodec defaultCodec;
029: private BeanModelAlterer bma;
030: private ViewParamsRegistry viewParamsRegistry;
031: private ViewIDInferrer viewIDInferrer;
032:
033: public void setDefaultCodec(CoreViewParamsCodec defaultCodec) {
034: this .defaultCodec = defaultCodec;
035: }
036:
037: public void setBeanModelAlterer(BeanModelAlterer bma) {
038: this .bma = bma;
039: }
040:
041: public void setViewParamsRegistry(
042: ViewParamsRegistry viewParamsRegistry) {
043: this .viewParamsRegistry = viewParamsRegistry;
044: }
045:
046: public void setViewIDInferrer(ViewIDInferrer viewIDInferrer) {
047: this .viewIDInferrer = viewIDInferrer;
048: }
049:
050: public boolean parseViewParams(ViewParameters targeto,
051: RawURLState rawstate, Map unusedParams) {
052: if (targeto instanceof SWFViewParams) {
053: SWFViewParams target = (SWFViewParams) targeto;
054: Map this Unused = new HashMap();
055: defaultCodec.parseViewParams(target, rawstate, this Unused);
056:
057: if (viewIDInferrer instanceof StaticViewIDInferrer
058: && target.event == null) {
059: String spec = ((StaticViewIDInferrer) viewIDInferrer)
060: .getViewIDSpec();
061: if (spec.startsWith(ViewParameters.TRUNK_PARSE_PREFIX)) {
062: // The only way we could acquire a trunk viewID is through Low Priority
063: spec = ViewParamUtil.LOW_PREFIX
064: + spec
065: .substring(ViewParameters.TRUNK_PARSE_PREFIX
066: .length());
067: }
068: String[] rawViewID = (String[]) rawstate.params
069: .get(spec);
070: String viewID = rawViewID == null ? null : rawViewID[0];
071: if (viewID != null) {
072: // if we find a viewID, declare a successful tunnel
073: ViewParameters exemPLAR = viewParamsRegistry
074: .getViewParamsExemplar(viewID);
075: // NB have not bothered to fix up unusedParams algorithm for trunk proxies, this
076: // parser will generally deal with them fine
077: defaultCodec.parseViewParams(exemPLAR,
078: new RawURLState(rawstate.params, null),
079: null);
080: target.target = exemPLAR;
081: }
082: }
083: if (target.target == null) {
084: target.params = this Unused;
085: }
086: // we consume ALL remaining parameters, since we can't rule out that something within SWF requires them
087: if (unusedParams != null) {
088: unusedParams.clear();
089: }
090: return true;
091: } else
092: return false;
093: }
094:
095: public ViewParamsMapInfo getMappingInfo(ViewParameters viewparamso) {
096: SWFViewParams viewparams = (SWFViewParams) viewparamso;
097: final ViewParamsMapInfo outer = defaultCodec
098: .getMappingInfo(viewparams);
099: if (viewparams.target != null) {
100: final ViewParamsMapInfo upstream = defaultCodec
101: .getMappingInfo(viewparams.target);
102: return new ViewParamsMapInfo() {
103: public String attributeToPath(String attribute) {
104: String uppath = upstream.attributeToPath(attribute);
105: return uppath == null ? null : "target." + uppath;
106: }
107:
108: public String pathToAttribute(String path) {
109: if (path.startsWith("target.")) {
110: String remainder = path.substring("target."
111: .length());
112: String upattr = upstream
113: .pathToAttribute(remainder);
114: // convert high priority trunk attrs to low priority so they do not pollute overall viewID
115: if (upattr
116: .startsWith(ViewParamUtil.HIGH_PREFIX)) {
117: upattr = ViewParamUtil.LOW_PREFIX
118: + upattr
119: .substring(ViewParamUtil.HIGH_PREFIX
120: .length());
121: }
122: return upattr;
123: } else
124: return outer.pathToAttribute(path);
125: }
126: };
127: } else
128: return outer;
129: }
130:
131: public RawURLState renderViewParams(ViewParameters toparseo) {
132: if (toparseo instanceof SWFViewParams) {
133: // Composite algorithm - first render the nested VPs directly, if there are any
134: // secondly render the outer VPs, which overwrite any values of the same name,
135: // including pathinfo.
136: RawURLState togo = new RawURLState();
137: SWFViewParams toparse = (SWFViewParams) toparseo;
138: if (toparse.target != null) {
139: togo.params = defaultCodec.renderViewParamsNonTrunk(
140: toparse.target, false);
141: } else if (toparse.params != null) {
142: togo.params = accreteRawParams(toparse.params);
143: }
144: if (togo.params == null) {
145: togo.params = new HashMap();
146: }
147: RawURLState outerstate = defaultCodec
148: .renderViewParams(toparse);
149:
150: togo.pathinfo = outerstate.pathinfo;
151: togo.params.putAll(outerstate.params);
152: if (outerstate.anchor != null && togo.anchor == null) {
153: togo.anchor = outerstate.anchor;
154: }
155: return togo;
156: } else {
157: return null;
158: }
159: }
160:
161: private Map accreteRawParams(Map orig) {
162: Map target = new HashMap();
163: for (Iterator keyit = orig.keySet().iterator(); keyit.hasNext();) {
164: String key = (String) keyit.next();
165: Object value = orig.get(key);
166: Object flat = bma.getFlattenedValue("", value, null, null);
167: if (flat instanceof String[]) {
168: target.put(key, flat);
169: } else if (flat instanceof String) {
170: target.put(key, new String[] { (String) flat });
171: }
172: }
173: return target;
174: }
175:
176: }
|