KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > google > inject > Scopes


1 /**
2  * Copyright (C) 2006 Google Inc.
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
17 package com.google.inject;
18
19 import com.google.inject.util.StackTraceElements;
20 import java.lang.annotation.Annotation JavaDoc;
21 import java.util.Map JavaDoc;
22
23 /**
24  * Built in scope implementations.
25  *
26  * @author crazybob@google.com (Bob Lee)
27  */

28 public class Scopes {
29
30   private Scopes() {}
31
32   /**
33    * One instance per {@link Injector}. Also see {@code @}{@link Singleton}.
34    */

35   public static final Scope SINGLETON = new Scope() {
36     public <T> Provider<T> scope(Key<T> key, final Provider<T> creator) {
37       return new Provider<T>() {
38
39         private volatile T instance;
40
41         // DCL on a volatile is safe as of Java 5, which we obviously require.
42
@SuppressWarnings JavaDoc("DoubleCheckedLocking")
43         public T get() {
44           if (instance == null) {
45             /*
46              * Use a pretty coarse lock. We don't want to run into deadlocks
47              * when two threads try to load circularly-dependent objects.
48              * Maybe one of these days we will identify independent graphs of
49              * objects and offer to load them in parallel.
50              */

51             synchronized (Injector.class) {
52               if (instance == null) {
53                 instance = creator.get();
54               }
55             }
56           }
57           return instance;
58         }
59
60         public String JavaDoc toString() {
61           return creator.toString();
62         }
63       };
64     }
65
66     public String JavaDoc toString() {
67       return "Scopes.SINGLETON";
68     }
69   };
70
71   /**
72    * Gets the scope for a type based on its annotations. Returns {@code null}
73    * if none specified.
74    *
75    * @param implementation type
76    * @param scopes map of scope names to scopes
77    * @param errorHandler handles errors
78    */

79   static Scope getScopeForType(Class JavaDoc<?> implementation,
80       Map JavaDoc<Class JavaDoc<? extends Annotation JavaDoc>, Scope> scopes,
81       ErrorHandler errorHandler) {
82     Class JavaDoc<? extends Annotation JavaDoc> found = null;
83     for (Annotation JavaDoc annotation : implementation.getAnnotations()) {
84       if (isScopeAnnotation(annotation)) {
85         if (found != null) {
86           errorHandler.handle(
87               StackTraceElements.forType(implementation),
88               ErrorMessages.DUPLICATE_SCOPE_ANNOTATIONS,
89               "@" + found.getSimpleName(),
90               "@" + annotation.annotationType().getSimpleName()
91           );
92         } else {
93           found = annotation.annotationType();
94         }
95       }
96     }
97
98     return scopes.get(found);
99   }
100
101   static boolean isScopeAnnotation(Annotation JavaDoc annotation) {
102     return isScopeAnnotation(annotation.annotationType());
103   }
104
105   static boolean isScopeAnnotation(Class JavaDoc<? extends Annotation JavaDoc> annotationType) {
106     return annotationType.isAnnotationPresent(ScopeAnnotation.class);
107   }
108
109   /**
110    * Scopes an internal factory.
111    */

112   static <T> InternalFactory<? extends T> scope(Key<T> key,
113       InjectorImpl injector, InternalFactory<? extends T> creator,
114       Scope scope) {
115     // No scope does nothing.
116
if (scope == null) {
117       return creator;
118     }
119     Provider<T> scoped = scope.scope(key,
120         new ProviderToInternalFactoryAdapter<T>(injector, creator));
121     return new InternalFactoryToProviderAdapter<T>(scoped);
122   }
123 }
124
Popular Tags