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.websocket;
20  
21  import java.util.Set;
22  
23  import javax.enterprise.inject.spi.Bean;
24  import javax.enterprise.inject.spi.BeanManager;
25  import javax.enterprise.inject.spi.CDI;
26  
27  import org.eclipse.jetty.cdi.core.AnyLiteral;
28  import org.eclipse.jetty.cdi.core.ScopedInstance;
29  import org.eclipse.jetty.util.component.ContainerLifeCycle;
30  import org.eclipse.jetty.util.component.LifeCycle;
31  import org.eclipse.jetty.util.log.Log;
32  import org.eclipse.jetty.util.log.Logger;
33  import org.eclipse.jetty.websocket.api.Session;
34  import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
35  import org.eclipse.jetty.websocket.common.scopes.WebSocketSessionScope;
36  
37  public class WebSocketCdiListener extends AbstractContainerListener
38  {
39      static final Logger LOG = Log.getLogger(WebSocketCdiListener.class);
40  
41      @SuppressWarnings(
42      { "rawtypes", "unchecked" })
43      public static <T> ScopedInstance<T> newInstance(Class<T> clazz)
44      {
45          BeanManager bm = CDI.current().getBeanManager();
46  
47          ScopedInstance sbean = new ScopedInstance();
48          Set<Bean<?>> beans = bm.getBeans(clazz,AnyLiteral.INSTANCE);
49          if (beans.size() > 0)
50          {
51              sbean.bean = beans.iterator().next();
52              sbean.creationalContext = bm.createCreationalContext(sbean.bean);
53              sbean.instance = bm.getReference(sbean.bean,clazz,sbean.creationalContext);
54              return sbean;
55          }
56          else
57          {
58              throw new RuntimeException(String.format("Can't find class %s",clazz));
59          }
60      }
61  
62      public static class ContainerListener extends AbstractContainerListener
63      {
64          private static final Logger LOG = Log.getLogger(WebSocketCdiListener.ContainerListener.class);
65          private final WebSocketContainerScope container;
66          private final ScopedInstance<WebSocketScopeContext> wsScope;
67  
68          public ContainerListener(WebSocketContainerScope container)
69          {
70              this.container = container;
71              this.wsScope = newInstance(WebSocketScopeContext.class);
72              this.wsScope.instance.create();
73          }
74  
75          @Override
76          public void lifeCycleStarted(LifeCycle event)
77          {
78              if (event == container)
79              {
80                  if (LOG.isDebugEnabled())
81                  {
82                      LOG.debug("starting websocket container [{}]",event);
83                  }
84                  wsScope.instance.begin();
85                  return;
86              }
87              
88              if (event instanceof WebSocketSessionScope)
89              {
90                  if (LOG.isDebugEnabled())
91                  {
92                      LOG.debug("starting websocket session [{}]",event);
93                  }
94                  wsScope.instance.setSession((Session)event);
95                  return;
96              }
97          }
98  
99          @Override
100         public void lifeCycleStopped(LifeCycle event)
101         {
102             if (event == container)
103             {
104                 if (LOG.isDebugEnabled())
105                 {
106                     LOG.debug("stopped websocket container [{}]",event);
107                 }
108                 this.wsScope.instance.end();
109                 this.wsScope.instance.destroy();
110                 this.wsScope.destroy();
111             }
112         }
113     }
114     
115     @Override
116     public void lifeCycleStarting(LifeCycle event)
117     {
118         if (event instanceof WebSocketContainerScope)
119         {
120             if (LOG.isDebugEnabled())
121             {
122                 LOG.debug("started websocket container [{}]",event);
123             }
124             ContainerListener listener = new ContainerListener((WebSocketContainerScope)event);
125             if (event instanceof ContainerLifeCycle)
126             {
127                 ContainerLifeCycle container = (ContainerLifeCycle)event;
128                 container.addLifeCycleListener(listener);
129                 container.addEventListener(listener);
130             }
131             else
132             {
133                 throw new RuntimeException("Unable to setup CDI against non-container: " + event.getClass().getName());
134             }
135         }
136     }
137 }