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.event.*;
22  
23  /*** The Qualifier class is the abstract base class for all Qualifier classes.
24   * A Qualifier is an object that is used to address/identify a selection of
25   * objects or single entity instance. A Qualifier that defines a single entity
26   * instance is called an identity qualifier. <BR><BR>
27   *
28   * The class defines three abstract methods that all non abstract qualifiers 
29   * must implement. All subclasses should also override the toString() method
30   * to provide a suitable readable description of the qualifier for logging 
31   * purposes. The class also provides a number of help methods to aid
32   * API-users in the construction of qualifiers. <BR><BR>
33   *
34   * Note that new non standard qualifiers must in some way be mapped or 
35   * interpreted by the IDataService:s that are to be used in colaberation with
36   * the qualifier. 
37   *
38   * @author  Dennis Zikovic
39   * @version 1.00
40   * 
41   *//* 
42   *
43   * WHEN        WHO               WHY & WHAT
44   * -----------------------------------------------------------------------------
45   * 2001-07-04  Dennis Zikovic    Creation
46   */
47  public abstract class Qualifier implements java.io.Serializable
48  {
49      // Data members ------------------------------------------------------------
50      private transient IQualifierListener mQualifierListener;
51      
52      // Static help methods -----------------------------------------------------
53      
54      /*** Creates a new relation qualifier defined by the defined by the provided 
55       * field descriptor and data value.
56       */
57      public static Qualifier create(IFieldDescriptor fieldDescriptor, Object relationValue)
58      {
59          return new RelationQualifier(fieldDescriptor, relationValue);
60      }
61      
62      /*** Creates a new relation qualifier defined by the defined by the provided 
63       * field descriptor, relation type and data value.
64       */
65      public static Qualifier create(IFieldDescriptor fieldDescriptor, RelationType relationType, Object relationValue)
66      {
67          return new RelationQualifier(fieldDescriptor, relationType, relationValue);
68      }
69      
70      /*** Creates a logic intersection between the qualifiers. Note that this
71       * method generally creates a new composite qualifier unless the called
72       * qualifier is a CompositeQualifier with the union type INTERSECTION.
73       */
74      public static Qualifier combine(Qualifier qualifier1, Qualifier qualifier2)
75      {
76          if(qualifier1==null)
77              return qualifier2;
78          else if(qualifier2==null)
79              return qualifier1;
80          else if(qualifier2 instanceof CompositeQualifier && ((CompositeQualifier)qualifier2).getUnionType()==CompositeQualifier.INTERSECTION)
81              return qualifier2.and(qualifier1);
82          else
83              return qualifier1.and(qualifier2);
84      }
85      
86      // Abstract methods --------------------------------------------------------
87      
88      /*** This abstract method must return true if the qualifier does select the
89       * provided entity object. 
90       */
91      public abstract boolean doesQualify(IEntity entity);
92      
93      /*** This abstract method must return true if the qualifier logically can  
94       * select entities of the type defined by the provided entity descriptor.
95       */
96      public abstract boolean canQualify(IEntityDescriptor entityDescriptor);
97      
98      /*** This abstract method must return true if the qualifier can select 
99       * entities of the type defined by the provided entity descriptor without
100      * the nead of any complementary data. No other information than can be
101      * accessed through the provided entity descriptor should be neaded if 
102      * this method returns true. This validates that the doesQualify method
103      * can be called for the called qualifier.
104      */
105     public abstract boolean canDirectlyQualify(IEntityDescriptor entityDescriptor);
106     
107     /*** This abstract method must return true if the qualifier can uniquely 
108      * select entities of the type defined by the provided entity descriptor. 
109      * If that is the case then the qualifier is an identity qualifier and can 
110      * never qualify more then a single entity instance of the specified type.
111      */
112     public abstract boolean canUniquelyQualify(IEntityDescriptor entityDescriptor);
113     
114     // Access methods ----------------------------------------------------------
115     
116     /*** Adds an IQualifierListener to receive notifications of contents and 
117      * structure changes from the Qualifier object.
118      */
119     public void addQualifierListener(IQualifierListener listener)
120     {
121         mQualifierListener = (IQualifierListener)CELEventMulticaster.add(mQualifierListener, listener);
122     }
123     
124     /*** Removes the specified IQualifierListener from the Qualifier.
125      */
126     public void removeQualifierListener(IQualifierListener listener)
127     {
128         mQualifierListener = (IQualifierListener)CELEventMulticaster.remove(mQualifierListener, listener);
129     }
130     
131     // Help methods ------------------------------------------------------------
132         
133     /*** Creates a logic intersection between the qualifiers. Note that this
134      * method generally creates a new composite qualifier unless the called
135      * qualifier is a CompositeQualifier with the union type INTERSECTION.
136      */
137     public Qualifier and(Qualifier qualifier)
138     {
139         if(this instanceof CompositeQualifier && ((CompositeQualifier)this).getUnionType()==CompositeQualifier.INTERSECTION)
140         {
141             ((CompositeQualifier)this).add(qualifier);
142             return this;
143         }
144         else
145             return new CompositeQualifier(this, qualifier, CompositeQualifier.INTERSECTION);
146     }
147     
148     /*** Creates a logic intersection between the qualifier and a new qualifier
149      * defined by the provided field descriptor and data value. Note that this
150      * method generally creates a new composite qualifier unless the called
151      * qualifier is a CompositeQualifier with the union type INTERSECTION.
152      */
153     public Qualifier and(IFieldDescriptor fieldDescriptor, Object relationValue)
154     {
155         return this.and(new RelationQualifier(fieldDescriptor, relationValue));
156     }
157     
158     /*** Creates a logic intersection between the qualifier and a new qualifier
159      * defined by the provided field descriptor and data value. Note that this
160      * method generally creates a new composite qualifier unless the called
161      * qualifier is a CompositeQualifier with the union type INTERSECTION.
162      */
163     public Qualifier and(IFieldDescriptor fieldDescriptor, RelationType relationType, Object relationValue)
164     {
165         return this.and(new RelationQualifier(fieldDescriptor, relationType, relationValue));
166     }
167     
168     /*** Creates a logic union between the qualifiers. Note that this
169      * method generally creates a new composite qualifier unless the called
170      * qualifier is a CompositeQualifier with the union type UNION.
171      */
172     public Qualifier or(Qualifier qualifier)
173     {
174         if(this instanceof CompositeQualifier && ((CompositeQualifier)this).getUnionType()==CompositeQualifier.UNION)
175         {
176             ((CompositeQualifier)this).add(qualifier);
177             return this;
178         }
179         else
180             return new CompositeQualifier(this, qualifier, CompositeQualifier.UNION);
181     }
182     
183     /*** Creates a logic union between the qualifier and a new qualifier
184      * defined by the provided field descriptor and data value. Note that this
185      * method generally creates a new composite qualifier unless the called
186      * qualifier is a CompositeQualifier with the union type UNION.
187      */
188     public Qualifier or(IFieldDescriptor fieldDescriptor, Object relationValue)
189     {
190         return this.or(new RelationQualifier(fieldDescriptor, relationValue));
191     }
192     
193     /*** Creates a logic union between the qualifier and a new qualifier
194      * defined by the provided field descriptor and data value. Note that this
195      * method generally creates a new composite qualifier unless the called
196      * qualifier is a CompositeQualifier with the union type UNION.
197      */
198     public Qualifier or(IFieldDescriptor fieldDescriptor, RelationType relationType, Object relationValue)
199     {
200         return this.or(new RelationQualifier(fieldDescriptor, relationType, relationValue));
201     }
202     
203     /*** Returns a negated version of the qualifier.
204      */
205     public Qualifier negate()
206     {
207         return new NegateQualifier(this);
208     }
209         
210     /*** Fire the provided QualifierEvent to all registered IQualifierListeners.
211      */
212     protected void fireQualifierEvent(QualifierEvent event)
213     {
214         if(mQualifierListener!=null)
215             mQualifierListener.structureChanged(event);
216     }
217     
218     /*** Fire a new QualifierEvent as a structure change notifictaion using the 
219      * current Qualifier as the source to all registered IQualifierListeners.
220      */
221     protected void fireStructureChangedEvent()
222     {
223         if(mQualifierListener!=null)
224             mQualifierListener.structureChanged(new QualifierEvent(this, QualifierEvent.STRUCTURE_CHANGED));
225     }
226     
227     /*** Fire a new QualifierEvent as a content change notifictaion using the 
228      * current Qualifier as the source to all registered IQualifierListeners.
229      */
230     protected void fireContentChangedEvent()
231     {
232         if(mQualifierListener!=null)
233             mQualifierListener.contentChanged(new QualifierEvent(this, QualifierEvent.CONTENT_CHANGED));
234     }
235     
236     // Nested classes ----------------------------------------------------------
237     
238     /*** Simple listener class that relays all received events to the listeners
239      * registered in the proxy object.
240      */
241     protected class RelayListener implements IQualifierListener
242     {
243         // IQualifierListener implemntation ------------------------------------
244         public void structureChanged(QualifierEvent event)
245         {
246             Qualifier.this.fireQualifierEvent(event);
247         }
248 
249         public void contentChanged(QualifierEvent event)
250         {
251             Qualifier.this.fireQualifierEvent(event);
252         }
253     }
254 }