1 /*
2 * Copyright (C) The Spice Group. All rights reserved.
3 *
4 * This software is published under the terms of the Spice
5 * Software License version 1.1, a copy of which has been included
6 * with this distribution in the LICENSE.txt file.
7 */
8 package org.realityforge.xinvoke.spi.impl;
9
10 import java.util.ArrayList;
11 import java.util.Map;
12 import org.apache.avalon.framework.activity.Disposable;
13 import org.apache.avalon.framework.activity.Initializable;
14 import org.apache.avalon.framework.configuration.Configurable;
15 import org.apache.avalon.framework.configuration.Configuration;
16 import org.apache.avalon.framework.configuration.ConfigurationException;
17 import org.apache.avalon.framework.container.ContainerUtil;
18 import org.apache.avalon.framework.logger.AbstractLogEnabled;
19 import org.apache.avalon.framework.service.DefaultServiceManager;
20 import org.realityforge.xinvoke.Interceptor;
21 import org.realityforge.xinvoke.spi.InterceptorManager;
22
23 /***
24 * A simple InterceptorManager that just builds the same
25 * chain of Interceptors for all objects. The chain is defined
26 * in the configuration supplied to component. The configuration format
27 * looks like;
28 *
29 * <interceptors>
30 * <interceptor class="org.realityforge.xinvoke.lib.AuthenticationInterceptor"/>
31 * <interceptor class="org.realityforge.xinvoke.lib.TransactionInterceptor">
32 * <!-- Period over which transaction will timeout -->
33 * <period>300</period>
34 * <!-- policy to use for locking resources -->
35 * <policy>pessimistic</policy>
36 * ...insert more config here...
37 * </interceptor>
38 * <interceptor class="org.realityforge.xinvoke.lib.JavaInvokeInterceptor"/>
39 * <interceptors>
40 *
41 * @author <a href="mailto:peter at www.stocksoftware.com.au">Peter Donald</a>
42 * @version $Revision: 1.1 $ $Date: 2003/04/16 10:47:01 $
43 */
44 public final class SimpleInterceptorManager
45 extends AbstractLogEnabled
46 implements InterceptorManager, Configurable, Initializable, Disposable
47 {
48 /***
49 * The interceptor at the head of chain that is managed by this component.
50 */
51 private Interceptor m_interceptor;
52
53 /***
54 * the configuration used to create the interceptor chain.
55 */
56 private Configuration m_configuration;
57
58 /***
59 * A list of interceptors in order that they were added.
60 * Only used to shutdown the interceptors
61 */
62 private final ArrayList m_elements = new ArrayList();
63
64 /***
65 * Specify configuration used to build interceptor chain.
66 *
67 * @param configuration the configuration
68 */
69 public void configure( final Configuration configuration )
70 {
71 m_configuration = configuration;
72 }
73
74 /***
75 * Init InterceptorManager which involves creating
76 * the InterceptorChain.
77 *
78 * @throws Exception if unable to initialize chain
79 */
80 public void initialize()
81 throws Exception
82 {
83 m_interceptor = createChain( m_configuration );
84 m_configuration = null;
85 }
86
87 /***
88 * Shutdown InterceptorManager which simply involes shutting down
89 * all the interceptors in chain.
90 */
91 public void dispose()
92 {
93 shutdownChain();
94 m_interceptor = null;
95 }
96
97 /***
98 * @see InterceptorManager#getInterceptor
99 */
100 public Interceptor getInterceptor( final Map parameters )
101 throws Exception
102 {
103 //Ignore the parameters as we will always
104 //return the same interceptor chain
105 return m_interceptor;
106 }
107
108 /***
109 * @see InterceptorManager#releaseInterceptor
110 */
111 public void releaseInterceptor( final Interceptor interceptor )
112 throws Exception
113 {
114 //Do nothing
115 }
116
117 /***
118 * Create the InterceptorChain.
119 *
120 * @param configuration
121 * @throws ConfigurationException
122 */
123 public Interceptor createChain( final Configuration configuration )
124 throws Exception
125 {
126 final Configuration[] children = configuration.getChildren( "interceptor" );
127 Interceptor lastInterceptor = null;
128 Interceptor firstInterceptor = null;
129 for( int i = children.length - 1; i >= 0; i-- )
130 {
131 final Configuration child = children[ i ];
132 final Interceptor interceptor = createInterceptor( child, lastInterceptor );
133 m_elements.add( interceptor );
134
135 if( 0 == i )
136 {
137 firstInterceptor = interceptor;
138 }
139 lastInterceptor = interceptor;
140 }
141
142 final String message =
143 "Created a singleton Interceptor that has " + children.length +
144 " interceptors in the chain.";
145 getLogger().info( message );
146
147 return firstInterceptor;
148 }
149
150 /***
151 * Shutdown the Interceptor chain by disposing each element.
152 */
153 private void shutdownChain()
154 {
155 final Interceptor[] interceptors =
156 (Interceptor[])m_elements.toArray( new Interceptor[ m_elements.size() ] );
157 m_elements.clear();
158 for( int i = interceptors.length - 1; i >= 0; i-- )
159 {
160 try
161 {
162 ContainerUtil.shutdown( interceptors[ i ] );
163 }
164 catch( final Exception e )
165 {
166 final String message =
167 "Error disposing Interceptor chain element " +
168 i + " due to " + e;
169 getLogger().error( message, e );
170 }
171 }
172 }
173
174 /***
175 * Create an interceptor in the chain.
176 *
177 * @param configuration the interceptors configuration
178 * @param previous the previous interceptor (if any)
179 * @return the newly created interceptor
180 */
181 private Interceptor createInterceptor( final Configuration configuration,
182 final Interceptor previous )
183 throws Exception
184 {
185 final String classname = configuration.getAttribute( "class" );
186 final Object object = Class.forName( classname ).newInstance();
187 if( !( object instanceof Interceptor ) )
188 {
189 final String message =
190 classname + " does not designate an Interceptor";
191 throw new Exception( message );
192 }
193 final Interceptor interceptor = (Interceptor)object;
194 ContainerUtil.enableLogging( interceptor, getLogger() );
195 ContainerUtil.configure( interceptor, configuration );
196 final DefaultServiceManager sm = new DefaultServiceManager();
197 sm.put( Interceptor.ROLE, previous );
198 sm.makeReadOnly();
199 ContainerUtil.service( interceptor, sm );
200 ContainerUtil.initialize( interceptor );
201 ContainerUtil.start( interceptor );
202 return interceptor;
203 }
204 }
This page was automatically generated by Maven