KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > avalon > meta > info > verifier > TypeVerifier


1 /*
2
3  ============================================================================
4                    The Apache Software License, Version 1.1
5  ============================================================================
6
7  Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
8
9  Redistribution and use in source and binary forms, with or without modifica-
10  tion, are permitted provided that the following conditions are met:
11
12  1. Redistributions of source code must retain the above copyright notice,
13     this list of conditions and the following disclaimer.
14
15  2. Redistributions in binary form must reproduce the above copyright notice,
16     this list of conditions and the following disclaimer in the documentation
17     and/or other materials provided with the distribution.
18
19  3. The end-user documentation included with the redistribution, if any, must
20     include the following acknowledgment: "This product includes software
21     developed by the Apache Software Foundation (http://www.apache.org/)."
22     Alternately, this acknowledgment may appear in the software itself, if
23     and wherever such third-party acknowledgments normally appear.
24
25  4. The names "Jakarta", "Apache Avalon", "Avalon Framework" and
26     "Apache Software Foundation" must not be used to endorse or promote
27     products derived from this software without prior written
28     permission. For written permission, please contact apache@apache.org.
29
30  5. Products derived from this software may not be called "Apache", nor may
31     "Apache" appear in their name, without prior written permission of the
32     Apache Software Foundation.
33
34  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
35  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
36  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
37  APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
38  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
39  DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
40  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
41  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
42  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
43  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44
45  This software consists of voluntary contributions made by many individuals
46  on behalf of the Apache Software Foundation. For more information on the
47  Apache Software Foundation, please see <http://www.apache.org/>.
48
49 */

50
51 package org.apache.avalon.meta.info.verifier;
52
53 import java.lang.reflect.Constructor JavaDoc;
54 import java.lang.reflect.Modifier JavaDoc;
55 import org.apache.avalon.excalibur.i18n.ResourceManager;
56 import org.apache.avalon.excalibur.i18n.Resources;
57 import org.apache.avalon.framework.activity.Disposable;
58 import org.apache.avalon.framework.activity.Initializable;
59 import org.apache.avalon.framework.activity.Startable;
60 import org.apache.avalon.framework.activity.Suspendable;
61 import org.apache.avalon.framework.component.Composable;
62 import org.apache.avalon.framework.component.Recomposable;
63 import org.apache.avalon.framework.configuration.Configurable;
64 import org.apache.avalon.framework.configuration.Reconfigurable;
65 import org.apache.avalon.framework.context.Contextualizable;
66 import org.apache.avalon.framework.context.Recontextualizable;
67 import org.apache.avalon.framework.logger.LogEnabled;
68 import org.apache.avalon.framework.parameters.Parameterizable;
69 import org.apache.avalon.framework.parameters.Reparameterizable;
70 import org.apache.avalon.framework.service.Serviceable;
71
72 /**
73  * Utility class to help verify that component respects the
74  * rules of an Avalon component.
75  *
76  * @author <a HREF="mailto:dev@avalon.apache.org">Avalon Development Team</a>
77  * @version $Revision: 1.3 $ $Date: 2003/07/18 08:26:31 $
78  */

