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