View Javadoc

    1   // ========================================================================
    2   // $Id: Configuration.java 3680 2008-09-21 10:37:13Z janb $
    3   // Copyright 2006 Mort Bay Consulting Pty. Ltd.
    4   // ------------------------------------------------------------------------
    5   // Licensed under the Apache License, Version 2.0 (the "License");
    6   // you may not use this file except in compliance with the License.
    7   // You may obtain a copy of the License at
    8   // http://www.apache.org/licenses/LICENSE-2.0
    9   // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  // ========================================================================
    15
    16  package org.mortbay.jetty.plus.webapp;
    17
    18  import java.util.Random;
    19
    20  import javax.naming.Context;
    21  import javax.naming.InitialContext;
    22  import javax.naming.NameNotFoundException;
    23
    24  import org.mortbay.jetty.plus.naming.EnvEntry;
    25  import org.mortbay.jetty.plus.naming.Link;
    26  import org.mortbay.jetty.plus.naming.NamingEntry;
    27  import org.mortbay.jetty.plus.naming.NamingEntryUtil;
    28  import org.mortbay.jetty.plus.naming.Transaction;
    29  import org.mortbay.log.Log;
    30  import org.mortbay.naming.NamingUtil;
    31
    32
    33  /**
    34   * Configuration
    35   *
    36   *
    37   */
    38  public class Configuration extends AbstractConfiguration
    39  {
    40
    41      private Integer _key;
    42
    43
    44      public Configuration ()
    45      {
    46
    47      }
    48
    49      /**
    50       * @see org.mortbay.jetty.plus.webapp.AbstractConfiguration#bindEnvEntry(java.lang.String, java.lang.String)
    51       * @param name
    52       * @param value
    53       * @throws Exception
    54       */
    55      public void bindEnvEntry(String name, Object value) throws Exception
    56      {
    57          InitialContext ic = null;
    58          boolean bound = false;
    59          //check to see if we bound a value and an EnvEntry with this name already
    60          //when we processed the server and the webapp's naming environment
    61          //@see EnvConfiguration.bindEnvEntries()
    62          ic = new InitialContext();
    63          try
    64          {
    65              NamingEntry ne = (NamingEntry)ic.lookup("java:comp/env/"+NamingEntryUtil.makeNamingEntryName(ic.getNameParser(""), name));
    66              if (ne!=null && ne instanceof EnvEntry)
    67              {
    68                  EnvEntry ee = (EnvEntry)ne;
    69                  bound = ee.isOverrideWebXml();
    70              }
    71          }
    72          catch (NameNotFoundException e)
    73          {
    74              bound = false;
    75          }
    76
    77          if (!bound)
    78          {
    79              //either nothing was bound or the value from web.xml should override
    80              Context envCtx = (Context)ic.lookup("java:comp/env");
    81              NamingUtil.bind(envCtx, name, value);
    82          }
    83      }
    84
    85      /**
    86       * Bind a resource reference.
    87       *
    88       * If a resource reference with the same name is in a jetty-env.xml
    89       * file, it will already have been bound.
    90       *
    91       * @see org.mortbay.jetty.plus.webapp.AbstractConfiguration#bindResourceRef(java.lang.String)
    92       * @param name
    93       * @throws Exception
    94       */
    95      public void bindResourceRef(String name, Class typeClass)
    96      throws Exception
    97      {
    98          bindEntry(name, typeClass);
    99      }
    100
    101     /**
    102      * @see org.mortbay.jetty.plus.webapp.AbstractConfiguration#bindResourceEnvRef(java.lang.String)
    103      * @param name
    104      * @throws Exception
    105      */
    106     public void bindResourceEnvRef(String name, Class typeClass)
    107     throws Exception
    108     {
    109         bindEntry(name, typeClass);
    110     }
    111
    112
    113     public void bindMessageDestinationRef(String name, Class typeClass)
    114     throws Exception
    115     {
    116         bindEntry(name, typeClass);
    117     }
    118
    119     public void bindUserTransaction ()
    120     throws Exception
    121     {
    122         try
    123         {
    124            Transaction.bindToENC();
    125         }
    126         catch (NameNotFoundException e)
    127         {
    128             Log.info("No Transaction manager found - if your webapp requires one, please configure one.");
    129         }
    130     }
    131
    132     public void configureClassLoader ()
    133     throws Exception
    134     {
    135         super.configureClassLoader();
    136     }
    137
    138
    139     public void configureDefaults ()
    140     throws Exception
    141     {
    142         super.configureDefaults();
    143     }
    144
    145
    146     public void configureWebApp ()
    147     throws Exception
    148     {
    149         super.configureWebApp();
    150         //lock this webapp's java:comp namespace as per J2EE spec
    151         ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
    152         Thread.currentThread().setContextClassLoader(getWebAppContext().getClassLoader());
    153         lockCompEnv();
    154         Thread.currentThread().setContextClassLoader(oldLoader);
    155     }
    156
    157     public void deconfigureWebApp() throws Exception
    158     {
    159         ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
    160         Thread.currentThread().setContextClassLoader(getWebAppContext().getClassLoader());
    161         unlockCompEnv();
    162         Thread.currentThread().setContextClassLoader(oldLoader);
    163         super.deconfigureWebApp();
    164     }
    165
    166     protected void lockCompEnv ()
    167     throws Exception
    168     {
    169         Random random = new Random ();
    170         _key = new Integer(random.nextInt());
    171         Context context = new InitialContext();
    172         Context compCtx = (Context)context.lookup("java:comp");
    173         compCtx.addToEnvironment("org.mortbay.jndi.lock", _key);
    174     }
    175
    176     protected void unlockCompEnv ()
    177     throws Exception
    178     {
    179         if (_key!=null)
    180         {
    181             Context context = new InitialContext();
    182             Context compCtx = (Context)context.lookup("java:comp");
    183             compCtx.addToEnvironment("org.mortbay.jndi.unlock", _key);
    184         }
    185     }
    186
    187     /**
    188      * @see org.mortbay.jetty.plus.webapp.AbstractConfiguration#parseAnnotations()
    189      */
    190     public void parseAnnotations() throws Exception
    191     {
    192         Log.info(getClass().getName()+" does not support annotations on source. Use org.mortbay.jetty.annotations.Configuration instead");
    193     }
    194
    195     /**
    196      * Bind a resource with the given name from web.xml of the given type
    197      * with a jndi resource from either the server or the webapp's naming
    198      * environment.
    199      *
    200      * As the servlet spec does not cover the mapping of names in web.xml with
    201      * names from the execution environment, jetty uses the concept of a Link, which is
    202      * a subclass of the NamingEntry class. A Link defines a mapping of a name
    203      * from web.xml with a name from the execution environment (ie either the server or the
    204      * webapp's naming environment).
    205      *
    206      * @param name name of the resource from web.xml
    207      * @param typeClass
    208      * @throws Exception
    209      */
    210     private void bindEntry (String name, Class typeClass)
    211     throws Exception
    212     {
    213         String nameInEnvironment = name;
    214         boolean bound = false;
    215
    216         //check if the name in web.xml has been mapped to something else
    217         //check a context-specific naming environment first
    218         Object scope = getWebAppContext();
    219         NamingEntry ne = NamingEntryUtil.lookupNamingEntry(scope, name);
    220
    221         if (ne!=null && (ne instanceof Link))
    222         {
    223             //if we found a mapping, get out name it is mapped to in the environment
    224             nameInEnvironment = (String)((Link)ne).getObjectToBind();
    225             Link l = (Link)ne;
    226         }
    227
    228         //try finding that mapped name in the webapp's environment first
    229         scope = getWebAppContext();
    230         bound = NamingEntryUtil.bindToENC(scope, name, nameInEnvironment);
    231
    232         if (bound)
    233             return;
    234
    235         //try the server's environment
    236         scope = getWebAppContext().getServer();
    237         bound = NamingEntryUtil.bindToENC(scope, name, nameInEnvironment);
    238         if (bound)
    239             return;
    240
    241         //try the jvm environment
    242         bound = NamingEntryUtil.bindToENC(null, name, nameInEnvironment);
    243         if (bound)
    244             return;
    245
    246
    247         //There is no matching resource so try a default name.
    248         //The default name syntax is: the [res-type]/default
    249         //eg       javax.sql.DataSource/default
    250         nameInEnvironment = typeClass.getName()+"/default";
    251         //First try the server scope
    252         NamingEntry defaultNE = NamingEntryUtil.lookupNamingEntry(getWebAppContext().getServer(), nameInEnvironment);
    253         if (defaultNE==null)
    254             defaultNE = NamingEntryUtil.lookupNamingEntry(null, nameInEnvironment);
    255
    256         if (defaultNE!=null)
    257             defaultNE.bindToENC(name);
    258         else
    259             throw new IllegalStateException("Nothing to bind for name "+nameInEnvironment);
    260     }
    261 }