001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.ejb.plugins.cmp.jdbc;
023:
024: import java.util.HashSet;
025: import java.util.Set;
026: import javax.ejb.EJBException;
027:
028: import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMRFieldBridge;
029:
030: /**
031: * This class holds data about one relationship. It maintains a lists of
032: * which relations have been added and removed. When the transaction is
033: * committed these list are retrieved and used to update the relation table.
034: *
035: * @author <a href="mailto:dain@daingroup.com">Dain Sundstrom</a>
036: * @version $Revision: 57209 $
037: */
038: public final class RelationData {
039: private final JDBCCMRFieldBridge leftCMRField;
040: private final JDBCCMRFieldBridge rightCMRField;
041:
042: public final Set addedRelations = new HashSet();
043: public final Set removedRelations = new HashSet();
044: public final Set notRelatedPairs = new HashSet();
045:
046: public RelationData(JDBCCMRFieldBridge leftCMRField,
047: JDBCCMRFieldBridge rightCMRField) {
048:
049: this .leftCMRField = leftCMRField;
050: this .rightCMRField = rightCMRField;
051: }
052:
053: public JDBCCMRFieldBridge getLeftCMRField() {
054: return leftCMRField;
055: }
056:
057: public JDBCCMRFieldBridge getRightCMRField() {
058: return rightCMRField;
059: }
060:
061: public void addRelation(JDBCCMRFieldBridge leftCMRField,
062: Object leftId, JDBCCMRFieldBridge rightCMRField,
063: Object rightId) {
064: // only need to bother if neither side has a foreign key
065: if (!leftCMRField.hasForeignKey()
066: && !rightCMRField.hasForeignKey()) {
067: RelationPair pair = createRelationPair(leftCMRField,
068: leftId, rightCMRField, rightId);
069: if (removedRelations.contains(pair)) {
070: // we were going to remove this relation
071: // and now we are adding it. Just
072: // remove it from the remove set and we are ok.
073: removedRelations.remove(pair);
074: } else {
075: addedRelations.add(pair);
076:
077: // if pair was specifically marked as
078: // not related, remove it to the not
079: // related set. See below.
080: if (notRelatedPairs.contains(pair)) {
081: notRelatedPairs.remove(pair);
082: }
083: }
084: }
085: }
086:
087: public void removeRelation(JDBCCMRFieldBridge leftCMRField,
088: Object leftId, JDBCCMRFieldBridge rightCMRField,
089: Object rightId) {
090: // only need to bother if neither side has a foreign key
091: if (!leftCMRField.hasForeignKey()
092: && !rightCMRField.hasForeignKey()) {
093: RelationPair pair = createRelationPair(leftCMRField,
094: leftId, rightCMRField, rightId);
095: if (addedRelations.contains(pair)) {
096: // we were going to add this relation
097: // and now we are removing it. Just
098: // remove it from the add set and we are ok.
099: addedRelations.remove(pair);
100:
101: // add it to the set of not related pairs
102: // so if remove is called again it is not
103: // added to the remove list. This avoids
104: // an extra 'DELETE FROM...' query.
105: // This happend when a object is moved from
106: // one relation to another. See
107: // JDBCCMRFieldBridge.createRelationLinks
108: notRelatedPairs.add(pair);
109: } else {
110: // if pair is related (not not related)
111: // add it to the remove set. See above.
112: if (!notRelatedPairs.contains(pair)) {
113: removedRelations.add(pair);
114: }
115: }
116: }
117: }
118:
119: public boolean isDirty() {
120: return addedRelations.size() > 0 || removedRelations.size() > 0;
121: }
122:
123: private RelationPair createRelationPair(
124: JDBCCMRFieldBridge leftCMRField, Object leftId,
125: JDBCCMRFieldBridge rightCMRField, Object rightId) {
126: if (this .leftCMRField == leftCMRField
127: && this .rightCMRField == rightCMRField) {
128: return new RelationPair(leftCMRField, leftId,
129: rightCMRField, rightId);
130: }
131:
132: if (this .leftCMRField == rightCMRField
133: && this .rightCMRField == leftCMRField) {
134: return new RelationPair(rightCMRField, rightId,
135: leftCMRField, leftId);
136: }
137: throw new EJBException("Error: cmrFields are of wrong type");
138: }
139: }
|