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  
19  package org.caleigo.core;
20  
21  import org.caleigo.core.exception.InvalidDescriptorException;
22  import org.caleigo.toolkit.log.*;
23  
24  
25  /*** Basic implementation of the IFieldRelation An IFieldRelation is allways an 
26   * agregate of an IEntityRelation that defines a link between two 
27   * IEntityRelation objects. The relation objects does combined with the 
28   * descriptor objects form a travesable graph. <BR><BR>
29   *
30   * This implementation of the IFieldRelation does not require that the classes
31   * of the linked descriptors has been loaded and initialized. The purpose is
32   * to avoid unnecesary expasions of the entire descriptor graph. 
33   *
34   * @author  Dennis Zikovic
35   * @version 1.00
36   *
37   *//* 
38   *
39   * WHEN        WHO               WHY & WHAT
40   * -----------------------------------------------------------------------------
41   * 2001-11-09  Dennis Zikovic    Creation
42   */
43  public class FieldRelation implements IFieldRelation
44  {
45      // Data members ------------------------------------------------------------
46      private IEntityRelation mEntityRelation;
47      
48      private final String mReferenceEntityClassName;
49      private final String mReferenceFieldSourceName;
50      private final String mTargetEntityClassName;
51      private final String mTargetFieldSourceName;
52      
53      private transient IFieldDescriptor mReferenceField;
54      private transient IFieldDescriptor mTargetField;
55      
56      // Constructors ------------------------------------------------------------
57      
58      /*** Constructor for FieldRelation. Note package scope to avoid missuse.
59       */
60      FieldRelation(String referenceEntityClassName, String referenceFieldSourceName, 
61              String targetEntityClassName, String targetFieldSourceName) 
62      {
63          mReferenceField = null;
64          mReferenceEntityClassName = referenceEntityClassName;
65          mReferenceFieldSourceName = referenceFieldSourceName;
66          
67          mTargetField = null;
68          mTargetEntityClassName = targetEntityClassName;
69          mTargetFieldSourceName = targetFieldSourceName;
70      }
71      
72      /*** Constructor for FieldRelation. Note package scope to avoid missuse.
73       */
74      FieldRelation(IFieldDescriptor referenceFieldDescriptor,
75              String targetEntityClassName, String targetFieldSourceName) 
76      {
77          mReferenceField = referenceFieldDescriptor;
78          mReferenceEntityClassName = referenceFieldDescriptor.getEntityDescriptor().getClass().getName();
79          mReferenceFieldSourceName = referenceFieldDescriptor.getSourceName();
80          
81          mTargetField = null;
82          mTargetEntityClassName = targetEntityClassName;
83          mTargetFieldSourceName = targetFieldSourceName;
84      }
85      
86      /*** Constructor for FieldRelation. Note package scope to avoid missuse.
87       */
88      FieldRelation(String referenceEntityClassName, String referenceFieldSourceName, 
89              IFieldDescriptor targetFieldDescriptor) 
90      {
91          mReferenceField = null;
92          mReferenceEntityClassName = referenceEntityClassName;
93          mReferenceFieldSourceName = referenceFieldSourceName;
94          
95          mTargetField = targetFieldDescriptor;
96          mTargetEntityClassName = targetFieldDescriptor.getEntityDescriptor().getClass().getName();
97          mTargetFieldSourceName = targetFieldDescriptor.getSourceName();
98      }
99      
100     /*** Constructor for FieldRelation. Note package scope to avoid missuse.
101      */
102     FieldRelation(IFieldDescriptor referenceFieldDescriptor,
103             IFieldDescriptor targetFieldDescriptor) 
104     {
105         mReferenceField = referenceFieldDescriptor;
106         mReferenceEntityClassName = referenceFieldDescriptor.getEntityDescriptor().getClass().getName();
107         mReferenceFieldSourceName = referenceFieldDescriptor.getSourceName();
108         
109         mTargetField = targetFieldDescriptor;
110         mTargetEntityClassName = targetFieldDescriptor.getEntityDescriptor().getClass().getName();
111         mTargetFieldSourceName = targetFieldDescriptor.getSourceName();
112     }
113     
114     // Superclass overrides ----------------------------------------------------
115     public boolean equals(Object obj)
116     {
117         if(obj==null || !(obj instanceof IFieldRelation))
118             return false;
119         
120         IFieldRelation relation = (IFieldRelation)obj;
121                 
122         return this.getReferenceField()==relation.getReferenceField()
123                 && this.getTargetField()==relation.getTargetField();
124     }
125     
126     // IFieldRelation implementation -------------------------------------------
127     
128     /*** Access method that return the IEntityRelation that the called
129      * IFieldRelation is a part of.
130      */ 
131     public IEntityRelation getEntityRelation()
132     {
133         return mEntityRelation;
134     }
135     
136     /*** Access method that return the IFieldDescriptor that is the 
137      * source/reference field that addresses another field. In RDB terms the
138      * reference field is or should be defined as a foreign key.  
139      */ 
140     public IFieldDescriptor getReferenceField()
141     {
142         if(mReferenceField==null)
143             mReferenceField = this.getFieldDescriptor(mReferenceEntityClassName, mReferenceFieldSourceName);
144         return mReferenceField;
145     }
146     
147     /*** Access method that return the IFieldDescriptor that is the 
148      * target field that are addressed by the reference field. In RDB terms the
149      * target field is usually a primary-key field.  
150      */ 
151     public IFieldDescriptor getTargetField()
152     {
153         if(mTargetField==null)
154             mTargetField = this.getFieldDescriptor(mTargetEntityClassName, mTargetFieldSourceName);
155         return mTargetField;
156     }
157     
158     // Help methods ------------------------------------------------------------
159     
160     /*** Mutation method with restricted access to avoid missuse.
161      */
162     void setEntityRelation(IEntityRelation relation)
163     {
164         mEntityRelation = relation;
165     }
166     
167     private IFieldDescriptor getFieldDescriptor(String entityDescriptorClassName, String fieldDescriptorSourceName)
168     {
169         IFieldDescriptor fieldDescriptor = null;
170         try
171         {
172             Class sourceClass = Class.forName(entityDescriptorClassName);
173             java.lang.reflect.Field field = sourceClass.getField("instance");
174             IEntityDescriptor descriptor = (IEntityDescriptor)field.get(null);
175             
176             for(int j=0; fieldDescriptor==null && j<descriptor.getFieldCount(); j++)
177                 if(descriptor.getFieldDescriptor(j).getSourceName().equals(fieldDescriptorSourceName))  
178                     fieldDescriptor = descriptor.getFieldDescriptor(j);
179             
180             fieldDescriptor.getDataType(); // Causes exception if not found.
181         }
182         catch(Exception e)
183         {
184             String msg = "Invalid field relation data in entity relation "+this.getEntityRelation().getCodeName()+": "+entityDescriptorClassName+" - "+fieldDescriptorSourceName;
185             Log.printError(this, msg);
186             throw new InvalidDescriptorException(msg, e);
187         }
188         return fieldDescriptor;
189     }
190 }