DefaultModletProvider.java

  1. /*
  2.  *   Copyright (C) Christian Schulte <cs@schulte.it>, 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: DefaultModletProvider.java 5043 2015-05-27 07:03:39Z schulte $
  29.  *
  30.  */
  31. package org.jomc.modlet;

  32. import java.net.URL;
  33. import java.text.MessageFormat;
  34. import java.util.Enumeration;
  35. import java.util.ResourceBundle;
  36. import java.util.logging.Level;
  37. import javax.xml.bind.JAXBContext;
  38. import javax.xml.bind.JAXBElement;
  39. import javax.xml.bind.JAXBException;
  40. import javax.xml.bind.UnmarshalException;
  41. import javax.xml.bind.Unmarshaller;

  42. /**
  43.  * Default {@code ModletProvider} implementation.
  44.  *
  45.  * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
  46.  * @version $JOMC: DefaultModletProvider.java 5043 2015-05-27 07:03:39Z schulte $
  47.  * @see ModelContext#findModlets(org.jomc.modlet.Modlets)
  48.  */
  49. public class DefaultModletProvider implements ModletProvider
  50. {

  51.     /**
  52.      * Constant for the name of the model context attribute backing property {@code enabled}.
  53.      *
  54.      * @see #findModlets(org.jomc.modlet.ModelContext, org.jomc.modlet.Modlets)
  55.      * @see ModelContext#getAttribute(java.lang.String)
  56.      * @since 1.2
  57.      */
  58.     public static final String ENABLED_ATTRIBUTE_NAME = "org.jomc.modlet.DefaultModletProvider.enabledAttribute";

  59.     /**
  60.      * Constant for the name of the system property controlling property {@code defaultEnabled}.
  61.      *
  62.      * @see #isDefaultEnabled()
  63.      * @since 1.2
  64.      */
  65.     private static final String DEFAULT_ENABLED_PROPERTY_NAME =
  66.         "org.jomc.modlet.DefaultModletProvider.defaultEnabled";

  67.     /**
  68.      * Default value of the flag indicating the provider is enabled by default.
  69.      *
  70.      * @see #isDefaultEnabled()
  71.      * @since 1.2
  72.      */
  73.     private static final Boolean DEFAULT_ENABLED = Boolean.TRUE;

  74.     /**
  75.      * Flag indicating the provider is enabled by default.
  76.      */
  77.     private static volatile Boolean defaultEnabled;

  78.     /**
  79.      * Flag indicating the provider is enabled.
  80.      */
  81.     private Boolean enabled;

  82.     /**
  83.      * Constant for the name of the model context attribute backing property {@code modletLocation}.
  84.      *
  85.      * @see #findModlets(org.jomc.modlet.ModelContext, org.jomc.modlet.Modlets)
  86.      * @see ModelContext#getAttribute(java.lang.String)
  87.      * @since 1.2
  88.      */
  89.     public static final String MODLET_LOCATION_ATTRIBUTE_NAME =
  90.         "org.jomc.modlet.DefaultModletProvider.modletLocationAttribute";

  91.     /**
  92.      * Constant for the name of the system property controlling property {@code defaultModletLocation}.
  93.      *
  94.      * @see #getDefaultModletLocation()
  95.      * @since 1.2
  96.      */
  97.     private static final String DEFAULT_MODLET_LOCATION_PROPERTY_NAME =
  98.         "org.jomc.modlet.DefaultModletProvider.defaultModletLocation";

  99.     /**
  100.      * Class path location searched for {@code Modlets} by default.
  101.      *
  102.      * @see #getDefaultModletLocation()
  103.      */
  104.     private static final String DEFAULT_MODLET_LOCATION = "META-INF/jomc-modlet.xml";

  105.     /**
  106.      * Default {@code Modlet} location.
  107.      */
  108.     private static volatile String defaultModletLocation;

  109.     /**
  110.      * Modlet location of the instance.
  111.      */
  112.     private String modletLocation;

  113.     /**
  114.      * Constant for the name of the model context attribute backing property {@code validating}.
  115.      *
  116.      * @see #findModlets(org.jomc.modlet.ModelContext, java.lang.String)
  117.      * @see ModelContext#getAttribute(java.lang.String)
  118.      * @since 1.2
  119.      */
  120.     public static final String VALIDATING_ATTRIBUTE_NAME =
  121.         "org.jomc.modlet.DefaultModletProvider.validatingAttribute";

  122.     /**
  123.      * Constant for the name of the system property controlling property {@code defaultValidating}.
  124.      *
  125.      * @see #isDefaultValidating()
  126.      * @since 1.2
  127.      */
  128.     private static final String DEFAULT_VALIDATING_PROPERTY_NAME =
  129.         "org.jomc.modlet.DefaultModletProvider.defaultValidating";

  130.     /**
  131.      * Default value of the flag indicating the provider is validating resources by default.
  132.      *
  133.      * @see #isDefaultValidating()
  134.      * @since 1.2
  135.      */
  136.     private static final Boolean DEFAULT_VALIDATING = Boolean.TRUE;

  137.     /**
  138.      * Flag indicating the provider is validating resources by default.
  139.      *
  140.      * @since 1.2
  141.      */
  142.     private static volatile Boolean defaultValidating;

  143.     /**
  144.      * Flag indicating the provider is validating resources.
  145.      *
  146.      * @since 1.2
  147.      */
  148.     private Boolean validating;

  149.     /**
  150.      * Constant for the name of the system property controlling property {@code defaultOrdinal}.
  151.      *
  152.      * @see #getDefaultOrdinal()
  153.      * @since 1.6
  154.      */
  155.     private static final String DEFAULT_ORDINAL_PROPERTY_NAME =
  156.         "org.jomc.modlet.DefaultModletProvider.defaultOrdinal";

  157.     /**
  158.      * Default value of the ordinal number of the provider.
  159.      *
  160.      * @see #getDefaultOrdinal()
  161.      * @since 1.6
  162.      */
  163.     private static final Integer DEFAULT_ORDINAL = 0;

  164.     /**
  165.      * Default ordinal number of the provider.
  166.      *
  167.      * @since 1.6
  168.      */
  169.     private static volatile Integer defaultOrdinal;

  170.     /**
  171.      * Ordinal number of the provider.
  172.      *
  173.      * @since 1.6
  174.      */
  175.     private Integer ordinal;

  176.     /**
  177.      * Creates a new {@code DefaultModletProvider} instance.
  178.      */
  179.     public DefaultModletProvider()
  180.     {
  181.         super();
  182.     }

  183.     /**
  184.      * Gets a flag indicating the provider is enabled by default.
  185.      * <p>
  186.      * The default enabled flag is controlled by system property
  187.      * {@code org.jomc.modlet.DefaultModletProvider.defaultEnabled} holding a value indicating the provider is
  188.      * enabled by default. If that property is not set, the {@code true} default is returned.
  189.      * </p>
  190.      *
  191.      * @return {@code true}, if the provider is enabled by default; {@code false}, if the provider is disabled by
  192.      * default.
  193.      *
  194.      * @see #isEnabled()
  195.      * @see #setDefaultEnabled(java.lang.Boolean)
  196.      */
  197.     public static boolean isDefaultEnabled()
  198.     {
  199.         if ( defaultEnabled == null )
  200.         {
  201.             defaultEnabled = Boolean.valueOf( System.getProperty(
  202.                 DEFAULT_ENABLED_PROPERTY_NAME, Boolean.toString( DEFAULT_ENABLED ) ) );

  203.         }

  204.         return defaultEnabled;
  205.     }

  206.     /**
  207.      * Sets the flag indicating the provider is enabled by default.
  208.      *
  209.      * @param value The new value of the flag indicating the provider is enabled by default or {@code null}.
  210.      *
  211.      * @see #isDefaultEnabled()
  212.      */
  213.     public static void setDefaultEnabled( final Boolean value )
  214.     {
  215.         defaultEnabled = value;
  216.     }

  217.     /**
  218.      * Gets a flag indicating the provider is enabled.
  219.      *
  220.      * @return {@code true}, if the provider is enabled; {@code false}, if the provider is disabled.
  221.      *
  222.      * @see #isDefaultEnabled()
  223.      * @see #setEnabled(java.lang.Boolean)
  224.      */
  225.     public final boolean isEnabled()
  226.     {
  227.         if ( this.enabled == null )
  228.         {
  229.             this.enabled = isDefaultEnabled();
  230.         }

  231.         return this.enabled;
  232.     }

  233.     /**
  234.      * Sets the flag indicating the provider is enabled.
  235.      *
  236.      * @param value The new value of the flag indicating the provider is enabled or {@code null}.
  237.      *
  238.      * @see #isEnabled()
  239.      */
  240.     public final void setEnabled( final Boolean value )
  241.     {
  242.         this.enabled = value;
  243.     }

  244.     /**
  245.      * Gets the default location searched for {@code Modlet} resources.
  246.      * <p>
  247.      * The default {@code Modlet} location is controlled by system property
  248.      * {@code org.jomc.modlet.DefaultModletProvider.defaultModletLocation} holding the location to search for
  249.      * {@code Modlet} resources by default. If that property is not set, the {@code META-INF/jomc-modlet.xml} default is
  250.      * returned.
  251.      * </p>
  252.      *
  253.      * @return The location searched for {@code Modlet} resources by default.
  254.      *
  255.      * @see #setDefaultModletLocation(java.lang.String)
  256.      */
  257.     public static String getDefaultModletLocation()
  258.     {
  259.         if ( defaultModletLocation == null )
  260.         {
  261.             defaultModletLocation = System.getProperty(
  262.                 DEFAULT_MODLET_LOCATION_PROPERTY_NAME, DEFAULT_MODLET_LOCATION );

  263.         }

  264.         return defaultModletLocation;
  265.     }

  266.     /**
  267.      * Sets the default location searched for {@code Modlet} resources.
  268.      *
  269.      * @param value The new default location to search for {@code Modlet} resources or {@code null}.
  270.      *
  271.      * @see #getDefaultModletLocation()
  272.      */
  273.     public static void setDefaultModletLocation( final String value )
  274.     {
  275.         defaultModletLocation = value;
  276.     }

  277.     /**
  278.      * Gets the location searched for {@code Modlet} resources.
  279.      *
  280.      * @return The location searched for {@code Modlet} resources.
  281.      *
  282.      * @see #getDefaultModletLocation()
  283.      * @see #setModletLocation(java.lang.String)
  284.      */
  285.     public final String getModletLocation()
  286.     {
  287.         if ( this.modletLocation == null )
  288.         {
  289.             this.modletLocation = getDefaultModletLocation();
  290.         }

  291.         return this.modletLocation;
  292.     }

  293.     /**
  294.      * Sets the location searched for {@code Modlet} resources.
  295.      *
  296.      * @param value The new location to search for {@code Modlet} resources or {@code null}.
  297.      *
  298.      * @see #getModletLocation()
  299.      */
  300.     public final void setModletLocation( final String value )
  301.     {
  302.         this.modletLocation = value;
  303.     }

  304.     /**
  305.      * Gets a flag indicating the provider is validating resources by default.
  306.      * <p>
  307.      * The default validating flag is controlled by system property
  308.      * {@code org.jomc.modlet.DefaultModletProvider.defaultValidating} holding a value indicating the provider is
  309.      * validating resources by default. If that property is not set, the {@code true} default is returned.
  310.      * </p>
  311.      *
  312.      * @return {@code true}, if the provider is validating resources by default; {@code false}, if the provider is not
  313.      * validating resources by default.
  314.      *
  315.      * @see #isValidating()
  316.      * @see #setDefaultValidating(java.lang.Boolean)
  317.      *
  318.      * @since 1.2
  319.      */
  320.     public static boolean isDefaultValidating()
  321.     {
  322.         if ( defaultValidating == null )
  323.         {
  324.             defaultValidating = Boolean.valueOf( System.getProperty(
  325.                 DEFAULT_VALIDATING_PROPERTY_NAME, Boolean.toString( DEFAULT_VALIDATING ) ) );

  326.         }

  327.         return defaultValidating;
  328.     }

  329.     /**
  330.      * Sets the flag indicating the provider is validating resources by default.
  331.      *
  332.      * @param value The new value of the flag indicating the provider is validating resources by default or
  333.      * {@code null}.
  334.      *
  335.      * @see #isDefaultValidating()
  336.      *
  337.      * @since 1.2
  338.      */
  339.     public static void setDefaultValidating( final Boolean value )
  340.     {
  341.         defaultValidating = value;
  342.     }

  343.     /**
  344.      * Gets a flag indicating the provider is validating resources.
  345.      *
  346.      * @return {@code true}, if the provider is validating resources; {@code false}, if the provider is not validating
  347.      * resources.
  348.      *
  349.      * @see #isDefaultValidating()
  350.      * @see #setValidating(java.lang.Boolean)
  351.      *
  352.      * @since 1.2
  353.      */
  354.     public final boolean isValidating()
  355.     {
  356.         if ( this.validating == null )
  357.         {
  358.             this.validating = isDefaultValidating();
  359.         }

  360.         return this.validating;
  361.     }

  362.     /**
  363.      * Sets the flag indicating the provider is validating resources.
  364.      *
  365.      * @param value The new value of the flag indicating the provider is validating resources or {@code null}.
  366.      *
  367.      * @see #isValidating()
  368.      *
  369.      * @since 1.2
  370.      */
  371.     public final void setValidating( final Boolean value )
  372.     {
  373.         this.validating = value;
  374.     }

  375.     /**
  376.      * Gets the default ordinal number of the provider.
  377.      * <p>
  378.      * The default ordinal number is controlled by system property
  379.      * {@code org.jomc.modlet.DefaultModletProvider.defaultOrdinal} holding the default ordinal number of the provider.
  380.      * If that property is not set, the {@code 0} default is returned.
  381.      * </p>
  382.      *
  383.      * @return The default ordinal number of the provider.
  384.      *
  385.      * @see #setDefaultOrdinal(java.lang.Integer)
  386.      *
  387.      * @since 1.6
  388.      */
  389.     public static int getDefaultOrdinal()
  390.     {
  391.         if ( defaultOrdinal == null )
  392.         {
  393.             defaultOrdinal = Integer.getInteger( DEFAULT_ORDINAL_PROPERTY_NAME, DEFAULT_ORDINAL );
  394.         }

  395.         return defaultOrdinal;
  396.     }

  397.     /**
  398.      * Sets the default ordinal number of the provider.
  399.      *
  400.      * @param value The new default ordinal number of the provider or {@code null}.
  401.      *
  402.      * @see #getDefaultOrdinal()
  403.      *
  404.      * @since 1.6
  405.      */
  406.     public static void setDefaultOrdinal( final Integer value )
  407.     {
  408.         defaultOrdinal = value;
  409.     }

  410.     /**
  411.      * Gets the ordinal number of the provider.
  412.      *
  413.      * @return The ordinal number of the provider.
  414.      *
  415.      * @see #getDefaultOrdinal()
  416.      * @see #setOrdinal(java.lang.Integer)
  417.      *
  418.      * @since 1.6
  419.      */
  420.     public final int getOrdinal()
  421.     {
  422.         if ( this.ordinal == null )
  423.         {
  424.             this.ordinal = getDefaultOrdinal();
  425.         }

  426.         return this.ordinal;
  427.     }

  428.     /**
  429.      * Sets the ordinal number of the provider.
  430.      *
  431.      * @param value The new ordinal number of the provider or {@code null}.
  432.      *
  433.      * @see #getOrdinal()
  434.      *
  435.      * @since 1.6
  436.      */
  437.     public final void setOrdinal( final Integer value )
  438.     {
  439.         this.ordinal = value;
  440.     }

  441.     /**
  442.      * Searches a given context for {@code Modlets}.
  443.      *
  444.      * @param context The context to search for {@code Modlets}.
  445.      * @param location The location to search at.
  446.      *
  447.      * @return The {@code Modlets} found at {@code location} in {@code context} or {@code null}, if no {@code Modlets}
  448.      * are found.
  449.      *
  450.      * @throws NullPointerException if {@code context} or {@code location} is {@code null}.
  451.      * @throws ModelException if searching the context fails.
  452.      *
  453.      * @see #isValidating()
  454.      * @see #VALIDATING_ATTRIBUTE_NAME
  455.      */
  456.     public Modlets findModlets( final ModelContext context, final String location ) throws ModelException
  457.     {
  458.         if ( context == null )
  459.         {
  460.             throw new NullPointerException( "context" );
  461.         }
  462.         if ( location == null )
  463.         {
  464.             throw new NullPointerException( "location" );
  465.         }

  466.         URL url = null;

  467.         try
  468.         {
  469.             boolean contextValidating = this.isValidating();
  470.             if ( DEFAULT_VALIDATING == contextValidating
  471.                      && context.getAttribute( VALIDATING_ATTRIBUTE_NAME ) instanceof Boolean )
  472.             {
  473.                 contextValidating = (Boolean) context.getAttribute( VALIDATING_ATTRIBUTE_NAME );
  474.             }

  475.             Modlets modlets = null;
  476.             final long t0 = System.currentTimeMillis();
  477.             final JAXBContext ctx = context.createContext( ModletObject.MODEL_PUBLIC_ID );
  478.             final Unmarshaller u = ctx.createUnmarshaller();
  479.             final Enumeration<URL> e = context.findResources( location );

  480.             if ( contextValidating )
  481.             {
  482.                 u.setSchema( context.createSchema( ModletObject.MODEL_PUBLIC_ID ) );
  483.             }

  484.             while ( e.hasMoreElements() )
  485.             {
  486.                 url = e.nextElement();
  487.                 Object content = u.unmarshal( url );
  488.                 if ( content instanceof JAXBElement<?> )
  489.                 {
  490.                     content = ( (JAXBElement<?>) content ).getValue();
  491.                 }

  492.                 if ( content instanceof Modlet )
  493.                 {
  494.                     if ( modlets == null )
  495.                     {
  496.                         modlets = new Modlets();
  497.                     }

  498.                     modlets.getModlet().add( (Modlet) content );
  499.                 }
  500.                 else if ( content instanceof Modlets )
  501.                 {
  502.                     if ( modlets == null )
  503.                     {
  504.                         modlets = new Modlets();
  505.                     }

  506.                     modlets.getModlet().addAll( ( (Modlets) content ).getModlet() );
  507.                 }
  508.             }

  509.             if ( context.isLoggable( Level.FINE ) )
  510.             {
  511.                 context.log( Level.FINE, getMessage( "contextReport",
  512.                                                      modlets != null ? modlets.getModlet().size() : 0,
  513.                                                      location, System.currentTimeMillis() - t0 ), null );

  514.             }

  515.             return modlets == null || modlets.getModlet().isEmpty() ? null : modlets;
  516.         }
  517.         catch ( final UnmarshalException e )
  518.         {
  519.             String message = getMessage( e );
  520.             if ( message == null && e.getLinkedException() != null )
  521.             {
  522.                 message = getMessage( e.getLinkedException() );
  523.             }

  524.             if ( url != null )
  525.             {
  526.                 message = getMessage( "unmarshalException", url.toExternalForm(),
  527.                                       message != null ? " " + message : "" );

  528.             }

  529.             throw new ModelException( message, e );
  530.         }
  531.         catch ( final JAXBException e )
  532.         {
  533.             String message = getMessage( e );
  534.             if ( message == null && e.getLinkedException() != null )
  535.             {
  536.                 message = getMessage( e.getLinkedException() );
  537.             }

  538.             throw new ModelException( message, e );
  539.         }
  540.     }

  541.     /**
  542.      * {@inheritDoc}
  543.      *
  544.      * @return The {@code Modlets} found in the context or {@code null}, if no {@code Modlets} are found or the provider
  545.      * is disabled.
  546.      *
  547.      * @see #isEnabled()
  548.      * @see #getModletLocation()
  549.      * @see #findModlets(org.jomc.modlet.ModelContext, java.lang.String)
  550.      * @see #ENABLED_ATTRIBUTE_NAME
  551.      * @see #MODLET_LOCATION_ATTRIBUTE_NAME
  552.      * @deprecated As of JOMC 1.6, this method has been replaced by {@link #findModlets(org.jomc.modlet.ModelContext, org.jomc.modlet.Modlets)}.
  553.      * This method will be removed in JOMC 2.0.
  554.      */
  555.     @Deprecated
  556.     public Modlets findModlets( final ModelContext context ) throws ModelException
  557.     {
  558.         if ( context == null )
  559.         {
  560.             throw new NullPointerException( "context" );
  561.         }

  562.         return this.findModlets( context, new Modlets() );
  563.     }

  564.     /**
  565.      * {@inheritDoc}
  566.      *
  567.      * @return The {@code Modlets} found in the context or {@code null}, if no {@code Modlets} are found or the provider
  568.      * is disabled.
  569.      *
  570.      * @see #isEnabled()
  571.      * @see #getModletLocation()
  572.      * @see #findModlets(org.jomc.modlet.ModelContext, java.lang.String)
  573.      * @see #ENABLED_ATTRIBUTE_NAME
  574.      * @see #MODLET_LOCATION_ATTRIBUTE_NAME
  575.      * @since 1.6
  576.      */
  577.     public Modlets findModlets( final ModelContext context, final Modlets modlets ) throws ModelException
  578.     {
  579.         if ( context == null )
  580.         {
  581.             throw new NullPointerException( "context" );
  582.         }
  583.         if ( modlets == null )
  584.         {
  585.             throw new NullPointerException( "context" );
  586.         }

  587.         Modlets provided = null;

  588.         boolean contextEnabled = this.isEnabled();
  589.         if ( DEFAULT_ENABLED == contextEnabled && context.getAttribute( ENABLED_ATTRIBUTE_NAME ) instanceof Boolean )
  590.         {
  591.             contextEnabled = (Boolean) context.getAttribute( ENABLED_ATTRIBUTE_NAME );
  592.         }

  593.         String contextModletLocation = this.getModletLocation();
  594.         if ( DEFAULT_MODLET_LOCATION.equals( contextModletLocation )
  595.                  && context.getAttribute( MODLET_LOCATION_ATTRIBUTE_NAME ) instanceof String )
  596.         {
  597.             contextModletLocation = (String) context.getAttribute( MODLET_LOCATION_ATTRIBUTE_NAME );
  598.         }

  599.         if ( contextEnabled )
  600.         {
  601.             final Modlets found = this.findModlets( context, contextModletLocation );

  602.             if ( found != null )
  603.             {
  604.                 provided = modlets.clone();
  605.                 provided.getModlet().addAll( found.getModlet() );
  606.             }
  607.         }
  608.         else if ( context.isLoggable( Level.FINER ) )
  609.         {
  610.             context.log( Level.FINER, getMessage( "disabled", this.getClass().getSimpleName() ), null );
  611.         }

  612.         return provided;
  613.     }

  614.     private static String getMessage( final String key, final Object... arguments )
  615.     {
  616.         return MessageFormat.format( ResourceBundle.getBundle(
  617.             DefaultModletProvider.class.getName().replace( '.', '/' ) ).getString( key ), arguments );

  618.     }

  619.     private static String getMessage( final Throwable t )
  620.     {
  621.         return t != null
  622.                    ? t.getMessage() != null && t.getMessage().trim().length() > 0
  623.                          ? t.getMessage()
  624.                          : getMessage( t.getCause() )
  625.                    : null;

  626.     }

  627. }