001    /*
002      Copyright (C) 2001-2003 Renaud Pawlak <renaud@aopsys.com>, 
003                              Laurent Martelli <laurent@aopsys.com>
004      
005      This program is free software; you can redistribute it and/or modify
006      it under the terms of the GNU Lesser General Public License as
007      published by the Free Software Foundation; either version 2 of the
008      License, or (at your option) any later version.
009    
010      This program is distributed in the hope that it will be useful,
011      but WITHOUT ANY WARRANTY; without even the implied warranty of
012      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013      GNU Lesser General Public License for more details.
014    
015      You should have received a copy of the GNU Lesser General Public License
016      along with this program; if not, write to the Free Software
017      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
018    
019    package org.objectweb.jac.core.rtti;
020    
021    /**
022     * This class defines the rtti aspect.
023     *
024     * <p>It allows the programmer to add some runtime type information on
025     * the classes of its applications.
026     *
027     * <p>Some configuration methods are useless since the type
028     * information is retrieved through bytecode analysis. They are kept
029     * in the interface in case of.
030     *
031     * @see ClassItem
032     * @see MethodItem
033     * @see FieldItem
034     * @see CollectionItem
035     *
036     * @author Renaud Pawlak
037     * @author Laurent Martelli
038     */
039    
040    public interface RttiConf {
041    
042        /**
043         * Introduces a new member (field or method) into a given
044         * class. <b>Does not work yet.</b>
045         *
046         * <p>The target class does not declare the member but is wrapped by
047         * a wrapper that contains a member that should be considered as a
048         * base-object member.
049         *
050         * <p>Once introduced, the member will behave like a regular member
051         * if accessed or setted through the RTTI.
052         *
053         * @param target the target class where to add the memeber
054         * @param roleType the type of the role wrapper that actually
055         * contains the member
056         * @param memberType the member's type
057         * @param memberName the member's name 
058         */
059        /*
060        void introduce(ClassItem target,ClassItem roleType,
061                       String memberType,String memberName);
062        */
063    
064        /**
065         * Adds some written fields to a given method.
066         *
067         * <p>This configuration method must be used when a method changes
068         * some field values and does not follow the naming conventions (it
069         * is not a setter or an adder for instance).
070         *
071         * @param method the method
072         * @param writtenFields some new fields the method writes 
073         */ 
074        void addWrittenFields(AbstractMethodItem method, String[] writtenFields);
075    
076        /**
077         * Adds some accessed fields to a given method.
078         *
079         * <p>This configuration method must be used when a method reads
080         * some field values and does not follow the naming conventions (it
081         * is not a getter for instance).
082         *
083         * @param method the method
084         * @param accessedFields some new fields the method reads 
085         */ 
086        void addAccessedFields(MethodItem method, String[] accessedFields);
087    
088        /**
089         * Declare a calculated field, which is a field with only a getter
090         * and no actual field.
091         *
092         * @param cl the class item of te calculated field
093         * @param fieldName the name of the calculated field
094         * @param getterName the name of the getter method
095         * @see #addDependentField(FieldItem,String)
096         */
097        void declareCalculatedField(ClassItem cl, String fieldName,
098                                    String getterName);
099    
100        /**
101         * Sets the setter of a field
102         * @param field the field
103         * @param setterName name of the setter method
104         */
105        void setSetter(FieldItem field, String setterName);
106    
107        /**
108         * Sets the getter of a field
109         * @param field the field
110         * @param getterName name of the getter method
111         */
112        void setGetter(FieldItem field, String getterName);
113    
114        /**
115         * Declares a field dependency. It will cause the field to be
116         * refreshed when the dependent field's value changes.
117         *
118         * @param field the field to refresh
119         * @param dependentField the name of the field it depends on. It
120         * must be in the same class as field.
121         * @see #declareCalculatedField(ClassItem,String,String)
122         */
123        void addDependentField(FieldItem field, String dependentField);
124    
125        /**
126         * Tells that when field changes, dependentField changes too.
127         */
128        void addFieldDependency(FieldItem field, FieldItem dependentField);
129    
130        /**
131         * Adds an adding method for a collection 
132         *
133         * @param collection the collection's name
134         * @param method the name of the adding method
135         */
136        void addAdder(CollectionItem collection,String method);
137    
138        /**
139         * Sets <em>the</em> adder of a collection.
140         * @param collection the collection
141         * @param method the name of the adder method
142         */
143        void setAdder(CollectionItem collection, String method);
144    
145        /**
146         * Adds a removing method for a collection 
147         * @param collection the collection
148         * @param method the name of the removing method
149         */
150        void addRemover(CollectionItem collection, String method);
151    
152        /**
153         * Sets <em>the</em> remover of a collection.
154         *
155         * @param collection the collection
156         * @param method the name of the remover method
157         */
158        void setRemover(CollectionItem collection, String method);
159    
160        /**
161         * Declares a field to be of a given type
162         * 
163         * @param field the field
164         * @param type the type
165         *
166         * @see #setDynamicFieldType(FieldItem,MethodItem)
167         */
168        void setFieldType(FieldItem field, String type);
169    
170        /**
171         * Use a method to dynamically determine the type of a field
172         * 
173         * @param field the field
174         * @param method a static method taking as arguments a FieldItem
175         * and an Object (holder of the field), and return a ClassItem or
176         * a VirtualClassItem or a String.
177         *
178         * @see #setFieldType(FieldItem,String)
179         */
180        void setDynamicFieldType(FieldItem field, MethodItem method);
181    
182        /**
183         * Sets the component type of a collection, i.e. the type of
184         * objects it contains.
185         *
186         * @param collection the collection 
187         * @param type the component type of the collection
188         */
189        void setComponentType(CollectionItem collection, String type);
190    
191        /**
192         * Declare a method's parameters to be of a given type
193         * 
194         * @param method the method
195         * @param types the types of each parameteropf the method
196         */
197        void setParametersType(AbstractMethodItem method, String[] types) ;
198    
199        /**
200         * Create a new virtual class. Virtual classes allow you extend and
201         * refine the types used by the application, so that aspects can
202         * behave differently. 
203         *
204         * @param className name of the new class
205         * @param actualType the actual primitive type that is extended
206         */
207        void newVirtualClass(String className, ClassItem actualType);
208    
209        /**
210         * Declare a repository to get instances of a class from, instead
211         * of fetching all instances of the class, when
212         * ObjectRepository.getObjects(ClassItem) is called.
213         *
214         * @param type the type of objects to add in the repository
215         * @param repositoryName the name of the object holding the repository
216         * @param repositoryCollection the collection to get the objects
217         * from. Any expression field can be used.
218         *
219         * @see org.objectweb.jac.core.ObjectRepository#getObjects(ClassItem) 
220         */
221        void defineRepository(ClassItem type, 
222                              String repositoryName,
223                              CollectionItem repositoryCollection); 
224    
225        /**
226         * This configuration method tells that the fields (references or
227         * collections) must be cloned when the class is cloned.
228         *
229         * @param className the class name
230         * @param fields the names of the fields that are cloned 
231         */
232        void setClonedFields(String className, String[] fields);
233    
234        /**
235         * Sets a user defined class on a class. This can be used by
236         * aspects user-defined configuration. 
237         *
238         * @param cli the class to redefine
239         * @param className the new class name
240         */
241        void setClass(ClassItem cli, String className);
242    
243        /**
244         * Sets a user defined class on a class' member. This can be used by
245         * aspects user-defined configuration. 
246         *
247         * @param member the member whose type to redefine
248         * @param className the new class name
249         */
250        void setClass(MemberItem member, String className);
251    
252        /**
253         * Specifies that the parameters of a method will be assigned to a
254         * given field. 
255         *
256         * <p>Other aspects (such as the GUI aspect) may use this
257         * information to provide better default behaviour for the
258         * paramters.</p> 
259         *
260         * @param method the of the method
261         * @param fields an array of field items, one per parameter of the
262         * method. Elements of this array may be null if some parameters
263         * are not assigned to any field.
264         */
265        void setParametersFields(AbstractMethodItem method, FieldItem[] fields);
266    
267        /**
268         * This configuration method tells that the field can be set to null
269         * (forbidden by default)
270         * 
271         * @param field the field
272         *
273         * @see #setNullAllowed(FieldItem,boolean)
274         */
275        void setNullAllowed(FieldItem field);
276    
277        /**
278         * This configuration method tells wether the field can be set to
279         * null or not. (forbidden by default)
280         * 
281         * @param field the field
282         * @param allowed wether to allow null values
283         *
284         * @see #setNullAllowed(FieldItem) 
285         */
286        void setNullAllowed(FieldItem field, boolean allowed);
287    
288        /**
289         * Tells if JAC object-typed (references) arguments of a method can take
290         * null value while the method's invocation or if they should be
291         * choosen in existing instances list.
292         *
293         * @param method the method
294         * @param nulls a flags array that tells for each parameter whether
295         * it can be null (true) or not (false). It has no effect if the
296         * parameter is not a JAC object (a reference) 
297         */
298        void setNullAllowedParameters(AbstractMethodItem method,
299                                      boolean[] nulls);
300    
301        /**
302         * Specify wether a Map implementing a collection is a mere index
303         * for the collection (this is not the default). In this case,
304         * CollectionItem.getActualCollection() returns the values
305         * contained in the hashtable, otherwise the (key,values) entries
306         * are returned.
307         *
308         * @param collection the collection
309         * @param isIndex wether the map is an index
310         *
311         * @see #setIndexedField(CollectionItem,FieldItem)
312         * @see CollectionItem#getActualCollection(Object)
313         * @see CollectionItem#getActualCollectionThroughAccessor(Object)
314         */
315        void setIsIndex(CollectionItem collection, boolean isIndex);
316    
317        /**
318         * Tells that a Map implementing a collection indexes a field of
319         * the contained objects.
320         *
321         * @param collection the collection
322         * @param indexedField the field which is indexed by the map
323         *
324         * @see #setIsIndex(CollectionItem,boolean)
325         * @see CollectionItem#getActualCollection(Object)
326         * @see CollectionItem#getActualCollectionThroughAccessor(Object) 
327         */
328        void setIndexedField(CollectionItem collection, FieldItem indexedField);
329    
330        /**
331         * Defines primary keys for a collection.
332         *
333         * <p>It is used to check for double entries in the collection by
334         * checking the precised fields (it is the same as primary keys in
335         * a database).</p>
336         */
337        void definePrimaryKey(CollectionItem collection, String[] fields);
338    
339        /**
340         * Tells wether a relation is an aggregation or not. By default,
341         * relations are not aggregations.
342         *
343         * @param field the relation
344         * @param isAggregation wether the relation is an aggregations or not.
345         */
346        void setAggregation(FieldItem field, boolean isAggregation);
347    
348        /**
349         * <p>Specify that a type can be safely casted into another type.</p>
350         *
351         * <p>It can be useful it you changed the type of a field to a
352         * subclass of the original type that only adds new methods, and a
353         * persistence aspect complains that it cannot load this field
354         * anymore. dest should have constructor which takes a value of
355         * type src as the only argument.</p>
356         *
357         * @param src type of the value to be casted
358         * @param dest type the value should be casted to 
359         */
360        void addAllowedCast(ClassItem src, ClassItem dest);
361    
362        /**
363         * Sets the opposite role of a reference or collection field
364         *
365         * @param field the field whose opposite role to set
366         * @param oppositeRole the opposite role of the fieldb
367         *
368         * @see #declareAssociation(FieldItem,FieldItem)
369         */
370        void setOppositeRole(FieldItem field, FieldItem oppositeRole);
371    
372        /**
373         * Declares an association made of two roles.
374         *
375         * <p>When declared, the relations that constitutes the
376         * association's roles are tagged in the RTTI by the
377         * <code>RttiAC.OPPOSITE_RELATION</code> attribute (then they can
378         * be interpreted by other aspects such as Integrity, GUI or
379         * Persistence).
380         *
381         * <p>For instance, if you have a Customer class and an Order
382         * class:</p>
383         *
384         * <pre>
385         *    ,----------. 1    n ,-------.
386         *    | Customer |--------| Order |
387         *    `----------'        `-------'
388         * </pre>
389         *
390         * @param roleA the starting role (e.g. Customer.orders)
391         * @param roleB the ending role (e.g. Order.customer)
392         */
393        void declareAssociation(FieldItem roleA, FieldItem roleB);
394    
395        /**
396         * Adds a mixin method to a class.
397         *
398         * <p>A mixin method of class is a method which is not defined in
399         * the code of that class, but which will be made available on
400         * that class's ClassItem.</p>
401         *
402         * @param cli a class
403         * @param method a static method whose 1st argument must be cli.
404         *
405         * @see MixinMethodItem#invoke(Object,Object[])
406         */
407        void addMixinMethod(ClassItem cli, MethodItem method) throws InvalidDelegateException;
408    }