View Javadoc

1   /*
2    * Copyright 2007 Tim Peierls
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *         http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.directwebremoting.guice;
17  
18  import com.google.inject.Key;
19  
20  import java.util.Collection;
21  import java.util.concurrent.ConcurrentHashMap;
22  import java.util.concurrent.ConcurrentMap;
23  
24  /**
25   * A specialization of {@link AbstractContextScope} using a concurrent map
26   * to hold registered instance providers. Concrete implementations must
27   * define {@code get()} to return the current context, and they must call
28   * {@code super(C.class)} in constructors.
29   * @author Tim Peierls [tim at peierls dot net]
30   */
31  public abstract class AbstractMapContextScope<C> 
32      extends AbstractContextScope<C, ConcurrentMap>
33  {
34      protected AbstractMapContextScope(Class<C> type, String scopeName)
35      {
36          super(type, scopeName);
37      }
38      
39      public abstract C get();
40      
41      
42      //
43      // ContextRegistry methods
44      //
45      
46      public ConcurrentMap registryFor(C context)
47      {
48          ConcurrentMap instanceMap = map.get(context);
49  
50          if (instanceMap == null) 
51          {
52              ConcurrentMap emptyMap = new ConcurrentHashMap();
53              instanceMap = map.putIfAbsent(context, emptyMap);
54              if (instanceMap == null) 
55              {
56                  instanceMap = emptyMap;
57              }
58          }
59  
60          return instanceMap;
61      }
62  
63      public <T> InstanceProvider<T> get(ConcurrentMap registry, Key<T> key, String keyString)
64      {
65          @SuppressWarnings("unchecked")
66          ConcurrentMap<Key<T>, InstanceProvider<T>> instanceMap =
67              (ConcurrentMap<Key<T>, InstanceProvider<T>>) registry;
68          return instanceMap.get(key);
69      }
70      
71      public <T> InstanceProvider<T> putIfAbsent(ConcurrentMap registry, 
72                                                 Key<T> key, String keyString, 
73                                                 InstanceProvider<T> creator)
74      {                                               
75          @SuppressWarnings("unchecked")
76          ConcurrentMap<Key<T>, InstanceProvider<T>> instanceMap =
77              (ConcurrentMap<Key<T>, InstanceProvider<T>>) registry;
78          
79          return instanceMap.putIfAbsent(key, creator);
80      }
81      
82      public <T> boolean remove(ConcurrentMap registry, Key<T> key, String keyString, 
83                                InstanceProvider<T> creator)
84      {
85          @SuppressWarnings("unchecked")
86          ConcurrentMap<Key<T>, InstanceProvider<T>> instanceMap =
87              (ConcurrentMap<Key<T>, InstanceProvider<T>>) registry;
88          
89          return instanceMap.remove(key, creator);
90      }
91  
92      private final ConcurrentMap<C, ConcurrentMap> map =
93            new ConcurrentHashMap<C, ConcurrentMap>();
94  }