001: /*
002: * Copyright (c) 1998 - 2005 Versant Corporation
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * Versant Corporation - initial API and implementation
010: */
011: package com.versant.core.jdo.sco;
012:
013: import com.versant.core.jdo.PMProxy;
014:
015: import javax.jdo.spi.PersistenceCapable;
016: import java.util.Collection;
017:
018: /**
019: * Utility methods to help SCOs implement inverse mappings.
020: */
021: public class SCOInverseUtil {
022:
023: /**
024: * Change the master reference on detailObject. This will remove the
025: * detail from its current master (if any and if different).
026: */
027: public static void addMasterOnDetail(Object detailObject,
028: PersistenceCapable owner, int detailFieldNo) {
029: if (owner == null)
030: return;
031: PersistenceCapable detail = (PersistenceCapable) detailObject;
032: if (!detail.jdoIsPersistent()) {
033: owner.jdoGetPersistenceManager().makePersistent(detail);
034: }
035: ((PMProxy) owner.jdoGetPersistenceManager()).setMasterOnDetail(
036: detail, detailFieldNo, owner, true);
037: }
038:
039: /**
040: * Clear the master reference on detailObject. This will <b>not</b> remove
041: * the detail from its current master. This can be done in bulk or more
042: * efficiently by the SCO.
043: */
044: public static void removeMasterOnDetail(Object detailObject,
045: PersistenceCapable owner, int detailFieldNo) {
046: if (owner == null)
047: return;
048: PersistenceCapable detail = (PersistenceCapable) detailObject;
049: if (!detail.jdoIsPersistent()) {
050: owner.jdoGetPersistenceManager().makePersistent(detail);
051: }
052: ((PMProxy) owner.jdoGetPersistenceManager()).setMasterOnDetail(
053: detail, detailFieldNo, null, false);
054: }
055:
056: /**
057: * Add to the other half of a many-to-many relationship.
058: *
059: * @param inverse The instance on the other side of the relationship
060: * @param inverseFieldNo The collection field on inverse to add to
061: * @param toAdd The instance to add to the collection on inverse
062: */
063: public static void addToOtherSideOfManyToMany(Object inverse,
064: int inverseFieldNo, PersistenceCapable toAdd) {
065: if (toAdd == null)
066: return;
067: final PMProxy pm = (PMProxy) toAdd.jdoGetPersistenceManager();
068:
069: PersistenceCapable pcInverse = (PersistenceCapable) inverse;
070: if (!pcInverse.jdoIsPersistent())
071: pm.makePersistent(pcInverse);
072:
073: Object otherSide = pm.getObjectField(pcInverse, inverseFieldNo);
074: if (otherSide instanceof VersantManagedSCOCollection) {
075: ((VersantManagedSCOCollection) otherSide)
076: .manyToManyAdd(toAdd);
077: } else {
078: ((Collection) otherSide).add(toAdd);
079: }
080: }
081:
082: /**
083: * Remove from the other half of a many-to-many relationship.
084: *
085: * @param inverse The instance on the other side of the relationship
086: * @param inverseFieldNo The collection field on inverse to remove from
087: * @param toRemove The instance to remve from the collection on inverse
088: */
089: public static void removeFromOtherSideOfManyToMany(Object inverse,
090: int inverseFieldNo, PersistenceCapable toRemove) {
091: if (toRemove == null)
092: return;
093: PMProxy pm = (PMProxy) toRemove.jdoGetPersistenceManager();
094:
095: Object otherSide = pm.getObjectField(
096: (PersistenceCapable) inverse, inverseFieldNo);
097: if (otherSide instanceof VersantManagedSCOCollection) {
098: ((VersantManagedSCOCollection) otherSide)
099: .manyToManyRemove(toRemove);
100: } else {
101: ((Collection) otherSide).remove(toRemove);
102: }
103: }
104:
105: }
|