001    package org.apache.fulcrum.yaafi.framework.component;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     *   http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    import org.apache.avalon.framework.activity.Disposable;
023    import org.apache.avalon.framework.activity.Executable;
024    import org.apache.avalon.framework.activity.Initializable;
025    import org.apache.avalon.framework.activity.Startable;
026    import org.apache.avalon.framework.activity.Suspendable;
027    import org.apache.avalon.framework.configuration.Configurable;
028    import org.apache.avalon.framework.configuration.Configuration;
029    import org.apache.avalon.framework.configuration.ConfigurationException;
030    import org.apache.avalon.framework.configuration.Reconfigurable;
031    import org.apache.avalon.framework.context.Context;
032    import org.apache.avalon.framework.context.ContextException;
033    import org.apache.avalon.framework.context.Contextualizable;
034    import org.apache.avalon.framework.logger.LogEnabled;
035    import org.apache.avalon.framework.logger.Logger;
036    import org.apache.avalon.framework.parameters.ParameterException;
037    import org.apache.avalon.framework.parameters.Parameterizable;
038    import org.apache.avalon.framework.parameters.Parameters;
039    import org.apache.avalon.framework.service.ServiceException;
040    import org.apache.avalon.framework.service.ServiceManager;
041    import org.apache.avalon.framework.service.Serviceable;
042    import org.apache.fulcrum.yaafi.framework.interceptor.AvalonInterceptorFactory;
043    import org.apache.fulcrum.yaafi.framework.interceptor.AvalonInterceptorService;
044    import org.apache.fulcrum.yaafi.framework.role.RoleEntry;
045    import org.apache.fulcrum.yaafi.framework.util.Validate;
046    
047    /**
048     * This class implements a service component singleton with
049     * an arbitray lifecycle.
050     *
051     * @author <a href="mailto:siegfried.goeschl@it20one.at">Siegfried Goeschl</a>
052     */
053    
054    public class AvalonServiceComponentImpl
055        extends ServiceComponentImpl
056    {
057        /**
058         * Constructor to parse the configuration.
059         *
060         * @param roleEntry The information extracted from the role configuration file
061         * @param parentLogger the logger of the service container
062         * @param logger The logger for the service instance
063         */
064        public AvalonServiceComponentImpl(
065            RoleEntry roleEntry, Logger parentLogger, Logger logger)
066        {
067            super( roleEntry, parentLogger, logger );
068        }
069    
070        /////////////////////////////////////////////////////////////////////////
071        // Service Component Lifecycle Implementation
072        /////////////////////////////////////////////////////////////////////////
073    
074        /**
075         * @see org.apache.fulcrum.yaafi.framework.component.ServiceComponent#incarnate()
076         */
077        protected void incarnateInstance() throws Exception
078        {
079            this.getParentLogger().debug( "Incarnating the service " + this.getShorthand() );
080    
081            if( this.getLogger() != null )
082            {
083                this.enableLogging( this.getLogger() );
084            }
085    
086            if( this.getContext() != null )
087            {
088                this.contextualize( this.getContext() );
089            }
090    
091            if( this.getServiceManager() != null )
092            {
093                this.service( this.getServiceManager() );
094            }
095    
096            if( this.getConfiguration() != null )
097            {
098                this.configure( this.getConfiguration() );
099            }
100    
101            if( this.getParamaters() != null )
102            {
103                this.parameterize( this.getParamaters() );
104            }
105    
106            this.initialize();
107            this.execute();
108            this.start();
109    
110            // create a dynamic proxy only if
111            //
112            // +) interceptors are enabled
113            // +) the instance is not an AvalonServiceInterceptor
114    
115            boolean isInterceptor = AvalonInterceptorService.class.isAssignableFrom(
116                this.getImplementationClazz()
117                );
118    
119            if( (this.getRoleEntry().hasDynamicProxy()) && (isInterceptor == false ) )
120            {
121                if( this.getParentLogger().isDebugEnabled() )
122                {
123                    this.getParentLogger().debug( "Creating a dynamic proxy for " + this.getShorthand() );
124                }
125    
126                Object proxyInstance = AvalonInterceptorFactory.create(
127                    this.getName(),
128                    this.getShorthand(),
129                    this.getServiceManager(),
130                    this.getRoleEntry().getInterceptorList(),
131                    this.getRawInstance(false)
132                    );
133    
134                this.setProxyInstance(proxyInstance);
135            }
136            else
137            {
138                this.getRoleEntry().setHasDynamicProxy(false);
139            }
140        }
141    
142        /**
143         * @see org.apache.fulcrum.yaafi.framework.component.ServiceComponent#reconfigure()
144         */
145        public void reconfigure() throws Exception
146        {
147            Throwable lastThrowable = null;
148    
149            this.getParentLogger().debug( "Reconfiguring " + this.getShorthand() );
150    
151            try
152            {
153                this.suspend();
154            }
155            catch (Throwable t)
156            {
157                String msg = "Suspending the following service failed : " + this.getShorthand();
158                this.getParentLogger().error( msg, t );
159                lastThrowable = t;
160            }
161    
162            try
163            {
164                if( this.getConfiguration() != null )
165                {
166                    this.reconfigure( this.getConfiguration() );
167                }
168            }
169            catch (Throwable t)
170            {
171                String msg = "Reconfiguring the following service failed : " + this.getShorthand();
172                this.getParentLogger().error( msg, t );
173                lastThrowable = t;
174            }
175    
176            try
177            {
178                this.resume();
179            }
180            catch (Throwable t)
181            {
182                String msg = "Resumimg the following service failed : " + this.getShorthand();
183                this.getParentLogger().error( msg, t );
184                lastThrowable = t;
185            }
186    
187            if( lastThrowable != null )
188            {
189                if( lastThrowable instanceof Exception )
190                {
191                    throw (Exception) lastThrowable;
192                }
193                else
194                {
195                    throw new RuntimeException( lastThrowable.getMessage() );
196                }
197            }
198        }
199    
200        /**
201         * Stop and dispose the service implementation.
202         *
203         * @see org.apache.fulcrum.yaafi.framework.component.ServiceComponent#decommision()
204         */
205        public void decommision() throws Exception
206        {
207            this.getParentLogger().debug( "Decommisioning the service " + this.getShorthand() );
208    
209            try
210            {
211                this.stop();
212            }
213            catch (Throwable e)
214            {
215                String msg = "Stopping the following service failed : " + this.getShorthand();
216                this.getParentLogger().error( msg, e );
217            }
218    
219            try
220            {
221                Object rawInstance = this.getRawInstance(false);
222    
223                // dispose the service implementation class
224    
225                if( rawInstance instanceof Disposable )
226                {
227                    try
228                    {
229                        this.getParentLogger().debug( "Disposable.dispose() for " + this.getShorthand() );
230                        ((Disposable) rawInstance).dispose();
231                    }
232                    catch (Exception e)
233                    {
234                        String msg = "Disposing the following service failed : " + this.getShorthand();
235                        this.getParentLogger().error(msg,e);
236                        throw new RuntimeException(msg);
237                    }
238                }
239            }
240            catch (Throwable e)
241            {
242                String msg = "Disposing the following service failed : " + this.getShorthand();
243                this.getParentLogger().error( msg, e );
244            }
245    
246            super.decommision();
247        }
248    
249        /////////////////////////////////////////////////////////////////////////
250        // Avalon Lifecycle Implementation
251        /////////////////////////////////////////////////////////////////////////
252    
253        /**
254         * @see org.apache.avalon.framework.logger.LogEnabled#enableLogging(org.apache.avalon.framework.logger.Logger)
255         */
256        public void enableLogging(Logger logger)
257        {
258            Object rawInstance = this.getRawInstance(false);
259    
260            if( rawInstance instanceof LogEnabled )
261            {
262                try
263                {
264                    this.getParentLogger().debug( "LogEnabled.enableLogging() for " + this.getShorthand() );
265                    ((LogEnabled) rawInstance).enableLogging(logger);
266                }
267                catch (Throwable t)
268                {
269                    String msg = "LogEnable the following service failed : " + this.getShorthand();
270                    this.getParentLogger().error(msg,t);
271                    throw new RuntimeException(msg);
272                }
273            }
274        }
275    
276        /**
277         * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
278         */
279        public void contextualize(Context context) throws ContextException
280        {
281            Object rawInstance = this.getRawInstance(false);
282    
283            if( rawInstance instanceof Contextualizable )
284            {
285                try
286                {
287                    this.getParentLogger().debug( "Contextualizable.contextualize() for " + this.getShorthand() );
288                    ((Contextualizable) rawInstance).contextualize(context);
289                }
290                catch (ContextException e)
291                {
292                    String msg = "Contextualizing the following service failed : " + this.getShorthand();
293                    this.getParentLogger().error(msg,e);
294                    throw e;
295                }
296                catch (Throwable t)
297                {
298                    String msg = "Contextualizing the following service failed : " + this.getShorthand();
299                    this.getParentLogger().error(msg,t);
300                    throw new ContextException(msg,t);
301                }
302            }
303        }
304    
305        /**
306         * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
307         */
308        public void service(ServiceManager serviceManager) throws ServiceException
309        {
310            Object rawInstance = this.getRawInstance(false);
311    
312            if( rawInstance instanceof Serviceable )
313            {
314                try
315                {
316                    this.getParentLogger().debug( "Serviceable.service() for " + this.getShorthand() );
317                    ((Serviceable) rawInstance).service(serviceManager);
318                }
319                catch (ServiceException e)
320                {
321                    String msg = "Servicing the following service failed : " + this.getShorthand();
322                    this.getParentLogger().error(msg,e);
323                    throw e;
324                }
325                catch (Throwable t)
326                {
327                    String msg = "Servicing the following service failed : " + this.getShorthand();
328                    this.getParentLogger().error(msg,t);
329                    throw new ServiceException(this.getShorthand(),msg,t);
330                }
331            }
332        }
333    
334        /**
335         * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
336         */
337        public void configure(Configuration configuration) throws ConfigurationException
338        {
339            Object rawInstance = this.getRawInstance(false);
340    
341            if( rawInstance instanceof Configurable )
342            {
343                try
344                {
345                    this.getParentLogger().debug( "Configurable.configure() for " + this.getShorthand() );
346                    ((Configurable) rawInstance).configure(configuration);
347                }
348                catch (ConfigurationException e)
349                {
350                    String msg = "Configuring the following service failed : " + this.getShorthand();
351                    this.getParentLogger().error(msg,e);
352                    throw e;
353                }
354                catch (Throwable t)
355                {
356                    String msg = "Configuring the following service failed : " + this.getShorthand();
357                    this.getParentLogger().error(msg,t);
358                    throw new ConfigurationException(msg,t);
359                }
360            }
361        }
362    
363        /**
364         * @see org.apache.avalon.framework.parameters.Parameterizable#parameterize(org.apache.avalon.framework.parameters.Parameters)
365         */
366        public void parameterize(Parameters parameters) throws ParameterException
367        {
368            Object rawInstance = this.getRawInstance(false);
369    
370            if( rawInstance instanceof Parameterizable )
371            {
372                try
373                {
374                    this.getParentLogger().debug( "Parameterizable.parametrize() for " + this.getShorthand() );
375                    ((Parameterizable) rawInstance).parameterize(parameters);
376                }
377                catch (ParameterException e)
378                {
379                    String msg = "Parameterizing the following service failed : " + this.getShorthand();
380                    this.getParentLogger().error(msg,e);
381                    throw e;
382                }
383                catch (Throwable t)
384                {
385                    String msg = "Parameterizing the following service failed : " + this.getShorthand();
386                    this.getParentLogger().error(msg,t);
387                    throw new ParameterException(msg,t);
388                }
389            }
390        }
391    
392        /**
393         * @see org.apache.avalon.framework.activity.Initializable#initialize()
394         */
395        public void initialize() throws Exception
396        {
397            Object rawInstance = this.getRawInstance(false);
398    
399            if( rawInstance instanceof Initializable )
400            {
401                try
402                {
403                    this.getParentLogger().debug( "Initializable.initialize() for " + this.getShorthand() );
404                    ((Initializable) rawInstance).initialize();
405                }
406                catch (Exception e)
407                {
408                    String msg = "Initializing the following service failed : " + this.getShorthand();
409                    this.getParentLogger().error(msg,e);
410                    throw e;
411                }
412                catch (Throwable t)
413                {
414                    String msg = "Initializing the following service failed : " + this.getShorthand();
415                    this.getParentLogger().error(msg,t);
416                    throw new RuntimeException(msg);
417                }
418            }
419        }
420    
421        /**
422         * @see org.apache.avalon.framework.activity.Executable#execute()
423         */
424        public void execute() throws Exception
425        {
426            Object rawInstance = this.getRawInstance(false);
427    
428            if( rawInstance instanceof Executable )
429            {
430                try
431                {
432                    this.getParentLogger().debug( "Executable.execute() for " + this.getShorthand() );
433                    ((Executable) rawInstance).execute();
434                }
435                catch (Exception e)
436                {
437                    String msg = "Executing the following service failed : " + this.getShorthand();
438                    this.getParentLogger().error(msg,e);
439                    throw e;
440                }
441                catch (Throwable t)
442                {
443                    String msg = "Executing the following service failed : " + this.getShorthand();
444                    this.getParentLogger().error(msg,t);
445                    throw new RuntimeException(msg);
446                }
447            }
448        }
449    
450        /**
451         * @see org.apache.avalon.framework.activity.Startable#start()
452         */
453        public void start() throws Exception
454        {
455            Object rawInstance = this.getRawInstance(false);
456    
457            if( rawInstance instanceof Startable )
458            {
459                try
460                {
461                    this.getParentLogger().debug( "Startable.start() for " + this.getShorthand() );
462                    ((Startable) rawInstance).start();
463                }
464                catch (Exception e)
465                {
466                    String msg = "Starting the following service failed : " + this.getShorthand();
467                    this.getParentLogger().error(msg,e);
468                    throw e;
469                }
470                catch (Throwable t)
471                {
472                    String msg = "Starting the following service failed : " + this.getShorthand();
473                    this.getParentLogger().error(msg,t);
474                    throw new RuntimeException(msg);
475                }
476            }
477        }
478    
479        /**
480         * @see org.apache.avalon.framework.activity.Startable#stop()
481         */
482        public void stop() throws Exception
483        {
484            Object rawInstance = this.getRawInstance(false);
485    
486            if( rawInstance instanceof Startable )
487            {
488                try
489                {
490                    this.getParentLogger().debug( "Startable.stop() for " + this.getShorthand() );
491                    ((Startable) rawInstance).stop();
492                }
493                catch (Exception e)
494                {
495                    String msg = "Stopping the following service failed : " + this.getShorthand();
496                    this.getParentLogger().error(msg,e);
497                    throw e;
498                }
499                catch (Throwable t)
500                {
501                    String msg = "Stopping the following service failed : " + this.getShorthand();
502                    this.getParentLogger().error(msg,t);
503                    throw new RuntimeException(msg);
504                }
505            }
506        }
507    
508        /**
509         * @see org.apache.avalon.framework.activity.Suspendable#resume()
510         */
511        public void resume()
512        {
513            Object rawInstance = this.getRawInstance(false);
514    
515            if( rawInstance instanceof Suspendable )
516            {
517                try
518                {
519                    this.getParentLogger().debug( "Suspendable.resume() for " + this.getShorthand() );
520                    ((Suspendable) rawInstance).resume();
521                }
522                catch (Throwable t)
523                {
524                    String msg = "Resuming the following service failed : " + this.getShorthand();
525                    this.getParentLogger().error(msg,t);
526                    throw new RuntimeException(msg);
527                }
528            }
529        }
530    
531        /**
532         * @see org.apache.avalon.framework.activity.Suspendable#suspend()
533         */
534        public void suspend()
535        {
536            Object rawInstance = this.getRawInstance(false);
537    
538            if( rawInstance instanceof Suspendable )
539            {
540                try
541                {
542                    this.getParentLogger().debug( "Suspendable.suspend() for " + this.getShorthand() );
543                    ((Suspendable) rawInstance).suspend();
544                }
545                catch (Throwable t)
546                {
547                    String msg = "Suspending the following service failed : " + this.getShorthand();
548                    this.getParentLogger().error(msg,t);
549                    throw new RuntimeException(msg);
550                }
551            }
552        }
553    
554        /**
555         * @see org.apache.avalon.framework.configuration.Reconfigurable#reconfigure(org.apache.avalon.framework.configuration.Configuration)
556         */
557        public void reconfigure(Configuration configuration) throws ConfigurationException
558        {
559            Validate.notNull( configuration, "configuration" );
560    
561            Object rawInstance = this.getRawInstance(false);
562    
563            if( rawInstance instanceof Reconfigurable )
564            {
565                try
566                {
567                    this.getParentLogger().debug( "Reconfigurable.reconfigure() for " + this.getShorthand() );
568                    ((Reconfigurable) rawInstance).reconfigure(configuration);
569                }
570                catch (Throwable t)
571                {
572                    String msg = "Reconfiguring the following service failed : " + this.getShorthand();
573                    this.getParentLogger().error(msg,t);
574                    throw new RuntimeException(msg);
575                }
576            }
577        }
578    }