001: package de.webman.acl;
002:
003: import com.teamkonzept.lib.TKException;
004: import com.teamkonzept.lib.TKVector;
005: import de.webman.acl.db.ObjectDBData;
006:
007: /**
008: * Base class of persistent objects. Provides a means for identification
009: * throughout the object system as well as the database system. Creation of
010: * such objects should be left to a corresponding factory to ensure uniqueness.
011: *
012: * @author $Author: mischa $
013: * @version $Revision: 1.1 $
014: */
015: public abstract class WMObject {
016:
017: // $Header: /cvsroot/webman-cms/source/webman/de/webman/acl/WMObject.java,v 1.1 2001/08/20 08:25:07 mischa Exp $
018:
019: // Attributes
020:
021: /**
022: * Specifies wether at least one of the attributes has been modified.
023: */
024: private boolean attributesModified = false;
025:
026: /**
027: * Specifies wether at least one of the associations has been modified.
028: */
029: private boolean associationsModified = false;
030:
031: /**
032: * Specifies wether the associations has been loaded.
033: */
034: private boolean associationsLoaded = false;
035:
036: /**
037: * The ID of the persistent object.
038: */
039: private Integer id = null;
040:
041: /**
042: * The string representation of the persistent object.
043: */
044: private String string = null;
045:
046: /**
047: * The IDs of the associated persistent objects.
048: */
049: private TKVector associations = null;
050:
051: // Constructors
052:
053: /**
054: * Provide instantion only to package classes or subclasses.
055: *
056: * @param data the initial object data.
057: */
058: protected WMObject(ObjectDBData data) {
059: this .id = data.getID();
060: }
061:
062: // Standard methods
063:
064: /**
065: * Checks wether the persistent and the given object can be treated as equal.
066: *
067: * @param object the object to be proved upon equality.
068: * @return <CODE>true</CODE> if both objects can be treated as equal,
069: * otherwise <CODE>false</CODE>.
070: */
071: public final boolean equals(Object object) {
072: if (object == null) {
073: return false;
074: }
075:
076: if (object.getClass() != getClass()) {
077: return false;
078: }
079:
080: return ((WMObject) object).getID().equals(this .id);
081: }
082:
083: /**
084: * Returns the hash code of the persistent object.
085: *
086: * @return the hash code of the persistent object.
087: */
088: public final int hashCode() {
089: return this .id.intValue();
090: }
091:
092: /**
093: * Returns the string representation of the persistent object.
094: *
095: * @return the string representation of the persistent object.
096: */
097: public final String toString() {
098: if (this .string == null) {
099: this .string = (new StringBuffer(getClass().getName()))
100: .append('.').append(id).toString();
101: }
102:
103: return this .string;
104: }
105:
106: // Method signatures
107:
108: /**
109: * Returns the factory of the object.
110: *
111: * @return the factory of the object.
112: * @exception com.teamkonzept.lib.TKException if an error occured during factory retrieval.
113: */
114: public abstract ObjectFactory getFactory() throws TKException;
115:
116: // Method implementations
117:
118: /**
119: * Returns the ID of the persistent object.
120: *
121: * @return the ID of the persistent object.
122: */
123: public final Integer getID() {
124: return id;
125: }
126:
127: /**
128: * Checks wether at least one of the attributes has been modified.
129: *
130: * @return <CODE>true</CODE> at least one of the attributes has been
131: * modified, otherwise <CODE>false</CODE>.
132: */
133: public final boolean isModifiedAttributes() {
134: return this .attributesModified;
135: }
136:
137: /**
138: * Checks wether at least one of the associations has been modified.
139: *
140: * @return <CODE>true</CODE> at least one of the associations has been
141: * modified, otherwise <CODE>false</CODE>.
142: */
143: public final boolean isModifiedAssociations() {
144: return this .associationsModified;
145: }
146:
147: // Attribute handling methods
148:
149: /**
150: * Informs the object about the modification of one of its attributes.
151: *
152: * @param pre the value of the attribute before the modification.
153: * @param post the value of the attribute after the modification.
154: */
155: protected final void modifyAttribute(Object pre, Object post) {
156: if (pre != null || post != null) {
157: try {
158: this .attributesModified = this .attributesModified
159: || !pre.equals(post);
160: } catch (NullPointerException npe) {
161: this .attributesModified = true;
162: }
163: }
164: }
165:
166: /**
167: * Informs the object about the succesful update of its attributes.
168: */
169: protected final void updatedAttributes() {
170: this .attributesModified = false;
171: }
172:
173: // Association handling methods
174:
175: /**
176: * Returns the IDs of all associated objects.
177: *
178: * @return the IDs of all associated objects.
179: * @exception com.teamkonzept.lib.TKException if an error occured during object retrieval.
180: */
181: protected final TKVector getAssociations() throws TKException {
182: loadAssociations();
183:
184: return this .associations;
185: }
186:
187: /**
188: * Adds an association with the given object.
189: *
190: * @param object the object.
191: * @exception com.teamkonzept.lib.TKException if an error occured during object retrieval.
192: */
193: protected final void addAssociation(WMObject object)
194: throws TKException {
195: loadAssociations();
196:
197: if (object != null) {
198: if (this .associations == null) {
199: this .associations = new TKVector();
200: }
201:
202: if (!this .associations.contains(object.getID())) {
203: this .associations.addElement(object.getID());
204: this .associationsModified = true;
205: }
206: }
207: }
208:
209: /**
210: * Removes the association with the given object.
211: *
212: * @param object the object.
213: * @exception com.teamkonzept.lib.TKException if an error occured during object retrieval.
214: */
215: protected final void removeAssociation(WMObject object)
216: throws TKException {
217: loadAssociations();
218:
219: if (object != null && this .associations != null) {
220: this .associationsModified = this .associationsModified
221: || this .associations.removeElement(object.getID());
222: }
223: }
224:
225: /**
226: * Removes the association with all objects.
227: *
228: * @exception com.teamkonzept.lib.TKException if an error occured during object retrieval.
229: */
230: protected final void removeAssociations() throws TKException {
231: loadAssociations();
232:
233: if (this .associations != null && this .associations.size() > 0) {
234: this .associations.removeAllElements();
235: this .associationsModified = true;
236: }
237: }
238:
239: /**
240: * Checks wether there is an association with the given object.
241: *
242: * @param object the object.
243: * @return <CODE>true</CODE> if there is an association with the
244: * given object, otherwise <CODE>false</CODE>.
245: * @exception com.teamkonzept.lib.TKException if an error occured during object retrieval.
246: */
247: protected final boolean containsAssociation(WMObject object)
248: throws TKException {
249: loadAssociations();
250:
251: if (object != null && this .associations != null) {
252: return this .associations.contains(object.getID());
253: }
254:
255: return false;
256: }
257:
258: /**
259: * Informs the object about the succesful update of its associations.
260: */
261: protected final void updatedAssociations() {
262: this .associationsModified = false;
263: }
264:
265: /**
266: * Loads the associations on demand.
267: *
268: * @exception com.teamkonzept.lib.TKException if an error occured during object retrieval.
269: */
270: protected final void loadAssociations() throws TKException {
271: if (!this .associationsLoaded) {
272: this .associations = getFactory()
273: .getObjectAssociations(this );
274: this .associationsLoaded = true;
275: }
276: }
277:
278: }
|