View Javadoc

1   package org.apache.fulcrum.yaafi.framework.component;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.avalon.framework.configuration.Configuration;
23  import org.apache.avalon.framework.configuration.ConfigurationException;
24  import org.apache.avalon.framework.context.Context;
25  import org.apache.avalon.framework.logger.Logger;
26  import org.apache.avalon.framework.parameters.Parameters;
27  import org.apache.avalon.framework.service.ServiceManager;
28  import org.apache.fulcrum.yaafi.framework.role.RoleEntry;
29  import org.apache.fulcrum.yaafi.framework.util.ReadWriteLock;
30  import org.apache.fulcrum.yaafi.framework.util.ToStringBuilder;
31  import org.apache.fulcrum.yaafi.framework.util.Validate;
32  
33  /**
34   * This class implements am abstract base service component singleton with
35   * an arbitrary lifecycle.
36   *
37   * @author <a href="mailto:siegfried.goeschl@it20one.at">Siegfried Goeschl</a>
38   */
39  
40  public abstract class ServiceComponentImpl
41      implements ServiceComponent
42  {
43      /** the information from the role configuration file */
44      private RoleEntry roleEntry;
45  
46      /** the actual implementation class of the service component */
47      private Class implementationClazz;
48  
49      /** the instance of the implementation class of the service component */
50      private Object instance;
51  
52      /** the proxy of the instance if any */
53      private Object proxy;
54  
55      /** the Avalon logger of the container */
56      private Logger parentLogger;
57  
58      /** the Avalon logger to be passed to the service component instance */
59      private Logger logger;
60  
61      /** The Avalon ServiceManager passed to the service component instance */
62      private ServiceManager serviceManager;
63  
64      /** The Avalon Context passed to the service component instance */
65      private Context context;
66  
67      /** The Avalon Configuration passed to the service component instance */
68      private Configuration configuration;
69  
70      /** The Avalon Parameters passed to the service component instance */
71      private Parameters parameters;
72  
73      /** read/write lock to snychronize access to services */
74      private ReadWriteLock readWriteLock;
75  
76      /**
77       * Constructor to parse the configuration.
78       *
79       * @param roleEntry The information extracted from the role configuration file
80       * @param parentLogger the logger of the service container
81       * @param logger The logger for the service instance
82       * @param readWriteLock the read/write lock to synchronize access to services
83       */
84      public ServiceComponentImpl(
85          RoleEntry roleEntry, Logger parentLogger, Logger logger, ReadWriteLock readWriteLock )
86      {
87          Validate.notNull( roleEntry, "roleEntry" );
88          Validate.notNull( parentLogger, "parentLogger" );
89          Validate.notNull( logger, "logger" );
90          Validate.notNull( readWriteLock, "readWriteLock" );
91  
92          this.roleEntry = roleEntry;
93          this.parentLogger = parentLogger;
94          this.logger = logger;
95          this.readWriteLock = readWriteLock;
96      }
97  
98      /////////////////////////////////////////////////////////////////////////
99      // Service Component Lifecycle Implementation
100     /////////////////////////////////////////////////////////////////////////
101 
102     /**
103      * @see org.apache.fulcrum.yaafi.framework.component.ServiceComponentLifecycle#loadImplemtationClass(java.lang.ClassLoader)
104      */
105     public void loadImplemtationClass(ClassLoader classLoader)
106     	throws ClassNotFoundException
107     {
108         ClassLoader currClassLoader = null;
109 
110         if( classLoader != null )
111         {
112             currClassLoader = classLoader;
113         }
114         else
115         {
116             currClassLoader = this.getClass().getClassLoader();
117         }
118 
119         try
120         {
121             this.implementationClazz = currClassLoader.loadClass(
122                 this.getRoleEntry().getImplementationClazzName()
123                 );
124         }
125 
126         catch(ClassNotFoundException e)
127         {
128             String msg = "Failed to load the implementation class "
129                 + this.getRoleEntry().getImplementationClazzName();
130 
131             this.getParentLogger().error(msg,e);
132 
133             throw e;
134         }
135     }
136 
137     /**
138      * @see org.apache.fulcrum.yaafi.framework.component.ServiceComponentLifecycle#getInstance()
139      */
140     public Object getInstance()
141         throws Exception
142     {
143         if( this.isInstantiated() == false )
144         {
145             this.createInstance();
146             this.incarnateInstance();
147         }
148 
149         return this.getRawInstance(true);
150     }
151 
152     /**
153      * @see org.apache.fulcrum.yaafi.framework.component.ServiceComponentLifecycle#incarnate()
154      */
155     public void incarnate() throws Exception
156     {
157         try
158         {
159             if( this.isEarlyInit() )
160             {
161                 this.getInstance();
162             }
163         }
164         catch(Throwable t)
165         {
166             String msg = "Failed initialize "
167                 + this.getRoleEntry().getImplementationClazzName();
168 
169             throw new ConfigurationException(msg,t);
170         }
171     }
172 
173     /**
174      * @see org.apache.fulcrum.yaafi.framework.component.ServiceComponentLifecycle#reconfigure()
175      */
176     public abstract void reconfigure() throws Exception;
177 
178     /**
179      * @see org.apache.fulcrum.yaafi.framework.component.ServiceComponentLifecycle#decommision()
180      */
181     public void decommision() throws Exception
182     {
183         this.instance = null;
184         this.proxy = null;
185     }
186 
187     /**
188      * @see org.apache.fulcrum.yaafi.framework.component.ServiceComponentLifecycle#dispose()
189      */
190     public void dispose()
191     {
192         this.roleEntry = null;
193         this.implementationClazz = null;
194         this.instance = null;
195         this.proxy = null;
196         this.parentLogger = null;
197         this.logger = null;
198         this.serviceManager = null;
199         this.context = null;
200         this.configuration = null;
201         this.parameters = null;
202         this.readWriteLock = null;
203     }
204 
205     /**
206      * @param logger The logger to set.
207      */
208     public void setLogger(Logger logger)
209     {
210         this.logger = logger;
211     }
212 
213     /**
214      * @param context The context to set.
215      */
216     public void setContext(Context context)
217     {
218         this.context = context;
219     }
220 
221     /**
222      * @param serviceManager The serviceManager to set.
223      */
224     public void setServiceManager(ServiceManager serviceManager)
225     {
226         this.serviceManager = serviceManager;
227     }
228 
229     /**
230      * @param configuration The configuration to set.
231      */
232     public void setConfiguration(Configuration configuration)
233     {
234         this.configuration = configuration;
235     }
236 
237     /**
238      * @param parameters The parameters to set.
239      */
240     public void setParameters(Parameters parameters)
241     {
242         this.parameters = parameters;
243     }
244 
245     /////////////////////////////////////////////////////////////////////////
246     // Generated getters and setters
247     /////////////////////////////////////////////////////////////////////////
248 
249     /**
250      * @return Return true if the service is created on startup
251      */
252     public boolean isEarlyInit()
253     {
254         return this.getRoleEntry().isEarlyInit();
255     }
256 
257     /**
258      * @see org.apache.fulcrum.yaafi.framework.component.ServiceComponent#getName()
259      */
260     public String getName()
261     {
262         return this.getRoleEntry().getName();
263     }
264 
265     /**
266      * @return Returns the roleEntry.
267      */
268     public RoleEntry getRoleEntry()
269     {
270         return roleEntry;
271     }
272 
273     /**
274      * @return Returns the logger.
275      */
276     public Logger getLogger()
277     {
278         return this.logger;
279     }
280 
281     /**
282      * @return Returns the parentLogger.
283      */
284     public Logger getParentLogger()
285     {
286         return parentLogger;
287     }
288 
289     /**
290      * @return Returns the implementationClazz.
291      */
292     public Class getImplementationClazz()
293     {
294         return this.implementationClazz;
295     }
296 
297     /**
298      * @return Returns the configuration.
299      */
300     public Configuration getConfiguration()
301     {
302         return configuration;
303     }
304 
305     /**
306      * @return Returns the context.
307      */
308     public Context getContext()
309     {
310         return context;
311     }
312 
313     /**
314      * @return Returns the paramaters.
315      */
316     public Parameters getParamaters()
317     {
318         return parameters;
319     }
320 
321     /**
322      * @return Returns the serviceManager.
323      */
324     public ServiceManager getServiceManager()
325     {
326         return serviceManager;
327     }
328 
329     /**
330      * @return the shorthand of the service
331      */
332     public String getShorthand()
333     {
334         return roleEntry.getShorthand();
335     }
336 
337     /////////////////////////////////////////////////////////////////////////
338     // Class implementation
339     /////////////////////////////////////////////////////////////////////////
340 
341     /**
342      * @see java.lang.Object#toString()
343      */
344     public String toString()
345     {
346         ToStringBuilder toStringBuilder = new ToStringBuilder(this);
347         toStringBuilder.append("roleEntry",this.roleEntry);
348         toStringBuilder.append("instance",this.instance);
349         toStringBuilder.append("proxy",this.proxy);
350         return toStringBuilder.toString();
351     }
352 
353     /**
354      * @return Returns <b>true</b> if the service instance was already instantiated.
355      */
356     protected final boolean isInstantiated()
357     {
358         return ( this.instance != null ? true : false );
359     }
360 
361     /**
362      * Create an instance of the service component implementation class
363      *
364      * @throws InstantiationException th
365      * @throws IllegalAccessException
366      */
367     protected Object createInstance()
368         throws InstantiationException, IllegalAccessException
369     {
370         if( this.getParentLogger().isDebugEnabled() )
371         {
372             this.getParentLogger().debug( "Instantiating the implementation class for " + this.getShorthand() );
373         }
374 
375         this.instance = this.implementationClazz.newInstance();
376         this.proxy = null;
377         return this.instance;
378     }
379 
380     /**
381      * @see org.apache.fulcrum.yaafi.framework.component.ServiceComponent#incarnate()
382      */
383     protected abstract void incarnateInstance() throws Exception;
384 
385     /**
386      * Get either the original service object or the dynamic proxy
387      *
388      * @return Returns the raw instance, i.e. does not incarnate
389      * the instance.
390      */
391     protected Object getRawInstance(boolean useProxy)
392     {
393         if( useProxy && (this.proxy != null) )
394         {
395             return this.proxy;
396         }
397         else
398         {
399             return this.instance;
400         }
401     }
402 
403     /**
404      * @param proxy the service proxy instance
405      */
406     protected void setProxyInstance(Object proxy)
407     {
408         this.proxy = proxy;
409     }
410 
411     /**
412      * @return Returns the readWriteLock.
413      */
414     protected final ReadWriteLock getReadWriteLock()
415     {
416         return readWriteLock;
417     }
418 }