1 15 package org.apache.tapestry.components; 16 17 import java.io.IOException ; 18 import java.util.ArrayList ; 19 import java.util.HashMap ; 20 import java.util.Iterator ; 21 import java.util.List ; 22 import java.util.Map ; 23 24 import org.apache.hivemind.ApplicationRuntimeException; 25 import org.apache.tapestry.IBinding; 26 import org.apache.tapestry.IForm; 27 import org.apache.tapestry.IMarkupWriter; 28 import org.apache.tapestry.IRequestCycle; 29 import org.apache.tapestry.Tapestry; 30 import org.apache.tapestry.TapestryUtils; 31 import org.apache.tapestry.coerce.ValueConverter; 32 import org.apache.tapestry.form.AbstractFormComponent; 33 import org.apache.tapestry.services.DataSqueezer; 34 import org.apache.tapestry.services.ExpressionEvaluator; 35 36 39 public abstract class ForBean extends AbstractFormComponent { 40 private static final char DESC_VALUE = 'V'; 41 private static final char DESC_PRIMARY_KEY = 'P'; 42 43 public abstract Object getSource(); 45 public abstract Object getFullSource(); 46 public abstract String getElement(); 47 public abstract boolean getVolatile(); 48 public abstract Object getDefaultValue(); 49 public abstract String getPrimaryKey(); 50 public abstract IPrimaryKeyConverter getConverter(); 51 public abstract String getKeyExpression(); 52 53 public abstract Map getPrimaryKeyMap(); 55 public abstract void setPrimaryKeyMap(Map primaryKeys); 56 57 public abstract DataSqueezer getDataSqueezer(); 59 public abstract ValueConverter getValueConverter(); 60 public abstract ExpressionEvaluator getExpressionEvaluator(); 61 62 63 private Object _value; 64 private int _index; 65 private boolean _rendering; 66 67 77 78 protected Iterator getSourceData() 79 { 80 Object source = getSource(); 81 if (source == null) 82 return null; 83 84 Iterator iteratorSource = (Iterator ) getValueConverter().coerceValue(source, Iterator .class); 85 86 return iteratorSource; 87 } 88 89 protected Iterator storeSourceData(IForm form, String name) 90 { 91 Iterator iteratorSource = getSourceData(); 92 if (iteratorSource == null) 93 return null; 94 95 StringBuffer pkDesc = new StringBuffer (); 97 List data = new ArrayList (); 98 List pks = new ArrayList (); 99 while (iteratorSource.hasNext()) { 100 Object value = iteratorSource.next(); 101 data.add(value); 102 103 Object pk = getPrimaryKeyFromValue(value); 104 if (pk == null) { 105 pk = value; 106 pkDesc.append(DESC_VALUE); 107 } 108 else 109 pkDesc.append(DESC_PRIMARY_KEY); 110 pks.add(pk); 111 } 112 113 form.addHiddenValue(name, pkDesc.toString()); 115 for (Iterator it = pks.iterator(); it.hasNext();) { 116 Object pk = it.next(); 117 try { 118 String stringRep = getDataSqueezer().squeeze(pk); 119 form.addHiddenValue(name, stringRep); 120 } catch (IOException ex) { 121 throw new ApplicationRuntimeException( 122 Tapestry.format("For.unable-to-convert-value", pk), 123 this, 124 null, 125 ex); 126 } 127 } 128 129 return data.iterator(); 130 } 131 132 protected Iterator getStoredData(IRequestCycle cycle, String name) 133 { 134 String [] submittedPrimaryKeys = cycle.getParameters(name); 135 String pkDesc = submittedPrimaryKeys[0]; 136 137 List data = new ArrayList (submittedPrimaryKeys.length-1); 139 List pks = new ArrayList (submittedPrimaryKeys.length-1); 140 for (int i = 1; i < submittedPrimaryKeys.length; i++) { 141 String stringRep = submittedPrimaryKeys[i]; 142 try { 143 Object value = getDataSqueezer().unsqueeze(stringRep); 144 data.add(value); 145 if (i <= pkDesc.length() && pkDesc.charAt(i-1) == DESC_PRIMARY_KEY) 146 pks.add(value); 147 } catch (IOException ex) { 148 throw new ApplicationRuntimeException( 149 Tapestry.format("For.unable-to-convert-string", stringRep), 150 this, 151 null, 152 ex); 153 } 154 } 155 156 IBinding primaryKeysBinding = getBinding("primaryKeys"); 158 if (primaryKeysBinding != null) 159 primaryKeysBinding.setObject(pks); 160 161 for (int i = 0; i < data.size(); i++) { 163 if (i <= pkDesc.length() && pkDesc.charAt(i) == DESC_PRIMARY_KEY) { 164 Object pk = data.get(i); 165 Object value = getValueFromPrimaryKey(pk); 166 data.set(i, value); 167 } 168 } 169 170 return data.iterator(); 171 } 172 173 178 179 protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle) 180 { 181 IForm form = (IForm) cycle.getAttribute(TapestryUtils.FORM_ATTRIBUTE); 183 184 boolean cycleRewinding = cycle.isRewinding(); 187 if (cycleRewinding && form != null && !form.isRewinding()) 188 return; 189 190 boolean bInForm = (form != null && !getVolatile()); 191 192 String name = ""; 193 if (form != null) 194 name = form.getElementId(this); 195 196 Iterator dataSource; 198 if (!bInForm) 199 dataSource = getSourceData(); 200 else if (cycleRewinding) 201 dataSource = getStoredData(cycle, name); 202 else 203 dataSource = storeSourceData(form, name); 204 205 206 if (dataSource == null) 209 return; 210 211 String element = getElement(); 212 213 try 215 { 216 _index = 0; 217 _rendering = true; 218 219 while (dataSource.hasNext()) 220 { 221 _value = dataSource.next(); 223 224 IBinding indexBinding = getBinding("index"); 226 if (indexBinding != null) 227 indexBinding.setObject(new Integer (_index)); 228 229 IBinding valueBinding = getBinding("value"); 230 if (valueBinding != null) 231 valueBinding.setObject(_value); 232 233 if (element != null) 235 { 236 writer.begin(element); 237 renderInformalParameters(writer, cycle); 238 } 239 240 renderBody(writer, cycle); 241 242 if (element != null) 243 writer.end(); 244 245 _index++; 246 } 247 } 248 finally 249 { 250 _rendering = false; 251 _value = null; 252 } 253 } 254 255 private Object restoreValue(IForm form, String name, Object primaryKey) 256 { 257 return getValueFromPrimaryKey(primaryKey); 258 } 259 260 private void storeValue(IForm form, String name, Object value) 261 { 262 Object convertedValue = getPrimaryKeyFromValue(value); 263 264 try 265 { 266 String externalValue = getDataSqueezer().squeeze(convertedValue); 267 form.addHiddenValue(name, externalValue); 268 } 269 catch (IOException ex) 270 { 271 throw new ApplicationRuntimeException( 272 Tapestry.format("For.unable-to-convert-value", value), 273 this, 274 null, 275 ex); 276 } 277 } 278 279 private Object getPrimaryKeyFromValue(Object value) { 280 Object primaryKey = null; 281 282 String keyExpression = getKeyExpression(); 283 if (keyExpression != null) 284 primaryKey = getExpressionEvaluator().read(value, keyExpression); 285 286 if (primaryKey == null) { 287 IPrimaryKeyConverter converter = getConverter(); 288 if (converter != null) 289 primaryKey = converter.getPrimaryKey(value); 290 } 291 292 return primaryKey; 293 } 294 295 private Object getValueFromPrimaryKey(Object primaryKey) { 296 Object value = null; 297 298 if (value == null && getKeyExpression() != null) { 299 String keyExpression = getKeyExpression(); 300 if (keyExpression != null) { 301 Map primaryKeys = getPrimaryKeyMap(); 302 if (primaryKeys == null) 303 primaryKeys = initializePrimaryKeysFromSource(keyExpression); 304 value = primaryKeys.get(primaryKeys); 305 } 306 } 307 308 if (value == null) { 309 IPrimaryKeyConverter converter = getConverter(); 310 if (converter != null) 311 value = converter.getValue(primaryKey); 312 } 313 314 if (value == null) 315 value = getDefaultValue(); 316 317 return value; 318 } 319 320 private Map initializePrimaryKeysFromSource(String keyExpression) 321 { 322 Map primaryKeys = new HashMap (); 323 324 Object fullSource = getFullSource(); 325 if (fullSource == null) 326 fullSource = getSource(); 327 if (fullSource == null) 328 return primaryKeys; 329 330 ExpressionEvaluator evaluator = getExpressionEvaluator(); 331 332 Iterator iteratorSource = (Iterator ) getValueConverter().coerceValue(fullSource, Iterator .class); 333 while (iteratorSource.hasNext()) { 334 Object value = iteratorSource.next(); 335 Object primaryKey = evaluator.read(value, keyExpression); 336 if (primaryKey != null) 337 primaryKeys.put(primaryKey, value); 338 } 339 340 setPrimaryKeyMap(primaryKeys); 341 return primaryKeys; 342 } 343 344 350 351 public final Object getValue() 352 { 353 if (!_rendering) 354 throw Tapestry.createRenderOnlyPropertyException(this, "value"); 355 356 return _value; 357 } 358 359 368 369 public int getIndex() 370 { 371 if (!_rendering) 372 throw Tapestry.createRenderOnlyPropertyException(this, "index"); 373 374 return _index; 375 } 376 377 public boolean isDisabled() 378 { 379 return false; 380 } 381 382 protected void renderFormComponent(IMarkupWriter writer, IRequestCycle cycle) { } 384 protected void rewindFormComponent(IMarkupWriter writer, IRequestCycle cycle) { } 385 } 386 | Popular Tags |