KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > avalon > fortress > impl > DefaultECMContainer


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17 package org.apache.avalon.fortress.impl;
18
19 import java.util.Iterator JavaDoc;
20 import java.util.Map JavaDoc;
21
22 import org.apache.avalon.fortress.MetaInfoEntry;
23 import org.apache.avalon.fortress.util.Service;
24 import org.apache.avalon.fortress.impl.handler.ComponentHandler;
25 import org.apache.avalon.fortress.impl.handler.LEAwareComponentHandler;
26 import org.apache.avalon.fortress.impl.lookup.FortressServiceSelector;
27 import org.apache.avalon.fortress.impl.role.ECMMetaInfoManager;
28 import org.apache.avalon.framework.configuration.Configuration;
29 import org.apache.avalon.framework.configuration.ConfigurationException;
30 import org.apache.avalon.framework.container.ContainerUtil;
31 import org.apache.avalon.framework.service.DefaultServiceManager;
32 import org.apache.avalon.framework.thread.SingleThreaded;
33 import org.apache.avalon.framework.thread.ThreadSafe;
34 import org.apache.excalibur.instrument.Instrumentable;
35 import org.d_haven.mpool.ObjectFactory;
36
37 /**
38  * Customize the Fortress container to handle ECM compatibility
39  *
40  * @author <a HREF="mailto:dev@avalon.apache.org">The Avalon Team</a>
41  * @version CVS $ Revision: 1.1 $
42  */

