View Javadoc

1   /***
2    * Redistribution  and use  in source  and binary  forms, with  or without
3    * modification, are permitted provided  that the following conditions are
4    * met :
5    *
6    * . Redistributions  of  source  code  must  retain  the  above copyright
7    *   notice, this list of conditions and the following disclaimer.
8    *
9    * . Redistributions in  binary form  must reproduce  the above  copyright
10   *   notice, this list of conditions  and the following disclaimer in  the
11   *   documentation and/or other materials provided with the distribution.
12   *
13   * . The name of the author may not be used to endorse or promote products
14   *   derived from this software without specific prior written permission.
15   *
16   * THIS SOFTWARE IS  PROVIDED BY THE  AUTHOR ``AS IS''  AND ANY EXPRESS  OR
17   * IMPLIED  WARRANTIES,  INCLUDING,  BUT   NOT  LIMITED  TO,  THE   IMPLIED
18   * WARRANTIES OF MERCHANTABILITY AND  FITNESS FOR A PARTICULAR  PURPOSE ARE
19   * DISCLAIMED.  IN NO  EVENT SHALL  THE AUTHOR  BE LIABLE  FOR ANY  DIRECT,
20   * INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR  CONSEQUENTIAL  DAMAGES
21   * (INCLUDING,  BUT  NOT LIMITED  TO,  PROCUREMENT OF  SUBSTITUTE  GOODS OR
22   * SERVICES;  LOSS  OF USE,  DATA,  OR PROFITS;  OR  BUSINESS INTERRUPTION)
23   * HOWEVER CAUSED  AND ON  ANY THEORY  OF LIABILITY,  WHETHER IN  CONTRACT,
24   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25   * ANY  WAY  OUT OF  THE  USE OF  THIS  SOFTWARE, EVEN  IF  ADVISED OF  THE
26   * POSSIBILITY OF SUCH DAMAGE.
27   *
28   * $Id: Context.java,v 1.8 2005/09/14 18:50:05 mat007 Exp $
29   */
30  
31  package jtge.engine.data;
32  
33  import java.lang.reflect.InvocationTargetException;
34  import java.lang.reflect.Method;
35  import java.util.Hashtable;
36  import java.util.Iterator;
37  import java.util.Map;
38  import java.util.Vector;
39  
40  /***
41   * Implements a container of data.
42   *
43   * @author Mathieu Champlon
44   * @version $Revision: 1.8 $ $Date: 2005/09/14 18:50:05 $
45   */
46  public class Context implements IContext
47  {
48      private final Map container;
49      private final Vector callbacks;
50  
51      /***
52       * Create a context.
53       */
54      public Context()
55      {
56          container = new Hashtable();
57          callbacks = new Vector();
58      }
59  
60      /***
61       * {@inheritDoc}
62       */
63      public final void put( final Object key, final Object data )
64      {
65          if( key == null )
66              throw new IllegalArgumentException( "argument 'key' is null" );
67          if( data == null )
68              container.remove( key );
69          else
70          {
71              container.put( key, data );
72              notify( data.getClass(), data );
73          }
74      }
75  
76      private void notify( final Class type, final Object data )
77      {
78          if( type == null )
79              return;
80          invoke( type, data );
81          invokeOnInterfaces( type, data );
82          notify( type.getSuperclass(), data );
83      }
84  
85      private void invokeOnInterfaces( final Class type, final Object data )
86      {
87          final Class[] interfaces = type.getInterfaces();
88          for( int i = 0; i < interfaces.length; i++ )
89              invoke( interfaces[0], data );
90      }
91  
92      private void invoke( final Class type, final Object data )
93      {
94          final Iterator iterator = callbacks.iterator();
95          while( iterator.hasNext() )
96              invokeOnCallback( iterator.next(), type, data );
97      }
98  
99      private void invokeOnCallback( final Object callback, final Class type, final Object data )
100     {
101         try
102         {
103             final Method method = callback.getClass().getMethod( "update", new Class[]
104             {
105                 type
106             } );
107             method.invoke( callback, new Object[]
108             {
109                 data
110             } );
111         }
112         catch( NoSuchMethodException e )
113         {
114             return;
115         }
116         catch( IllegalAccessException e )
117         {
118             return;
119         }
120         catch( InvocationTargetException e )
121         {
122             throw new RuntimeException( e );
123         }
124     }
125 
126     /***
127      * {@inheritDoc}
128      */
129     public final Object get( final Object key )
130     {
131         return container.get( key );
132     }
133 
134     /***
135      * {@inheritDoc}
136      */
137     public final void register( final Object callback )
138     {
139         if( callback != null )
140             callbacks.add( callback );
141     }
142 }