001: /*
002: * Created on 07-May-2006
003: */
004: package uk.org.ponder.rsf.viewstate.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.mapping.DARList;
012: import uk.org.ponder.mapping.DataAlterationRequest;
013: import uk.org.ponder.rsf.viewstate.CoreViewParamsCodec;
014: import uk.org.ponder.rsf.viewstate.RawURLState;
015: import uk.org.ponder.rsf.viewstate.ViewParamUtil;
016: import uk.org.ponder.rsf.viewstate.ViewParameters;
017: import uk.org.ponder.rsf.viewstate.ViewParamsCodec;
018: import uk.org.ponder.rsf.viewstate.ViewParamsMapInfo;
019: import uk.org.ponder.stringutil.CharWrap;
020: import uk.org.ponder.stringutil.StringUtil;
021:
022: /**
023: * Framework class performing the function of parsing and rendering
024: * ViewParameters objects to and from their raw representations.
025: *
026: * @author Antranig Basman (antranig@caret.cam.ac.uk)
027: *
028: */
029:
030: public class ViewParamsMapper implements CoreViewParamsCodec {
031:
032: private BeanModelAlterer bma;
033:
034: private ViewParamsMappingInfoManager vpmim;
035:
036: public void setVPMappingInfoManager(
037: ViewParamsMappingInfoManager vpmim) {
038: this .vpmim = vpmim;
039: }
040:
041: public ViewParamsMappingInfoManager getVPMappingInfoManager() {
042: return vpmim;
043: }
044:
045: public void setBeanModelAlterer(BeanModelAlterer bma) {
046: this .bma = bma;
047: }
048:
049: public BeanModelAlterer getBeanModelAlterer() {
050: return bma;
051: }
052:
053: public ViewParamsMapInfo getMappingInfo(ViewParameters target) {
054: return vpmim.getMappingInfo(target);
055: }
056:
057: public boolean parseViewParams(ViewParameters target,
058: RawURLState rawstate, Map unusedParams) {
059: parseViewParameters(target, rawstate.params, rawstate.pathinfo,
060: unusedParams);
061: return true;
062: }
063:
064: public RawURLState renderViewParams(ViewParameters torender) {
065: RawURLState togo = new RawURLState();
066: togo.pathinfo = toPathInfo(torender);
067: togo.params = renderViewParamAttributes(torender);
068: String anchorfield = torender.getAnchorField();
069: if (anchorfield != null) {
070: String value = (String) bma.getFlattenedValue(anchorfield,
071: torender, String.class, null);
072: togo.anchor = value;
073: }
074: return togo;
075: }
076:
077: /**
078: * Parse the supplied raw URL information into a ViewParameters object, whose
079: * type has already been deduced.
080: *
081: * @param target The ViewParameters object onto which URL information is to be
082: * parsed.
083: * @param params The raw URL parameter map, a map of String onto String[].
084: * @param pathinfo The "pathinfo" segment of the URL, which starts with a
085: * leading slash (/).
086: */
087: public void parseViewParameters(ViewParameters target, Map params,
088: String pathinfo, Map unusedParams) {
089: ConcreteViewParamsMapInfo mapinfo = vpmim
090: .getMappingInfo(target);
091: DARList toapply = new DARList();
092:
093: if (pathinfo != null) {
094: String[] segments = StringUtil.split(pathinfo, '/', false);
095: for (int i = 0; i < mapinfo.trunkpaths.length; ++i) {
096: // An extra segment will be produced for the initial /
097: int reqindex = i + 1;
098: if (reqindex < segments.length) {
099: // look for surrogate attributes first
100: Object segment = params.get(ViewParamUtil
101: .getAttrIndex(i, true));
102: // only apply low priority if we are at an endpoint
103: if (segment == null && unusedParams == null) {
104: segment = params.get(ViewParamUtil
105: .getAttrIndex(i, false));
106: }
107: if (segment == null) {
108: segment = segments[reqindex];
109: }
110:
111: toapply.add(new DataAlterationRequest(
112: mapinfo.trunkpaths[i], segment));
113: }
114: }
115: }
116: for (Iterator keyit = params.keySet().iterator(); keyit
117: .hasNext();) {
118: String attr = (String) keyit.next();
119: Object valueo = params.get(attr);
120: String path = mapinfo.attributeToPath(attr);
121: if (path != null) {
122: if (valueo != null) {
123: toapply
124: .add(new DataAlterationRequest(path, valueo));
125: }
126: } else {
127: if (unusedParams != null)
128: unusedParams.put(attr, valueo);
129: }
130: }
131: bma.applyAlterations(target, toapply, null);
132: }
133:
134: public String toPathInfo(ViewParameters toconvert) {
135: CharWrap togo = new CharWrap();
136: ConcreteViewParamsMapInfo mapinfo = vpmim
137: .getMappingInfo(toconvert);
138: boolean nullstarted = false;
139: for (int i = 0; i < mapinfo.trunkpaths.length; ++i) {
140: String trunkpath = mapinfo.trunkpaths[i];
141: // errors would be checked at parse assembly time
142: String attrval = (String) bma.getFlattenedValue(trunkpath,
143: toconvert, null, null);
144: if (attrval != null) {
145: if (nullstarted) {
146: throw new IllegalArgumentException(
147: "Illegal outgoing URL state - value "
148: + attrval + " at trunk position "
149: + i
150: + " follows previous missing value");
151: }
152: togo.append('/').append(attrval);
153: } else {
154: nullstarted = true;
155: }
156: }
157: return togo.toString();
158: }
159:
160: /**
161: * Converts the attributes portion of the ViewParameters object to a map of
162: * String to String[].
163: */
164:
165: public Map renderViewParamAttributes(ViewParameters toconvert) {
166: Map togo = new HashMap();
167: ConcreteViewParamsMapInfo mapinfo = vpmim
168: .getMappingInfo(toconvert);
169: for (int i = 0; i < mapinfo.attrnames.length; ++i) {
170: String attrname = mapinfo.attrnames[i];
171: String path = mapinfo.paths[i];
172: putAttr(togo, path, attrname, toconvert);
173: }
174: return togo;
175: }
176:
177: public boolean isSupported(ViewParameters viewparams) {
178: return true;
179: }
180:
181: public Map renderViewParamsNonTrunk(ViewParameters torender,
182: boolean highpriority) {
183: Map togo = renderViewParamAttributes(torender);
184: ConcreteViewParamsMapInfo mapinfo = vpmim
185: .getMappingInfo(torender);
186: for (int i = 0; i < mapinfo.trunkpaths.length; ++i) {
187: putAttr(togo, mapinfo.trunkpaths[i], ViewParamUtil
188: .getAttrIndex(i, highpriority), torender);
189: }
190: return togo;
191: }
192:
193: private void putAttr(Map target, String path, String attrname,
194: ViewParameters torender) {
195: Object attrval = bma.getFlattenedValue(path, torender, null,
196: null);
197: if (attrval instanceof String[]) {
198: target.put(attrname, attrval);
199: } else if (attrval instanceof String) {
200: target.put(attrname, new String[] { (String) attrval });
201: }
202: }
203:
204: }
|