KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jac > aspects > integrity > RoleWrapper


1 /*
2   Copyright (C) 2001-2004 Laurent Martelli <laurent@aopsys.com>
3
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU Lesser General Public License as
6   published by the Free Software Foundation; either version 2 of the
7   License, or (at your option) any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12   GNU Lesser General Public License for more details.
13
14   You should have received a copy of the GNU Lesser General Public License
15   along with this program; if not, write to the Free Software
16   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */

17
18 package org.objectweb.jac.aspects.integrity;
19
20 import org.aopalliance.intercept.ConstructorInvocation;
21 import org.aopalliance.intercept.MethodInvocation;
22 import org.apache.log4j.Logger;
23 import org.objectweb.jac.core.AspectComponent;
24 import org.objectweb.jac.core.Collaboration;
25 import org.objectweb.jac.core.Interaction;
26 import org.objectweb.jac.core.Wrapper;
27 import org.objectweb.jac.core.rtti.ClassItem;
28 import org.objectweb.jac.core.rtti.CollectionItem;
29 import org.objectweb.jac.core.rtti.FieldItem;
30 import org.objectweb.jac.core.rtti.MethodItem;
31 import org.objectweb.jac.core.rtti.RttiAC;
32
33 /**
34  * Wrapper for updating opposite roles.
35  */

