KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > web > AbstractWebDeployer


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.web;
23
24 import java.net.MalformedURLException JavaDoc;
25 import java.net.URL JavaDoc;
26 import java.net.URLClassLoader JavaDoc;
27 import java.util.ArrayList JavaDoc;
28 import java.util.HashSet JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.Set JavaDoc;
31 import java.security.Policy JavaDoc;
32 import javax.management.MBeanServer JavaDoc;
33 import javax.naming.Context JavaDoc;
34 import javax.naming.InitialContext JavaDoc;
35 import javax.naming.LinkRef JavaDoc;
36 import javax.naming.NamingException JavaDoc;
37 import javax.security.jacc.PolicyConfiguration JavaDoc;
38 import javax.security.jacc.PolicyConfigurationFactory JavaDoc;
39 import javax.security.jacc.PolicyContextException JavaDoc;
40
41 import org.jboss.deployment.DeploymentException;
42 import org.jboss.deployment.DeploymentInfo;
43 import org.jboss.deployment.J2eeApplicationMetaData;
44 import org.jboss.ejb.Container;
45 import org.jboss.ejb.EjbUtil;
46 import org.jboss.logging.Logger;
47 import org.jboss.metadata.EjbLocalRefMetaData;
48 import org.jboss.metadata.EjbRefMetaData;
49 import org.jboss.metadata.EnvEntryMetaData;
50 import org.jboss.metadata.MessageDestinationMetaData;
51 import org.jboss.metadata.MessageDestinationRefMetaData;
52 import org.jboss.metadata.ResourceEnvRefMetaData;
53 import org.jboss.metadata.ResourceRefMetaData;
54 import org.jboss.metadata.WebMetaData;
55 import org.jboss.mx.loading.LoaderRepositoryFactory;
56 import org.jboss.mx.util.MBeanProxyExt;
57 import org.jboss.naming.NonSerializableFactory;
58 import org.jboss.naming.Util;
59 import org.jboss.security.AuthorizationManager;
60 import org.jboss.security.authorization.PolicyRegistration;
61 import org.jboss.security.plugins.AuthorizationManagerServiceMBean;
62 import org.jboss.web.AbstractWebContainer.WebDescriptorParser;
63 import org.jboss.webservice.ServiceRefHandler;
64 import org.jboss.webservice.ServiceRefHandlerFactory;
65 import org.omg.CORBA.ORB JavaDoc;
66
67 /** A template pattern class for web deployer integration into JBoss. This class
68 should be subclasses by war deployers providers wishing to integrate into
69 a JBoss server.
70
71 It provides support for mapping the following web-app.xml/jboss-web.xml elements
72 into the JBoss server JNDI namespace:
73 - env-entry
74 - resource-ref
75 - resource-env-ref
76 - ejb-ref
77 - ejb-local-ref
78 - security-domain
79
80 Subclasses need to implement the {@link #performDeploy(WebApplication, String,
81  WebDescriptorParser) performDeploy()}
82 and {@link #performUndeploy(String, WebApplication) performUndeploy()} methods to perform the
83 container specific steps and return the web application info required by the
84 AbstractWebContainer class.
85
86 Integration with the JBossSX security framework is based on the establishment
87 of a java:comp/env/security context as described in the
88 {@link #linkSecurityDomain(String,Context) linkSecurityDomain } comments.
89 The security context provides access to the JBossSX security mgr interface
90 implementations for use by subclass request interceptors. A outline of the
91 steps for authenticating a user is:
92 <code>
93    // Get the username & password from the request context...
94    String username = f(request);
95    String password = f(request);
96    // Get the JBoss security manager from the ENC context
97    InitialContext iniCtx = new InitialContext();
98    SecurityManager securityMgr = (SecurityManager) iniCtx.lookup("java:comp/env/security/securityMgr");
99    SimplePrincipal principal = new SimplePrincipal(username);
100    if( securityMgr.isValid(principal, password) )
101    {
102    // Indicate the user is allowed access to the web content...
103
104    // Propagate the user info to JBoss for any calls into made by the servlet
105    SecurityAssociation.setPrincipal(principal);
106    SecurityAssociation.setCredential(password.toCharArray());
107    }
108    else
109    {
110    // Deny access...
111    }
112 </code>
113
114 An outline of the steps for authorizing the user is:
115 <code>
116    // Get the username & required roles from the request context...
117    String username = f(request);
118    String[] roles = f(request);
119    // Get the JBoss security manager from the ENC context
120    InitialContext iniCtx = new InitialContext();
121    RealmMapping securityMgr = (RealmMapping) iniCtx.lookup("java:comp/env/security/realmMapping");
122    SimplePrincipal principal = new SimplePrincipal(username);
123    Set requiredRoles = new HashSet(Arrays.asList(roles));
124    if( securityMgr.doesUserHaveRole(principal, requiredRoles) )
125    {
126    // Indicate the user has the required roles for the web content...
127    }
128    else
129    {
130    // Deny access...
131    }
132 </code>
133
134 The one thing to be aware of is the relationship between the thread context
135 class loader and the JNDI ENC context. Any method that attempts to access
136 the JNDI ENC context must have the ClassLoader in the WebApplication returned
137 from the {@link #performDeploy(WebApplication, String, WebDescriptorParser) performDeploy} as its thread
138 context ClassLoader or else the lookup for java:comp/env will fail with a
139 name not found exception, or worse, it will receive some other web application
140 ENC context. If your adapting a web container that is trying be compatible with
141 both 1.1 and 1.2 Java VMs this is something you need to pay special attention
142 to. For example, I have seen problems a request interceptor that was handling
143 the authentication/authorization callouts in tomcat3.2.1 not having the same
144 thread context ClassLoader as was used to dispatch the http service request.
145
146 @see #performDeploy(WebApplication webApp, String warUrl,
147         WebDescriptorParser webAppParser)
148 @see #performUndeploy(String, WebApplication)
149 @see #parseWebAppDescriptors(DeploymentInfo,ClassLoader, WebMetaData)
150 @see #linkSecurityDomain(String, Context)
151 @see org.jboss.security.RealmMapping;
152 @see org.jboss.security.SimplePrincipal;
153 @see org.jboss.security.SecurityAssociation;
154
155 @deprecated see org.jboss.web.deployers.AbstractWarDeployment
156
157
158 @author Scott.Stark@jboss.org
159 @version $Revision: 58116 $
160 */

