EMMA Coverage Report (generated Fri Feb 21 04:03:47 CET 2014)
[all classes][org.jomc.modlet]

COVERAGE SUMMARY FOR SOURCE FILE [DefaultModletProcessor.java]

nameclass, %method, %block, %line, %
DefaultModletProcessor.java100% (2/2)61%  (14/23)67%  (347/521)66%  (78/119)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class DefaultModletProcessor$1100% (1/1)25%  (1/4)18%  (9/50)10%  (1/10)
error (TransformerException): void 0%   (0/1)0%   (0/14)0%   (0/3)
fatalError (TransformerException): void 0%   (0/1)0%   (0/14)0%   (0/3)
warning (TransformerException): void 0%   (0/1)0%   (0/13)0%   (0/3)
DefaultModletProcessor$1 (DefaultModletProcessor, ModelContext): void 100% (1/1)100% (9/9)100% (1/1)
     
class DefaultModletProcessor100% (1/1)68%  (13/19)72%  (338/471)71%  (77/109)
access$000 (Throwable): String 0%   (0/1)0%   (0/3)0%   (0/1)
getDefaultOrdinal (): int 0%   (0/1)0%   (0/9)0%   (0/3)
getMessage (Throwable): String 0%   (0/1)0%   (0/19)0%   (0/1)
getOrdinal (): int 0%   (0/1)0%   (0/11)0%   (0/3)
setDefaultOrdinal (Integer): void 0%   (0/1)0%   (0/3)0%   (0/2)
setOrdinal (Integer): void 0%   (0/1)0%   (0/4)0%   (0/2)
processModlets (ModelContext, Modlets): Modlets 100% (1/1)70%  (130/187)67%  (26/39)
findTransformers (ModelContext, String): List 100% (1/1)83%  (133/160)79%  (26/33)
<static initializer> 100% (1/1)100% (6/6)100% (2/2)
DefaultModletProcessor (): void 100% (1/1)100% (3/3)100% (2/2)
getDefaultTransformerLocation (): String 100% (1/1)100% (8/8)100% (3/3)
getMessage (String, Object []): String 100% (1/1)100% (12/12)100% (1/1)
getTransformerLocation (): String 100% (1/1)100% (9/9)100% (3/3)
isDefaultEnabled (): boolean 100% (1/1)100% (12/12)100% (3/3)
isEnabled (): boolean 100% (1/1)100% (11/11)100% (3/3)
setDefaultEnabled (Boolean): void 100% (1/1)100% (3/3)100% (2/2)
setDefaultTransformerLocation (String): void 100% (1/1)100% (3/3)100% (2/2)
setEnabled (Boolean): void 100% (1/1)100% (4/4)100% (2/2)
setTransformerLocation (String): void 100% (1/1)100% (4/4)100% (2/2)

