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 }