View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one
    3    * or more contributor license agreements.  See the NOTICE file
    4    * distributed with this work for additional information
    5    * regarding copyright ownership.  The ASF licenses this file
    6    * to you under the Apache License, Version 2.0 (the
    7    * "License"); you may not use this file except in compliance
    8    * with the License.  You may obtain a copy of the License at
    9    *
    10   *   http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing,
    13   * software distributed under the License is distributed on an
    14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    15   * KIND, either express or implied.  See the License for the
    16   * specific language governing permissions and limitations
    17   * under the License.
    18   */
    19
    20  package org.apache.myfaces.shared_orchestra.config;
    21
    22  import org.apache.commons.logging.Log;
    23  import org.apache.commons.logging.LogFactory;
    24
    25  import org.apache.myfaces.shared_orchestra.util.ClassUtils;
    26  import javax.faces.context.ExternalContext;
    27  import javax.servlet.ServletContext;
    28
    29  /**
    30   * Holds all configuration init parameters (from web.xml) that are independent
    31   * from the core implementation. The parameters in this class are available to
    32   * all shared, component and implementation classes.
    33   * See RuntimeConfig for configuration infos that come from the faces-config
    34   * files and are needed by the core implementation.
    35   *
    36   * MyfacesConfig is meant for components that implement some of the extended features
    37   * of MyFaces. Anyhow, using the MyFaces JSF implementation is no precondition for using
    38   * MyfacesConfig in custom components. Upon using another JSF implementation
    39   * (or omitting the extended init parameters) all config properties will simply have
    40   * their default values.
    41   *
    42   * @author Manfred Geiler (latest modification by $Author: lu4242 $)
    43   * @version $Revision: 682429 $ $Date: 2008-08-04 10:55:32 -0500 (Mon, 04 Aug 2008) $
    44   */
    45  public class MyfacesConfig
    46  {
    47      private static final Log log = LogFactory.getLog(MyfacesConfig.class);
    48
    49      private static final String APPLICATION_MAP_PARAM_NAME = MyfacesConfig.class.getName();
    50
    51      public static final String INIT_PARAM_CONFIG_REFRESH_PERIOD = "org.apache.myfaces.CONFIG_REFRESH_PERIOD";
    52      public static final long INIT_PARAM_CONFIG_REFRESH_PERIOD_DEFAULT = 2;
    53
    54      public static final String  INIT_PARAM_RESOURCE_VIRTUAL_PATH = "org.apache.myfaces.RESOURCE_VIRTUAL_PATH";
    55      public static final String  INIT_PARAM_RESOURCE_VIRTUAL_PATH_DEFAULT = "/faces/myFacesExtensionResource";
    56
    57      private static final String  INIT_PARAM_PRETTY_HTML = "org.apache.myfaces.PRETTY_HTML";
    58      private static final boolean INIT_PARAM_PRETTY_HTML_DEFAULT = true;
    59
    60      private static final String  INIT_PARAM_ALLOW_JAVASCRIPT = "org.apache.myfaces.ALLOW_JAVASCRIPT";
    61      private static final boolean INIT_PARAM_ALLOW_JAVASCRIPT_DEFAULT = true;
    62
    63      private static final String  INIT_PARAM_DETECT_JAVASCRIPT = "org.apache.myfaces.DETECT_JAVASCRIPT";
    64      private static final boolean INIT_PARAM_DETECT_JAVASCRIPT_DEFAULT = false;
    65
    66      private static final String  INIT_PARAM_AUTO_SCROLL = "org.apache.myfaces.AUTO_SCROLL";
    67      private static final boolean INIT_PARAM_AUTO_SCROLL_DEFAULT = false;
    68
    69      private static final String INIT_PARAM_ADD_RESOURCE_CLASS = "org.apache.myfaces.ADD_RESOURCE_CLASS";
    70      private static final String INIT_PARAM_ADD_RESOURCE_CLASS_DEFAULT = "org.apache.myfaces.renderkit.html.util.DefaultAddResource";
    71
    72      private static final String  INIT_CHECK_EXTENSIONS_FILTER = "org.apache.myfaces.CHECK_EXTENSIONS_FILTER";
    73      private static final boolean INIT_CHECK_EXTENSIONS_FILTER_DEFAULT = true;
    74
    75      private static final String INIT_READONLY_AS_DISABLED_FOR_SELECT = "org.apache.myfaces.READONLY_AS_DISABLED_FOR_SELECTS";
    76      private static final boolean INIT_READONLY_AS_DISABLED_FOR_SELECT_DEFAULT = true;
    77
    78      private static final String  INIT_PARAM_RENDER_VIEWSTATE_ID = "org.apache.myfaces.RENDER_VIEWSTATE_ID";
    79      private static final boolean INIT_PARAM_RENDER_VIEWSTATE_ID_DEFAULT = true;
    80
    81      private static final String  INIT_PARAM_STRICT_XHTML_LINKS = "org.apache.myfaces.STRICT_XHTML_LINKS";
    82      private static final boolean INIT_PARAM_STRICT_XHTML_LINKS_DEFAULT = true;
    83
    84      private boolean _prettyHtml;
    85      private boolean _detectJavascript;
    86      private boolean _allowJavascript;
    87      private boolean _autoScroll;
    88      private long _configRefreshPeriod;
    89      private String _addResourceClass;
    90      private String _resourceVirtualPath;
    91      private boolean _checkExtensionsFilter;
    92      private boolean _readonlyAsDisabledForSelect;
    93      private boolean _renderViewStateId;
    94      private boolean _strictXhtmlLinks;
    95
    96      private static final boolean TOMAHAWK_AVAILABLE;
    97      private static final boolean MYFACES_IMPL_AVAILABLE;
    98      private static final boolean RI_IMPL_AVAILABLE;
    99
    100     static
    101     {
    102         boolean tomahawkAvailable;
    103         try
    104         {
    105             ClassUtils.classForName("org.apache.myfaces.webapp.filter.ExtensionsFilter");
    106             tomahawkAvailable = true;
    107         }
    108         catch (ClassNotFoundException e)
    109         {
    110             tomahawkAvailable = false;
    111         }
    112         TOMAHAWK_AVAILABLE = tomahawkAvailable;
    113     }
    114
    115     static
    116     {
    117         boolean myfacesImplAvailable;
    118         try
    119         {
    120             ClassUtils.classForName("org.apache.myfaces.application.ApplicationImpl");
    121             myfacesImplAvailable = true;
    122         }
    123         catch (ClassNotFoundException e)
    124         {
    125             myfacesImplAvailable = false;
    126         }
    127         MYFACES_IMPL_AVAILABLE = myfacesImplAvailable;
    128     }
    129
    130     static
    131     {
    132         boolean riImplAvailable;
    133         try
    134         {
    135             ClassUtils.classForName("com.sun.faces.application.ApplicationImpl");
    136             riImplAvailable = true;
    137         }
    138         catch (ClassNotFoundException e)
    139         {
    140             riImplAvailable = false;
    141         }
    142         RI_IMPL_AVAILABLE = riImplAvailable;
    143     }
    144
    145     public static MyfacesConfig getCurrentInstance(ExternalContext extCtx)
    146     {
    147         MyfacesConfig myfacesConfig = (MyfacesConfig)extCtx
    148                                         .getApplicationMap().get(APPLICATION_MAP_PARAM_NAME);
    149         if (myfacesConfig == null)
    150         {
    151
    152             myfacesConfig = createAndInitializeMyFacesConfig(extCtx);
    153
    154             extCtx.getApplicationMap().put(APPLICATION_MAP_PARAM_NAME, myfacesConfig);
    155
    156         }
    157
    158         return myfacesConfig;
    159     }
    160
    161     private static MyfacesConfig createAndInitializeMyFacesConfig(ExternalContext extCtx) {
    162         MyfacesConfig myfacesConfig = new MyfacesConfig();
    163
    164         myfacesConfig.setPrettyHtml(getBooleanInitParameter(extCtx, INIT_PARAM_PRETTY_HTML,
    165                                                             INIT_PARAM_PRETTY_HTML_DEFAULT));
    166         myfacesConfig.setAllowJavascript(getBooleanInitParameter(extCtx, INIT_PARAM_ALLOW_JAVASCRIPT,
    167                                                                  INIT_PARAM_ALLOW_JAVASCRIPT_DEFAULT));
    168
    169         myfacesConfig.setReadonlyAsDisabledForSelect(getBooleanInitParameter(extCtx, INIT_READONLY_AS_DISABLED_FOR_SELECT,
    170                                                                  INIT_READONLY_AS_DISABLED_FOR_SELECT_DEFAULT));
    171         myfacesConfig.setRenderViewStateId(getBooleanInitParameter(extCtx, INIT_PARAM_RENDER_VIEWSTATE_ID,
    172                                                                    INIT_PARAM_RENDER_VIEWSTATE_ID_DEFAULT));
    173         myfacesConfig.setStrictXhtmlLinks(getBooleanInitParameter(extCtx, INIT_PARAM_STRICT_XHTML_LINKS,
    174                                                                   INIT_PARAM_STRICT_XHTML_LINKS_DEFAULT));
    175
    176         myfacesConfig.setConfigRefreshPeriod(getLongInitParameter(extCtx, INIT_PARAM_CONFIG_REFRESH_PERIOD,
    177                 INIT_PARAM_CONFIG_REFRESH_PERIOD_DEFAULT));
    178
    179         if (TOMAHAWK_AVAILABLE)
    180         {
    181             myfacesConfig.setDetectJavascript(getBooleanInitParameter(extCtx, INIT_PARAM_DETECT_JAVASCRIPT,
    182                 INIT_PARAM_DETECT_JAVASCRIPT_DEFAULT));
    183             myfacesConfig.setAutoScroll(getBooleanInitParameter(extCtx, INIT_PARAM_AUTO_SCROLL,
    184                     INIT_PARAM_AUTO_SCROLL_DEFAULT));
    185             myfacesConfig.setAddResourceClass(getStringInitParameter(extCtx, INIT_PARAM_ADD_RESOURCE_CLASS,
    186                                                                      INIT_PARAM_ADD_RESOURCE_CLASS_DEFAULT));
    187             myfacesConfig.setResourceVirtualPath(getStringInitParameter(extCtx, INIT_PARAM_RESOURCE_VIRTUAL_PATH,
    188                     INIT_PARAM_RESOURCE_VIRTUAL_PATH_DEFAULT));
    189
    190             myfacesConfig.setCheckExtensionsFilter(getBooleanInitParameter(extCtx, INIT_CHECK_EXTENSIONS_FILTER,
    191                     INIT_CHECK_EXTENSIONS_FILTER_DEFAULT));
    192         }
    193         else
    194         {
    195             if (log.isInfoEnabled())
    196             {
    197                 log.info("Tomahawk jar not available. Autoscrolling, DetectJavascript, AddResourceClass and CheckExtensionsFilter are disabled now.");
    198             }
    199         }
    200
    201         if(RI_IMPL_AVAILABLE)
    202         {
    203             if(log.isInfoEnabled())
    204             {
    205                 log.info("Starting up Tomahawk on the RI-JSF-Implementation.");
    206             }
    207         }
    208
    209         if(MYFACES_IMPL_AVAILABLE)
    210         {
    211             if(log.isInfoEnabled())
    212             {
    213                 log.info("Starting up Tomahawk on the MyFaces-JSF-Implementation");
    214             }
    215         }
    216
    217         if(RI_IMPL_AVAILABLE && MYFACES_IMPL_AVAILABLE)
    218         {
    219             log.error("Both MyFaces and the RI are on your classpath. Please make sure to use only one of the two JSF-implementations.");
    220         }
    221         return myfacesConfig;
    222     }
    223
    224     private static boolean getBooleanInitParameter(ExternalContext externalContext,
    225                                                    String paramName,
    226                                                    boolean defaultValue)
    227     {
    228         String strValue = externalContext.getInitParameter(paramName);
    229         if (strValue == null)
    230         {
    231             if (log.isInfoEnabled()) log.info("No context init parameter '" + paramName + "' found, using default value " + defaultValue);
    232             return defaultValue;
    233         }
    234         else if (strValue.equalsIgnoreCase("true") || strValue.equalsIgnoreCase("on") || strValue.equalsIgnoreCase("yes"))
    235         {
    236             return true;
    237         }
    238         else if (strValue.equalsIgnoreCase("false") || strValue.equalsIgnoreCase("off") || strValue.equalsIgnoreCase("no"))
    239         {
    240             return false;
    241         }
    242         else
    243         {
    244             if (log.isWarnEnabled()) log.warn("Wrong context init parameter '" + paramName + "' (='" + strValue + "'), using default value " + defaultValue);
    245             return defaultValue;
    246         }
    247     }
    248
    249     private static long getLongInitParameter(ExternalContext externalContext,
    250                                                    String paramName,
    251                                                    long defaultValue)
    252     {
    253         String strValue = externalContext.getInitParameter(paramName);
    254         if (strValue == null)
    255         {
    256             if (log.isInfoEnabled()) log.info("No context init parameter '" + paramName + "' found, using default value " + defaultValue);
    257             return defaultValue;
    258         }
    259         else
    260         {
    261             try {
    262                 return Long.parseLong(strValue);
    263             } catch (NumberFormatException e) {
    264                 if (log.isWarnEnabled()) log.warn("Wrong context init parameter '" + paramName + "' (='" + strValue + "'), using default value " + defaultValue);
    265             }
    266             return defaultValue;
    267         }
    268     }
    269
    270     private static String getStringInitParameter(ExternalContext externalContext,
    271                                                  String paramName,
    272                                                  String defaultValue)
    273     {
    274         String strValue = externalContext.getInitParameter(paramName);
    275         if (strValue == null)
    276         {
    277             if (log.isInfoEnabled()) log.info("No context init parameter '" + paramName + "' found, using default value " + defaultValue); //defaultValue==null should not be a problem here
    278             return defaultValue;
    279         }
    280         else
    281         {
    282             return strValue;
    283         }
    284     }
    285
    286      private void setResourceVirtualPath( String resourceVirtualPath )
    287      {
    288          this._resourceVirtualPath = resourceVirtualPath;
    289      }
    290
    291      public String getResourceVirtualPath()
    292      {
    293          return this._resourceVirtualPath;
    294      }
    295
    296     public boolean isPrettyHtml()
    297     {
    298         return _prettyHtml;
    299     }
    300
    301     private void setPrettyHtml(boolean prettyHtml)
    302     {
    303         _prettyHtml = prettyHtml;
    304     }
    305
    306     public boolean isDetectJavascript()
    307     {
    308         return _detectJavascript;
    309     }
    310
    311     private void setDetectJavascript(boolean detectJavascript)
    312     {
    313         _detectJavascript = detectJavascript;
    314     }
    315
    316     private void setReadonlyAsDisabledForSelect(boolean readonlyAsDisabledForSelect)
    317     {
    318         _readonlyAsDisabledForSelect = readonlyAsDisabledForSelect;
    319     }
    320
    321     public boolean isReadonlyAsDisabledForSelect()
    322     {
    323         return _readonlyAsDisabledForSelect;
    324     }
    325
    326     /**
    327      * JSF API 1.2 defines a "javax.faces.ViewState" client parameter, that must be rendered as both the "name"
    328      * and the "id" attribute of the hidden input that is rendered for the purpose of state saving
    329      * (see <a href="http://java.sun.com/javaee/javaserverfaces/1.2/docs/api/javax/faces/render/ResponseStateManager.html#VIEW_STATE_PARAM">API</a>).
    330      * Actually this causes duplicate id attributes and thus invalid XHTML pages when multiple forms are rendered on
    331      * one page. With the {@link #INIT_PARAM_RENDER_VIEWSTATE_ID} context parameter you can tune this behaviour.
    332      * <br/>Set it to
    333      * <ul><li>true - to render JSF 1.2 compliant id attributes (that might cause invalid XHTML), or</li>
    334      * <li>false - to omit rendering of the id attribute (which is only needed for very special AJAX/Javascript components)</li></ul>
    335      * Default value is: true (for backwards compatibility and JSF 1.2 compliancy)
    336      * @return true, if the client state hidden input "javax.faces.ViewState" id attribute should be rendered
    337      */
    338     public boolean isRenderViewStateId() {
    339         return _renderViewStateId;
    340     }
    341
    342     public void setRenderViewStateId(boolean renderViewStateId) {
    343         _renderViewStateId = renderViewStateId;
    344     }
    345
    346     /**
    347      * <p>W3C recommends to use the "&amp;amp;" entity instead of a plain "&amp;" character within HTML.
    348      * This also applies to attribute values and thus to the "href" attribute of &lt;a&gt; elements as well.
    349      * Even more, when XHTML is used as output the usage of plain "&amp;" characters is forbidden and would lead to
    350      * invalid XML code.
    351      * Therefore, since version 1.1.6 MyFaces renders the correct "&amp;amp;" entity for links.</p>
    352      * <p>The init parameter
    353      * {@link #INIT_PARAM_STRICT_XHTML_LINKS} makes it possible to restore the old behaviour and to make MyFaces
    354      * "bug compatible" to the Sun RI which renders plain "&amp;" chars in links as well.</p>
    355      * @see <a href="http://www.w3.org/TR/html401/charset.html#h-5.3.2">HTML 4.01 Specification</a>
    356      * @see <a href="http://issues.apache.org/jira/browse/MYFACES-1774">Jira: MYFACES-1774</a>
    357      * @return true if ampersand characters ("&amp;") should be correctly rendered as "&amp;amp;" entities within link urls (=default),
    358      *         false for old (XHTML incompatible) behaviour
    359      */
    360     public boolean isStrictXhtmlLinks() {
    361         return _strictXhtmlLinks;
    362     }
    363
    364     public void setStrictXhtmlLinks(boolean strictXhtmlLinks) {
    365         _strictXhtmlLinks = strictXhtmlLinks;
    366     }
    367
    368     public boolean isTomahawkAvailable()
    369     {
    370         return TOMAHAWK_AVAILABLE;
    371     }
    372
    373     public boolean isMyfacesImplAvailable()
    374     {
    375         return MYFACES_IMPL_AVAILABLE;
    376     }
    377
    378     public boolean isRiImplAvailable()
    379     {
    380         return RI_IMPL_AVAILABLE;
    381     }
    382
    383     /**
    384      * Do not use this in renderers directly!
    385      * You should use {@link org.apache.myfaces.shared_orchestra.renderkit.html.util.JavascriptUtils#isJavascriptAllowed}
    386      * to determine if javascript is allowed or not.
    387      */
    388     public boolean isAllowJavascript()
    389     {
    390         return _allowJavascript;
    391     }
    392
    393     private void setAllowJavascript(boolean allowJavascript)
    394     {
    395         _allowJavascript = allowJavascript;
    396     }
    397
    398     public boolean isAutoScroll()
    399     {
    400         return _autoScroll;
    401     }
    402
    403     private void setAutoScroll(boolean autoScroll)
    404     {
    405         _autoScroll = autoScroll;
    406     }
    407
    408     private void setAddResourceClass(String addResourceClass)
    409     {
    410         _addResourceClass = addResourceClass;
    411     }
    412
    413     public String getAddResourceClass()
    414     {
    415         return _addResourceClass;
    416     }
    417
    418     /**
    419      * ExtensionFilter needs access to AddResourceClass init param without having
    420      * an ExternalContext at hand.
    421      */
    422     public static String getAddResourceClassFromServletContext(ServletContext servletContext)
    423     {
    424         String addResourceClass = servletContext.getInitParameter(INIT_PARAM_ADD_RESOURCE_CLASS);
    425         if (addResourceClass == null)
    426         {
    427             return INIT_PARAM_ADD_RESOURCE_CLASS_DEFAULT;
    428         }
    429         else
    430         {
    431             return addResourceClass;
    432         }
    433     }
    434
    435     /**
    436      * Should the environment be checked so that the ExtensionsFilter will work properly.
    437      */
    438     public boolean isCheckExtensionsFilter()
    439     {
    440         return _checkExtensionsFilter;
    441     }
    442
    443     public void setCheckExtensionsFilter(boolean extensionsFilter)
    444     {
    445         _checkExtensionsFilter = extensionsFilter;
    446     }
    447
    448     public long getConfigRefreshPeriod() {
    449         return _configRefreshPeriod;
    450     }
    451
    452     public void setConfigRefreshPeriod(long configRefreshPeriod) {
    453         _configRefreshPeriod = configRefreshPeriod;
    454     }
    455 }