1/*
2 *   Copyright (C) Christian Schulte, 2014-005
3 *   All rights reserved.
4 *
5 *   Redistribution and use in source and binary forms, with or without
6 *   modification, are permitted provided that the following conditions
7 *   are met:
8 *
9 *     o Redistributions of source code must retain the above copyright
10 *       notice, this list of conditions and the following disclaimer.
11 *
12 *     o Redistributions in binary form must reproduce the above copyright
13 *       notice, this list of conditions and the following disclaimer in
14 *       the documentation and/or other materials provided with the
15 *       distribution.
16 *
17 *   THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
18 *   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
19 *   AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20 *   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 *   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 *   NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 *   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 *   $JOMC: DefaultModletProcessor.java 4871 2014-02-17 18:00:51Z schulte $
29 *
30 */
31package org.jomc.modlet;
32 
33import java.net.URISyntaxException;
34import java.net.URL;
35import java.text.MessageFormat;
36import java.util.Enumeration;
37import java.util.LinkedList;
38import java.util.List;
39import java.util.Locale;
40import java.util.Map;
41import java.util.ResourceBundle;
42import java.util.logging.Level;
43import javax.xml.bind.JAXBContext;
44import javax.xml.bind.JAXBElement;
45import javax.xml.bind.JAXBException;
46import javax.xml.bind.util.JAXBResult;
47import javax.xml.bind.util.JAXBSource;
48import javax.xml.transform.ErrorListener;
49import javax.xml.transform.Transformer;
50import javax.xml.transform.TransformerConfigurationException;
51import javax.xml.transform.TransformerException;
52import javax.xml.transform.TransformerFactory;
53import javax.xml.transform.stream.StreamSource;
54 
55/**
56 * Default {@code ModletProcessor} implementation.
57 *
58 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
59 * @version $JOMC: DefaultModletProcessor.java 4871 2014-02-17 18:00:51Z schulte $
60 * @see ModelContext#processModlets(org.jomc.modlet.Modlets)
61 * @since 1.6
62 */
63public class DefaultModletProcessor implements ModletProcessor
64{
65 
66    /**
67     * Constant for the name of the model context attribute backing property {@code enabled}.
68     * @see #processModlets(org.jomc.modlet.ModelContext, org.jomc.modlet.Modlets)
69     * @see ModelContext#getAttribute(java.lang.String)
70     */
71    public static final String ENABLED_ATTRIBUTE_NAME = "org.jomc.modlet.DefaultModletProcessor.enabledAttribute";
72 
73    /**
74     * Constant for the name of the system property controlling property {@code defaultEnabled}.
75     * @see #isDefaultEnabled()
76     */
77    private static final String DEFAULT_ENABLED_PROPERTY_NAME =
78        "org.jomc.modlet.DefaultModletProcessor.defaultEnabled";
79 
80    /**
81     * Default value of the flag indicating the processor is enabled by default.
82     * @see #isDefaultEnabled()
83     */
84    private static final Boolean DEFAULT_ENABLED = Boolean.TRUE;
85 
86    /** Flag indicating the processor is enabled by default. */
87    private static volatile Boolean defaultEnabled;
88 
89    /** Flag indicating the processor is enabled. */
90    private Boolean enabled;
91 
92    /**
93     * Constant for the name of the system property controlling property {@code defaultOrdinal}.
94     * @see #getDefaultOrdinal()
95     */
96    private static final String DEFAULT_ORDINAL_PROPERTY_NAME =
97        "org.jomc.modlet.DefaultModletProcessor.defaultOrdinal";
98 
99    /**
100     * Default value of the ordinal number of the processor.
101     * @see #getDefaultOrdinal()
102     */
103    private static final Integer DEFAULT_ORDINAL = 0;
104 
105    /**
106     * Default ordinal number of the processor.
107     */
108    private static volatile Integer defaultOrdinal;
109 
110    /**
111     * Ordinal number of the processor.
112     */
113    private Integer ordinal;
114 
115    /**
116     * Constant for the name of the model context attribute backing property {@code transformerLocation}.
117     * @see #processModlets(org.jomc.modlet.ModelContext, org.jomc.modlet.Modlets)
118     * @see ModelContext#getAttribute(java.lang.String)
119     * @since 1.2
120     */
121    public static final String TRANSFORMER_LOCATION_ATTRIBUTE_NAME =
122        "org.jomc.modlet.DefaultModletProcessor.transformerLocationAttribute";
123 
124    /**
125     * Constant for the name of the system property controlling property {@code defaultTransformerLocation}.
126     * @see #getDefaultTransformerLocation()
127     */
128    private static final String DEFAULT_TRANSFORMER_LOCATION_PROPERTY_NAME =
129        "org.jomc.modlet.DefaultModletProcessor.defaultTransformerLocation";
130 
131    /**
132     * Class path location searched for transformers by default.
133     * @see #getDefaultTransformerLocation()
134     */
135    private static final String DEFAULT_TRANSFORMER_LOCATION = "META-INF/jomc-modlet.xsl";
136 
137    /** Default transformer location. */
138    private static volatile String defaultTransformerLocation;
139 
140    /** Transformer location of the instance. */
141    private String transformerLocation;
142 
143    /** Creates a new {@code DefaultModletProcessor} instance. */
144    public DefaultModletProcessor()
145    {
146        super();
147    }
148 
149    /**
150     * Gets a flag indicating the processor is enabled by default.
151     * <p>The default enabled flag is controlled by system property
152     * {@code org.jomc.modlet.DefaultModletProcessor.defaultEnabled} holding a value indicating the processor is
153     * enabled by default. If that property is not set, the {@code true} default is returned.</p>
154     *
155     * @return {@code true}, if the processor is enabled by default; {@code false}, if the processor is disabled by
156     * default.
157     *
158     * @see #isEnabled()
159     * @see #setDefaultEnabled(java.lang.Boolean)
160     */
161    public static boolean isDefaultEnabled()
162    {
163        if ( defaultEnabled == null )
164        {
165            defaultEnabled = Boolean.valueOf( System.getProperty(
166                DEFAULT_ENABLED_PROPERTY_NAME, Boolean.toString( DEFAULT_ENABLED ) ) );
167 
168        }
169 
170        return defaultEnabled;
171    }
172 
173    /**
174     * Sets the flag indicating the processor is enabled by default.
175     *
176     * @param value The new value of the flag indicating the processor is enabled by default or {@code null}.
177     *
178     * @see #isDefaultEnabled()
179     */
180    public static void setDefaultEnabled( final Boolean value )
181    {
182        defaultEnabled = value;
183    }
184 
185    /**
186     * Gets a flag indicating the processor is enabled.
187     *
188     * @return {@code true}, if the processor is enabled; {@code false}, if the processor is disabled.
189     *
190     * @see #isDefaultEnabled()
191     * @see #setEnabled(java.lang.Boolean)
192     */
193    public final boolean isEnabled()
194    {
195        if ( this.enabled == null )
196        {
197            this.enabled = isDefaultEnabled();
198        }
199 
200        return this.enabled;
201    }
202 
203    /**
204     * Sets the flag indicating the processor is enabled.
205     *
206     * @param value The new value of the flag indicating the processor is enabled or {@code null}.
207     *
208     * @see #isEnabled()
209     */
210    public final void setEnabled( final Boolean value )
211    {
212        this.enabled = value;
213    }
214 
215    /**
216     * Gets the default ordinal number of the processor.
217     * <p>The default ordinal number is controlled by system property
218     * {@code org.jomc.modlet.DefaultModletProvider.defaultOrdinal} holding the default ordinal number of the processor.
219     * If that property is not set, the {@code 0} default is returned.</p>
220     *
221     * @return The default ordinal number of the processor.
222     *
223     * @see #setDefaultOrdinal(java.lang.Integer)
224     */
225    public static int getDefaultOrdinal()
226    {
227        if ( defaultOrdinal == null )
228        {
229            defaultOrdinal = Integer.getInteger( DEFAULT_ORDINAL_PROPERTY_NAME, DEFAULT_ORDINAL );
230        }
231 
232        return defaultOrdinal;
233    }
234 
235    /**
236     * Sets the default ordinal number of the processor.
237     *
238     * @param value The new default ordinal number of the processor or {@code null}.
239     *
240     * @see #getDefaultOrdinal()
241     */
242    public static void setDefaultOrdinal( final Integer value )
243    {
244        defaultOrdinal = value;
245    }
246 
247    /**
248     * Gets the ordinal number of the processor.
249     *
250     * @return The ordinal number of the processor.
251     *
252     * @see #getDefaultOrdinal()
253     * @see #setOrdinal(java.lang.Integer)
254     */
255    public final int getOrdinal()
256    {
257        if ( this.ordinal == null )
258        {
259            this.ordinal = getDefaultOrdinal();
260        }
261 
262        return this.ordinal;
263    }
264 
265    /**
266     * Sets the ordinal number of the processor.
267     *
268     * @param value The new ordinal number of the processor or {@code null}.
269     *
270     * @see #getOrdinal()
271     */
272    public final void setOrdinal( final Integer value )
273    {
274        this.ordinal = value;
275    }
276 
277    /**
278     * Gets the default location searched for transformer resources.
279     * <p>The default transformer location is controlled by system property
280     * {@code org.jomc.modlet.DefaultModletProcessor.defaultTransformerLocation} holding the location to search
281     * for transformer resources by default. If that property is not set, the {@code META-INF/jomc-modlet.xsl} default
282     * is returned.</p>
283     *
284     * @return The location searched for transformer resources by default.
285     *
286     * @see #setDefaultTransformerLocation(java.lang.String)
287     */
288    public static String getDefaultTransformerLocation()
289    {
290        if ( defaultTransformerLocation == null )
291        {
292            defaultTransformerLocation =
293                System.getProperty( DEFAULT_TRANSFORMER_LOCATION_PROPERTY_NAME, DEFAULT_TRANSFORMER_LOCATION );
294 
295        }
296 
297        return defaultTransformerLocation;
298    }
299 
300    /**
301     * Sets the default location searched for transformer resources.
302     *
303     * @param value The new default location to search for transformer resources or {@code null}.
304     *
305     * @see #getDefaultTransformerLocation()
306     */
307    public static void setDefaultTransformerLocation( final String value )
308    {
309        defaultTransformerLocation = value;
310    }
311 
312    /**
313     * Gets the location searched for transformer resources.
314     *
315     * @return The location searched for transformer resources.
316     *
317     * @see #getDefaultTransformerLocation()
318     * @see #setTransformerLocation(java.lang.String)
319     */
320    public final String getTransformerLocation()
321    {
322        if ( this.transformerLocation == null )
323        {
324            this.transformerLocation = getDefaultTransformerLocation();
325        }
326 
327        return this.transformerLocation;
328    }
329 
330    /**
331     * Sets the location searched for transformer resources.
332     *
333     * @param value The new location to search for transformer resources or {@code null}.
334     *
335     * @see #getTransformerLocation()
336     */
337    public final void setTransformerLocation( final String value )
338    {
339        this.transformerLocation = value;
340    }
341 
342    /**
343     * Searches a given context for transformers.
344     *
345     * @param context The context to search for transformers.
346     * @param location The location to search at.
347     *
348     * @return The transformers found at {@code location} in {@code context} or {@code null}, if no transformers are
349     * found.
350     *
351     * @throws NullPointerException if {@code context} or {@code location} is {@code null}.
352     * @throws ModelException if getting the transformers fails.
353     */
354    public List<Transformer> findTransformers( final ModelContext context, final String location ) throws ModelException
355    {
356        if ( context == null )
357        {
358            throw new NullPointerException( "context" );
359        }
360        if ( location == null )
361        {
362            throw new NullPointerException( "location" );
363        }
364 
365        try
366        {
367            final long t0 = System.currentTimeMillis();
368            final List<Transformer> transformers = new LinkedList<Transformer>();
369            final TransformerFactory transformerFactory = TransformerFactory.newInstance();
370            final Enumeration<URL> resources = context.findResources( location );
371            final ErrorListener errorListener = new ErrorListener()
372            {
373 
374                public void warning( final TransformerException exception ) throws TransformerException
375                {
376                    if ( context.isLoggable( Level.WARNING ) )
377                    {
378                        context.log( Level.WARNING, getMessage( exception ), exception );
379                    }
380                }
381 
382                public void error( final TransformerException exception ) throws TransformerException
383                {
384                    if ( context.isLoggable( Level.SEVERE ) )
385                    {
386                        context.log( Level.SEVERE, getMessage( exception ), exception );
387                    }
388 
389                    throw exception;
390                }
391 
392                public void fatalError( final TransformerException exception ) throws TransformerException
393                {
394                    if ( context.isLoggable( Level.SEVERE ) )
395                    {
396                        context.log( Level.SEVERE, getMessage( exception ), exception );
397                    }
398 
399                    throw exception;
400                }
401 
402            };
403 
404            transformerFactory.setErrorListener( errorListener );
405 
406            int count = 0;
407            while ( resources.hasMoreElements() )
408            {
409                count++;
410                final URL url = resources.nextElement();
411 
412                if ( context.isLoggable( Level.FINEST ) )
413                {
414                    context.log( Level.FINEST, getMessage( "processing", url.toExternalForm() ), null );
415                }
416 
417                final Transformer transformer =
418                    transformerFactory.newTransformer( new StreamSource( url.toURI().toASCIIString() ) );
419 
420                transformer.setErrorListener( errorListener );
421 
422                for ( Map.Entry<Object, Object> e : System.getProperties().entrySet() )
423                {
424                    transformer.setParameter( e.getKey().toString(), e.getValue() );
425                }
426 
427                transformers.add( transformer );
428            }
429 
430            if ( context.isLoggable( Level.FINE ) )
431            {
432                context.log( Level.FINE, getMessage( "contextReport", count, location,
433                                                     Long.valueOf( System.currentTimeMillis() - t0 ) ), null );
434 
435            }
436 
437            return transformers.isEmpty() ? null : transformers;
438        }
439        catch ( final URISyntaxException e )
440        {
441            throw new ModelException( getMessage( e ), e );
442        }
443        catch ( final TransformerConfigurationException e )
444        {
445            String message = getMessage( e );
446            if ( message == null && e.getException() != null )
447            {
448                message = getMessage( e.getException() );
449            }
450 
451            throw new ModelException( message, e );
452        }
453    }
454 
455    /**
456     * {@inheritDoc}
457     *
458     * @see #isEnabled()
459     * @see #getTransformerLocation()
460     * @see #findTransformers(org.jomc.modlet.ModelContext, java.lang.String)
461     * @see #ENABLED_ATTRIBUTE_NAME
462     * @see #TRANSFORMER_LOCATION_ATTRIBUTE_NAME
463     */
464    public Modlets processModlets( final ModelContext context, final Modlets modlets ) throws ModelException
465    {
466        if ( context == null )
467        {
468            throw new NullPointerException( "context" );
469        }
470        if ( modlets == null )
471        {
472            throw new NullPointerException( "modlets" );
473        }
474 
475        try
476        {
477            Modlets processed = null;
478 
479            boolean contextEnabled = this.isEnabled();
480            if ( DEFAULT_ENABLED == contextEnabled
481                 && context.getAttribute( ENABLED_ATTRIBUTE_NAME ) instanceof Boolean )
482            {
483                contextEnabled = (Boolean) context.getAttribute( ENABLED_ATTRIBUTE_NAME );
484            }
485 
486            String contextTransformerLocation = this.getTransformerLocation();
487            if ( DEFAULT_TRANSFORMER_LOCATION.equals( contextTransformerLocation )
488                 && context.getAttribute( TRANSFORMER_LOCATION_ATTRIBUTE_NAME ) instanceof String )
489            {
490                contextTransformerLocation = (String) context.getAttribute( TRANSFORMER_LOCATION_ATTRIBUTE_NAME );
491            }
492 
493            if ( contextEnabled )
494            {
495                final org.jomc.modlet.ObjectFactory objectFactory = new org.jomc.modlet.ObjectFactory();
496                final JAXBContext jaxbContext = context.createContext( ModletObject.MODEL_PUBLIC_ID );
497                final List<Transformer> transformers = this.findTransformers( context, contextTransformerLocation );
498 
499                if ( transformers != null )
500                {
501                    processed = modlets.clone();
502 
503                    for ( int i = 0, s0 = transformers.size(); i < s0; i++ )
504                    {
505                        final JAXBElement<Modlets> e = objectFactory.createModlets( processed );
506                        final JAXBSource source = new JAXBSource( jaxbContext, e );
507                        final JAXBResult result = new JAXBResult( jaxbContext );
508                        transformers.get( i ).transform( source, result );
509 
510                        if ( result.getResult() instanceof JAXBElement<?>
511                             && ( (JAXBElement<?>) result.getResult() ).getValue() instanceof Modlets )
512                        {
513                            processed = (Modlets) ( (JAXBElement<?>) result.getResult() ).getValue();
514                        }
515                        else
516                        {
517                            throw new ModelException( getMessage( "illegalTransformationResult" ) );
518                        }
519                    }
520                }
521            }
522            else if ( context.isLoggable( Level.FINER ) )
523            {
524                context.log( Level.FINER, getMessage( "disabled", this.getClass().getSimpleName() ), null );
525            }
526 
527            return processed;
528        }
529        catch ( final TransformerException e )
530        {
531            String message = getMessage( e );
532            if ( message == null && e.getException() != null )
533            {
534                message = getMessage( e.getException() );
535            }
536 
537            throw new ModelException( message, e );
538        }
539        catch ( final JAXBException e )
540        {
541            String message = getMessage( e );
542            if ( message == null && e.getLinkedException() != null )
543            {
544                message = getMessage( e.getLinkedException() );
545            }
546 
547            throw new ModelException( message, e );
548        }
549    }
550 
551    private static String getMessage( final String key, final Object... args )
552    {
553        return MessageFormat.format( ResourceBundle.getBundle(
554            DefaultModletProcessor.class.getName().replace( '.', '/' ), Locale.getDefault() ).getString( key ), args );
555 
556    }
557 
558    private static String getMessage( final Throwable t )
559    {
560        return t != null
561               ? t.getMessage() != null && t.getMessage().trim().length() > 0
562                 ? t.getMessage()
563                 : getMessage( t.getCause() )
564               : null;
565 
566    }
567 
568}

[all classes][org.jomc.modlet]
EMMA 2.1.5320 (stable) (C) Vladimir Roubtsov