1 19 20 package org.apache.cayenne.access; 21 22 import org.apache.cayenne.DataChannelListener; 23 import org.apache.cayenne.ObjectId; 24 import org.apache.cayenne.PersistenceState; 25 import org.apache.cayenne.Persistent; 26 import org.apache.cayenne.access.ObjectStore.SnapshotEventDecorator; 27 import org.apache.cayenne.access.event.SnapshotEvent; 28 import org.apache.cayenne.graph.GraphChangeHandler; 29 import org.apache.cayenne.graph.GraphDiff; 30 import org.apache.cayenne.graph.GraphEvent; 31 import org.apache.cayenne.reflect.AttributeProperty; 32 import org.apache.cayenne.reflect.ClassDescriptor; 33 import org.apache.cayenne.reflect.Property; 34 import org.apache.cayenne.reflect.PropertyVisitor; 35 import org.apache.cayenne.reflect.ToManyProperty; 36 import org.apache.cayenne.reflect.ToOneProperty; 37 import org.apache.cayenne.util.Util; 38 39 46 class DataContextMergeHandler implements GraphChangeHandler, DataChannelListener { 50 51 private boolean active; 52 private DataContext context; 53 54 DataContextMergeHandler(DataContext context) { 55 this.active = true; 56 this.context = context; 57 } 58 59 void setActive(boolean active) { 60 this.active = active; 61 } 62 63 67 private boolean shouldProcessEvent(GraphEvent e) { 68 69 if (!active) { 70 return false; 71 } 72 73 return e.getSource() == context.getChannel() 76 && e.getPostedBy() != context 77 && e.getPostedBy() != context.getChannel(); 78 79 } 83 84 private Property propertyForId(Object nodeId, String propertyName) { 85 ClassDescriptor descriptor = context.getEntityResolver().getClassDescriptor( 86 ((ObjectId) nodeId).getEntityName()); 87 return descriptor.getProperty(propertyName); 88 } 89 90 92 public void graphChanged(GraphEvent event) { 93 if (shouldProcessEvent(event)) { 95 96 GraphDiff diff = event.getDiff(); 98 if (diff instanceof SnapshotEventDecorator) { 99 SnapshotEvent decoratedEvent = ((SnapshotEventDecorator) diff).getEvent(); 100 context.getObjectStore().processSnapshotEvent(decoratedEvent); 101 } 102 else { 103 synchronized (context.getObjectStore()) { 104 diff.apply(this); 105 } 106 } 107 108 context.fireDataChannelChanged(event.getPostedBy(), event.getDiff()); 110 } 111 } 112 113 public void graphFlushed(GraphEvent event) { 114 if (shouldProcessEvent(event)) { 116 event.getDiff().apply(this); 117 118 context.fireDataChannelChanged(event.getPostedBy(), event.getDiff()); 120 } 121 } 122 123 public void graphRolledback(GraphEvent event) { 124 127 } 131 132 134 public void nodeIdChanged(Object nodeId, Object newId) { 135 context.getObjectStore().processIdChange(nodeId, newId); 136 } 137 138 public void nodeCreated(Object nodeId) { 139 } 141 142 public void nodeRemoved(Object nodeId) { 143 ObjectStore os = context.getObjectStore(); 144 synchronized (os) { 145 os.processDeletedID(nodeId); 146 } 147 } 148 149 public void nodePropertyChanged( 150 Object nodeId, 151 String property, 152 Object oldValue, 153 Object newValue) { 154 155 Persistent object = (Persistent) context.getGraphManager().getNode(nodeId); 156 if (object != null && object.getPersistenceState() != PersistenceState.HOLLOW) { 157 158 Property p = propertyForId(nodeId, property); 160 if (Util.nullSafeEquals(p.readPropertyDirectly(object), oldValue)) { 161 p.writePropertyDirectly(object, oldValue, newValue); 162 } 163 } 164 } 165 166 public void arcCreated(Object nodeId, Object targetNodeId, Object arcId) { 167 arcChanged(nodeId, targetNodeId, arcId); 168 } 169 170 public void arcDeleted(Object nodeId, Object targetNodeId, Object arcId) { 171 arcChanged(nodeId, targetNodeId, arcId); 172 } 173 174 private void arcChanged(Object nodeId, Object targetNodeId, Object arcId) { 176 177 final Persistent source = (Persistent) context.getGraphManager().getNode(nodeId); 178 if (source != null && source.getPersistenceState() != PersistenceState.HOLLOW) { 179 180 final int state = source.getPersistenceState(); 181 182 Property p = propertyForId(nodeId, arcId.toString()); 183 p.visit(new PropertyVisitor() { 184 185 public boolean visitAttribute(AttributeProperty property) { 186 return false; 187 } 188 189 public boolean visitToMany(ToManyProperty property) { 190 if (state == PersistenceState.COMMITTED) { 191 property.invalidate(source); 192 } 193 194 return false; 195 } 196 197 public boolean visitToOne(ToOneProperty property) { 198 if (state == PersistenceState.COMMITTED) { 199 property.invalidate(source); 200 } 201 return false; 204 } 205 }); 206 } 207 } 208 } 209 | Popular Tags |