KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > avalon > fortress > MetaInfoEntry


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

17
18 package org.apache.avalon.fortress;
19
20 import java.util.*;
21
22 /**
23  * Keeps track of the relationship of all the associated meta data for a
24  * component type. It records all the roles, short name, component class, and
25  * the handler class used to manage it. The short name is included strictly
26  * to enable "self-healing" configuration files.
27  *
28  * @author <a HREF="mailto:dev@avalon.apache.org">Avalon Development Team</a>
29  * @version $Revision: 1.10 $ $Date: 2004/02/28 15:16:24 $
30  */

31 public final class MetaInfoEntry
32 {
33     public static final String JavaDoc THREADSAFE_HANDLER = "org.apache.avalon.fortress.impl.handler.ThreadSafeComponentHandler";
34     public static final String JavaDoc POOLABLE_HANDLER = "org.apache.avalon.fortress.impl.handler.PoolableComponentHandler";
35     public static final String JavaDoc FACTORY_HANDLER = "org.apache.avalon.fortress.impl.handler.FactoryComponentHandler";
36     public static final String JavaDoc PER_THREAD_HANDLER = "org.apache.avalon.fortress.impl.handler.PerThreadComponentHandler";
37
38     private final Class JavaDoc m_klass;
39     private final String JavaDoc m_configName;
40     private final Class JavaDoc m_handler;
41     private final Set m_roles;
42     private volatile boolean m_readOnly = false;
43
44     /** Translate from lifestyle to component handler. */
45     private static final Map m_lifecycleMap;
46     private final List m_dependencies;
47     private static final String JavaDoc TYPE_SINGLETON = "singleton";
48     private static final String JavaDoc TYPE_THREAD = "thread";
49     private static final String JavaDoc TYPE_POOLED = "pooled";
50     private static final String JavaDoc TYPE_TRANSIENT = "transient";
51
52     // Initialize the scope map
53
static
54     {
55         Map lifecycleMap = new HashMap();
56         lifecycleMap.put( TYPE_SINGLETON, THREADSAFE_HANDLER );
57         lifecycleMap.put( TYPE_THREAD, PER_THREAD_HANDLER );
58         lifecycleMap.put( TYPE_POOLED, POOLABLE_HANDLER );
59         lifecycleMap.put( TYPE_TRANSIENT, FACTORY_HANDLER );
60
61         m_lifecycleMap = Collections.unmodifiableMap( lifecycleMap );
62     }
63
64     /**
65      * Create a MetaInfoEntry from the supplied component class, and the
66      * supplied meta information.
67      *
68      * @param componentClass The <code>Class</code> for the component type
69      * @param properties The <code>Properties</code> object for meta info
70      *
71      * @throws ClassNotFoundException if the component handler class could not be found
72      */

73     public MetaInfoEntry( final Class JavaDoc componentClass, final Properties properties, final List deps ) throws ClassNotFoundException JavaDoc
74     {
75         if ( null == componentClass ) throw new NullPointerException JavaDoc( "\"componentClass\" cannot be null." );
76         if ( null == properties ) throw new NullPointerException JavaDoc( "\"properties\" cannot be null." );
77         if ( null == deps ) throw new NullPointerException JavaDoc( "\"deps\" cannot be null." );
78
79         m_klass = componentClass;
80         m_configName = properties.getProperty( "x-avalon.name", createShortName( componentClass.getName() ) );
81         m_handler = Thread.currentThread().getContextClassLoader().loadClass( getHandler( properties ) );
82         m_roles = new HashSet();
83         m_dependencies = deps;
84     }
85
86     /**
87      * Create a MetaInfoEntry from the supplied <code>RoleEntry</code>.
88      *
89      * @param roleEntry The <code>RoleEntry</code> to convert
90      */

91     public MetaInfoEntry( final RoleEntry roleEntry )
92     {
93         if ( null == roleEntry ) throw new NullPointerException JavaDoc( "\"roleEntry\" cannot be null." );
94
95         m_klass = roleEntry.getComponentClass();
96         m_configName = roleEntry.getShortname();
97         m_handler = roleEntry.getHandlerClass();
98         m_roles = new HashSet();
99         m_roles.add( roleEntry.getRole() );
100         m_dependencies = new ArrayList();
101         makeReadOnly();
102     }
103
104     /**
105      * Make the component entry read only, so no more services can be added.
106      */

107     public void makeReadOnly()
108     {
109         m_readOnly = true;
110     }
111
112     /**
113      * Get the <code>Class</code> for the component type.
114      *
115      * @return the <code>Class</code>
116      */

117     public Class JavaDoc getComponentClass()
118     {
119         return m_klass;
120     }
121
122     /**
123      * Get the <code>Class</code> for the component type's
124      * {@link org.apache.avalon.fortress.impl.handler.ComponentHandler}.
125      *
126      * @return the <code>Class</code>
127      */

128     public Class JavaDoc getHandlerClass()
129     {
130         return m_handler;
131     }
132
133     /**
134      * Get the configuration name for the component type. This is used in
135      * "self-healing" configuration files.
136      *
137      * @return the config name
138      */

139     public String JavaDoc getConfigurationName()
140     {
141         return m_configName;
142     }
143
144     /**
145      * Add a service/role for the component entry.
146      *
147      * @param role The new role
148      *
149      * @throws SecurityException if this MetaInfoEntry is read-only
150      */

151     public void addRole( final String JavaDoc role )
152     {
153         if ( null == role ) throw new NullPointerException JavaDoc( "\"role\" cannot be null" );
154         if ( m_readOnly ) throw new SecurityException JavaDoc( "This MetaInfoEntry is read-only." );
155
156         m_roles.add( role );
157     }
158
159     /**
160      * Tests to see if a component exposes a role.
161      *
162      * @param role The role to check
163      * @return <code>true</code> if it does
164      */

165     public boolean containsRole( final String JavaDoc role )
166     {
167         if ( null == role ) throw new NullPointerException JavaDoc( "\"role\" cannot be null" );
168         return m_roles.contains( role );
169     }
170
171     /**
172      * Get an iterator for all the roles.
173      *
174      * @return the iterator
175      */

176     public Iterator getRoles()
177     {
178         return m_roles.iterator();
179     }
180
181     /**
182      * Get a reference to the dependencies list.
183      *
184      * @return the dependency list
185      */

186     public List getDependencies()
187     {
188         return m_dependencies;
189     }
190
191     /**
192      * Get the name of the requested component handler.
193      *
194      * @param meta The properties object from the constructor
195      * @return String name of the component handler
196      */

197     private String JavaDoc getHandler( final Properties meta )
198     {
199         final String JavaDoc lifecycle = meta.getProperty( "x-avalon.lifestyle", null );
200         String JavaDoc handler;
201
202         if ( null != lifecycle )
203         {
204             handler = (String JavaDoc) m_lifecycleMap.get( lifecycle );
205         }
206         else
207         {
208             handler = meta.getProperty( "fortress.handler" );
209         }
210
211         if ( null == handler )
212         {
213             handler = PER_THREAD_HANDLER;
214         }
215
216         return handler;
217     }
218
219     /**
220      * Convert a Component implmentation classname into a shorthand
221      * name. It assumes all classnames for a particular component is
222      * unique.
223      *
224      * @param className The classname of a component
225      * @return String the short name
226      */

227     public static final String JavaDoc createShortName( final String JavaDoc className )
228     {
229         final StringBuffer JavaDoc shortName = new StringBuffer JavaDoc();
230
231         final char[] name = className.substring(
232             className.lastIndexOf( '.' ) + 1 ).toCharArray();
233         char last = '\0';
234
235         for (int i = 0; i < name.length; i++)
236         {
237             if (Character.isUpperCase(name[i]))
238             {
239                 if ( Character.isLowerCase( last ) )
240                 {
241                     shortName.append('-');
242                 }
243
244                 shortName.append(Character.toLowerCase(name[i]));
245             }
246             else
247             {
248                 shortName.append(name[i]);
249             }
250
251             last = name[i];
252         }
253
254         return shortName.toString().toLowerCase();
255     }
256
257 }
258
Popular Tags