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  /*** A ProxyQualifier acts as a proxy to another Qualifier object that may set 
24   * by simple access a methods. All events are forwarded transparently.
25   *
26   * If a ProxyQualifier does not have a source object it does not qualify any
27   * entities of any type, making them effectivelly useless. In other words it 
28   * allways returns false on calls to doesSelect, canSelect and canUniquelySelect.
29   *
30   * @author  Dennis Zikovic
31   * @version 1.00
32   *
33   *//* 
34   *
35   * WHEN        WHO               WHY & WHAT
36   * -----------------------------------------------------------------------------
37   * 2001-11-22  Dennis Zikovic    Creation
38   */
39  public class ProxyQualifier extends Qualifier
40  {
41      // Data members ------------------------------------------------------------
42      private Qualifier mRemoteQualifier;
43      
44      private transient ProxyRelayListener mRelayListener;
45      private transient IProxyListener mProxyListener;
46      
47      // Constructors ------------------------------------------------------------
48      
49      /*** Creates new ProxyQualifier
50       */
51      public ProxyQualifier() 
52      {
53      }
54      
55      /*** Creates new ProxyQualifier
56       */
57      public ProxyQualifier(Qualifier qualifier) 
58      {
59          this.setRemoteQualifier(qualifier);
60      }
61      
62      // Superclass overrides ----------------------------------------------------
63      
64      /*** This abstract method must return true if the qualifier does select the
65       * provided entity object.
66       */
67      public boolean doesQualify(IEntity entity)
68      {
69          if(mRemoteQualifier!=null)
70              return mRemoteQualifier.doesQualify(entity);
71          else
72              return false;
73      }
74      
75      /*** This abstract method must return true if the qualifier can select 
76       * entities of the type defined by the provided entity descriptor.
77       */
78      public boolean canQualify(IEntityDescriptor entityDescriptor)
79      {
80          if(mRemoteQualifier!=null)
81              return mRemoteQualifier.canQualify(entityDescriptor);
82          else
83              return false;
84      }
85      
86      /*** This abstract method must return true if the qualifier can select 
87       * entities of the type defined by the provided entity descriptor without
88       * the nead of any complementary data. No other information than can be
89       * accessed through the provided entity descriptor should be neaded if 
90       * this method returns true. This validates that the doesQualify method
91       * can be called for the called qualifier.
92       */
93      public boolean canDirectlyQualify(IEntityDescriptor entityDescriptor)
94      {
95          if(mRemoteQualifier!=null)
96              return mRemoteQualifier.canDirectlyQualify(entityDescriptor);
97          else
98              return false;
99      }
100     
101     /*** This abstract method must return true if the qualifier can uniquely 
102      * select entities of the type defined by the provided entity descriptor. 
103      * If that is the case then the qualifier is an identity qualifier and can 
104      * never qualify more then a single entity instance of the specified type.
105      */
106     public boolean canUniquelyQualify(IEntityDescriptor entityDescriptor)
107     {
108         if(mRemoteQualifier!=null)
109             return mRemoteQualifier.canUniquelyQualify(entityDescriptor);
110         else
111             return false;
112     }
113     
114     /*** The toString method returns an "abstract" expression of what the 
115      * qualifier selects. Note that this expresion is only intended for visual
116      * aid and is not a valid SQL expresion. 
117      */
118     public String toString()
119     {
120         if(mRemoteQualifier!=null)
121             return mRemoteQualifier.toString();
122         else
123             return "(EMPTY PROXY)";
124     }
125 
126     // Access methods ----------------------------------------------------------
127     
128     /*** Boolean access method that returns true if the proxy has a remote
129      * Qualifier if false then getRemoteQualifier() will return null.
130      */
131     public boolean hasRemoteQualifier()
132     {
133         return mRemoteQualifier!=null;
134     }
135     
136     /*** Access method that returns the remote Qualifier of the proxy.
137      * May return null if the proxy does not currently have a remote.
138      */
139     public Qualifier getRemoteQualifier()
140     {
141         return mRemoteQualifier;
142     }
143     
144     /*** Boolean access method that returns true if the proxy has a source
145      * Qualifier if false then getSourceQualifier() will return null.
146      */
147     public boolean hasSourceQualifier()
148     {
149         return this.getSourceQualifier()!=null;
150     }
151     
152     /*** Access method that returns the source Qualifier of the proxy.
153      * May return null if the proxy does not currently have a source Qualifier.
154      */
155     public Qualifier getSourceQualifier()
156     {
157         if(mRemoteQualifier==null)
158             return null;
159         if(mRemoteQualifier instanceof ProxyQualifier)
160             return ((ProxyQualifier)mRemoteQualifier).getSourceQualifier();
161         else
162             return this.getRemoteQualifier();
163     }
164     
165     /*** Optional mutation method that throws an UnsupportedOperationException 
166      * if the implementing class does not support the method. Note that setting
167      * a new remote qualifier is and should be considered as a structural
168      * change in the Qualifier causing a QualifierEvent to be fired.
169      */
170     public void setRemoteQualifier(Qualifier qualifier)
171     {
172         // Ignore entity if equal to the current remote entity.
173         if(mRemoteQualifier==qualifier)
174             return; 
175         
176         // Remove all listeners in the remote object.
177         if(mRemoteQualifier!=null && mRelayListener!=null)
178         {
179             mRemoteQualifier.removeQualifierListener(mRelayListener);
180             if(mRemoteQualifier instanceof ProxyQualifier)
181                  ((ProxyQualifier)mRemoteQualifier).removeProxyListener(mRelayListener);
182         }
183         
184         // Update the stored remote entity.
185         mRemoteQualifier = qualifier;
186         
187         // Register listeners on the new remote object.
188         if(mRemoteQualifier!=null)
189         {
190             if(mRelayListener==null)
191                 mRelayListener = new ProxyRelayListener();
192             mRemoteQualifier.addQualifierListener(mRelayListener);
193             if(mRemoteQualifier instanceof ProxyQualifier)
194                  ((ProxyQualifier)mRemoteQualifier).addProxyListener(mRelayListener);
195         }
196         
197         // Fire relevant proxy and qualifier events..
198         this.fireProxyEvent(ProxyEvent.CHANGED);
199         this.fireStructureChangedEvent();
200     }
201     
202     /*** Adds IProxyListener to receive notifications of performed 
203      * data operations on the Qualifier object.
204      */
205     public void addProxyListener(IProxyListener listener)
206     {
207         mProxyListener = (IProxyListener)CELEventMulticaster.add(mProxyListener, listener);
208     }
209     
210     /*** Removes the specified IProxyListener from the Qualifier object.
211      */
212     public void removeProxyListener(IProxyListener listener)
213     {
214         mProxyListener = (IProxyListener)CELEventMulticaster.remove(mProxyListener, listener);
215     }
216     
217     // Help methods ------------------------------------------------------------
218     
219     /*** Fires a ProxyEvent with the provided operation type to all registered
220      * IProxyListener objects.
221      */
222     protected void fireProxyEvent(int eventType)
223     {
224         if(mProxyListener==null)
225             return;
226         else if(eventType == ProxyEvent.CHANGED)
227             mProxyListener.remoteChanged(new ProxyEvent(this, eventType));
228         else if(eventType == ProxyEvent.EXPANDED)
229             mProxyListener.remoteExpanded(new ProxyEvent(this, eventType));
230     }
231     
232     // Nested classes ----------------------------------------------------------
233     
234     /*** Simple listener class that relays all received events to the listeners
235      * registered in the proxy object.
236      */
237     private class ProxyRelayListener extends RelayListener implements IProxyListener
238     {
239         public void remoteExpanded(ProxyEvent event)
240         {
241             if(mProxyListener!=null)
242                 mProxyListener.remoteExpanded(event);
243         }
244         
245         public void remoteChanged(ProxyEvent event)
246         {
247             if(mProxyListener!=null)
248                 mProxyListener.remoteChanged(event);
249         }
250     }
251 }