43 public class DefaultECMContainer extends DefaultContainer {
44
45     /**
46      * Retrieve the role for the component.
47      *
48      * @param config the component configuration
49      * @return the class name
50      */

51     private String JavaDoc getRole( final Configuration config )
52     throws ConfigurationException {
53         final String JavaDoc className;
54
55         if ( "component".equals( config.getName() ) )
56         {
57             className = config.getAttribute( "role" );
58         }
59         else
60         {
61             final MetaInfoEntry roleEntry = m_metaManager.getMetaInfoForShortName( config.getName() );
62             if ( null == roleEntry )
63             {
64
65                 final String JavaDoc message = "No class found matching configuration name " +
66                         "[name: " + config.getName() + ", location: " + config.getLocation() + "]";
67                 throw new ConfigurationException( message );
68             }
69
70             Iterator JavaDoc roleIterator = roleEntry.getRoles();
71             if ( roleIterator.hasNext() )
72             {
73                 className = (String JavaDoc)roleIterator.next();
74             }
75             else
76             {
77                 className = roleEntry.getComponentClass().getName();
78             }
79         }
80
81         return className;
82     }
83
84     /**
85      * Retrieve the classname (impl) for the component.
86      *
87      * @param config the component configuration
88      * @return the class name
89      */

90     private String JavaDoc getClassname( final Configuration config )
91     throws ConfigurationException {
92         final String JavaDoc className;
93
94         if ( "component".equals( config.getName() ) )
95         {
96             className = config.getAttribute( "class" );
97         }
98         else
99         {
100             if ( config.getAttribute("class", null) != null )
101             {
102                 className = config.getAttribute("class");
103             }
104             else
105             {
106                 final MetaInfoEntry roleEntry = m_metaManager.getMetaInfoForShortName( config.getName() );
107                 if ( null == roleEntry )
108                 {
109
110                     final String JavaDoc message = "No class found matching configuration name " +
111                         "[name: " + config.getName() + ", location: " + config.getLocation() + "]";
112                     throw new ConfigurationException( message );
113                 }
114
115                 className = roleEntry.getComponentClass().getName();
116             }
117         }
118
119         return className;
120     }
121
122     /**
123      * Provide some validation for the core Cocoon components
124      *
125      * @param conf The configuration
126      * @throws ConfigurationException if the coniguration is invalid
127      */

128     public void configure( Configuration conf )
129     throws ConfigurationException {
130         this.interpretProxy( conf.getAttribute("proxy-type", this.getDefaultProxyType()) );
131
132         final Configuration[] elements = conf.getChildren();
133         for ( int i = 0; i < elements.length; i++ )
134         {
135             final Configuration element = elements[i];
136
137             // figure out Role
138
String JavaDoc role = getRole( element );
139             if ( role.endsWith("Selector") )
140             {
141                 processSelector(role.substring(0, role.length()-8), element );
142             }
143             else
144             {
145
146                 // get the implementation
147
final String JavaDoc className = getClassname( element );
148
149                 final int pos = role.indexOf('/');
150                 final String JavaDoc hint;
151                 if ( pos != -1 )
152                 {
153                     hint = role.substring(pos+1);
154                     role = role.substring(0, pos);
155                 }
156                 else
157                 {
158                     hint = null;
159                 }
160
161                 final String JavaDoc shortName;
162                 if ( "component".equals( element.getName() ))
163                 {
164                     shortName = null;
165                 }
166                 else
167                 {
168                     shortName = element.getName();
169                 }
170
171                 this.addComponent(role, hint, shortName, className, element );
172             }
173
174             if ( getLogger().isDebugEnabled() )
175             {
176                 getLogger().debug( "Configuration processed for: " + role );
177             }
178         }
179     }
180
181     /**
182      * Get a ComponentHandler with the default constructor for the component class passed in.
183      *
184      * @param classname the name of the component's class
185      * @param handlerClass the class used to handle the component
186      * @param metaData the information needed to construct a ComponentHandler for the component
187      * @return the component handler
188      * @throws Exception if unable to provide a componenthandler
189      */

190     private ComponentHandler getComponentHandler( final String JavaDoc classname,
191                                                   final Class JavaDoc handlerClass,
192                                                   final ComponentHandlerMetaData metaData)
193             throws Exception JavaDoc
194     {
195         final Configuration configuration = metaData.getConfiguration();
196
197         // get info from params
198
final ComponentHandler handler;
199
200         try
201         {
202             final ObjectFactory factory =
203                     createObjectFactory( classname, configuration );
204
205             // create the appropriate handler instance
206
final ComponentHandler targetHandler =
207                     (ComponentHandler) handlerClass.newInstance();
208
209             // do the handler lifecycle
210
ContainerUtil.enableLogging( targetHandler, getLogger() );
211             ContainerUtil.contextualize( targetHandler, m_context );
212             final DefaultServiceManager serviceManager =
213                     new DefaultServiceManager( getServiceManager() );
214             serviceManager.put( ObjectFactory.class.getName(), factory );
215             serviceManager.makeReadOnly();
216
217             ContainerUtil.service( targetHandler, serviceManager );
218             ContainerUtil.configure( targetHandler, configuration );
219             ContainerUtil.initialize( targetHandler );
220
221             if ( targetHandler instanceof Instrumentable )
222             {
223                 final Instrumentable instrumentable = (Instrumentable) targetHandler;
224                 final String JavaDoc name = instrumentable.getInstrumentableName();
225                 m_instrumentManager.registerInstrumentable( instrumentable, name );
226             }
227
228             // no other lifecycle stages supported for ComponentHandler;
229
// ComponentHandler is not a "true" avalon component
230

231             handler = new LEAwareComponentHandler( targetHandler, m_extManager, m_context );
232         }
233         catch ( final Exception JavaDoc e )
234         {
235             // if anything went wrong, the component cannot be worked with
236
// and it cannot be added into the impl, so don't provide
237
// a handler
238
if ( getLogger().isDebugEnabled() )
239             {
240                 final String JavaDoc message =
241                         "Could not create the handler for the '" +
242                         classname + "' component.";
243                 getLogger().debug( message, e );
244             }
245             throw e;
246         }
247
248         if ( getLogger().isDebugEnabled() )
249         {
250             final String JavaDoc message =
251                     "Component " + classname +
252                     " uses handler " + handlerClass.getName();
253             getLogger().debug( message );
254         }
255
256         // we're still here, so everything went smooth. Register the handler
257
// and return it
258
final ComponentHandlerEntry entry =
259                 new ComponentHandlerEntry( handler, metaData );
260         m_components.add( entry );
261
262         return handler;
263     }
264
265     protected Class JavaDoc getComponentHandlerClass(final String JavaDoc defaultClassName, final String JavaDoc shortName )
266         throws Exception JavaDoc
267     {
268         if ( shortName == null )
269         {
270             String JavaDoc handlerClassName = null;
271
272             Class JavaDoc clazz;
273             try
274             {
275                 clazz = m_classLoader.loadClass( defaultClassName );
276
277                 if ( ThreadSafe.class.isAssignableFrom( clazz ) )
278                 {
279                     handlerClassName = MetaInfoEntry.THREADSAFE_HANDLER;
280                 }
281                 else if ( Service.isClassPoolable(clazz) )
282                 {
283                     handlerClassName = MetaInfoEntry.POOLABLE_HANDLER;
284                 }
285                 else if ( SingleThreaded.class.isAssignableFrom( clazz) )
286                 {
287                     handlerClassName = MetaInfoEntry.FACTORY_HANDLER;
288                 }
289             }
290             catch ( final Exception JavaDoc e )
291             {
292                 final String JavaDoc message =
293                     "Unable to load class " + defaultClassName + ". Using dfault component handler.";
294                 getLogger().warn( message );
295             }
296
297             // Don't know, use default
298
if ( handlerClassName == null )
299             {
300                 handlerClassName = MetaInfoEntry.THREADSAFE_HANDLER;
301             }
302             return m_classLoader.loadClass( handlerClassName ) ;
303         }
304         else
305         {
306             final MetaInfoEntry roleEntry = m_metaManager.getMetaInfoForShortName( shortName );
307             if ( null == roleEntry )
308             {
309
310                 final String JavaDoc message = "No class found matching configuration name " +
311                         "[name: " + shortName + "]";
312                 throw new ConfigurationException( message );
313             }
314
315             return roleEntry.getHandlerClass();
316         }
317     }
318
319     protected void processSelector(String JavaDoc role, Configuration config)
320         throws ConfigurationException
321     {
322         final String JavaDoc selectorRole = role + "Selector";
323         FortressServiceSelector fss = new FortressServiceSelector(this, selectorRole);
324         Map JavaDoc hintMap = createHintMap();
325         hintMap.put( DEFAULT_ENTRY, fss );
326         hintMap.put( SELECTOR_ENTRY,
327                     new FortressServiceSelector( this, selectorRole ) );
328         m_mapper.put( selectorRole, hintMap );
329
330         final Configuration[] children = config.getChildren();
331         if ( children != null )
332         {
333             for(int i=0; i<children.length; i++)
334             {
335                 final Configuration element = children[i];
336                 final String JavaDoc hint = element.getAttribute("name");
337                 final String JavaDoc className = element.getAttribute("class");
338
339                 if ( m_metaManager instanceof ECMMetaInfoManager )
340                 {
341                     try
342                     {
343                         ((ECMMetaInfoManager)m_metaManager).addSelectorComponent(role, hint, className, getComponentHandlerClass(className, null).getName());
344                     }
345                     catch (ConfigurationException ce )
346                     {
347                         throw ce;
348                     }
349                     catch (Exception JavaDoc e)
350                     {
351                         throw new ConfigurationException("Unable to add selector component.", e);
352                     }
353                 }
354                 addComponent(role, hint, null, className, element );
355             }
356         }
357     }
358
359     protected void addComponent(final String JavaDoc role,
360                                 String JavaDoc hint,
361                                 String JavaDoc shortName,
362                                 final String JavaDoc className,
363                                 final Configuration element)
364         throws ConfigurationException
365     {
366         final int activation = ComponentHandlerMetaData.ACTIVATION_BACKGROUND;
367
368         // Fortress requires a hint, so we just give it one :) (if missing)
369
final String JavaDoc metaDataHint = element.getAttribute( "id", element.getLocation() );
370
371         if ( hint == null )
372         {
373             hint = metaDataHint;
374         }
375
376         final ComponentHandlerMetaData metaData =
377             new ComponentHandlerMetaData( metaDataHint, className, element, activation );
378
379         try
380         {
381
382             if ( DEFAULT_ENTRY.equals( metaData.getName() ) ||
383                     SELECTOR_ENTRY.equals( metaData.getName() ) )
384             {
385                 throw new IllegalArgumentException JavaDoc( "Using a reserved id name" + metaData.getName() );
386             }
387
388             // create a handler for the combo of Role+MetaData
389
final ComponentHandler handler =
390                     getComponentHandler( className,
391                                          getComponentHandlerClass( className, shortName),
392                                          metaData );
393
394             // put the role into our role mapper. If the role doesn't exist
395
// yet, just stuff it in as DEFAULT_ENTRY. If it does, we create a
396
// ServiceSelector and put that in as SELECTOR_ENTRY.
397
Map JavaDoc hintMap = (Map JavaDoc) m_mapper.get( role );
398
399             // Initialize the hintMap if it doesn't exist yet.
400
if ( null == hintMap )
401             {
402                 hintMap = createHintMap();
403                 hintMap.put( DEFAULT_ENTRY, handler );
404                 hintMap.put( SELECTOR_ENTRY,
405                         new FortressServiceSelector( this, role ) );
406                 m_mapper.put( role, hintMap );
407             }
408
409             hintMap.put( hint, handler );
410
411             if ( element.getAttributeAsBoolean( "default", false ) )
412             {
413                 hintMap.put( DEFAULT_ENTRY, handler );
414             }
415         }
416         catch ( ConfigurationException ce )
417         {
418             throw ce;
419         }
420         catch ( Exception JavaDoc e )
421         {
422             throw new ConfigurationException( "Could not add component", e );
423         }
424     }
425
426     /**
427      * Return the default proxy type.
428      * This method can be overwritten in subclasses to provide a different
429      * default proxy type.
430      */

431     protected String JavaDoc getDefaultProxyType() {
432         return "none";
433     }
434 }
435
Popular Tags