KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cayenne > CayenneContextGraphAction


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;
21
22 import org.apache.cayenne.reflect.ArcProperty;
23 import org.apache.cayenne.reflect.AttributeProperty;
24 import org.apache.cayenne.reflect.PropertyVisitor;
25 import org.apache.cayenne.reflect.ToManyProperty;
26 import org.apache.cayenne.reflect.ToOneProperty;
27 import org.apache.cayenne.util.ObjectContextGraphAction;
28
29 /**
30  * An action object that processes graph change calls from Persistent object. It handles
31  * GraphManager notifications and bi-directional graph consistency.
32  *
33  * @since 1.2
34  * @author Andrus Adamchik
35  */

36 class CayenneContextGraphAction extends ObjectContextGraphAction {
37
38     ThreadLocal JavaDoc arcChangeInProcess;
39
40     CayenneContextGraphAction(ObjectContext context) {
41         super(context);
42         this.arcChangeInProcess = new ThreadLocal JavaDoc();
43     }
44
45     protected void handleArcPropertyChange(
46             Persistent object,
47             ArcProperty property,
48             Object JavaDoc oldValue,
49             Object JavaDoc newValue) {
50
51         if (isArchChangeInProcess()) {
52             return;
53         }
54
55         // prevent reverse actions down the stack
56
setArcChangeInProcess(true);
57
58         try {
59             if (oldValue instanceof Persistent) {
60                 context.getGraphManager().arcDeleted(
61                         object.getObjectId(),
62                         ((Persistent) oldValue).getObjectId(),
63                         property.getName());
64
65                 unsetReverse(property, object, (Persistent) oldValue);
66                 markAsDirty(object);
67             }
68
69             if (newValue instanceof Persistent) {
70                 context.getGraphManager().arcCreated(
71                         object.getObjectId(),
72                         ((Persistent) newValue).getObjectId(),
73                         property.getName());
74
75                 setReverse(property, object, (Persistent) newValue);
76                 markAsDirty(object);
77             }
78         }
79         finally {
80             setArcChangeInProcess(false);
81         }
82     }
83
84     protected void handleSimplePropertyChange(
85             Persistent object,
86             String JavaDoc propertyName,
87             Object JavaDoc oldValue,
88             Object JavaDoc newValue) {
89         context.getGraphManager().nodePropertyChanged(
90                 object.getObjectId(),
91                 propertyName,
92                 oldValue,
93                 newValue);
94         markAsDirty(object);
95     }
96
97     /**
98      * Returns true if the current thread is in the process of changing the arc property.
99      * This method is used to prevent cycles when setting reverse relationships.
100      */

101     boolean isArchChangeInProcess() {
102         return arcChangeInProcess.get() != null;
103     }
104
105     /**
106      * Sets the flag indicating whether the current thread is in the process of changing
107      * the arc property. This method is used to prevent cycles when setting reverse
108      * relationships.
109      */

110     void setArcChangeInProcess(boolean flag) {
111         arcChangeInProcess.set(flag ? Boolean.TRUE : null);
112     }
113
114     private void setReverse(
115             ArcProperty property,
116             final Persistent sourceObject,
117             final Persistent targetObject) {
118
119         ArcProperty reverseArc = property.getComplimentaryReverseArc();
120         if (reverseArc != null) {
121             reverseArc.visit(new PropertyVisitor() {
122
123                 public boolean visitToMany(ToManyProperty property) {
124                     property.addTarget(targetObject, sourceObject, false);
125                     return false;
126                 }
127
128                 public boolean visitToOne(ToOneProperty property) {
129                     property.setTarget(targetObject, sourceObject, false);
130                     return false;
131                 }
132
133                 public boolean visitAttribute(AttributeProperty property) {
134                     return false;
135                 }
136
137             });
138
139             context.getGraphManager().arcCreated(
140                     targetObject.getObjectId(),
141                     sourceObject.getObjectId(),
142                     reverseArc.getName());
143
144             markAsDirty(targetObject);
145         }
146     }
147
148     private void unsetReverse(
149             ArcProperty property,
150             Persistent sourceObject,
151             Persistent targetObject) {
152
153         ArcProperty reverseArc = property.getComplimentaryReverseArc();
154         if (reverseArc != null) {
155             reverseArc.writePropertyDirectly(targetObject, sourceObject, null);
156
157             context.getGraphManager().arcDeleted(
158                     targetObject.getObjectId(),
159                     sourceObject.getObjectId(),
160                     reverseArc.getName());
161
162             markAsDirty(targetObject);
163         }
164     }
165 }
166
Popular Tags