KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2   Copyright (C) 2002-2003 Renaud Pawlak <renaud@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 java.util.HashMap JavaDoc;
21 import java.util.List JavaDoc;
22 import java.util.Set JavaDoc;
23 import java.util.Vector JavaDoc;
24 import org.aopalliance.intercept.MethodInvocation;
25 import org.apache.log4j.Logger;
26 import org.objectweb.jac.core.AspectComponent;
27 import org.objectweb.jac.core.Collaboration;
28 import org.objectweb.jac.core.Wrapper;
29 import org.objectweb.jac.core.rtti.CollectionItem;
30 import org.objectweb.jac.core.rtti.FieldItem;
31 import org.objectweb.jac.core.rtti.MethodItem;
32 import org.objectweb.jac.core.rtti.RttiAC;
33 import org.objectweb.jac.util.Strings;
34
35 /**
36  * This aspect handle different kinds of data integrity among objects
37  * sets. */

38
39 public class IntegrityAC extends AspectComponent implements IntegrityConf {
40     static final Logger loggerRep = Logger.getLogger("integrity.repository");
41
42     HashMap JavaDoc preConditionsFields = new HashMap JavaDoc();
43     HashMap JavaDoc postConditionsFields = new HashMap JavaDoc();
44
45     RoleWrapper roleWrapper = new RoleWrapper(this);
46
47     public static final String JavaDoc CONSTRAINTS = "IntegrityAC.CONSTRAINTS";
48     public static final String JavaDoc DISABLE_ROLE_UPDATES =
49         "IntegrityAC.DISABLE_ROLE_UPDATES";
50
51     public static final String JavaDoc DISABLE_ADD_TO_REPOSITORY =
52         "IntegrityAC.DISABLE_ADD_TO_REPOSITORY";
53
54     public void declareRepository(
55         String JavaDoc repositoryName,
56         CollectionItem collection,
57         FieldItem field)
58     {
59         RepositoryWrapper rw =
60             new RepositoryWrapper(
61                 this,
62                 repositoryName,
63                 collection,
64                 field,
65                 RepositoryWrapper.ADDER);
66         if (field instanceof CollectionItem) {
67             pointcut(
68                 "ALL",
69                 field.getParent().getName(),
70                 "ADDERS(" + field.getName() + ")",
71                 rw,
72                 null);
73         } else {
74             pointcut(
75                 "ALL",
76                 field.getParent().getName(),
77                 "SETTERS(" + field.getName() + ")",
78                 rw,
79                 null);
80         }
81
82         // This pointcut adds an attribute in context so that we can
83
// avoid adding an object twice in the repository
84
pointcut(repositoryName,collection.getParent().getName(),
85                  "ADDERS("+collection.getName()+")",
86                  new AntiDupWrapper(this,collection),null);
87     }
88
89     class AntiDupWrapper extends Wrapper {
90         public AntiDupWrapper(AspectComponent ac, CollectionItem collection) {
91             super(ac);
92             this.collection = collection;
93         }
94         CollectionItem collection;
95         public Object JavaDoc invoke(MethodInvocation invocation) throws Throwable JavaDoc {
96             disableAddToRepository(collection);
97             loggerRep.debug("doAddToRepository " + collection);
98             try {
99                 return proceed(invocation);
100             } finally {
101                 enableAddToRepository(collection);
102             }
103         }
104     }
105
106     public void declareConstraint(
107         FieldItem relation,
108         FieldItem target,
109         String JavaDoc constraint)
110     {
111         List JavaDoc constraints = (List JavaDoc) target.getAttributeAlways(CONSTRAINTS);
112         if (constraints == null) {
113             constraints = new Vector JavaDoc();
114             target.setAttribute(CONSTRAINTS, constraints);
115         }
116         int c;
117         if (constraint.compareToIgnoreCase("DELETE_CASCADE") == 0) {
118             warning("DELETE_CASCADE is not implemented yet");
119             c = Constraint.DELETE_CASCADE;
120         } else if (constraint.compareToIgnoreCase("SET_NULL") == 0) {
121             c = Constraint.SET_NULL;
122         } else if (constraint.compareToIgnoreCase("FORBIDDEN") == 0) {
123             c = Constraint.FORBIDDEN;
124         } else {
125             throw new RuntimeException JavaDoc("Unknown constraint type " + constraint);
126         }
127         constraints.add(new Constraint(relation, c));
128         if (target instanceof CollectionItem) {
129             pointcut(
130                 "ALL",
131                 target.getParent().getName(),
132                 "REMOVERS(" + target.getName() + ")",
133                 new RepositoryWrapper(
134                     this,
135                     "",
136                     (CollectionItem) target,
137                     null,
138                     RepositoryWrapper.REMOVER),
139                 null);
140         } else {
141             pointcut(
142                 "ALL",
143                 target.getParent().getName(),
144                 "SETTERS(" + target.getName() + ")",
145                 new RepositoryWrapper(
146                     this,
147                     "",
148                     null,
149                     target,
150                     RepositoryWrapper.REMOVER),
151                 null);
152         }
153     }
154
155     boolean hasConditions = false;
156
157     private void addCondition(
158         FieldItem field,
159         MethodItem constraint,
160         Object JavaDoc[] params,
161         String JavaDoc errorMsg,
162         HashMap JavaDoc conditionsList)
163     {
164         hasConditions = true;
165         field.setAttribute(RttiAC.CONSTRAINTS, Boolean.TRUE);
166
167         Vector JavaDoc vect = (Vector JavaDoc) conditionsList.get(field);
168         if (vect == null)
169             vect = new Vector JavaDoc();
170
171         ConstraintDescriptor obj =
172             new ConstraintDescriptor(constraint, params, errorMsg);
173         vect.add(obj);
174         conditionsList.put(field, vect);
175     }
176
177     public void addPostCondition(
178         FieldItem field,
179         MethodItem constraint,
180         Object JavaDoc[] params,
181         String JavaDoc errorMsg)
182     {
183         addCondition(
184             field,
185             constraint,
186             params,
187             errorMsg,
188             postConditionsFields);
189     }
190
191     public void addPreCondition(
192         FieldItem field,
193         MethodItem constraint,
194         Object JavaDoc[] params,
195         String JavaDoc errorMsg)
196     {
197         addCondition(
198             field,
199             constraint,
200             params,
201             errorMsg,
202             preConditionsFields);
203     }
204
205     /**
206      * Activates constraints checking.
207      *
208      * <p>This method must be called once after all calls to
209      * <code>addPreCondition</code> and <code>addPostCondition</code>
210      * to effectively add pointcuts for these methods.</p>
211      *
212      * @see #addPreCondition(FieldItem,MethodItem,Object[],String)
213      * @see #addPostCondition(FieldItem,MethodItem,Object[],String)
214      */

215     protected void doCheck() {
216         ConstraintWrapper cw = new ConstraintWrapper(this);
217         pointcut(
218             "ALL",
219             "ALL",
220             "SETTERS(<" + RttiAC.CONSTRAINTS + ">)",
221             cw,
222             null);
223     }
224
225     /**
226      * Activates primary keys checking.
227      *
228      * <p>This method must be called once in the file integrity.acc to
229      * effectively add pointcuts for primary key checking methods.</p>
230      *
231      * @see org.objectweb.jac.core.rtti.RttiAC#definePrimaryKey(ClassItem,String,String[])
232      */

233     void doPrimaryKeyCheck() {
234         PrimaryKeyWrapper pw = new PrimaryKeyWrapper(this);
235         pointcut(
236             "ALL",
237             "ALL",
238             "ADDERS(<" + RttiAC.PRIMARY_KEY + ">)",
239             pw,
240             null);
241     }
242
243     boolean updateAssociations = false;
244     public void updateAssociations() {
245         this.updateAssociations = true;
246     }
247
248     public void whenConfigured() {
249         if (!updateAssociations)
250             return;
251         if (hasConditions) {
252             doCheck();
253         }
254         doPrimaryKeyCheck();
255         Set JavaDoc classes = ((RttiAC)getAC("rtti")).getClassesWithAssociations();
256         if (!classes.isEmpty()) {
257             String JavaDoc classExpr = Strings.join(classes, " || ");
258             pointcut(
259                 "ALL",
260                 classExpr,
261                 "ADDERS(<" + RttiAC.OPPOSITE_ROLE + ">) "
262                 + "|| REMOVERS(<" + RttiAC.OPPOSITE_ROLE + ">) "
263                 + "|| SETTERS(<" + RttiAC.OPPOSITE_ROLE + ">) "
264                 + "|| CONSTRUCTORS",
265                 roleWrapper,
266                 null);
267             //pointcut("ALL",classExpr,"CONSTRUCTORS",
268
// roleWrapper,null);
269
}
270     }
271
272     /**
273      * Tells wether adding objects to a repository collection is enabled or not.
274      * @param collection the repository collection to test
275      */

276     public static boolean isAddToRepositoryEnabled(CollectionItem collection) {
277         List JavaDoc disabled = getDisabled();
278         loggerRep.debug("isAddToRepositoryEnabled "+collection+" (disabled="+disabled+") ?");
279         return !disabled.contains(collection);
280     }
281
282     /**
283      * Disables adding objects to a repository collection.
284      * @param collection the repository collection to disable
285      */

286     public static void disableAddToRepository(CollectionItem collection) {
287         Collaboration collab = Collaboration.get();
288         List JavaDoc disabled = getDisabled();
289         loggerRep.debug("disableAddToRepository "+collection+
290                         " (disabled="+disabled+")");
291         disabled.add(collection);
292     }
293
294     /**
295      * Enables adding objects to a repository collection.
296      * @param collection the repository collection to enable
297      */

298     public static void enableAddToRepository(CollectionItem collection) {
299         loggerRep.debug("enableAddToRepository "+collection);
300         List JavaDoc disabled = getDisabled();
301         disabled.remove(collection);
302     }
303
304     /**
305      * Gets the list of disabled repository
306      */

307     protected static List JavaDoc getDisabled() {
308         List JavaDoc disabled =
309             (List JavaDoc)Collaboration.get().getAttribute(
310                 IntegrityAC.DISABLE_ADD_TO_REPOSITORY);
311         if (disabled==null) {
312             disabled = new Vector JavaDoc();
313             Collaboration.get().addAttribute(
314                 IntegrityAC.DISABLE_ADD_TO_REPOSITORY,
315                 disabled);
316         }
317         return disabled;
318     }
319
320     public static void disableRoleUpdates() {
321         Collaboration.get().addAttribute(DISABLE_ROLE_UPDATES,Boolean.TRUE);
322     }
323     public static void enableRoleUpdates() {
324         Collaboration.get().removeAttribute(DISABLE_ROLE_UPDATES);
325     }
326 }
327
Popular Tags