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.lang.annotation.Annotation;
22  import java.util.List;
23  import java.util.Set;
24  
25  import javax.enterprise.context.spi.Context;
26  import javax.enterprise.context.spi.Contextual;
27  import javax.enterprise.context.spi.CreationalContext;
28  import javax.enterprise.inject.spi.Bean;
29  import javax.enterprise.inject.spi.BeanManager;
30  import javax.inject.Inject;
31  
32  import org.eclipse.jetty.cdi.core.AnyLiteral;
33  import org.eclipse.jetty.cdi.core.ScopedInstance;
34  import org.eclipse.jetty.cdi.core.SimpleBeanStore;
35  import org.eclipse.jetty.cdi.websocket.annotation.WebSocketScope;
36  import org.eclipse.jetty.util.log.Log;
37  import org.eclipse.jetty.util.log.Logger;
38  import org.eclipse.jetty.websocket.api.Session;
39  
40  /**
41   * WebSocket Scope Context.
42   * <p>
43   * A CDI Context definition for how CDI will use objects defined to belong to the WebSocketScope
44   */
45  public class WebSocketScopeContext implements Context
46  {
47      private static final Logger LOG = Log.getLogger(WebSocketScopeContext.class);
48  
49      private static ThreadLocal<WebSocketScopeContext> current = new ThreadLocal<>();
50  
51      public static WebSocketScopeContext current()
52      {
53          return current.get();
54      }
55  
56      private SimpleBeanStore beanStore;
57  
58      @Inject
59      private BeanManager beanManager;
60  
61      private ThreadLocal<org.eclipse.jetty.websocket.api.Session> session = new ThreadLocal<>();
62  
63      public void begin()
64      {
65          if (LOG.isDebugEnabled())
66          {
67              LOG.debug("{} begin()",this);
68          }
69          current.set(this);
70      }
71  
72      public void create()
73      {
74          if (LOG.isDebugEnabled())
75          {
76              LOG.debug("{} create()",this);
77          }
78          current.set(this);
79          beanStore = new SimpleBeanStore();
80      }
81  
82      public void destroy()
83      {
84          if (LOG.isDebugEnabled())
85          {
86              LOG.debug("{} destroy()",this);
87          }
88  
89          beanStore.destroy();
90      }
91  
92      public void end()
93      {
94          if (LOG.isDebugEnabled())
95          {
96              LOG.debug("{} end()",this);
97          }
98          beanStore.clear();
99      }
100 
101     @SuppressWarnings({ "unchecked" })
102     @Override
103     public <T> T get(Contextual<T> contextual)
104     {
105         if (LOG.isDebugEnabled())
106         {
107             LOG.debug("{} get({})",this,contextual);
108         }
109 
110         Bean<T> bean = (Bean<T>)contextual;
111 
112         if (bean.getBeanClass().isAssignableFrom(Session.class))
113         {
114             return (T)this.session;
115         }
116         
117         if (beanStore == null)
118         {
119             return null;
120         }
121 
122         List<ScopedInstance<?>> beans = beanStore.getBeans(contextual);
123 
124         if ((beans != null) && (!beans.isEmpty()))
125         {
126             return (T)beans.get(0).instance;
127         }
128 
129         return null;
130     }
131 
132     @SuppressWarnings("unchecked")
133     @Override
134     public <T> T get(Contextual<T> contextual, CreationalContext<T> creationalContext)
135     {
136         if (LOG.isDebugEnabled())
137         {
138             LOG.debug("{} get({},{})",this,contextual,creationalContext);
139         }
140 
141         Bean<T> bean = (Bean<T>)contextual;
142 
143         if (bean.getBeanClass().isAssignableFrom(Session.class))
144         {
145             return (T)this.session;
146         }
147 
148         if (beanStore == null)
149         {
150             beanStore = new SimpleBeanStore();
151         }
152 
153         List<ScopedInstance<?>> beans = beanStore.getBeans(contextual);
154 
155         if ((beans != null) && (!beans.isEmpty()))
156         {
157             for (ScopedInstance<?> instance : beans)
158             {
159                 if (instance.bean.equals(bean))
160                 {
161                     return (T)instance.instance;
162                 }
163             }
164         }
165 
166         // no bean found, create it
167         T t = bean.create(creationalContext);
168         ScopedInstance<T> customInstance = new ScopedInstance<>();
169         customInstance.bean = bean;
170         customInstance.creationalContext = creationalContext;
171         customInstance.instance = t;
172         beanStore.addBean(customInstance);
173         return t;
174     }
175 
176     @Override
177     public Class<? extends Annotation> getScope()
178     {
179         return WebSocketScope.class;
180     }
181 
182     @Override
183     public boolean isActive()
184     {
185         return true;
186     }
187 
188     @SuppressWarnings({ "unchecked", "rawtypes" })
189     public <T> T newInstance(Class<T> clazz)
190     {
191         if (LOG.isDebugEnabled())
192         {
193             LOG.debug("newInstance({})",clazz);
194         }
195         Set<Bean<?>> beans = beanManager.getBeans(clazz,AnyLiteral.INSTANCE);
196         if (beans.isEmpty())
197         {
198             return null;
199         }
200 
201         Bean bean = beans.iterator().next();
202         CreationalContext cc = beanManager.createCreationalContext(bean);
203         return (T)beanManager.getReference(bean,clazz,cc);
204     }
205 
206     public void setSession(org.eclipse.jetty.websocket.api.Session sess)
207     {
208         if (LOG.isDebugEnabled())
209         {
210             LOG.debug("{} setSession({})",this,sess);
211         }
212         current.set(this);
213         this.session.set(sess);
214     }
215 
216     public org.eclipse.jetty.websocket.api.Session getSession()
217     {
218         if (LOG.isDebugEnabled())
219         {
220             LOG.debug("{} getSession()",this);
221         }
222         return this.session.get();
223     }
224 
225     @Override
226     public String toString()
227     {
228         return String.format("%s@%X[%s]",this.getClass().getSimpleName(),hashCode(),beanStore);
229     }
230 }