View Javadoc

1   /* (c) Copyright 2003 Caleigo AB, All rights reserved. 
2    * 
3    * This library is free software; you can redistribute it and/or
4    * modify it under the terms of the GNU Lesser General Public
5    * License as published by the Free Software Foundation; either
6    * version 2.1 of the License, or (at your option) any later version.
7    * 
8    * This library is distributed in the hope that it will be useful,
9    * but WITHOUT ANY WARRANTY; without even the implied warranty of
10   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11   * Lesser General Public License for more details.
12   * 
13   * You should have received a copy of the GNU Lesser General Public
14   * License along with this library; if not, write to the Free Software
15   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16   *  
17   */
18  package org.caleigo.core;
19  
20  import org.caleigo.toolkit.util.*;
21  
22  /*** <Description for EntityRelation>
23   *
24   * @author  Dennis Zikovic
25   * @version 1.00
26   *
27   *//* 
28   *
29   * WHEN        WHO               WHY & WHAT
30   * -----------------------------------------------------------------------------
31   * 2001-09-13  Dennis Zikovic    Creation
32   * 2004-01-29  Niklas Norberg    rm bug's in methods:
33   *                                  toString(),
34   *                              getForwardDisplayName() &
35   *                              getReverseDisplayName().
36   * 2004-04-15   Niklas Norberg  added call to added setEntityRelation for
37   *                              CompositeFieldRelation(s) in constructor
38   */
39  public class EntityRelation implements IEntityRelation
40  {
41      // Constants ---------------------------------------------------------------
42      
43      // Data members ------------------------------------------------------------
44      private IFieldRelation[] mFieldRelations;
45      
46      private transient IEntityDescriptor mReferenceEntity;
47      private transient IEntityDescriptor mTargetEntity;
48      
49      private String mCodeName;
50      private String mForwardDisplayName;
51      private String mReverseDisplayName;
52      
53      // Constructors ------------------------------------------------------------
54      
55      /*** Creates new EntityRelation. Package scope to avoid missuse.
56       * @depricated
57       */
58  //    EntityRelation(IFieldRelation fieldRelation) 
59  //    {
60  //        this(new IFieldRelation[] {fieldRelation});
61  //    }
62      
63      /*** Creates new EntityRelation. Package scope to avoid missuse.
64       */
65      EntityRelation(IFieldRelation fieldRelation, String codeName, String forwardName, String reverseName) 
66      {
67          this(new IFieldRelation[] {fieldRelation}, codeName, forwardName, reverseName);
68      }
69      
70      /*** Creates new EntityRelation. Package scope to avoid missuse.
71       * @depricated
72       */
73  //    EntityRelation(IFieldRelation[] fieldRelation) 
74  //    {
75  //        mFieldRelations = fieldRelation;
76  //        
77  //        // Register entity relation to contained field relations
78  //        for(int j=0; j<fieldRelation.length; j++)
79  //            if(fieldRelation[j] instanceof FieldRelation)
80  //                ((FieldRelation)fieldRelation[j]).setEntityRelation(this);
81  //    }
82      
83      /*** Creates new EntityRelation. Package scope to avoid missuse.
84       */
85      EntityRelation(IFieldRelation[] fieldRelation, String codeName, String forwardName, String reverseName) 
86      {
87          mFieldRelations = fieldRelation;
88          mCodeName = codeName;
89          mForwardDisplayName = forwardName;
90          mReverseDisplayName = reverseName;
91          
92          // Register entity relation to contained field relations
93          for(int j=0; j<fieldRelation.length; j++)
94          {
95              if(fieldRelation[j] instanceof FieldRelation)
96                  ((FieldRelation)fieldRelation[j]).setEntityRelation(this);
97              else if(fieldRelation[j] instanceof CompositeEntityDescriptor.CompositeFieldRelation)
98                  ((CompositeEntityDescriptor.CompositeFieldRelation)fieldRelation[j]).setEntityRelation(this);
99          }
100             
101     }
102     
103     // Superclass overrides ----------------------------------------------------
104     
105     public String toString()
106     {
107         return "EntityRelation ["+this.getReferenceEntityDescriptor()+"-->"+this.getTargetEntityDescriptor()+"]";
108     }
109     
110     public int hashCode()
111     {
112         int code = 0;
113         for(int j=0; j<this.getFieldCount(); j++)
114             code += this.getFieldRelation(j).hashCode();
115         return code;
116     }
117     
118     public boolean equals(Object obj)
119     {
120         if(obj==null || !(obj instanceof IEntityRelation))
121             return false;
122         
123         IEntityRelation relation = (IEntityRelation)obj;
124         for(int j=0; j<this.getFieldCount(); j++)
125             if(!this.getFieldRelation(j).equals(relation.getFieldRelation(j)))
126                 return false;
127 
128         return true;
129     }
130 
131     // IEntityRelation implementation ------------------------------------------
132     
133     /*** Access method that returns the referenced IEntityDescriptor.
134      */
135     public IEntityDescriptor getReferenceEntityDescriptor()
136     {
137         if(mReferenceEntity==null)
138             mReferenceEntity = mFieldRelations[0].getReferenceField().getEntityDescriptor();
139         return mReferenceEntity;
140     }
141     
142     /*** Access method that returns an iterator containing all the
143      * IFieldDescriptors from the reference/source descriptor.
144      */
145     public java.util.Iterator getReferenceFieldDescriptors()
146     {
147         return new Iterators.ArrayIterator(mFieldRelations)
148                 {
149                     public Object next()
150                     {
151                         return ((IFieldRelation)super.next()).getReferenceField();
152                     }
153                     public Object previous()
154                     {
155                         return ((IFieldRelation)super.previous()).getReferenceField();
156                     }
157                 };
158     }
159     
160     /*** Access method that returns the tageteted IEntityDescriptor.
161      */
162     public IEntityDescriptor getTargetEntityDescriptor()
163     {
164         if(mTargetEntity==null)
165             mTargetEntity = mFieldRelations[0].getTargetField().getEntityDescriptor();
166         return mTargetEntity;
167     }
168     
169     /*** Access method that returns an iterator containing all the
170      * IFieldDescriptors from the targeted descriptor.
171      */
172     public java.util.Iterator getTargetFieldDescriptors()
173     {
174         return new Iterators.ArrayIterator(mFieldRelations)
175                 {
176                     public Object next()
177                     {
178                         return ((IFieldRelation)super.next()).getTargetField();
179                     }
180                     public Object previous()
181                     {
182                         return ((IFieldRelation)super.previous()).getReferenceField();
183                     }
184                 };
185     }
186         
187     /*** Access method that returns the number of IFieldRelation:s that defines
188      * the entity relation.
189      */
190     public int getFieldCount()
191     {
192         return mFieldRelations.length;
193     }
194     
195     /*** Access method that returns an iterator for all contained
196      * IFieldRelation objects.
197      */
198     public java.util.Iterator getFieldRelations()
199     {
200         return Iterators.iterate(mFieldRelations);
201     }
202     
203     /*** Access method that returns the indexed contained IFieldRelation.
204      */
205     public IFieldRelation getFieldRelation(int index)
206     {
207         return mFieldRelations[index];
208     }
209 
210     /*** Returns an identifying name that can be used to address the relation in
211      * client software.
212      */
213     public String getCodeName()
214     {
215         return mCodeName;
216     }
217         
218     /*** Returns a displayable name for the relation in the forward direction.
219      */
220     public String getForwardDisplayName()
221     {
222         return ResourceProvider.getString(this.getReferenceEntityDescriptor().getCodeName(), mCodeName+".forward", mForwardDisplayName);
223         
224     }
225     
226     /*** Returns a displayable name for the relation in the reverse direction.
227      */
228     public String getReverseDisplayName()
229     {
230         return ResourceProvider.getString(this.getReferenceEntityDescriptor().getCodeName(), mCodeName+".reverse", mReverseDisplayName);
231     }
232 
233     /*** Help method that returns true if the provided entity descriptor is one 
234      * of the fysical node descriptors of the relation objects. Custom entities
235      * that contains the fields that are a part of the relation will not qualify
236      * by this method.
237      */
238     public boolean isRelationNode(IEntityDescriptor entityDescriptor)
239     {
240         return entityDescriptor==this.getReferenceEntityDescriptor() || entityDescriptor==this.getTargetEntityDescriptor();
241     }
242     
243     /*** Help method that returns true if the provided field descriptor exists
244      * as a part of one of the entity relations contained field relations.
245      */
246     public boolean isRelationField(IFieldDescriptor fieldDescriptor)
247     {
248         boolean found = false;
249         for(int j=0; !found && j<mFieldRelations.length; j++)
250             found = mFieldRelations[j].getReferenceField()==fieldDescriptor || mFieldRelations[j].getTargetField()==fieldDescriptor;
251         return found;
252     }
253     
254     /*** Returns true if the relation is required. Required relation does 
255      * allways for each entity instance of the reference node side in 
256      * the relation.
257      */
258     public boolean isRequired()
259     {
260         boolean required = true;
261         for(int j=0; required && j<mFieldRelations.length; j++)
262             required = required && mFieldRelations[j].getReferenceField().isRequired();
263         return required;
264     }
265     
266     /*** Boolean help method that returns true if the provided IEntityDescriptor
267      * can act as a reference object according to the relation object. Either
268      * fully or partially that is if the descriptor can adreess one ore more 
269      * of the targetet entity type.
270      */
271     public boolean canBeReference(IEntityDescriptor entityDescriptor)
272     {
273         if(entityDescriptor==this.getReferenceEntityDescriptor())
274             return true;
275         
276         boolean found = false;
277         for(int j=0; !found && j<mFieldRelations.length; j++)
278             found = entityDescriptor.getFieldIndex(mFieldRelations[j].getReferenceField())>=0;
279         return found;
280     }
281     
282     /*** Boolean help method that returns true if the provided IEntityDescriptor
283      * can act as a complete reference object according to the relation object.
284      * Complete/full reference means that all the reference field descriptors
285      * are satisfied and that a single entity instance of the targeted entity
286      * type can be addressed.
287      */
288     public boolean canBeFullReference(IEntityDescriptor entityDescriptor)
289     {
290         if(entityDescriptor==this.getReferenceEntityDescriptor())
291             return true;
292         
293         boolean found = true;
294         for(int j=0; found && j<mFieldRelations.length; j++)
295             found = entityDescriptor.getFieldIndex(mFieldRelations[j].getReferenceField())>=0;
296         return found;
297     }
298     
299     /*** Boolean help method that returns true if the provided IEntityDescriptor
300      * can be a targeted entity type according to the relation object.
301      */
302     public boolean canBeTarget(IEntityDescriptor entityDescriptor)
303     {
304         if(entityDescriptor==this.getTargetEntityDescriptor())
305             return true;
306         
307         boolean found = false;
308         for(int j=0; !found && j<mFieldRelations.length; j++)
309             found = entityDescriptor.getFieldIndex(mFieldRelations[j].getTargetField())>=0;
310         return found;
311     }
312     
313     /*** Help method that returns that returns "the other" entity descriptor
314      * that link together by the relation object. If the provided descriptor
315      * is not a node in the realtion then null is returned.
316      */
317     public IEntityDescriptor getRelatedEntityDescriptor(IEntityDescriptor entityDescriptor)
318     {
319         if(this.canBeReference(entityDescriptor))
320             return this.getTargetEntityDescriptor();
321         else if(this.canBeTarget(entityDescriptor))
322             return this.getReferenceEntityDescriptor();
323         else
324             return null;
325     }
326     
327     /*** Returns a Qualifier that specifies the requirements to satisfy all
328      * field relations for the entity relation.
329      */
330     public Qualifier getRelationQualifier()
331     {
332         Qualifier qualifier = Qualifier.create(mFieldRelations[0].getReferenceField(), mFieldRelations[0].getTargetField());
333         for(int j=1; j<this.getFieldCount(); j++)
334             qualifier = qualifier.and(mFieldRelations[j].getReferenceField(), mFieldRelations[j].getTargetField());   
335         return qualifier;
336     }
337 }