EMMA Coverage Report (generated Wed Feb 03 01:24:19 UTC 2010)
[all classes][org.jomc.model.bootstrap]

COVERAGE SUMMARY FOR SOURCE FILE [BootstrapContext.java]

nameclass, %method, %block, %line, %
BootstrapContext.java67%  (2/3)80%  (12/15)57%  (299/523)52%  (64/122)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class BootstrapContext$10%   (0/1)0%   (0/2)0%   (0/20)0%   (0/2)
BootstrapContext$1 (BootstrapContext, ClassLoader): void 0%   (0/1)0%   (0/7)0%   (0/1)
toString (): String 0%   (0/1)0%   (0/13)0%   (0/1)
     
class BootstrapContext100% (1/1)91%  (10/11)59%  (289/493)53%  (62/118)
setBootstrapContextClassName (String): void 0%   (0/1)0%   (0/3)0%   (0/2)
createBootstrapContext (ClassLoader): BootstrapContext 100% (1/1)14%  (10/70)12%  (2/17)
getClassLoader (): ClassLoader 100% (1/1)46%  (6/13)67%  (2/3)
loadProviders (Class): Collection 100% (1/1)63%  (111/176)58%  (19/33)
findSchemas (): Schemas 100% (1/1)65%  (55/85)55%  (12/22)
findServices (): Services 100% (1/1)65%  (55/85)55%  (12/22)
findResources (String): Enumeration 100% (1/1)67%  (12/18)60%  (3/5)
findClass (String): Class 100% (1/1)81%  (13/16)60%  (3/5)
BootstrapContext (ClassLoader): void 100% (1/1)100% (6/6)100% (3/3)
findResource (String): URL 100% (1/1)100% (12/12)100% (3/3)
getBootstrapContextClassName (): String 100% (1/1)100% (9/9)100% (3/3)
     
class BootstrapContext$2100% (1/1)100% (2/2)100% (10/10)100% (2/2)
BootstrapContext$2 (BootstrapContext): void 100% (1/1)100% (6/6)100% (1/1)
compare (String, String): int 100% (1/1)100% (4/4)100% (1/1)