79 public class TypeVerifier
80 {
81     private static final Resources REZ =
82         ResourceManager.getPackageResources( TypeVerifier.class );
83
84     private static final Class JavaDoc[] EMPTY_TYPES = new Class JavaDoc[ 0 ];
85
86     /**
87      * The interfaces representing lifecycle stages.
88      */

89     private static final Class JavaDoc[] FRAMEWORK_CLASSES = new Class JavaDoc[]
90     {
91         LogEnabled.class,
92         Contextualizable.class,
93         Recontextualizable.class,
94         Composable.class,
95         Recomposable.class,
96         Serviceable.class,
97         Configurable.class,
98         Reconfigurable.class,
99         Parameterizable.class,
100         Reparameterizable.class,
101         Initializable.class,
102         Startable.class,
103         Suspendable.class,
104         Disposable.class
105     };
106
107     /**
108      * Verify that the supplied implementation class
109      * and service classes are valid for a component.
110      *
111      * @param name the name of component
112      * @param implementation the implementation class of component
113      * @param services the classes representing services
114      * @throws VerifyException if error thrown on failure and
115      * component fails check
116      */

117     public void verifyType( final String JavaDoc name,
118                                  final Class JavaDoc implementation,
119                                  final Class JavaDoc[] services )
120         throws VerifyException
121     {
122         verifyClass( name, implementation );
123         verifyLifecycles( name, implementation );
124         verifyServices( name, services );
125         verifyImplementsServices( name, implementation, services );
126     }
127
128
129     /**
130      * Verify that the supplied implementation implements the specified
131      * services.
132      *
133      * @param name the name of component
134      * @param implementation the class representign component
135      * @param services the services that the implementation must provide
136      * @throws VerifyException if error thrown on failure and
137      * component fails check
138      */

139     public void verifyImplementsServices( final String JavaDoc name,
140                                           final Class JavaDoc implementation,
141                                           final Class JavaDoc[] services )
142         throws VerifyException
143     {
144         for( int i = 0; i < services.length; i++ )
145         {
146             if( !services[ i ].isAssignableFrom( implementation ) )
147             {
148                 final String JavaDoc message =
149                     REZ.getString( "verifier.noimpl-service.error",
150                                    name,
151                                    implementation.getName(),
152                                    services[ i ].getName() );
153                 throw new VerifyException( message );
154             }
155         }
156     }
157
158     /**
159      * Verify that the supplied class is a valid class for
160      * a Component.
161      *
162      * @param name the name of component
163      * @param clazz the class representing component
164      * @throws VerifyException if error thrown on failure and
165      * component fails check
166      */

167     public void verifyClass( final String JavaDoc name,
168                              final Class JavaDoc clazz )
169         throws VerifyException
170     {
171         verifyNoArgConstructor( name, clazz );
172         verifyNonAbstract( name, clazz );
173         verifyNonArray( name, clazz );
174         verifyNonInterface( name, clazz );
175         verifyNonPrimitive( name, clazz );
176         verifyPublic( name, clazz );
177     }
178
179     /**
180      * Verify that the supplied classes are valid classes for
181      * a service.
182      *
183      * @param name the name of component
184      * @param classes the classes representign services
185      * @throws VerifyException if error thrown on failure and
186      * component fails check
187      */

188     public void verifyServices( final String JavaDoc name,
189                                 final Class JavaDoc[] classes )
190         throws VerifyException
191     {
192         for( int i = 0; i < classes.length; i++ )
193         {
194             verifyService( name, classes[ i ] );
195         }
196     }
197
198     /**
199      * Verify that the supplied class is a valid class for
200      * a service.
201      *
202      * @param name the name of component
203      * @param clazz the class representign service
204      * @throws VerifyException if error thrown on failure and
205      * component fails check
206      */

207     public void verifyService( final String JavaDoc name,
208                                final Class JavaDoc clazz )
209         throws VerifyException
210     {
211         verifyServiceIsPublic( name, clazz );
212
213         //
214
// the following two validation points need more work
215
// (a) it is valid to pass a class as a service because the class may be a proxy
216
// (b) when (a) is a class, it may be implementing lifecycle interfaces which could
217
// could be hidden under another proxy
218
//
219

220         //verifyServiceIsaInterface( name, clazz );
221
//verifyServiceNotALifecycle( name, clazz );
222
}
223
224     /**
225      * Verify that the implementation class does not
226      * implement incompatible lifecycle interfaces.
227      *
228      * @param name the name of component
229      * @param implementation the implementation class
230      * @throws VerifyException if error thrown on failure and
231      * component fails check
232      */

233     public void verifyLifecycles( final String JavaDoc name,
234                                   final Class JavaDoc implementation )
235         throws VerifyException
236     {
237         final boolean composable =
238             Composable.class.isAssignableFrom( implementation )
239             || Recomposable.class.isAssignableFrom( implementation );
240         final boolean serviceable = Serviceable.class.isAssignableFrom( implementation );
241         if( serviceable && composable )
242         {
243             final String JavaDoc message =
244                 REZ.getString( "verifier.incompat-serviceable.error",
245                                name,
246                                implementation.getName() );
247             throw new VerifyException( message );
248         }
249     }
250
251     /**
252      * Verify that the service implemented by
253      * specified component is an interface.
254      *
255      * @param name the name of component
256      * @param clazz the class representign service
257      * @throws VerifyException if error thrown on failure and
258      * component fails check
259      */

260     public void verifyServiceIsaInterface( final String JavaDoc name,
261                                            final Class JavaDoc clazz )
262         throws VerifyException
263     {
264         if( !clazz.isInterface() )
265         {
266             final String JavaDoc message =
267                 REZ.getString( "verifier.non-interface-service.error",
268                                name,
269                                clazz.getName() );
270             throw new VerifyException( message );
271         }
272     }
273
274     /**
275      * Verify that the service implemented by
276      * specified component is public.
277      *
278      * @param name the name of component
279      * @param clazz the class representign service
280      * @throws VerifyException if error thrown on failure and
281      * component fails check
282      */

283     public void verifyServiceIsPublic( final String JavaDoc name,
284                                        final Class JavaDoc clazz )
285         throws VerifyException
286     {
287         final boolean isPublic =
288             Modifier.isPublic( clazz.getModifiers() );
289         if( !isPublic )
290         {
291             final String JavaDoc message =
292                 REZ.getString( "verifier.non-public-service.error",
293                                name,
294                                clazz.getName() );
295             throw new VerifyException( message );
296         }
297     }
298
299     /**
300      * Verify that the service implemented by
301      * specified component does not extend any lifecycle interfaces.
302      *
303      * @param name the name of component
304      * @param clazz the class representign service
305      * @throws VerifyException if error thrown on failure and
306      * component fails check
307      */

308     public void verifyServiceNotALifecycle( final String JavaDoc name,
309                                             final Class JavaDoc clazz )
310         throws VerifyException
311     {
312         for( int i = 0; i < FRAMEWORK_CLASSES.length; i++ )
313         {
314             final Class JavaDoc lifecycle = FRAMEWORK_CLASSES[ i ];
315             if( lifecycle.isAssignableFrom( clazz ) )
316             {
317                 final String JavaDoc message =
318                     REZ.getString( "verifier.service-isa-lifecycle.error",
319                                    name,
320                                    clazz.getName(),
321                                    lifecycle.getName() );
322                 throw new VerifyException( message );
323             }
324         }
325     }
326
327     /**
328      * Verify that the component has a no-arg aka default
329      * constructor.
330      *
331      * @param name the name of component
332      * @param clazz the class representign component
333      * @throws VerifyException if error thrown on failure and
334      * component fails check
335      */

336     public void verifyNoArgConstructor( final String JavaDoc name,
337                                         final Class JavaDoc clazz )
338         throws VerifyException
339     {
340         try
341         {
342             final Constructor JavaDoc ctor = clazz.getConstructor( EMPTY_TYPES );
343             if( !Modifier.isPublic( ctor.getModifiers() ) )
344             {
345                 final String JavaDoc message =
346                     REZ.getString( "verifier.non-public-ctor.error",
347                                    name,
348                                    clazz.getName() );
349                 throw new VerifyException( message );
350             }
351         }
352         catch( final NoSuchMethodException JavaDoc nsme )
353         {
354             final String JavaDoc message =
355                 REZ.getString( "verifier.missing-noargs-ctor.error",
356                                name,
357                                clazz.getName() );
358             throw new VerifyException( message );
359         }
360     }
361
362     /**
363      * Verify that the component is not represented by
364      * abstract class.
365      *
366      * @param name the name of component
367      * @param clazz the class representign component
368      * @throws VerifyException if error thrown on failure and
369      * component fails check
370      */

371     public void verifyNonAbstract( final String JavaDoc name,
372                                    final Class JavaDoc clazz )
373         throws VerifyException
374     {
375         final boolean isAbstract =
376             Modifier.isAbstract( clazz.getModifiers() );
377         if( isAbstract )
378         {
379             final String JavaDoc message =
380                 REZ.getString( "verifier.abstract-class.error",
381                                name,
382                                clazz.getName() );
383             throw new VerifyException( message );
384         }
385     }
386
387     /**
388      * Verify that the component is not represented by
389      * abstract class.
390      *
391      * @param name the name of component
392      * @param clazz the class representign component
393      * @throws VerifyException if error thrown on failure and
394      * component fails check
395      */

396     public void verifyPublic( final String JavaDoc name,
397                               final Class JavaDoc clazz )
398         throws VerifyException
399     {
400         final boolean isPublic =
401             Modifier.isPublic( clazz.getModifiers() );
402         if( !isPublic )
403         {
404             final String JavaDoc message =
405                 REZ.getString( "verifier.nonpublic-class.error",
406                                name,
407                                clazz.getName() );
408             throw new VerifyException( message );
409         }
410     }
411
412     /**
413      * Verify that the component is not represented by
414      * primitive class.
415      *
416      * @param name the name of component
417      * @param clazz the class representign component
418      * @throws VerifyException if error thrown on failure and
419      * component fails check
420      */

421     public void verifyNonPrimitive( final String JavaDoc name,
422                                     final Class JavaDoc clazz )
423         throws VerifyException
424     {
425         if( clazz.isPrimitive() )
426         {
427             final String JavaDoc message =
428                 REZ.getString( "verifier.primitive-class.error",
429                                name,
430                                clazz.getName() );
431             throw new VerifyException( message );
432         }
433     }
434
435     /**
436      * Verify that the component is not represented by
437      * interface class.
438      *
439      * @param name the name of component
440      * @param clazz the class representign component
441      * @throws VerifyException if error thrown on failure and
442      * component fails check
443      */

444     public void verifyNonInterface( final String JavaDoc name,
445                                     final Class JavaDoc clazz )
446         throws VerifyException
447     {
448         if( clazz.isInterface() )
449         {
450             final String JavaDoc message =
451                 REZ.getString( "verifier.interface-class.error",
452                                name,
453                                clazz.getName() );
454             throw new VerifyException( message );
455         }
456     }
457
458     /**
459      * Verify that the component is not represented by
460      * an array class.
461      *
462      * @param name the name of component
463      * @param clazz the class representign component
464      * @throws VerifyException if error thrown on failure and
465      * component fails check
466      */

467     public void verifyNonArray( final String JavaDoc name,
468                                 final Class JavaDoc clazz )
469         throws VerifyException
470     {
471         if( clazz.isArray() )
472         {
473             final String JavaDoc message =
474                 REZ.getString( "verifier.array-class.error",
475                                name,
476                                clazz.getName() );
477             throw new VerifyException( message );
478         }
479     }
480 }
481
Popular Tags