36
37 public class RoleWrapper extends Wrapper {
38     static final Logger logger = Logger.getLogger("integrity");
39
40     public RoleWrapper(AspectComponent ac) {
41         super(ac);
42     }
43
44     /**
45      * Tells the integrity aspect to update the opposite roles of the
46      * declared associations.
47      */

48     public Object JavaDoc updateOppositeRole(Interaction interaction) {
49         logger.debug("updateOppositeRoles " + interaction.method + "...");
50         if (attr("rtti.updateOpposite") != null ||
51             attr(IntegrityAC.DISABLE_ROLE_UPDATES)!=null)
52             return interaction.proceed();
53
54         doUpdate(interaction);
55
56         Object JavaDoc result = interaction.proceed();
57         return result;
58     }
59
60     protected void doUpdate(Interaction interaction) {
61         logger.debug(
62             "updateOppositeRoles "+interaction.wrappee+"."+
63             interaction.method+"("+interaction.args[0]+")");
64         ClassItem cli = interaction.getClassItem();
65         MethodItem method = (MethodItem) interaction.method;
66
67         // References
68
FieldItem[] fields = method.getWrittenFields();
69         FieldItem opposite;
70         Object JavaDoc newValue = interaction.args[0];
71         for (int i = 0; fields != null && i < fields.length; i++) {
72             FieldItem field = fields[i];
73             Object JavaDoc currentValue = field.getThroughAccessor(interaction.wrappee);
74             opposite = (FieldItem) field.getAttribute(RttiAC.OPPOSITE_ROLE);
75             if (opposite != null) {
76                 try {
77                     attrdef("rtti.updateOpposite", opposite);
78                     logger.debug(
79                         "UpdateOppositeRole in "+interaction.method+" : "+
80                         fields[i].getName()+" -> "+opposite.getName());
81                     logger.debug(
82                         "wrappee = "+interaction.wrappee+" ; "+
83                         "currentValue = "+currentValue);
84                     if (opposite instanceof CollectionItem) {
85                         CollectionItem oppositeCollection =
86                             (CollectionItem) opposite;
87                         if (currentValue != null)
88                             oppositeCollection.removeThroughRemover(
89                                 currentValue,
90                                 interaction.wrappee);
91                         if (newValue != null
92                             && !oppositeCollection.contains(
93                                 newValue,
94                                 interaction.wrappee))
95                             oppositeCollection.addThroughAdder(
96                                 newValue,
97                                 interaction.wrappee);
98                     } else {
99                         if (currentValue != null) {
100                             opposite.setThroughWriter(currentValue, null);
101                         }
102                         if (newValue!=null)
103                             opposite.setThroughWriter(
104                                 newValue,
105                                 interaction.wrappee);
106                     }
107                 } catch (Exception JavaDoc e) {
108                     logger.error(
109                         "Failed to update opposite role "+opposite.getLongName()+" of "+
110                         field.getLongName()+" on "+interaction.wrappee,e);
111                 } finally {
112                     attrdef("rtti.updateOpposite", null);
113                 }
114             }
115         }
116
117         // Adders
118
CollectionItem[] collections = method.getAddedCollections();
119         Object JavaDoc addedValue = interaction.args[0];
120         for (int i = 0; collections != null && i < collections.length; i++) {
121             CollectionItem collection = collections[i];
122             opposite =
123                 (FieldItem) collection.getAttribute(RttiAC.OPPOSITE_ROLE);
124             if (opposite == null) {
125                 logger.debug(
126                     collection.getParent().getName()+"."+collection.toString()+
127                     " has no opposite role");
128                 continue;
129             }
130             logger.debug(
131                 "UpdateOppositeRole #"+i+" in "+interaction.method+" : "+
132                 collection.getName()+" -> "+opposite.getName());
133             try {
134                 attrdef("rtti.updateOpposite", opposite);
135                 if (opposite instanceof CollectionItem) {
136                     CollectionItem oppositeCollection =
137                         (CollectionItem) opposite;
138                     if (addedValue != null
139                         && !oppositeCollection.contains(
140                             addedValue,
141                             interaction.wrappee))
142                         oppositeCollection.addThroughAdder(
143                             addedValue,
144                             interaction.wrappee);
145                 } else {
146                     if (addedValue != null) {
147                         Object JavaDoc currentValue = opposite.get(addedValue);
148                         logger.debug(" currentValue="+currentValue+
149                                      ", interaction.wrappee="+interaction.wrappee);
150                         if (currentValue != null &&
151                             currentValue != interaction.wrappee) {
152                             collection.removeThroughRemover(
153                                 currentValue,
154                                 addedValue);
155                         }
156                         opposite.setThroughWriter(
157                             addedValue,
158                             interaction.wrappee);
159                     }
160                 }
161             } catch (Exception JavaDoc e) {
162                 logger.error(
163                     "Failed to update opposite role "+opposite.getLongName()+" of "+
164                     collection.getLongName()+" on "+interaction.wrappee,e);
165             } finally {
166                 attrdef("rtti.updateOpposite", null);
167             }
168         }
169
170         // Removers
171
collections = method.getRemovedCollections();
172         Object JavaDoc removedValue = interaction.args[0];
173         for (int i = 0; collections != null && i < collections.length; i++) {
174             CollectionItem collection = collections[i];
175             logger.debug("removed collection " + collection);
176             opposite =
177                 (FieldItem) collection.getAttribute(RttiAC.OPPOSITE_ROLE);
178             try {
179                 attrdef("rtti.updateOpposite", opposite);
180                 if (opposite == null) {
181                     logger.debug(
182                         collection.getParent().getName()+"."+collection.toString()+
183                         " has no opposite role");
184                     continue;
185                 }
186                 logger.debug(
187                     "UpdateOppositeRole in "+interaction.method+" : "+collection.getName()+
188                     " -> "+opposite.getName());
189                 if (removedValue != null) {
190                     if (opposite instanceof CollectionItem) {
191                         ((CollectionItem) opposite).removeThroughRemover(
192                             removedValue,
193                             interaction.wrappee);
194                     } else {
195                         opposite.setThroughWriter(removedValue, null);
196                     }
197                 }
198             } catch (Exception JavaDoc e) {
199                 logger.error("Failed to update opposite role "+opposite.getLongName()+" of "
200                              +collection.getLongName()+" on "+interaction.wrappee,e);
201             } finally {
202                 attrdef("rtti.updateOpposite", null);
203             }
204
205         }
206     }
207
208     /**
209      * Initializes the opposite role of an object auto created on an
210      * adder or reference setter if there's an attribute
211      * GuiAC.AUTOCREATE_REASON in the context, whose value is an
212      * Interaction. */

213     public Object JavaDoc initAutoCreatedObject(Interaction interaction) {
214         Object JavaDoc result = interaction.proceed();
215         Collaboration collab = Collaboration.get();
216         Interaction reason =
217             (Interaction) collab.getAttribute("GuiAC.AUTOCREATE_REASON");
218         if (reason != null) {
219             logger.debug(
220                 "initAutoCreatedObject for "
221                     + interaction + " because of " + reason);
222             reason.args[0] = interaction.wrappee;
223             // We better unset the attribute now because doUpdate() may
224
// create objects (under weird circumtances) and we do not
225
// want to apply the initialization on them
226
collab.removeAttribute("GuiAC.AUTOCREATE_REASON");
227             doUpdate(reason);
228         }
229         return result;
230     }
231
232     /**
233      * Disable opposite role updating
234      * @param role role for which opposite role updating must be disabled
235      */

236     public static void disableRoleUpdate(FieldItem role) {
237         Collaboration.get().addAttribute("rtti.updateOpposite", role);
238     }
239
240     public static void enableRoleUpdate(FieldItem role) {
241         Collaboration.get().removeAttribute("rtti.updateOpposite");
242     }
243
244     public Object JavaDoc invoke(MethodInvocation invocation) throws Throwable JavaDoc {
245         return this.updateOppositeRole((Interaction) invocation);
246     }
247
248     public Object JavaDoc construct(ConstructorInvocation invocation)
249         throws Throwable JavaDoc
250     {
251         return this.initAutoCreatedObject((Interaction) invocation);
252     }
253 }
254
Popular Tags