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 }