View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.cdi.servlet;
20  
21  import java.io.IOException;
22  import java.util.Collections;
23  import java.util.Set;
24  
25  import javax.servlet.ServletContext;
26  
27  import org.eclipse.jetty.servlet.ServletContextHandler;
28  import org.eclipse.jetty.util.log.Log;
29  import org.eclipse.jetty.util.log.Logger;
30  import org.eclipse.jetty.util.resource.Resource;
31  import org.jboss.weld.environment.servlet.EnhancedListener;
32  
33  /**
34   * Handy {@link ServletContextHandler} implementation that hooks up
35   * all of the various CDI related components and listeners from Weld.
36   */
37  public class EmbeddedCdiHandler extends ServletContextHandler
38  {
39      private static final Logger LOG = Log.getLogger(EmbeddedCdiHandler.class);
40      
41      private static final String[] REQUIRED_BEANS_XML_PATHS = new String[] { 
42          "/WEB-INF/beans.xml", 
43          "/META-INF/beans.xml", 
44          "/WEB-INF/classes/META-INF/beans.xml" 
45      };
46  
47      public EmbeddedCdiHandler()
48      {
49          super();
50      }
51  
52      public EmbeddedCdiHandler(int options)
53      {
54          super(options);
55      }
56  
57      @Override
58      protected void doStart() throws Exception
59      {
60          // Required of CDI
61          Resource baseResource = getBaseResource();
62          if (baseResource == null)
63          {
64              throw new NullPointerException("baseResource must be set (to so it can find the beans.xml)");
65          }
66          
67          boolean foundBeansXml = false;
68  
69          // Verify that beans.xml is present, otherwise weld will fail silently.
70          for(String beansXmlPath: REQUIRED_BEANS_XML_PATHS) {
71              Resource res = baseResource.addPath(beansXmlPath);
72              if (res == null)
73              {
74                  // not found, skip it
75                  continue;
76              }
77              
78              if (res.exists())
79              {
80                  foundBeansXml = true;
81              }
82  
83              if (res.isDirectory())
84              {
85                  throw new IOException("Directory conflicts with expected file: " + res.getURI().toASCIIString());
86              }
87          }
88          
89          if (!foundBeansXml)
90          {
91              StringBuilder err = new StringBuilder();
92              err.append("Unable to find required beans.xml from the baseResource: ");
93              err.append(baseResource.getURI().toASCIIString()).append(System.lineSeparator());
94              err.append("Searched for: ");
95              for (String beansXmlPath : REQUIRED_BEANS_XML_PATHS)
96              {
97                  err.append(System.lineSeparator());
98                  err.append("  ").append(beansXmlPath);
99              }
100             LOG.warn("ERROR: {}",err.toString());
101             throw new IOException(err.toString());
102         }
103 
104         // Initialize Weld
105         JettyWeldInitializer.initContext(this);
106 
107         // Wire up Weld (what's usually done via the ServletContainerInitializer)
108         ServletContext ctx = getServletContext();
109         
110         // Fake the call to ServletContainerInitializer
111         ClassLoader orig = Thread.currentThread().getContextClassLoader();
112         try
113         {
114             Thread.currentThread().setContextClassLoader(ctx.getClassLoader());
115             
116             EnhancedListener weldListener = new EnhancedListener();
117             Set<Class<?>> classes = Collections.emptySet();
118             weldListener.onStartup(classes,ctx);
119             
120             // add the rest of the Weld Listeners
121             ctx.addListener(weldListener);
122         }
123         finally
124         {
125             Thread.currentThread().setContextClassLoader(orig);
126         }
127 
128         // Let normal ServletContextHandler startup continue its merry way
129         super.doStart();
130     }
131 }