161 public abstract class AbstractWebDeployer
162 {
163    public static final String JavaDoc ERROR = "org.jboss.web.AbstractWebContainer.error";
164    protected Logger log;
165
166    protected MBeanServer JavaDoc server;
167    /**
168     * The parent class loader first model flag
169     */

170    protected boolean java2ClassLoadingCompliance = false;
171    /**
172     * A flag indicating if war archives should be unpacked
173     */

174    protected boolean unpackWars = true;
175    /**
176     * If true, ejb-links that don't resolve don't cause an error (fallback to
177     * jndi-name)
178     */

179    protected boolean lenientEjbLink = false;
180
181    /**
182     * The default security-domain name to use
183     */

184    protected String JavaDoc defaultSecurityDomain;
185
186    public AbstractWebDeployer()
187    {
188       log = Logger.getLogger(getClass());
189    }
190
191    public abstract void init(Object JavaDoc containerConfig) throws Exception JavaDoc;
192
193    public MBeanServer JavaDoc getServer()
194    {
195       return server;
196    }
197
198    public void setServer(MBeanServer JavaDoc server)
199    {
200       this.server = server;
201    }
202
203    /**
204     * Get the flag indicating if the normal Java2 parent first class loading
205     * model should be used over the servlet 2.3 web container first model.
206     * @return true for parent first, false for the servlet 2.3 model
207     * @jmx.managed-attribute
208     */

209    public boolean getJava2ClassLoadingCompliance()
210    {
211       return java2ClassLoadingCompliance;
212    }
213
214    /**
215     * Set the flag indicating if the normal Java2 parent first class loading
216     * model should be used over the servlet 2.3 web container first model.
217     * @param flag true for parent first, false for the servlet 2.3 model
218     * @jmx.managed-attribute
219     */

220    public void setJava2ClassLoadingCompliance(boolean flag)
221    {
222       java2ClassLoadingCompliance = flag;
223    }
224
225    /**
226     * Get the flag indicating if war archives should be unpacked. This may need
227     * to be set to false as long extraction paths under deploy can show up as
228     * deployment failures on some platforms.
229     * @return true is war archives should be unpacked
230     * @jmx.managed-attribute
231     */

232    public boolean getUnpackWars()
233    {
234       return unpackWars;
235    }
236
237    /**
238     * Get the flag indicating if war archives should be unpacked. This may need
239     * to be set to false as long extraction paths under deploy can show up as
240     * deployment failures on some platforms.
241     * @param flag , true is war archives should be unpacked
242     * @jmx.managed-attribute
243     */

244    public void setUnpackWars(boolean flag)
245    {
246       this.unpackWars = flag;
247    }
248
249    /**
250     * Get the flag indicating if ejb-link errors should be ignored in favour of
251     * trying the jndi-name in jboss-web.xml
252     * @return a <code>boolean</code> value
253     * @jmx.managed-attribute
254     */

255    public boolean getLenientEjbLink()
256    {
257       return lenientEjbLink;
258    }
259
260    /**
261     * Set the flag indicating if ejb-link errors should be ignored in favour of
262     * trying the jndi-name in jboss-web.xml
263     * @jmx.managed-attribute
264     */

265    public void setLenientEjbLink(boolean flag)
266    {
267       lenientEjbLink = flag;
268    }
269
270    /**
271     * Get the default security domain implementation to use if a war does not
272     * declare a security-domain.
273     * @return jndi name of the security domain binding to use.
274     * @jmx.managed-attribute
275     */

276    public String JavaDoc getDefaultSecurityDomain()
277    {
278       return defaultSecurityDomain;
279    }
280
281    /**
282     * Set the default security domain implementation to use if a war does not
283     * declare a security-domain.
284     * @param defaultSecurityDomain - jndi name of the security domain binding to
285     * use.
286     * @jmx.managed-attribute
287     */

288    public void setDefaultSecurityDomain(String JavaDoc defaultSecurityDomain)
289    {
290       this.defaultSecurityDomain = defaultSecurityDomain;
291    }
292
293    /**
294     * A template pattern implementation of the deploy() method. This method
295     * calls the {@link #performDeploy(WebApplication, String,
296       * WebDescriptorParser) performDeploy()} method to perform the container
297     * specific deployment steps and registers the returned WebApplication in the
298     * deployment map. The steps performed are:
299     *
300     * ClassLoader appClassLoader = thread.getContextClassLoader();
301     * URLClassLoader warLoader = URLClassLoader.newInstance(empty,
302     * appClassLoader); thread.setContextClassLoader(warLoader);
303     * WebDescriptorParser webAppParser = ...; WebMetaData metaData =
304     * di.metaData; // Create JACC permissions, contextID, etc. ...
305     * WebApplication warInfo = new WebApplication(metaData);
306     * performDeploy(warInfo, warUrl, webAppParser); deploymentMap.put(warUrl,
307     * warInfo); thread.setContextClassLoader(appClassLoader);
308     *
309     * The subclass performDeploy() implementation needs to invoke
310     * webAppParser.parseWebAppDescriptors(loader, warInfo) to have the JNDI
311     * java:comp/env namespace setup before any web app component can access this
312     * namespace.
313     *
314     * Also, an MBean for each servlet deployed should be created and its JMX
315     * ObjectName placed into the DeploymentInfo.mbeans list so that the JSR77
316     * layer can create the approriate model view. The servlet MBean needs to
317     * provide access to the min, max and total time in milliseconds. Expose this
318     * information via MinServiceTime, MaxServiceTime and TotalServiceTime
319     * attributes to integrate seemlessly with the JSR77 factory layer.
320     * @param di The deployment info that contains the context-root element value
321     * from the J2EE application/module/web application.xml descriptor. This may
322     * be null if war was is not being deployed as part of an enterprise
323     * application. It also contains the URL of the web application war.
324     */

325    public synchronized WebApplication start(DeploymentInfo di) throws DeploymentException
326    {
327       Thread JavaDoc thread = Thread.currentThread();
328       ClassLoader JavaDoc appClassLoader = thread.getContextClassLoader();
329       WebApplication warInfo = null;
330       try
331       {
332          // Create a classloader for the war to ensure a unique ENC
333
URL JavaDoc[] empty = {};
334          URLClassLoader JavaDoc warLoader1 = URLClassLoader.newInstance(empty, di.ucl);
335          URLClassLoader JavaDoc warLoader = warLoader1;
336          thread.setContextClassLoader(warLoader);
337          WebDescriptorParser webAppParser = new DescriptorParser(di);
338          String JavaDoc webContext = di.webContext;
339          if (webContext != null && webContext.startsWith("/") == false)
340             webContext = "/" + webContext;
341
342          // Get the war URL
343
URL JavaDoc warURL = di.localUrl != null ? di.localUrl : di.url;
344
345          log.debug("webContext: " + webContext);
346          log.debug("warURL: " + warURL);
347          log.debug("webAppParser: " + webAppParser);
348
349          // Get the web.xml and jboss-web.xml descriptor metadata
350
WebMetaData webMetaData = (WebMetaData) di.metaData;
351
352          // inherit the security setup from jboss-app.xml
353
if (di.parent != null && di.parent.metaData instanceof J2eeApplicationMetaData)
354          {
355             J2eeApplicationMetaData appMetaData = (J2eeApplicationMetaData) di.parent.metaData;
356
357             if (webMetaData.getSecurityDomain() == null)
358                webMetaData.setSecurityDomain(appMetaData.getSecurityDomain());
359
360             webMetaData.mergeSecurityRoles(appMetaData.getSecurityRoles());
361          }
362
363          // Register the permissions with the JACC layer
364
String JavaDoc contextID = di.shortName;
365          if (contextID == null)
366             contextID = di.shortName;
367          webMetaData.setJaccContextID(contextID);
368          PolicyConfigurationFactory JavaDoc pcFactory = PolicyConfigurationFactory.getPolicyConfigurationFactory();
369          PolicyConfiguration JavaDoc pc = pcFactory.getPolicyConfiguration(contextID, true);
370          createPermissions(webMetaData, pc);
371          // Link this to the parent PC
372
DeploymentInfo current = di;
373          while (current.parent != null)
374             current = current.parent;
375          PolicyConfiguration JavaDoc parentPC = (PolicyConfiguration JavaDoc)
376             current.context.get("javax.security.jacc.PolicyConfiguration");
377          if (parentPC != null && parentPC != pc)
378             parentPC.linkConfiguration(pc);
379
380          // Commit the policy configuration
381
pc.commit();
382          // Allow the policy to incorporate the policy configs
383
Policy.getPolicy().refresh();
384
385          warInfo = new WebApplication(webMetaData);
386          warInfo.setClassLoader(warLoader);
387          performDeploy(warInfo, warURL.toString(), webAppParser);
388       }
389       catch (DeploymentException e)
390       {
391          di.context.put(ERROR, e);
392          throw e;
393       }
394       catch (Exception JavaDoc e)
395       {
396          DeploymentException ex = new DeploymentException("Error during deploy", e);
397          di.context.put(ERROR, ex);
398          throw ex;
399       }
400       finally
401       {
402          thread.setContextClassLoader(appClassLoader);
403       }
404       return warInfo;
405    }
406
407    /**
408     * This method is called by the deploy() method template and must be
409     * overriden by subclasses to perform the web container specific deployment
410     * steps.
411     * @param webApp The web application information context. This contains the
412     * metadata such as the context-root element value from the J2EE
413     * application/module/web application.xml descriptor and virtual-host.
414     * @param warUrl The string for the URL of the web application war.
415     * @param webAppParser The callback interface the web container should use to
416     * setup the web app JNDI environment for use by the web app components. This
417     * needs to be invoked after the web app class loader is known, but before
418     * and web app components attempt to access the java:comp/env JNDI
419     * namespace.
420     */

421    protected abstract void performDeploy(WebApplication webApp, String JavaDoc warUrl,
422                                          WebDescriptorParser webAppParser) throws Exception JavaDoc;
423
424    /**
425     * A template pattern implementation of the undeploy() method. This method
426     * calls the {@link #performUndeploy(String, WebApplication)
427     * performUndeploy()} method to perform the container specific undeployment
428     * steps and unregisters the the warUrl from the deployment map.
429     */

430    public synchronized void stop(DeploymentInfo di)
431       throws DeploymentException
432    {
433       URL JavaDoc warURL = di.localUrl != null ? di.localUrl : di.url;
434       String JavaDoc warUrl = warURL.toString();
435       try
436       {
437          WebApplication webApp = (WebApplication) di.context.get(AbstractWebContainer.WEB_APP);
438          performUndeploy(warUrl, webApp);
439          // Unregister the permissions with the JACC layer
440
WebMetaData webMetaData = (WebMetaData) di.metaData;
441          String JavaDoc contextID = webMetaData.getJaccContextID();
442          PolicyConfigurationFactory JavaDoc pcFactory = PolicyConfigurationFactory.getPolicyConfigurationFactory();
443          PolicyConfiguration JavaDoc pc = pcFactory.getPolicyConfiguration(contextID, true);
444          pc.delete();
445          //Unregister any xacml policies
446
String JavaDoc prefixedSecurityDomain = webApp.getMetaData().getSecurityDomain();
447          if(prefixedSecurityDomain != null)
448          {
449             AuthorizationManager authzmgr =
450                 org.jboss.security.Util.getAuthorizationManager(prefixedSecurityDomain);
451             if(authzmgr instanceof PolicyRegistration)
452             {
453                PolicyRegistration xam = (PolicyRegistration)authzmgr;
454                xam.deRegisterPolicy(contextID);
455             }
456          }
457       }
458       catch (DeploymentException e)
459       {
460          throw e;
461       }
462       catch (Exception JavaDoc e)
463       {
464          throw new DeploymentException("Error during deploy", e);
465       }
466    }
467
468    /**
469     * Called as part of the undeploy() method template to ask the subclass for
470     * perform the web container specific undeployment steps.
471     */

472    protected abstract void performUndeploy(String JavaDoc warUrl, WebApplication webApp)
473       throws Exception JavaDoc;
474
475    /**
476     * This method is invoked from within subclass performDeploy() method
477     * implementations when they invoke WebDescriptorParser.parseWebAppDescriptors().
478     * @param loader the ClassLoader for the web application. May not be null.
479     * @param metaData the WebMetaData from the WebApplication object passed to
480     * the performDeploy method.
481     */

482    protected void parseWebAppDescriptors(DeploymentInfo di, ClassLoader JavaDoc loader,
483       WebMetaData metaData)
484       throws Exception JavaDoc
485    {
486       log.debug("AbstractWebContainer.parseWebAppDescriptors, Begin");
487       InitialContext JavaDoc iniCtx = new InitialContext JavaDoc();
488       Context JavaDoc envCtx = null;
489       Thread JavaDoc currentThread = Thread.currentThread();
490       ClassLoader JavaDoc currentLoader = currentThread.getContextClassLoader();
491       try
492       {
493          // Create a java:comp/env environment unique for the web application
494
log.debug("Creating ENC using ClassLoader: " + loader);
495          ClassLoader JavaDoc parent = loader.getParent();
496          while (parent != null)
497          {
498             log.debug(".." + parent);
499             parent = parent.getParent();
500          }
501          // TODO: Where does this ENC get tidied up?
502
currentThread.setContextClassLoader(loader);
503          metaData.setENCLoader(loader);
504          envCtx = (Context JavaDoc) iniCtx.lookup("java:comp");
505
506          ORB JavaDoc orb = null;
507          try
508          {
509             orb = (ORB JavaDoc) server.getAttribute(Container.ORB_NAME, "ORB");
510          }
511          catch (Throwable JavaDoc t)
512          {
513             log.debug("Unable to retrieve orb" + t.toString());
514          }
515
516          // Bind the orb
517
if (orb != null)
518          {
519             NonSerializableFactory.rebind(envCtx, "ORB", orb);
520             log.debug("Bound java:comp/ORB");
521          }
522          
523          // Add a link to the global transaction manager
524
envCtx.bind("UserTransaction", new LinkRef JavaDoc("UserTransaction"));
525          log.debug("Linked java:comp/UserTransaction to JNDI name: UserTransaction");
526          envCtx = envCtx.createSubcontext("env");
527          processEncReferences(metaData, envCtx, di);
528       }
529       finally
530       {
531          currentThread.setContextClassLoader(currentLoader);
532       }
533
534       String JavaDoc securityDomain = metaData.getSecurityDomain();
535       log.debug("linkSecurityDomain");
536       linkSecurityDomain(securityDomain, envCtx);
537       log.debug("AbstractWebContainer.parseWebAppDescriptors, End");
538    }
539
540    protected void processEncReferences(WebMetaData metaData, Context JavaDoc envCtx, DeploymentInfo di)
541            throws ClassNotFoundException JavaDoc, NamingException JavaDoc, DeploymentException
542    {
543       Iterator JavaDoc envEntries = metaData.getEnvironmentEntries();
544       log.debug("addEnvEntries");
545       addEnvEntries(envEntries, envCtx);
546       Iterator JavaDoc resourceEnvRefs = metaData.getResourceEnvReferences();
547       log.debug("linkResourceEnvRefs");
548       linkResourceEnvRefs(resourceEnvRefs, envCtx);
549       Iterator JavaDoc resourceRefs = metaData.getResourceReferences();
550       log.debug("linkResourceRefs");
551       linkResourceRefs(resourceRefs, envCtx);
552       log.debug("linkMessageDestinationRefs");
553       linkMessageDestinationRefs(metaData, envCtx, di);
554       Iterator JavaDoc ejbRefs = metaData.getEjbReferences();
555       log.debug("linkEjbRefs");
556       linkEjbRefs(ejbRefs, envCtx, di);
557       Iterator JavaDoc ejbLocalRefs = metaData.getEjbLocalReferences();
558       log.debug("linkEjbLocalRefs");
559       linkEjbLocalRefs(ejbLocalRefs, envCtx, di);
560       Iterator JavaDoc serviceRefs = metaData.getServiceReferences();
561       log.debug("linkServiceRefs");
562       ServiceRefHandler refHandler = ServiceRefHandlerFactory.newInstance();
563       if (refHandler != null && serviceRefs.hasNext())
564          refHandler.setupServiceRefEnvironment(envCtx, serviceRefs, di);
565    }
566
567    protected void addEnvEntries(Iterator JavaDoc envEntries, Context JavaDoc envCtx)
568       throws ClassNotFoundException JavaDoc, NamingException JavaDoc
569    {
570       while (envEntries.hasNext())
571       {
572          EnvEntryMetaData entry = (EnvEntryMetaData) envEntries.next();
573          log.debug("Binding env-entry: " + entry.getName() + " of type: " +
574             entry.getType() + " to value:" + entry.getValue());
575          EnvEntryMetaData.bindEnvEntry(envCtx, entry);
576       }
577    }
578
579    protected void linkResourceEnvRefs(Iterator JavaDoc resourceEnvRefs, Context JavaDoc envCtx)
580       throws NamingException JavaDoc
581    {
582       while (resourceEnvRefs.hasNext())
583       {
584          ResourceEnvRefMetaData ref = (ResourceEnvRefMetaData) resourceEnvRefs.next();
585          String JavaDoc resourceName = ref.getJndiName();
586          String JavaDoc refName = ref.getRefName();
587          if (ref.getType().equals("java.net.URL"))
588          {
589             try
590             {
591                log.debug("Binding '" + refName + "' to URL: " + resourceName);
592                URL JavaDoc url = new URL JavaDoc(resourceName);
593                Util.bind(envCtx, refName, url);
594             }
595             catch (MalformedURLException JavaDoc e)
596             {
597                throw new NamingException JavaDoc("Malformed URL:" + e.getMessage());
598             }
599          }
600          else if (resourceName != null)
601          {
602             log.debug("Linking '" + refName + "' to JNDI name: " + resourceName);
603             Util.bind(envCtx, refName, new LinkRef JavaDoc(resourceName));
604          }
605          else
606          {
607             throw new NamingException JavaDoc("resource-env-ref: " + refName
608                + " has no valid JNDI binding. Check the jboss-web/resource-env-ref.");
609          }
610       }
611    }
612
613    protected void linkResourceRefs(Iterator JavaDoc resourceRefs, Context JavaDoc envCtx)
614       throws NamingException JavaDoc
615    {
616       while (resourceRefs.hasNext())
617       {
618          ResourceRefMetaData ref = (ResourceRefMetaData) resourceRefs.next();
619          String JavaDoc jndiName = ref.getJndiName();
620          String JavaDoc refName = ref.getRefName();
621          if (ref.getType().equals("java.net.URL"))
622          {
623             try
624             {
625                String JavaDoc resURL = ref.getResURL();
626                if (ref.getResURL() != null)
627                {
628                   log.debug("Binding '" + refName + "' to URL: " + resURL);
629                   URL JavaDoc url = new URL JavaDoc(resURL);
630                   Util.bind(envCtx, refName, url);
631                }
632                else
633                {
634                   log.debug("Linking '" + refName + "' to URL: " + resURL);
635                   LinkRef JavaDoc urlLink = new LinkRef JavaDoc(jndiName);
636                   Util.bind(envCtx, refName, urlLink);
637                }
638             }
639             catch (MalformedURLException JavaDoc e)
640             {
641                throw new NamingException JavaDoc("Malformed URL:" + e.getMessage());
642             }
643          }
644          else if (jndiName != null)
645          {
646             log.debug("Linking '" + refName + "' to JNDI name: " + jndiName);
647             Util.bind(envCtx, refName, new LinkRef JavaDoc(jndiName));
648          }
649          else
650          {
651             throw new NamingException JavaDoc("resource-ref: " + refName
652                + " has no valid JNDI binding. Check the jboss-web/resource-ref.");
653          }
654       }
655    }
656
657    protected void linkMessageDestinationRefs(WebMetaData metaData, Context JavaDoc envCtx, DeploymentInfo di)
658       throws NamingException JavaDoc, DeploymentException
659    {
660       Iterator JavaDoc i = metaData.getMessageDestinationReferences();
661
662       while (i.hasNext())
663       {
664          MessageDestinationRefMetaData ref = (MessageDestinationRefMetaData) i.next();
665
666          String JavaDoc refName = ref.getRefName();
667          String JavaDoc jndiName = ref.getJNDIName();
668          String JavaDoc link = ref.getLink();
669          if (link != null)
670          {
671             if (jndiName == null)
672             {
673                MessageDestinationMetaData messageDestination = EjbUtil.findMessageDestination(server, di, link);
674                if (messageDestination == null)
675                   throw new DeploymentException("message-destination-ref '" + refName +
676                      "' message-destination-link '" + link + "' not found and no jndi-name in jboss-web.xml");
677                else
678                {
679                   String JavaDoc linkJNDIName = messageDestination.getJNDIName();
680                   if (linkJNDIName == null)
681                      log.warn("message-destination '" + link + "' has no jndi-name in jboss-web.xml");
682                   else
683                      jndiName = linkJNDIName;
684                }
685             }
686             else
687                log.warn("message-destination-ref '" + refName +
688                   "' ignoring message-destination-link '" + link + "' because it has a jndi-name in jboss-web.xml");
689          }
690          else if (jndiName == null)
691             throw new DeploymentException("message-destination-ref '" + refName +
692                "' has no message-destination-link in web.xml and no jndi-name in jboss-web.xml");
693          Util.bind(envCtx, refName, new LinkRef JavaDoc(jndiName));
694       }
695    }
696
697    protected void linkEjbRefs(Iterator JavaDoc ejbRefs, Context JavaDoc envCtx, DeploymentInfo di)
698       throws NamingException JavaDoc
699    {
700       while (ejbRefs.hasNext())
701       {
702          EjbRefMetaData ejb = (EjbRefMetaData) ejbRefs.next();
703          String JavaDoc name = ejb.getName();
704          String JavaDoc linkName = ejb.getLink();
705          String JavaDoc jndiName = null;
706          
707          //use ejb-link if it is specified
708
if (linkName != null)
709          {
710             jndiName = EjbUtil.findEjbLink(server, di, linkName);
711              
712             //if flag does not allow misconfigured ejb-links, it is an error
713
if ((jndiName == null) && !(getLenientEjbLink()))
714                throw new NamingException JavaDoc("ejb-ref: " + name + ", no ejb-link match");
715          }
716
717          
718          //fall through to the jndiName
719
if (jndiName == null)
720          {
721             jndiName = ejb.getJndiName();
722             if (jndiName == null)
723                throw new NamingException JavaDoc("ejb-ref: " + name + ", no ejb-link in web.xml and no jndi-name in jboss-web.xml");
724          }
725
726          log.debug("Linking ejb-ref: " + name + " to JNDI name: " + jndiName);
727          Util.bind(envCtx, name, new LinkRef JavaDoc(jndiName));
728       }
729    }
730
731    protected void linkEjbLocalRefs(Iterator JavaDoc ejbRefs, Context JavaDoc envCtx, DeploymentInfo di)
732       throws NamingException JavaDoc
733    {
734       while (ejbRefs.hasNext())
735       {
736          EjbLocalRefMetaData ejb = (EjbLocalRefMetaData) ejbRefs.next();
737          String JavaDoc name = ejb.getName();
738          String JavaDoc linkName = ejb.getLink();
739          String JavaDoc jndiName = null;
740
741          //use the ejb-link field if it is specified
742
if (linkName != null)
743          {
744             jndiName = EjbUtil.findLocalEjbLink(server, di, linkName);
745              
746             //if flag does not allow misconfigured ejb-links, it is an error
747
if ((jndiName == null) && !(getLenientEjbLink()))
748                throw new NamingException JavaDoc("ejb-ref: " + name + ", no ejb-link match");
749          }
750
751
752          if (jndiName == null)
753          {
754             jndiName = ejb.getJndiName();
755             if (jndiName == null)
756             {
757                String JavaDoc msg = null;
758                if (linkName == null)
759                {
760                   msg = "ejb-local-ref: '" + name + "', no ejb-link in web.xml and "
761                      + "no local-jndi-name in jboss-web.xml";
762                }
763                else
764                {
765                   msg = "ejb-local-ref: '" + name + "', with web.xml ejb-link: '"
766                      + linkName + "' failed to resolve to an ejb with a LocalHome";
767                }
768                throw new NamingException JavaDoc(msg);
769             }
770          }
771
772          log.debug("Linking ejb-local-ref: " + name + " to JNDI name: " + jndiName);
773          Util.bind(envCtx, name, new LinkRef JavaDoc(jndiName));
774       }
775    }
776
777    /**
778     * This creates a java:comp/env/security context that contains a securityMgr
779     * binding pointing to an AuthenticationManager implementation and a
780     * realmMapping binding pointing to a RealmMapping implementation. If the
781     * jboss-web.xml descriptor contained a security-domain element then the
782     * bindings are LinkRefs to the jndi name specified by the security-domain
783     * element. If there was no security-domain element then the bindings are to
784     * NullSecurityManager instance which simply allows all access.
785     */

786    protected void linkSecurityDomain(String JavaDoc securityDomain, Context JavaDoc envCtx)
787       throws NamingException JavaDoc
788    {
789       if (securityDomain == null)
790       {
791          securityDomain = getDefaultSecurityDomain();
792          log.debug("No security-domain given, using default: " + securityDomain);
793       }
794       log.debug("Linking security/securityMgr to JNDI name: " + securityDomain);
795       Util.bind(envCtx, "security/securityMgr", new LinkRef JavaDoc(securityDomain));
796       Util.bind(envCtx, "security/realmMapping", new LinkRef JavaDoc(securityDomain+"/realmMapping"));
797       Util.bind(envCtx, "security/authorizationMgr", new LinkRef JavaDoc(securityDomain+"/authorizationMgr"));
798       Util.bind(envCtx, "security/security-domain", new LinkRef JavaDoc(securityDomain));
799       Util.bind(envCtx, "security/subject", new LinkRef JavaDoc(securityDomain + "/subject"));
800    }
801
802    /**
803     * A utility method that searches the given loader for the resources:
804     * "javax/servlet/resources/web-app_2_3.dtd", "org/apache/jasper/resources/jsp12.dtd",
805     * and "javax/ejb/EJBHome.class" and returns an array of URL strings. Any
806     * jar: urls are reduced to the underlying <url> portion of the
807     * 'jar:<url>!/{entry}' construct.
808     */

809    public String JavaDoc[] getStandardCompileClasspath(ClassLoader JavaDoc loader)
810    {
811       String JavaDoc[] jspResources = {
812          "javax/servlet/resources/web-app_2_3.dtd",
813          "org/apache/jasper/resources/jsp12.dtd",
814          "javax/ejb/EJBHome.class"
815       };
816       ArrayList JavaDoc tmp = new ArrayList JavaDoc();
817       for (int j = 0; j < jspResources.length; j++)
818       {
819          URL JavaDoc rsrcURL = loader.getResource(jspResources[j]);
820          if (rsrcURL != null)
821          {
822             String JavaDoc url = rsrcURL.toExternalForm();
823             if (rsrcURL.getProtocol().equals("jar"))
824             {
825                // Parse the jar:<url>!/{entry} URL
826
url = url.substring(4);
827                int seperator = url.indexOf('!');
828                url = url.substring(0, seperator);
829             }
830             tmp.add(url);
831          }
832          else
833          {
834             log.warn("Failed to fin jsp rsrc: " + jspResources[j]);
835          }
836       }
837       log.trace("JSP StandardCompileClasspath: " + tmp);
838       String JavaDoc[] cp = new String JavaDoc[tmp.size()];
839       tmp.toArray(cp);
840       return cp;
841    }
842
843    /**
844     * A utility method that walks up the ClassLoader chain starting at the given
845     * loader and queries each ClassLoader for a 'URL[] getURLs()' method from
846     * which a complete classpath of URL strings is built.
847     */

848    public String JavaDoc[] getCompileClasspath(ClassLoader JavaDoc loader)
849    {
850       HashSet JavaDoc tmp = new HashSet JavaDoc();
851       ClassLoader JavaDoc cl = loader;
852       while (cl != null)
853       {
854          URL JavaDoc[] urls = AbstractWebContainer.getClassLoaderURLs(cl);
855          addURLs(tmp, urls);
856          cl = cl.getParent();
857       }
858       try
859       {
860          URL JavaDoc[] globalUrls = (URL JavaDoc[]) server.getAttribute(LoaderRepositoryFactory.DEFAULT_LOADER_REPOSITORY,
861             "URLs");
862          addURLs(tmp, globalUrls);
863       }
864       catch (Exception JavaDoc e)
865       {
866          log.warn("Could not get global URL[] from default loader repository!", e);
867       } // end of try-catch
868
log.trace("JSP CompileClasspath: " + tmp);
869       String JavaDoc[] cp = new String JavaDoc[tmp.size()];
870       tmp.toArray(cp);
871       return cp;
872    }
873
874    private void addURLs(Set JavaDoc urlSet, URL JavaDoc[] urls)
875    {
876       for (int u = 0; u < urls.length; u++)
877       {
878          URL JavaDoc url = urls[u];
879          urlSet.add(url.toExternalForm());
880       }
881    }
882
883    /**
884     * Create the JACC permission based on the security constraints obtained from
885     * the web.xml metadata.
886     * @param metaData
887     * @param pc
888     * @throws PolicyContextException
889     */

890    protected void createPermissions(WebMetaData metaData, PolicyConfiguration JavaDoc pc)
891       throws PolicyContextException JavaDoc
892    {
893       WebPermissionMapping.createPermissions(metaData, pc);
894    }
895
896    /**
897     * An inner class that maps the WebDescriptorParser.parseWebAppDescriptors()
898     * onto the protected parseWebAppDescriptors() AbstractWebContainer method.
899     */

900    private class DescriptorParser implements WebDescriptorParser
901    {
902       DeploymentInfo di;
903
904       DescriptorParser(DeploymentInfo di)
905       {
906          this.di = di;
907       }
908
909       public void parseWebAppDescriptors(ClassLoader JavaDoc loader, WebMetaData metaData)
910          throws Exception JavaDoc
911       {
912          AbstractWebDeployer.this.parseWebAppDescriptors(di, loader, metaData);
913       }
914
915       public DeploymentInfo getDeploymentInfo()
916       {
917          return di;
918       }
919    }
920 }
921
Popular Tags