1/*
2 *   Copyright (c) 2009 The JOMC Project
3 *   Copyright (c) 2005 Christian Schulte <cs@jomc.org>
4 *   All rights reserved.
5 *
6 *   Redistribution and use in source and binary forms, with or without
7 *   modification, are permitted provided that the following conditions
8 *   are met:
9 *
10 *     o Redistributions of source code must retain the above copyright
11 *       notice, this list of conditions and the following disclaimer.
12 *
13 *     o Redistributions in binary form must reproduce the above copyright
14 *       notice, this list of conditions and the following disclaimer in
15 *       the documentation and/or other materials provided with the
16 *       distribution.
17 *
18 *   THIS SOFTWARE IS PROVIDED BY THE JOMC PROJECT AND CONTRIBUTORS "AS IS"
19 *   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20 *   THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 *   PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JOMC PROJECT OR
22 *   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 *   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 *   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 *   OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 *   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 *   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 *   $Id: BootstrapContext.java 1393 2010-01-27 18:34:30Z schulte2005 $
31 *
32 */
33package org.jomc.model.bootstrap;
34 
35import java.io.BufferedReader;
36import java.io.File;
37import java.io.FileInputStream;
38import java.io.IOException;
39import java.io.InputStream;
40import java.io.InputStreamReader;
41import java.lang.reflect.Constructor;
42import java.lang.reflect.InvocationTargetException;
43import java.net.URL;
44import java.util.Collection;
45import java.util.Comparator;
46import java.util.Enumeration;
47import java.util.Map;
48import java.util.TreeMap;
49import javax.xml.bind.JAXBContext;
50import javax.xml.bind.JAXBException;
51import javax.xml.bind.Marshaller;
52import javax.xml.bind.Unmarshaller;
53import javax.xml.bind.util.JAXBSource;
54import javax.xml.validation.Validator;
55import org.xml.sax.SAXException;
56 
57/**
58 * Object management and configuration model bootstrap context interface.
59 *
60 * @author <a href="mailto:cs@jomc.org">Christian Schulte</a>
61 * @version $Id: BootstrapContext.java 1393 2010-01-27 18:34:30Z schulte2005 $
62 * @see #createBootstrapContext(java.lang.ClassLoader)
63 */
64public abstract class BootstrapContext
65{
66 
67    /** Class name of the {@code BootstrapContext} implementation. */
68    private static volatile String bootstrapContextClassName;
69 
70    /** The class loader of the context. */
71    private ClassLoader classLoader;
72 
73    /**
74     * Creates a new {@code BootstrapContext} instance taking a class loader.
75     *
76     * @param classLoader The class loader of the context.
77     */
78    public BootstrapContext( final ClassLoader classLoader )
79    {
80        super();
81        this.classLoader = classLoader;
82    }
83 
84    /**
85     * Gets the class loader of the context.
86     *
87     * @return The class loader of the context.
88     */
89    public ClassLoader getClassLoader()
90    {
91        if ( this.classLoader == null )
92        {
93            this.classLoader = new ClassLoader( null )
94            {
95 
96                @Override
97                public String toString()
98                {
99                    return BootstrapContext.class.getName() + ".BootstrapClassLoader@" +
100                           System.identityHashCode( this );
101 
102                }
103 
104            };
105 
106        }
107 
108        return this.classLoader;
109    }
110 
111    /**
112     * Gets the name of the class providing the {@code BootstrapContext} implementation.
113     * <p>The name of the class providing the {@code BootstrapContext} implementation returned by method
114     * {@link #createBootstrapContext(java.lang.ClassLoader)} is controlled by system property
115     * {@code org.jomc.model.bootstrap.BootstrapContext.className}. If that property is not set, the name of the
116     * {@link DefaultBootstrapContext} class is returned.</p>
117     *
118     * @return The name of the class providing the {@code BootstrapContext} implementation.
119     *
120     * @see #setBootstrapContextClassName(java.lang.String)
121     */
122    public static String getBootstrapContextClassName()
123    {
124        if ( bootstrapContextClassName == null )
125        {
126            bootstrapContextClassName = System.getProperty( "org.jomc.model.bootstrap.BootstrapContext.className",
127                                                            DefaultBootstrapContext.class.getName() );
128 
129        }
130 
131        return bootstrapContextClassName;
132    }
133 
134    /**
135     * Sets the name of the class providing the {@code BootstrapContext} implementation.
136     *
137     * @param value The new name of the class providing the {@code BootstrapContext} implementation or {@code null}.
138     *
139     * @see #getBootstrapContextClassName()
140     */
141    public static void setBootstrapContextClassName( final String value )
142    {
143        bootstrapContextClassName = value;
144    }
145 
146    /**
147     * Searches the context for a class with a given name.
148     *
149     * @param name The name of the class to return.
150     *
151     * @return A Class object of the class with name {@code name} or {@code null} if no such class is found.
152     *
153     * @throws NullPointerException if {@code name} is {@code null}.
154     * @throws BootstrapException if searching fails.
155     */
156    public Class findClass( final String name ) throws BootstrapException
157    {
158        if ( name == null )
159        {
160            throw new NullPointerException( "name" );
161        }
162 
163        try
164        {
165            return Class.forName( name, true, this.getClassLoader() );
166        }
167        catch ( final ClassNotFoundException e )
168        {
169            return null;
170        }
171    }
172 
173    /**
174     * Searches the context for a resource with a given name.
175     *
176     * @param name The name of the resource to return.
177     *
178     * @return An URL object for reading the resource or {@code null} if no such resource is found.
179     *
180     * @throws NullPointerException if {@code name} is {@code null}.
181     * @throws BootstrapException if searching fails.
182     */
183    public URL findResource( final String name ) throws BootstrapException
184    {
185        if ( name == null )
186        {
187            throw new NullPointerException( "name" );
188        }
189 
190        return this.getClassLoader().getResource( name );
191    }
192 
193    /**
194     * Searches the context for resources with a given name.
195     *
196     * @param name The name of the resources to return.
197     *
198     * @return An enumeration of URL objects for reading the resources. If no resources are found, the enumeration will
199     * be empty.
200     *
201     * @throws NullPointerException if {@code name} is {@code null}.
202     * @throws BootstrapException if searching fails.
203     */
204    public Enumeration<URL> findResources( final String name ) throws BootstrapException
205    {
206        if ( name == null )
207        {
208            throw new NullPointerException( "name" );
209        }
210 
211        try
212        {
213            return this.getClassLoader().getResources( name );
214        }
215        catch ( final IOException e )
216        {
217            throw new BootstrapException( e );
218        }
219    }
220 
221    /**
222     * Searches the context for schemas.
223     * <p>This method loads {@code SchemaProvider} classes setup via
224     * {@code META-INF/services/org.jomc.model.bootstrap.SchemaProvider} resources and returns a list of provided
225     * schemas.</p>
226     *
227     * @return The schemas found in the context.
228     *
229     * @throws BootstrapException if searching schemas fails.
230     *
231     * @see SchemaProvider#findSchemas(org.jomc.model.bootstrap.BootstrapContext)
232     */
233    public Schemas findSchemas() throws BootstrapException
234    {
235        try
236        {
237            final Schemas schemas = new Schemas();
238 
239            final Collection<Class<SchemaProvider>> providers = this.loadProviders( SchemaProvider.class );
240            for ( Class<SchemaProvider> provider : providers )
241            {
242                final SchemaProvider schemaProvider = provider.newInstance();
243                final Schemas provided = schemaProvider.findSchemas( this );
244                if ( provided != null )
245                {
246                    schemas.getSchema().addAll( provided.getSchema() );
247                }
248            }
249 
250            final javax.xml.validation.Schema bootstrapSchema = this.createSchema();
251            final Validator validator = bootstrapSchema.newValidator();
252            validator.validate( new JAXBSource( this.createContext(), new ObjectFactory().createSchemas( schemas ) ) );
253 
254            return schemas;
255        }
256        catch ( final InstantiationException e )
257        {
258            throw new BootstrapException( e );
259        }
260        catch ( final IllegalAccessException e )
261        {
262            throw new BootstrapException( e );
263        }
264        catch ( final JAXBException e )
265        {
266            throw new BootstrapException( e );
267        }
268        catch ( final SAXException e )
269        {
270            throw new BootstrapException( e );
271        }
272        catch ( final IOException e )
273        {
274            throw new BootstrapException( e );
275        }
276    }
277 
278    /**
279     * Searches the context for services.
280     * <p>This method loads {@code ServiceProvider} classes setup via
281     * {@code META-INF/services/org.jomc.model.bootstrap.ServiceProvider} resources and returns a list of provided
282     * services.</p>
283     *
284     * @return The services found in the context.
285     *
286     * @throws BootstrapException if searching services fails.
287     *
288     * @see ServiceProvider#findServices(org.jomc.model.bootstrap.BootstrapContext)
289     */
290    public Services findServices() throws BootstrapException
291    {
292        try
293        {
294            final Services services = new Services();
295 
296            final Collection<Class<ServiceProvider>> providers = this.loadProviders( ServiceProvider.class );
297            for ( Class<ServiceProvider> provider : providers )
298            {
299                final ServiceProvider serviceProvider = provider.newInstance();
300                final Services provided = serviceProvider.findServices( this );
301                if ( provided != null )
302                {
303                    services.getService().addAll( provided.getService() );
304                }
305            }
306 
307            final javax.xml.validation.Schema bootstrapSchema = this.createSchema();
308            final Validator validator = bootstrapSchema.newValidator();
309            validator.validate( new JAXBSource( this.createContext(), new ObjectFactory().createServices( services ) ) );
310 
311            return services;
312        }
313        catch ( final InstantiationException e )
314        {
315            throw new BootstrapException( e );
316        }
317        catch ( final IllegalAccessException e )
318        {
319            throw new BootstrapException( e );
320        }
321        catch ( final JAXBException e )
322        {
323            throw new BootstrapException( e );
324        }
325        catch ( final SAXException e )
326        {
327            throw new BootstrapException( e );
328        }
329        catch ( final IOException e )
330        {
331            throw new BootstrapException( e );
332        }
333    }
334 
335    /**
336     * Creates a new object management and configuration model {@code BootstrapContext} instance.
337     *
338     * @param classLoader The class loader to create a new object management and configuration model bootstrap context
339     * instance with or {@code null} to create a new bootstrap context using the platform's bootstrap class loader.
340     *
341     * @return A new {@code BootstrapContext} instance.
342     *
343     * @throws BootstrapException if creating a new object management and configuration model bootstrap context instance
344     * fails.
345     *
346     * @see #getBootstrapContextClassName()
347     */
348    public static BootstrapContext createBootstrapContext( final ClassLoader classLoader ) throws BootstrapException
349    {
350        if ( DefaultBootstrapContext.class.getName().equals( getBootstrapContextClassName() ) )
351        {
352            return new DefaultBootstrapContext( classLoader );
353        }
354 
355        try
356        {
357            final Class clazz = Class.forName( getBootstrapContextClassName(), true, classLoader );
358            final Constructor ctor = clazz.getConstructor( ClassLoader.class );
359            return (BootstrapContext) ctor.newInstance( classLoader );
360        }
361        catch ( final ClassNotFoundException e )
362        {
363            throw new BootstrapException( e );
364        }
365        catch ( final NoSuchMethodException e )
366        {
367            throw new BootstrapException( e );
368        }
369        catch ( final InstantiationException e )
370        {
371            throw new BootstrapException( e );
372        }
373        catch ( final IllegalAccessException e )
374        {
375            throw new BootstrapException( e );
376        }
377        catch ( final InvocationTargetException e )
378        {
379            throw new BootstrapException( e );
380        }
381        catch ( final ClassCastException e )
382        {
383            throw new BootstrapException( e );
384        }
385    }
386 
387    /**
388     * Creates a new object management and configuration model bootstrap JAXP schema instance.
389     *
390     * @return A new object management and configuration model bootstrap JAXP schema instance.
391     *
392     * @throws BootstrapException if creating a new object management and configuration model bootstrap JAXP schema
393     * instance fails.
394     */
395    public abstract javax.xml.validation.Schema createSchema() throws BootstrapException;
396 
397    /**
398     * Creates a new object management and configuration model bootstrap JAXB context instance.
399     *
400     * @return A new object management and configuration model bootstrap JAXB context instance.
401     *
402     * @throws BootstrapException if creating a new object management and configuration model bootstrap JAXB context
403     * instance fails.
404     */
405    public abstract JAXBContext createContext() throws BootstrapException;
406 
407    /**
408     * Creates a new object management and configuration model bootstrap JAXB marshaller instance.
409     *
410     * @return A new object management and configuration model bootstrap JAXB marshaller instance.
411     *
412     * @throws BootstrapException if creating a new object management and configuration model bootstrap JAXB marshaller
413     * instance fails.
414     */
415    public abstract Marshaller createMarshaller() throws BootstrapException;
416 
417    /**
418     * Creates a new object management and configuration model bootstrap JAXB unmarshaller instance.
419     *
420     * @return A new object management and configuration model bootstrap JAXB unmarshaller instance.
421     *
422     * @throws BootstrapException if creating a new object management and configuration model bootstrap JAXB
423     * unmarshaller instance fails.
424     */
425    public abstract Unmarshaller createUnmarshaller() throws BootstrapException;
426 
427    private <T> Collection<Class<T>> loadProviders( final Class<T> providerClass ) throws BootstrapException
428    {
429        try
430        {
431            final String providerNamePrefix = providerClass.getName() + ".";
432            final Map<String, Class<T>> providers = new TreeMap<String, Class<T>>( new Comparator<String>()
433            {
434 
435                public int compare( final String key1, final String key2 )
436                {
437                    return key1.compareTo( key2 );
438                }
439 
440            } );
441 
442            final File platformProviders = new File( new StringBuilder().append( System.getProperty( "java.home" ) ).
443                append( File.separator ).append( "jre" ).append( File.separator ).append( "lib" ).
444                append( File.separator ).append( "jomc.properties" ).toString() );
445 
446            if ( platformProviders.exists() )
447            {
448                InputStream in = null;
449                final java.util.Properties p = new java.util.Properties();
450 
451                try
452                {
453                    in = new FileInputStream( platformProviders );
454                    p.load( in );
455                }
456                finally
457                {
458                    if ( in != null )
459                    {
460                        in.close();
461                    }
462                }
463 
464                for ( Map.Entry e : p.entrySet() )
465                {
466                    if ( e.getKey().toString().startsWith( providerNamePrefix ) )
467                    {
468                        final Class<T> provider = this.findClass( e.getValue().toString() );
469                        if ( provider != null )
470                        {
471                            providers.put( e.getKey().toString(), provider );
472                        }
473                    }
474                }
475            }
476 
477            final Enumeration<URL> serviceProviders =
478                this.findResources( "META-INF/services/" + providerClass.getName() );
479 
480            while ( serviceProviders.hasMoreElements() )
481            {
482                final URL url = serviceProviders.nextElement();
483                final BufferedReader reader = new BufferedReader( new InputStreamReader( url.openStream(), "UTF-8" ) );
484 
485                String line = null;
486                while ( ( line = reader.readLine() ) != null )
487                {
488                    if ( line.contains( "#" ) )
489                    {
490                        continue;
491                    }
492 
493                    final Class<T> provider = this.findClass( line );
494                    if ( provider != null )
495                    {
496                        providers.put( providerNamePrefix + providers.size(), provider );
497                    }
498                }
499 
500                reader.close();
501            }
502 
503            return providers.values();
504        }
505        catch ( final IOException e )
506        {
507            throw new BootstrapException( e );
508        }
509    }
510 
511}

[all classes][org.jomc.model.bootstrap]
EMMA 2.0.5312 (C) Vladimir Roubtsov