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

COVERAGE SUMMARY FOR SOURCE FILE [DefaultModelProcessor.java]

nameclass, %method, %block, %line, %
DefaultModelProcessor.java100% (2/2)74%  (14/19)70%  (354/506)71%  (77/108)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class DefaultModelProcessor$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)
DefaultModelProcessor$1 (DefaultModelProcessor, ModelContext): void 100% (1/1)100% (9/9)100% (1/1)
     
class DefaultModelProcessor100% (1/1)87%  (13/15)76%  (345/456)78%  (76/98)
access$000 (Throwable): String 0%   (0/1)0%   (0/3)0%   (0/1)
getMessage (Throwable): String 0%   (0/1)0%   (0/19)0%   (0/1)
processModel (ModelContext, Model): Model 100% (1/1)69%  (136/198)67%  (26/39)
findTransformers (ModelContext, String): List 100% (1/1)83%  (133/160)79%  (26/33)
<static initializer> 100% (1/1)100% (3/3)100% (1/1)
DefaultModelProcessor (): void 100% (1/1)100% (3/3)100% (2/2)
getDefaultTransformerLocation (): String 100% (1/1)100% (10/10)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% (14/14)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, 2005-206
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: DefaultModelProcessor.java 4760 2013-04-08 17:56:26Z schulte $
29 *
30 */
31package org.jomc.model.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;
54import org.jomc.modlet.Model;
55import org.jomc.modlet.ModelContext;
56import org.jomc.modlet.ModelException;
57import org.jomc.modlet.ModelProcessor;
58 
59/**
60 * Default object management and configuration {@code ModelProcessor} implementation.
61 *
62 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
63 * @version $JOMC: DefaultModelProcessor.java 4760 2013-04-08 17:56:26Z schulte $
64 * @see ModelContext#processModel(org.jomc.modlet.Model)
65 */
66public class DefaultModelProcessor implements ModelProcessor
67{
68 
69    /**
70     * Constant for the name of the model context attribute backing property {@code enabled}.
71     * @see #processModel(org.jomc.modlet.ModelContext, org.jomc.modlet.Model)
72     * @see ModelContext#getAttribute(java.lang.String)
73     * @since 1.2
74     */
75    public static final String ENABLED_ATTRIBUTE_NAME = "org.jomc.model.modlet.DefaultModelProcessor.enabledAttribute";
76 
77    /**
78     * Constant for the name of the system property controlling property {@code defaultEnabled}.
79     * @see #isDefaultEnabled()
80     */
81    private static final String DEFAULT_ENABLED_PROPERTY_NAME =
82        "org.jomc.model.modlet.DefaultModelProcessor.defaultEnabled";
83 
84    /**
85     * Constant for the name of the deprecated system property controlling property {@code defaultEnabled}.
86     * @see #isDefaultEnabled()
87     */
88    private static final String DEPRECATED_DEFAULT_ENABLED_PROPERTY_NAME =
89        "org.jomc.model.DefaultModelProcessor.defaultEnabled";
90 
91    /**
92     * Default value of the flag indicating the processor is enabled by default.
93     * @see #isDefaultEnabled()
94     * @since 1.2
95     */
96    private static final Boolean DEFAULT_ENABLED = Boolean.TRUE;
97 
98    /** Flag indicating the processor is enabled by default. */
99    private static volatile Boolean defaultEnabled;
100 
101    /** Flag indicating the processor is enabled. */
102    private Boolean enabled;
103 
104    /**
105     * Constant for the name of the model context attribute backing property {@code transformerLocation}.
106     * @see #processModel(org.jomc.modlet.ModelContext, org.jomc.modlet.Model)
107     * @see ModelContext#getAttribute(java.lang.String)
108     * @since 1.2
109     */
110    public static final String TRANSFORMER_LOCATION_ATTRIBUTE_NAME =
111        "org.jomc.model.modlet.DefaultModelProcessor.transformerLocationAttribute";
112 
113    /**
114     * Constant for the name of the system property controlling property {@code defaultTransformerLocation}.
115     * @see #getDefaultTransformerLocation()
116     */
117    private static final String DEFAULT_TRANSFORMER_LOCATION_PROPERTY_NAME =
118        "org.jomc.model.modlet.DefaultModelProcessor.defaultTransformerLocation";
119 
120    /**
121     * Constant for the name of the deprecated system property controlling property {@code defaultTransformerLocation}.
122     * @see #getDefaultTransformerLocation()
123     */
124    private static final String DEPRECATED_DEFAULT_TRANSFORMER_LOCATION_PROPERTY_NAME =
125        "org.jomc.model.DefaultModelProcessor.defaultTransformerLocation";
126 
127    /**
128     * Class path location searched for transformers by default.
129     * @see #getDefaultTransformerLocation()
130     */
131    private static final String DEFAULT_TRANSFORMER_LOCATION = "META-INF/jomc.xsl";
132 
133    /** Default transformer location. */
134    private static volatile String defaultTransformerLocation;
135 
136    /** Transformer location of the instance. */
137    private String transformerLocation;
138 
139    /** Creates a new {@code DefaultModelProcessor} instance. */
140    public DefaultModelProcessor()
141    {
142        super();
143    }
144 
145    /**
146     * Gets a flag indicating the processor is enabled by default.
147     * <p>The default enabled flag is controlled by system property
148     * {@code org.jomc.model.modlet.DefaultModelProcessor.defaultEnabled} holding a value indicating the processor is
149     * enabled by default. If that property is not set, the {@code true} default is returned.</p>
150     *
151     * @return {@code true}, if the processor is enabled by default; {@code false}, if the processor is disabled by
152     * default.
153     *
154     * @see #setDefaultEnabled(java.lang.Boolean)
155     */
156    public static boolean isDefaultEnabled()
157    {
158        if ( defaultEnabled == null )
159        {
160            defaultEnabled =
161                Boolean.valueOf( System.getProperty( DEFAULT_ENABLED_PROPERTY_NAME,
162                                                     System.getProperty( DEPRECATED_DEFAULT_ENABLED_PROPERTY_NAME,
163                                                                         Boolean.toString( DEFAULT_ENABLED ) ) ) );
164 
165        }
166 
167        return defaultEnabled;
168    }
169 
170    /**
171     * Sets the flag indicating the processor is enabled by default.
172     *
173     * @param value The new value of the flag indicating the processor is enabled by default or {@code null}.
174     *
175     * @see #isDefaultEnabled()
176     */
177    public static void setDefaultEnabled( final Boolean value )
178    {
179        defaultEnabled = value;
180    }
181 
182    /**
183     * Gets a flag indicating the processor is enabled.
184     *
185     * @return {@code true}, if the processor is enabled; {@code false}, if the processor is disabled.
186     *
187     * @see #isDefaultEnabled()
188     * @see #setEnabled(java.lang.Boolean)
189     */
190    public final boolean isEnabled()
191    {
192        if ( this.enabled == null )
193        {
194            this.enabled = isDefaultEnabled();
195        }
196 
197        return this.enabled;
198    }
199 
200    /**
201     * Sets the flag indicating the processor is enabled.
202     *
203     * @param value The new value of the flag indicating the processor is enabled or {@code null}.
204     *
205     * @see #isEnabled()
206     */
207    public final void setEnabled( final Boolean value )
208    {
209        this.enabled = value;
210    }
211 
212    /**
213     * Gets the default location searched for transformer resources.
214     * <p>The default transformer location is controlled by system property
215     * {@code org.jomc.model.modlet.DefaultModelProcessor.defaultTransformerLocation} holding the location to search for
216     * transformer resources by default. If that property is not set, the {@code META-INF/jomc.xsl} default is
217     * returned.</p>
218     *
219     * @return The location searched for transformer resources by default.
220     *
221     * @see #setDefaultTransformerLocation(java.lang.String)
222     */
223    public static String getDefaultTransformerLocation()
224    {
225        if ( defaultTransformerLocation == null )
226        {
227            defaultTransformerLocation =
228                System.getProperty( DEFAULT_TRANSFORMER_LOCATION_PROPERTY_NAME,
229                                    System.getProperty( DEPRECATED_DEFAULT_TRANSFORMER_LOCATION_PROPERTY_NAME,
230                                                        DEFAULT_TRANSFORMER_LOCATION ) );
231 
232        }
233 
234        return defaultTransformerLocation;
235    }
236 
237    /**
238     * Sets the default location searched for transformer resources.
239     *
240     * @param value The new default location to search for transformer resources or {@code null}.
241     *
242     * @see #getDefaultTransformerLocation()
243     */
244    public static void setDefaultTransformerLocation( final String value )
245    {
246        defaultTransformerLocation = value;
247    }
248 
249    /**
250     * Gets the location searched for transformer resources.
251     *
252     * @return The location searched for transformer resources.
253     *
254     * @see #getDefaultTransformerLocation()
255     * @see #setTransformerLocation(java.lang.String)
256     */
257    public final String getTransformerLocation()
258    {
259        if ( this.transformerLocation == null )
260        {
261            this.transformerLocation = getDefaultTransformerLocation();
262        }
263 
264        return this.transformerLocation;
265    }
266 
267    /**
268     * Sets the location searched for transformer resources.
269     *
270     * @param value The new location to search for transformer resources or {@code null}.
271     *
272     * @see #getTransformerLocation()
273     */
274    public final void setTransformerLocation( final String value )
275    {
276        this.transformerLocation = value;
277    }
278 
279    /**
280     * Searches a given context for transformers.
281     *
282     * @param context The context to search for transformers.
283     * @param location The location to search at.
284     *
285     * @return The transformers found at {@code location} in {@code context} or {@code null}, if no transformers are
286     * found.
287     *
288     * @throws NullPointerException if {@code context} or {@code location} is {@code null}.
289     * @throws ModelException if getting the transformers fails.
290     */
291    public List<Transformer> findTransformers( final ModelContext context, final String location ) throws ModelException
292    {
293        if ( context == null )
294        {
295            throw new NullPointerException( "context" );
296        }
297        if ( location == null )
298        {
299            throw new NullPointerException( "location" );
300        }
301 
302        try
303        {
304            final long t0 = System.currentTimeMillis();
305            final List<Transformer> transformers = new LinkedList<Transformer>();
306            final TransformerFactory transformerFactory = TransformerFactory.newInstance();
307            final Enumeration<URL> resources = context.findResources( location );
308            final ErrorListener errorListener = new ErrorListener()
309            {
310 
311                public void warning( final TransformerException exception ) throws TransformerException
312                {
313                    if ( context.isLoggable( Level.WARNING ) )
314                    {
315                        context.log( Level.WARNING, getMessage( exception ), exception );
316                    }
317                }
318 
319                public void error( final TransformerException exception ) throws TransformerException
320                {
321                    if ( context.isLoggable( Level.SEVERE ) )
322                    {
323                        context.log( Level.SEVERE, getMessage( exception ), exception );
324                    }
325 
326                    throw exception;
327                }
328 
329                public void fatalError( final TransformerException exception ) throws TransformerException
330                {
331                    if ( context.isLoggable( Level.SEVERE ) )
332                    {
333                        context.log( Level.SEVERE, getMessage( exception ), exception );
334                    }
335 
336                    throw exception;
337                }
338 
339            };
340 
341            transformerFactory.setErrorListener( errorListener );
342 
343            int count = 0;
344            while ( resources.hasMoreElements() )
345            {
346                count++;
347                final URL url = resources.nextElement();
348 
349                if ( context.isLoggable( Level.FINEST ) )
350                {
351                    context.log( Level.FINEST, getMessage( "processing", url.toExternalForm() ), null );
352                }
353 
354                final Transformer transformer =
355                    transformerFactory.newTransformer( new StreamSource( url.toURI().toASCIIString() ) );
356 
357                transformer.setErrorListener( errorListener );
358 
359                for ( Map.Entry<Object, Object> e : System.getProperties().entrySet() )
360                {
361                    transformer.setParameter( e.getKey().toString(), e.getValue() );
362                }
363 
364                transformers.add( transformer );
365            }
366 
367            if ( context.isLoggable( Level.FINE ) )
368            {
369                context.log( Level.FINE, getMessage( "contextReport", count, location,
370                                                     Long.valueOf( System.currentTimeMillis() - t0 ) ), null );
371 
372            }
373 
374            return transformers.isEmpty() ? null : transformers;
375        }
376        catch ( final URISyntaxException e )
377        {
378            throw new ModelException( getMessage( e ), e );
379        }
380        catch ( final TransformerConfigurationException e )
381        {
382            String message = getMessage( e );
383            if ( message == null && e.getException() != null )
384            {
385                message = getMessage( e.getException() );
386            }
387 
388            throw new ModelException( message, e );
389        }
390    }
391 
392    /**
393     * {@inheritDoc}
394     *
395     * @see #isEnabled()
396     * @see #getTransformerLocation()
397     * @see #findTransformers(org.jomc.modlet.ModelContext, java.lang.String)
398     * @see #ENABLED_ATTRIBUTE_NAME
399     * @see #TRANSFORMER_LOCATION_ATTRIBUTE_NAME
400     */
401    public Model processModel( final ModelContext context, final Model model ) throws ModelException
402    {
403        if ( context == null )
404        {
405            throw new NullPointerException( "context" );
406        }
407        if ( model == null )
408        {
409            throw new NullPointerException( "model" );
410        }
411 
412        try
413        {
414            Model processed = model;
415 
416            boolean contextEnabled = this.isEnabled();
417            if ( DEFAULT_ENABLED == contextEnabled
418                 && context.getAttribute( ENABLED_ATTRIBUTE_NAME ) instanceof Boolean )
419            {
420                contextEnabled = (Boolean) context.getAttribute( ENABLED_ATTRIBUTE_NAME );
421            }
422 
423            String contextTransformerLocation = this.getTransformerLocation();
424            if ( DEFAULT_TRANSFORMER_LOCATION.equals( contextTransformerLocation )
425                 && context.getAttribute( TRANSFORMER_LOCATION_ATTRIBUTE_NAME ) instanceof String )
426            {
427                contextTransformerLocation = (String) context.getAttribute( TRANSFORMER_LOCATION_ATTRIBUTE_NAME );
428            }
429 
430            if ( contextEnabled )
431            {
432                final org.jomc.modlet.ObjectFactory objectFactory = new org.jomc.modlet.ObjectFactory();
433                final JAXBContext jaxbContext = context.createContext( model.getIdentifier() );
434                final List<Transformer> transformers = this.findTransformers( context, contextTransformerLocation );
435                processed = model.clone();
436 
437                if ( transformers != null )
438                {
439                    for ( int i = 0, s0 = transformers.size(); i < s0; i++ )
440                    {
441                        final JAXBElement<Model> e = objectFactory.createModel( processed );
442                        final JAXBSource source = new JAXBSource( jaxbContext, e );
443                        final JAXBResult result = new JAXBResult( jaxbContext );
444                        transformers.get( i ).transform( source, result );
445 
446                        if ( result.getResult() instanceof JAXBElement<?>
447                             && ( (JAXBElement<?>) result.getResult() ).getValue() instanceof Model )
448                        {
449                            processed = (Model) ( (JAXBElement<?>) result.getResult() ).getValue();
450                        }
451                        else
452                        {
453                            throw new ModelException( getMessage(
454                                "illegalTransformationResult", model.getIdentifier() ) );
455 
456                        }
457                    }
458                }
459            }
460            else if ( context.isLoggable( Level.FINER ) )
461            {
462                context.log( Level.FINER, getMessage( "disabled", this.getClass().getSimpleName(),
463                                                      model.getIdentifier() ), null );
464 
465            }
466 
467            return processed;
468        }
469        catch ( final TransformerException e )
470        {
471            String message = getMessage( e );
472            if ( message == null && e.getException() != null )
473            {
474                message = getMessage( e.getException() );
475            }
476 
477            throw new ModelException( message, e );
478        }
479        catch ( final JAXBException e )
480        {
481            String message = getMessage( e );
482            if ( message == null && e.getLinkedException() != null )
483            {
484                message = getMessage( e.getLinkedException() );
485            }
486 
487            throw new ModelException( message, e );
488        }
489    }
490 
491    private static String getMessage( final String key, final Object... args )
492    {
493        return MessageFormat.format( ResourceBundle.getBundle(
494            DefaultModelProcessor.class.getName().replace( '.', '/' ), Locale.getDefault() ).getString( key ), args );
495 
496    }
497 
498    private static String getMessage( final Throwable t )
499    {
500        return t != null
501               ? t.getMessage() != null && t.getMessage().trim().length() > 0
502                 ? t.getMessage()
503                 : getMessage( t.getCause() )
504               : null;
505 
506    }
507 
508}

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