1 56 package org.objectstyle.cayenne.modeler.dialog.objentity; 57 58 import java.util.ArrayList ; 59 import java.util.Collection ; 60 import java.util.Collections ; 61 import java.util.Iterator ; 62 import java.util.List ; 63 64 import org.apache.log4j.Logger; 65 import org.objectstyle.cayenne.CayenneRuntimeException; 66 import org.objectstyle.cayenne.map.DbEntity; 67 import org.objectstyle.cayenne.map.DbRelationship; 68 import org.objectstyle.cayenne.map.Entity; 69 import org.objectstyle.cayenne.map.ObjEntity; 70 import org.objectstyle.cayenne.map.ObjRelationship; 71 import org.objectstyle.cayenne.map.Relationship; 72 import org.objectstyle.cayenne.modeler.util.Comparators; 73 import org.objectstyle.cayenne.util.Util; 74 import org.scopemvc.core.IntIndexSelector; 75 import org.scopemvc.core.ModelChangeEvent; 76 import org.scopemvc.core.Selector; 77 import org.scopemvc.model.basic.BasicModel; 78 import org.scopemvc.model.collection.ListModel; 79 80 87 public class ObjRelationshipInfoModel extends BasicModel { 88 static final Logger logObj = Logger.getLogger(ObjRelationshipInfoModel.class); 89 90 91 public static final Selector DB_RELATIONSHIP_PATH_SELECTOR = 92 Selector.fromString("dbRelationshipPath"); 93 public static final Selector SOURCE_ENTITY_NAME_SELECTOR = 94 Selector.fromString("relationship.sourceEntity.name"); 95 public static final Selector SELECTED_PATH_COMPONENT_SELECTOR = 96 Selector.fromString("selectedPathComponent"); 97 public static final Selector OBJECT_TARGET_SELECTOR = 98 Selector.fromString("objectTarget"); 99 public static final Selector OBJECT_TARGETS_SELECTOR = 100 Selector.fromString("objectTargets"); 101 public static final Selector RELATIONSHIP_NAME_SELECTOR = 102 Selector.fromString("relationshipName"); 103 104 protected ObjRelationship relationship; 105 protected ListModel dbRelationshipPath; 106 protected EntityRelationshipsModel selectedPathComponent; 107 protected ObjEntity objectTarget; 108 protected List objectTargets; 109 protected String relationshipName; 110 111 public ObjRelationshipInfoModel( 112 ObjRelationship relationship, 113 Collection objEntities) { 114 115 this.relationship = relationship; 116 this.relationshipName = relationship.getName(); 117 this.objectTarget = (ObjEntity) relationship.getTargetEntity(); 118 119 121 this.objectTargets = new ArrayList (objEntities.size()); 122 Iterator entities = objEntities.iterator(); 123 while (entities.hasNext()) { 124 ObjEntity entity = (ObjEntity) entities.next(); 125 if (entity.getDbEntity() != null) { 126 objectTargets.add(entity); 127 } 128 } 129 130 Collections.sort(objectTargets, Comparators.getNamedObjectComparator()); 131 132 validateCanMap(); 136 137 this.dbRelationshipPath = new ListModel(); 139 Iterator it = relationship.getDbRelationships().iterator(); 140 while (it.hasNext()) { 141 DbRelationship dbRelationship = (DbRelationship) it.next(); 142 this.dbRelationshipPath.add(new EntityRelationshipsModel(dbRelationship)); 143 } 144 145 connectEnds(); 147 this.dbRelationshipPath.addModelChangeListener(this); 148 } 149 150 public ObjRelationship getRelationship() { 151 return relationship; 152 } 153 154 public ListModel getDbRelationshipPath() { 155 return dbRelationshipPath; 156 } 157 158 public EntityRelationshipsModel getSelectedPathComponent() { 159 return selectedPathComponent; 160 } 161 162 public void setSelectedPathComponent(EntityRelationshipsModel selectedPathComponent) { 163 if (this.selectedPathComponent != selectedPathComponent) { 164 unlistenOldSubmodel(SELECTED_PATH_COMPONENT_SELECTOR); 165 this.selectedPathComponent = selectedPathComponent; 166 listenNewSubmodel(SELECTED_PATH_COMPONENT_SELECTOR); 167 fireModelChange( 168 ModelChangeEvent.VALUE_CHANGED, 169 SELECTED_PATH_COMPONENT_SELECTOR); 170 } 171 } 172 173 176 public ObjEntity getObjectTarget() { 177 return objectTarget; 178 } 179 180 183 public void setObjectTarget(ObjEntity objectTarget) { 184 if (this.objectTarget != objectTarget) { 185 unlistenOldSubmodel(OBJECT_TARGET_SELECTOR); 186 this.objectTarget = objectTarget; 187 listenNewSubmodel(OBJECT_TARGET_SELECTOR); 188 fireModelChange(ModelChangeEvent.VALUE_CHANGED, OBJECT_TARGET_SELECTOR); 189 190 breakChain(-1); 192 connectEnds(); 193 fireModelChange( 194 ModelChangeEvent.VALUE_CHANGED, 195 DB_RELATIONSHIP_PATH_SELECTOR); 196 } 197 } 198 199 202 public List getObjectTargets() { 203 return objectTargets; 204 } 205 206 public String getRelationshipName() { 207 return relationshipName; 208 } 209 210 public void setRelationshipName(String relationshipName) { 211 this.relationshipName = relationshipName; 212 } 213 214 public void modelChanged(ModelChangeEvent event) { 215 216 Selector selector = event.getSelector(); 218 while (selector != null) { 219 if (selector instanceof IntIndexSelector) { 220 IntIndexSelector indexSel = (IntIndexSelector) selector; 221 relationshipChanged(indexSel.getIndex()); 222 break; 223 } 224 225 selector = selector.getNext(); 226 } 227 228 super.modelChanged(event); 229 } 230 231 234 public synchronized void relationshipChanged(int index) { 235 breakChain(index); 237 238 connectEnds(); 240 241 dbRelationshipPath.fireModelChange(VALUE_CHANGED, null); 243 } 244 245 248 public synchronized boolean savePath() { 249 if (relationship.getTargetEntity() == objectTarget) { 251 if (Util.nullSafeEquals(relationship.getName(), relationshipName)) { 252 List oldPath = relationship.getDbRelationships(); 253 if (oldPath.size() == dbRelationshipPath.size()) { 254 boolean hasChanges = false; 255 for (int i = 0; i < oldPath.size(); i++) { 256 EntityRelationshipsModel next = 257 (EntityRelationshipsModel) dbRelationshipPath.get(i); 258 if (oldPath.get(i) != next.getSelectedRelationship()) { 259 hasChanges = true; 260 break; 261 } 262 } 263 264 if (!hasChanges) { 265 return false; 266 } 267 } 268 } 269 } 270 271 relationship.clearDbRelationships(); 273 274 relationship.setTargetEntity(objectTarget); 278 relationship.setName(relationshipName); 279 280 Iterator it = dbRelationshipPath.iterator(); 281 while (it.hasNext()) { 282 EntityRelationshipsModel next = (EntityRelationshipsModel) it.next(); 283 Relationship nextPathComponent = next.getSelectedRelationship(); 284 if (nextPathComponent == null) { 285 break; 286 } 287 288 relationship.addDbRelationship((DbRelationship) nextPathComponent); 289 } 290 291 return true; 292 } 293 294 private void breakChain(int index) { 295 dbRelationshipPath.makeActive(false); 297 298 try { 299 while (dbRelationshipPath.size() > (index + 1)) { 300 dbRelationshipPath.remove(dbRelationshipPath.size() - 1); 302 } 303 } 304 finally { 305 dbRelationshipPath.makeActive(true); 306 } 307 } 308 309 private void connectEnds() { 312 Relationship last = null; 313 314 int size = dbRelationshipPath.size(); 315 if (size > 0) { 316 EntityRelationshipsModel wrapper = 317 (EntityRelationshipsModel) dbRelationshipPath.get(size - 1); 318 last = wrapper.getSelectedRelationship(); 319 320 } 321 322 Entity target = getEndEntity(); 323 324 if (last == null || last.getTargetEntity() != target) { 325 327 Entity source = (last == null) ? getStartEntity() : last.getTargetEntity(); 328 Relationship anyConnector = source.getAnyRelationship(target); 329 EntityRelationshipsModel connector = null; 330 331 connector = 332 (anyConnector == null) 333 ? new EntityRelationshipsModel(source, getEndEntity()) 334 : new EntityRelationshipsModel(anyConnector); 335 336 dbRelationshipPath.makeActive(false); 337 try { 338 dbRelationshipPath.add(connector); 339 } 340 finally { 341 dbRelationshipPath.makeActive(true); 342 } 343 } 344 } 345 346 private void validateCanMap() { 347 if (relationship.getSourceEntity() == null) { 348 throw new CayenneRuntimeException("Can't map relationship without source entity."); 349 } 350 351 if (relationship.getTargetEntity() == null) { 352 throw new CayenneRuntimeException("Can't map relationship without target entity."); 353 } 354 355 if (getStartEntity() == null) { 356 throw new CayenneRuntimeException("Can't map relationship without source DbEntity."); 357 } 358 359 if (getEndEntity() == null) { 360 throw new CayenneRuntimeException("Can't map relationship without target DbEntity."); 361 } 362 } 363 364 public DbEntity getStartEntity() { 365 return ((ObjEntity) relationship.getSourceEntity()).getDbEntity(); 366 } 367 368 public DbEntity getEndEntity() { 369 return objectTarget.getDbEntity(); 370 } 371 } 372 | Popular Tags |