1 29 30 package nextapp.echo2.app.update; 31 32 import java.io.Serializable ; 33 import java.util.ArrayList ; 34 import java.util.Arrays ; 35 import java.util.Collection ; 36 import java.util.Comparator ; 37 import java.util.HashMap ; 38 import java.util.Iterator ; 39 import java.util.Map ; 40 41 import nextapp.echo2.app.ApplicationInstance; 42 import nextapp.echo2.app.Command; 43 import nextapp.echo2.app.Component; 44 45 49 public class ServerUpdateManager 50 implements Serializable { 51 52 56 private static final Comparator hierarchyDepthUpdateComparator = new Comparator () { 57 58 61 public int compare(Object a, Object b) { 62 return getDepth(((ServerComponentUpdate) a).getParent()) - getDepth(((ServerComponentUpdate) b).getParent()); 63 } 64 65 68 public boolean equals(Object o) { 69 return false; 70 } 71 72 78 private int getDepth(Component component) { 79 int count = 0; 80 while (component != null) { 81 component = component.getParent(); 82 ++count; 83 } 84 return count; 85 } 86 }; 87 88 private Map applicationUpdateMap; 89 private ArrayList commands; 90 private Map componentUpdateMap; 91 private ServerComponentUpdate fullRefreshUpdate; 92 private ClientUpdateManager clientUpdateManager; 93 private ApplicationInstance applicationInstance; 94 95 104 public ServerUpdateManager(ApplicationInstance applicationInstance) { 105 super(); 106 this.applicationInstance = applicationInstance; 107 applicationUpdateMap = new HashMap (); 108 commands = new ArrayList (); 109 componentUpdateMap = new HashMap (); 110 fullRefreshUpdate = new ServerComponentUpdate(null); 111 } 112 113 122 private ServerComponentUpdate createComponentUpdate(Component parent) { 123 124 ServerComponentUpdate update; 125 if (componentUpdateMap.containsKey(parent)) { 126 update = (ServerComponentUpdate) componentUpdateMap.get(parent); 127 } else { 128 update = new ServerComponentUpdate(parent); 129 componentUpdateMap.put(parent, update); 130 } 131 return update; 132 } 133 134 139 public void enqueueCommand(Command command) { 140 commands.add(command); 141 } 142 143 151 public PropertyUpdate getApplicationPropertyUpdate(String propertyName) { 152 return (PropertyUpdate) applicationUpdateMap.get(propertyName); 153 } 154 155 161 public Command[] getCommands() { 162 return (Command[])commands.toArray(new Command[commands.size()]); 163 } 164 165 173 public ServerComponentUpdate[] getComponentUpdates() { 174 if (isFullRefreshRequired()) { 175 return new ServerComponentUpdate[]{fullRefreshUpdate}; 176 } else { 177 Collection hierarchyUpdates = componentUpdateMap.values(); 178 ServerComponentUpdate[] serverComponentUpdates = (ServerComponentUpdate[]) 179 hierarchyUpdates.toArray(new ServerComponentUpdate[hierarchyUpdates.size()]); 180 Arrays.sort(serverComponentUpdates, hierarchyDepthUpdateComparator); 181 return serverComponentUpdates; 182 } 183 } 184 185 192 public void init(ClientUpdateManager clientUpdateManager) { 193 this.clientUpdateManager = clientUpdateManager; 194 } 195 196 202 private boolean isAncestorBeingAdded(Component component) { 203 Component child = component; 204 Component parent = component.getParent(); 205 while (parent != null) { 206 ServerComponentUpdate update = (ServerComponentUpdate) componentUpdateMap.get(parent); 207 if (update != null) { 208 if (update.hasAddedChild(child)) { 209 return true; 210 } 211 } 212 child = parent; 213 parent = parent.getParent(); 214 } 215 return false; 216 } 217 218 223 public boolean isEmpty() { 224 return componentUpdateMap.size() == 0; 225 } 226 227 232 public boolean isFullRefreshRequired() { 233 return fullRefreshUpdate != null; 234 } 235 236 243 public void processApplicationPropertyUpdate(String propertyName, Object oldValue, Object newValue) { 244 Object clientValue = clientUpdateManager.getApplicationUpdatePropertyValue(propertyName); 245 if (clientValue == newValue || (clientValue != null && clientValue.equals(newValue))) { 246 applicationUpdateMap.remove(propertyName); 248 } else { 249 applicationUpdateMap.put(propertyName, new PropertyUpdate(oldValue, newValue)); 250 } 251 } 252 253 260 public void processComponentAdd(Component parent, Component child) { 261 if (isFullRefreshRequired()) { 262 return; 263 } 264 if (!child.isRenderVisible()) { 265 return; 266 } 267 if (isAncestorBeingAdded(child)) { 268 return; 269 } 270 271 ServerComponentUpdate update = createComponentUpdate(parent); 272 update.addChild(child); 273 } 274 275 282 public void processComponentLayoutDataUpdate(Component updatedComponent) { 283 if (isFullRefreshRequired()) { 284 return; 285 } 286 if (!updatedComponent.isRenderVisible()) { 287 return; 288 } 289 290 Component parentComponent = updatedComponent.getParent(); 291 if (parentComponent == null || isAncestorBeingAdded(parentComponent)) { 292 return; 294 } 295 ServerComponentUpdate update = createComponentUpdate(parentComponent); 296 update.updateLayoutData(updatedComponent); 297 } 298 299 309 public void processComponentPropertyUpdate(Component updatedComponent, String propertyName, Object oldValue, Object newValue) { 310 if (isFullRefreshRequired()) { 311 return; 312 } 313 if (!updatedComponent.isRenderVisible()) { 314 return; 315 } 316 if (isAncestorBeingAdded(updatedComponent)) { 317 return; 318 } 319 320 ClientComponentUpdate clientComponentUpdate = clientUpdateManager.getComponentUpdate(updatedComponent); 324 if (clientComponentUpdate != null) { 325 if (clientComponentUpdate.hasInput(propertyName)) { 326 Object inputValue = clientComponentUpdate.getInputValue(propertyName); 327 if (inputValue == newValue || (inputValue != null && inputValue.equals(newValue))) { 328 ServerComponentUpdate update = (ServerComponentUpdate) componentUpdateMap.get(updatedComponent); 329 if (update != null) { 330 update.cancelUpdateProperty(propertyName); 331 } 332 return; 333 } 334 } 335 } 336 337 ServerComponentUpdate update = createComponentUpdate(updatedComponent); 338 update.updateProperty(propertyName, oldValue, newValue); 339 } 340 341 348 public void processComponentRemove(Component parent, Component child) { 349 if (isFullRefreshRequired()) { 350 return; 351 } 352 if (!parent.isRenderVisible()) { 353 return; 354 } 355 if (isAncestorBeingAdded(parent)) { 356 return; 357 } 358 ServerComponentUpdate update = createComponentUpdate(parent); 359 update.removeChild(child); 360 361 Iterator it = componentUpdateMap.keySet().iterator(); 365 while (it.hasNext()) { 366 Component testComponent = (Component) it.next(); 367 if (child.isAncestorOf(testComponent)) { 368 ServerComponentUpdate childUpdate = (ServerComponentUpdate) componentUpdateMap.get(testComponent); 369 update.appendRemovedDescendants(childUpdate); 370 it.remove(); 371 } 372 } 373 } 374 375 382 public void processComponentVisibilityUpdate(Component updatedComponent) { 383 Component parentComponent = updatedComponent.getParent(); 384 if (updatedComponent.isVisible()) { 385 processComponentAdd(parentComponent, updatedComponent); 386 } else { 387 processComponentRemove(parentComponent, updatedComponent); 388 } 389 } 390 391 395 public void processFullRefresh() { 396 if (fullRefreshUpdate != null) { 397 return; 398 } 399 400 fullRefreshUpdate = new ServerComponentUpdate(null); 401 402 if (applicationInstance.getDefaultWindow() != null) { 403 fullRefreshUpdate.removeDescendant(applicationInstance.getDefaultWindow()); 406 } 407 408 Iterator it = componentUpdateMap.keySet().iterator(); 409 while (it.hasNext()) { 410 Component testComponent = (Component) it.next(); 411 ServerComponentUpdate childUpdate = (ServerComponentUpdate) componentUpdateMap.get(testComponent); 412 fullRefreshUpdate.appendRemovedDescendants(childUpdate); 413 it.remove(); 414 } 415 } 416 417 422 void purge() { 423 applicationUpdateMap.clear(); 424 componentUpdateMap.clear(); 425 commands.clear(); 426 fullRefreshUpdate = null; 427 } 428 } 429 | Popular Tags |