1 7 package fr.improve.struts.taglib.layout.datagrid; 8 9 import java.beans.PropertyDescriptor ; 10 import java.lang.reflect.InvocationTargetException ; 11 import java.util.ArrayList ; 12 import java.util.Collection ; 13 import java.util.Collections ; 14 import java.util.HashMap ; 15 import java.util.HashSet ; 16 import java.util.Iterator ; 17 import java.util.List ; 18 import java.util.Map ; 19 import java.util.Set ; 20 import java.util.TreeMap ; 21 22 import org.apache.commons.beanutils.BasicDynaBean; 23 import org.apache.commons.beanutils.BasicDynaClass; 24 import org.apache.commons.beanutils.DynaBean; 25 import org.apache.commons.beanutils.DynaClass; 26 import org.apache.commons.beanutils.DynaProperty; 27 import org.apache.commons.beanutils.PropertyUtils; 28 import org.apache.commons.logging.Log; 29 import org.apache.commons.logging.LogFactory; 30 31 46 public class DatagridImpl extends Datagrid implements DynaBean { 47 50 private static Log LOG = LogFactory.getLog(DatagridImpl.class); 51 52 55 private List data; 56 57 60 private Map addedData; 61 62 65 private Map modifiedData; 66 67 71 private Map dataWithStates = new HashMap (); 72 73 77 private Map indexWithStates = new HashMap (); 78 79 83 private Set addedAndRemoved = new HashSet (); 84 85 88 private Class dataClass; 89 90 94 private DynaClass dataDynaClass; 95 96 99 private Set booleans = new HashSet (); 100 101 104 private Map booleanStates = new HashMap (); 105 106 107 110 private static final int STATUS_NEW = 0; 111 112 115 private static final int STATUS_SET = 1; 116 117 120 private static final int STATUS_DIRTY = 2; 121 122 125 private static final int STATUS_READ = 3; 126 127 130 private int status = STATUS_NEW; 131 132 133 134 137 DatagridImpl() { 138 139 } 140 141 143 148 protected Object getModifiedObject(int in_index) { 149 Object o = data.get(in_index); 151 152 modifiedData.put(new Integer (in_index), o); 154 155 return o; 157 } 158 159 167 protected Object getAddedObject(int in_index) { 168 Integer lc_int = new Integer (in_index); 169 170 Object o = addedData.get(lc_int); 172 173 if (o==null) { 174 if (dataClass==null) { 175 throw new RuntimeException ("dataClass property is not set"); 176 } 177 try { 178 o = dataClass.newInstance(); 180 } catch (InstantiationException e) { 181 throwException(e); 182 } catch (IllegalAccessException e) { 183 throwException(e); 184 } 185 186 if (!addedAndRemoved.contains(lc_int)) { 188 addedData.put(lc_int, o); 189 } 190 } 191 192 return o; 194 } 195 196 private void throwException(Exception e) { 197 LOG.error("Fail to create an object of class " + dataClass.getName(), e); 198 throw new RuntimeException ("A " + e.getClass().getName() + " occured while creating an object of class " + dataClass.getName() + " : " + e.getMessage()); 199 } 200 201 207 protected boolean checkNotAddedAndRemoved(int in_index, Object in_value) { 208 if (in_index >= data.size() && Datagrid.REMOVED.equals(in_value)) { 209 Integer lc_int = new Integer (in_index); 210 addedData.remove(lc_int); 211 addedAndRemoved.add(lc_int); 212 return false; 213 } else { 214 return true; 215 } 216 } 217 218 220 public DynaClass getDynaClass() { 221 return dataDynaClass; 222 } 223 224 227 public void set(String in_propertyName, int in_index, Object in_value) { 228 moveToStatus(STATUS_DIRTY); 229 if (in_index < 0 ) { 230 throw new IllegalArgumentException ("Negative in_index !"); 232 } 233 234 if ("dataState".equals(in_propertyName)) { 235 if (in_value!=null) { 238 if (checkNotAddedAndRemoved(in_index, in_value)) { 239 setDataState(in_index, in_value.toString()); 240 } 241 } 242 return; 245 } 246 247 Object o; 249 if (in_index >= data.size()) { 250 o = getAddedObject(in_index); 252 } else { 253 if (booleans.contains(in_propertyName)) { 254 o = data.get(in_index); 257 } else { 258 if (in_value.equals(get(in_propertyName, in_index))) { 260 return; 262 } 263 o = getModifiedObject(in_index); 264 } 265 } 266 try { 267 PropertyUtils.setProperty(o, in_propertyName, in_value); 269 } catch (IllegalAccessException e) { 270 LOG.error("Could not set new object property value", e); 271 } catch (InvocationTargetException e) { 272 LOG.error("Could not set new object property value", e); 273 } catch (NoSuchMethodException e) { 274 LOG.error("Could not set new object property value", e); 275 } 276 } 277 278 282 public Object get(String in_propertyName, int in_index) { 283 Object o = data.get(in_index); 284 Object ret = null; 285 try { 286 ret = PropertyUtils.getProperty(o, in_propertyName); 287 } catch (IllegalAccessException e) { 288 LOG.error("Could not get object property value", e); 289 } catch (InvocationTargetException e) { 290 LOG.error("Could not get object property value", e); 291 } catch (NoSuchMethodException e) { 292 LOG.error("Could not get object property value", e); 293 } 294 return ret; 295 } 296 297 299 302 public void setData(List in_list) { 303 data = in_list; 304 addedData = new TreeMap (); 305 modifiedData = new HashMap (); 306 dataWithStates.clear(); 307 indexWithStates.clear(); 308 addedAndRemoved.clear(); 309 status = STATUS_SET; 310 } 311 312 316 public void setDataClass(Class in_class) { 317 dataClass = in_class; 319 320 PropertyDescriptor [] lc_descriptors = PropertyUtils.getPropertyDescriptors(in_class); 322 List lc_list = new ArrayList (lc_descriptors.length+1); 323 for (int i = 0; i < lc_descriptors.length; i++) { 324 PropertyDescriptor lc_descriptor = lc_descriptors[i]; 325 if (lc_descriptor.getWriteMethod()!=null) { 326 DynaProperty lc_property = new DynaProperty(lc_descriptor.getName(), lc_descriptor.getPropertyType()); 327 lc_list.add(lc_property); 328 } 329 } 330 331 DynaProperty lc_property = new DynaProperty("dataState", String .class); 333 lc_list.add(lc_property); 334 335 DynaProperty[] lc_properties = (DynaProperty[]) lc_list.toArray(new DynaProperty[lc_list.size()]); 336 dataDynaClass = new BasicDynaClass(in_class.getName(), BasicDynaBean.class, lc_properties); 337 } 338 339 342 public void setDataState(int in_index, String in_state) { 343 if (in_state==null) { 344 throw new IllegalArgumentException ("in_state null"); 345 } 346 Integer lc_int = new Integer (in_index); 347 348 String lc_oldState = (String ) indexWithStates.get(lc_int); 350 if (lc_oldState!=null) { 351 Collection lc_list = (Collection ) dataWithStates.get(lc_oldState); 352 if (lc_list!=null) { 353 lc_list.remove(lc_int); 354 } 355 } 356 357 Collection lc_list = (Collection ) dataWithStates.get(in_state); 359 if (lc_list==null) { 360 lc_list = new HashSet (); 361 dataWithStates.put(in_state, lc_list); 362 } 363 lc_list.add(lc_int); 364 365 indexWithStates.put(lc_int, in_state); 367 } 368 369 public Collection getData() { 370 Collection lc_collection = new ArrayList (); 371 lc_collection.addAll(data); 372 lc_collection.addAll(addedData.values()); 373 return lc_collection; 374 } 375 376 379 public Collection getDeletedData() { 380 moveToStatus(STATUS_READ); 381 return getDataWithState(REMOVED); 382 } 383 384 387 public Collection getDataWithState(String in_state) { 388 moveToStatus(STATUS_READ); 389 390 Collection goodStateList = (Collection ) dataWithStates.get(in_state); 392 393 if (goodStateList==null || goodStateList.isEmpty()) { 394 return Collections.EMPTY_LIST; 396 } else { 397 ArrayList lc_list = new ArrayList (); 399 Iterator lc_it = goodStateList.iterator(); 400 Object o; 401 while (lc_it.hasNext()) { 402 Integer lc_int = (Integer )lc_it.next(); 403 if (lc_int.intValue()<data.size()) { 404 o = data.get(lc_int.intValue()); 405 lc_list.add(o); 406 } else { 407 o = addedData.get(lc_int); 408 lc_list.add(o); 409 } 410 } 411 return lc_list; 412 } 413 } 414 415 418 public Collection getSelectedData() { 419 moveToStatus(STATUS_READ); 420 return getDataWithState(SELECTED); 421 } 422 423 426 public Collection getAddedData() { 427 moveToStatus(STATUS_READ); 428 return addedData.values(); 429 } 430 431 434 public Collection getModifiedData() { 435 moveToStatus(STATUS_READ); 436 return modifiedData.values(); 437 } 438 439 public String getObjectState(int in_index) { 440 String lc_state = (String ) indexWithStates.get(new Integer (in_index)); 441 return lc_state == null ? "" : lc_state; 442 } 443 444 446 449 public boolean contains(String name, String key) { 450 return false; 452 } 453 454 457 public Object get(String name, String key) { 458 return null; 460 } 461 462 465 public Object get(String name) { 466 return null; 468 } 469 470 473 public void remove(String name, String key) { 474 } 476 477 480 public void set(String name, Object value) { 481 } 483 484 487 public void set(String name, String key, Object value) { 488 } 490 491 494 public void preUpdate() { 495 Iterator lc_it = booleans.iterator(); 496 Boolean falseValue = Boolean.FALSE; 497 while (lc_it.hasNext()) { 498 String lc_booleanProperty = (String ) lc_it.next(); 499 Map objects = (Map ) booleanStates.get(lc_booleanProperty); 500 if (objects==null) { 501 objects = new HashMap (); 502 booleanStates.put(lc_booleanProperty, objects); 503 } 504 Iterator lc_elements = data.iterator(); 505 while (lc_elements.hasNext()) { 506 Object lc_element = lc_elements.next(); 507 try { 508 objects.put(lc_element, PropertyUtils.getProperty(lc_element, lc_booleanProperty)); 509 PropertyUtils.setProperty(lc_element, lc_booleanProperty, falseValue); 510 } catch (Exception e) { 511 LOG.error("Fail to reset property " + lc_booleanProperty, e); 512 } 513 } 514 } 515 status = STATUS_DIRTY; 516 } 517 518 private void postUpdate() { 519 Iterator lc_it = booleans.iterator(); 520 while (lc_it.hasNext()) { 521 String lc_booleanProperty = (String ) lc_it.next(); 522 Map objects = (Map ) booleanStates.get(lc_booleanProperty); 523 Iterator lc_elements = data.iterator(); 524 int i = 0; 525 while (lc_elements.hasNext()) { 526 try { 527 Object lc_element = lc_elements.next(); 528 Boolean oldValue = (Boolean ) objects.get(lc_element); 529 Boolean newValue = (Boolean ) PropertyUtils.getProperty(lc_element, lc_booleanProperty); 530 if (!oldValue.equals(newValue)) { 531 getModifiedObject(i); 532 } 533 } catch (Exception e) { 534 LOG.error("Fail to check property " + lc_booleanProperty, e); 535 } 536 i++; 537 } 538 } 539 } 540 541 private void moveToStatus(int in_status) { 542 if (status!=in_status) { 543 switch (in_status) { 544 case STATUS_DIRTY: 545 preUpdate(); 546 break; 547 case STATUS_READ: 548 postUpdate(); 549 break; 550 } 551 status = in_status; 552 } 553 554 } 555 556 void addBooleanProperty(String in_property) { 557 booleans.add(in_property); 558 } 559 } 560 | Popular Tags |