KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cayenne > util > PersistentObjectHolder


1 /*****************************************************************
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  ****************************************************************/

19
20 package org.apache.cayenne.util;
21
22 import java.util.List JavaDoc;
23
24 import org.apache.cayenne.CayenneRuntimeException;
25 import org.apache.cayenne.FaultFailureException;
26 import org.apache.cayenne.Persistent;
27 import org.apache.cayenne.ValueHolder;
28
29 /**
30  * A ValueHolder implementation that holds a single Persistent object related to an object
31  * used to initialize PersistentObjectHolder. Value is resolved on first access.
32  *
33  * @since 1.2
34  * @author Andrus Adamchik
35  */

36 public class PersistentObjectHolder extends RelationshipFault implements ValueHolder {
37
38     protected boolean fault;
39     protected Object JavaDoc value;
40
41     // exists for the benefit of manual serialization schemes such as the one in Hessian.
42
private PersistentObjectHolder() {
43         fault = true;
44     }
45
46     public PersistentObjectHolder(Persistent relationshipOwner, String JavaDoc relationshipName) {
47         super(relationshipOwner, relationshipName);
48         fault = !isTransientParent();
49     }
50
51     /**
52      * Returns true if this holder is not resolved, meaning its object is not yet known.
53      */

54     public boolean isFault() {
55         return fault;
56     }
57
58     public void invalidate() {
59         fault = true;
60         value = null;
61     }
62
63     /**
64      * Returns a value resolving it via a query on the first call to this method.
65      */

66     public Object JavaDoc getValue() throws CayenneRuntimeException {
67
68         if (fault) {
69             resolve();
70         }
71
72         return value;
73     }
74     
75     public Object JavaDoc getValueDirectly() throws CayenneRuntimeException {
76         return value;
77     }
78
79     /**
80      * Sets an object value, marking this ValueHolder as resolved.
81      */

82     public synchronized Object JavaDoc setValue(Object JavaDoc value) throws CayenneRuntimeException {
83
84         if (fault) {
85             resolve();
86         }
87
88         Object JavaDoc oldValue = setValueDirectly(value);
89
90         if (oldValue != value) {
91             // notify ObjectContext
92
if (relationshipOwner.getObjectContext() != null) {
93                 relationshipOwner.getObjectContext().propertyChanged(
94                         relationshipOwner,
95                         relationshipName,
96                         oldValue,
97                         value);
98             }
99         }
100
101         return oldValue;
102     }
103
104     public Object JavaDoc setValueDirectly(Object JavaDoc value) throws CayenneRuntimeException {
105
106         // must obtain the value from the local context
107
if (value instanceof Persistent) {
108             value = connect((Persistent) value);
109         }
110
111         Object JavaDoc oldValue = this.value;
112
113         this.value = value;
114         this.fault = false;
115
116         return oldValue;
117     }
118
119     /**
120      * Returns an object that should be stored as a value in this ValueHolder, ensuring
121      * that it is registered with the same context.
122      */

123     protected Object JavaDoc connect(Persistent persistent) {
124
125         if (persistent == null) {
126             return null;
127         }
128
129         if (relationshipOwner.getObjectContext() != persistent.getObjectContext()) {
130             throw new CayenneRuntimeException(
131                     "Cannot set object as destination of relationship "
132                             + relationshipName
133                             + " because it is in a different ObjectContext");
134         }
135
136         return persistent;
137     }
138
139     /**
140      * Reads an object from the database.
141      */

142     protected synchronized void resolve() {
143         if (!fault) {
144             return;
145         }
146
147         // TODO: should build a HOLLOW object instead of running a query if relationship
148
// is required and thus expected to be not null.
149

150         List JavaDoc objects = resolveFromDB();
151
152         if (objects.size() == 0) {
153             this.value = null;
154         }
155         else if (objects.size() == 1) {
156             this.value = objects.get(0);
157         }
158         else {
159             throw new FaultFailureException(
160                     "Expected either no objects or a single object, instead fault query resolved to "
161                             + objects.size()
162                             + " objects.");
163         }
164
165         fault = false;
166     }
167 }
168
Popular Tags