001: /*
002: * Copyright (C) 2007 Google Inc.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package com.bm.ejb3guice.inject;
018:
019: import com.bm.ejb3guice.binder.AnnotatedConstantBindingBuilder;
020: import com.bm.ejb3guice.binder.ConstantBindingBuilder;
021: import com.bm.ejb3guice.inject.Key.AnnotationStrategy;
022: import com.bm.ejb3guice.internal.Annotations;
023: import com.bm.ejb3guice.internal.Objects;
024: import com.bm.ejb3guice.internal.StackTraceElements;
025:
026: import java.lang.annotation.Annotation;
027:
028: /**
029: * Builds a constant binding.
030: */
031: class ConstantBindingBuilderImpl implements
032: AnnotatedConstantBindingBuilder, ConstantBindingBuilder {
033:
034: BindingInfo<?> bindingInfo;
035: AnnotationStrategy annotationStrategy;
036: final Object source;
037: private BinderImpl binder;
038:
039: ConstantBindingBuilderImpl(BinderImpl binder, Object source) {
040: this .binder = binder;
041: this .source = source;
042: }
043:
044: public ConstantBindingBuilder annotatedWith(
045: Class<? extends Annotation> annotationType) {
046: Objects.nonNull(annotationType, "annotation type");
047: validateAnnotation(annotationType);
048: annotationStrategy = Key.strategyFor(annotationType);
049: return this ;
050: }
051:
052: public ConstantBindingBuilder annotatedWith(Annotation annotation) {
053: Objects.nonNull(annotation, "annotation");
054: validateAnnotation(annotation.annotationType());
055: annotationStrategy = Key.strategyFor(annotation);
056: return this ;
057: }
058:
059: void validateAnnotation(Class<? extends Annotation> annotationType) {
060: if (annotationStrategy != null) {
061: binder.addError(source,
062: ErrorMessages.ANNOTATION_ALREADY_SPECIFIED);
063: return;
064: }
065:
066: boolean retainedAtRuntime = Annotations
067: .isRetainedAtRuntime(annotationType);
068: boolean bindingAnnotation = Key
069: .isBindingAnnotation(annotationType);
070:
071: if (!retainedAtRuntime) {
072: binder.addError(StackTraceElements.forType(annotationType),
073: ErrorMessages.MISSING_RUNTIME_RETENTION, source);
074: }
075:
076: if (!bindingAnnotation) {
077: binder.addError(StackTraceElements.forType(annotationType),
078: ErrorMessages.MISSING_BINDING_ANNOTATION, source);
079: }
080: }
081:
082: boolean hasValue() {
083: return bindingInfo != null;
084: }
085:
086: Object getSource() {
087: return source;
088: }
089:
090: public void to(String value) {
091: to(String.class, value);
092: }
093:
094: public void to(int value) {
095: to(int.class, value);
096: }
097:
098: public void to(long value) {
099: to(long.class, value);
100: }
101:
102: public void to(boolean value) {
103: to(boolean.class, value);
104: }
105:
106: public void to(double value) {
107: to(double.class, value);
108: }
109:
110: public void to(float value) {
111: to(float.class, value);
112: }
113:
114: public void to(short value) {
115: to(short.class, value);
116: }
117:
118: public void to(char value) {
119: to(char.class, value);
120: }
121:
122: public void to(Class<?> value) {
123: to(Class.class, value);
124: }
125:
126: public <E extends Enum<E>> void to(E value) {
127: to(value.getDeclaringClass(), value);
128: }
129:
130: /**
131: * Maps a constant value to the given type and name.
132: */
133: <T> void to(final Class<T> type, final T value) {
134: if (this .bindingInfo != null) {
135: binder.addError(source,
136: ErrorMessages.CONSTANT_VALUE_ALREADY_SET);
137: } else {
138: this .bindingInfo = new BindingInfo<T>(type, value,
139: annotationStrategy, source);
140: }
141: }
142:
143: BindingImpl<?> createBinding(InjectorImpl injector) {
144: return bindingInfo.createBinding(injector);
145: }
146:
147: private static class BindingInfo<T> {
148:
149: final Class<T> type;
150: final T value;
151: final AnnotationStrategy annotationStrategy;
152: final Object source;
153:
154: BindingInfo(Class<T> type, T value,
155: AnnotationStrategy annotationStrategy, Object source) {
156: this .type = type;
157: this .value = value;
158: this .annotationStrategy = annotationStrategy;
159: this .source = source;
160: }
161:
162: BindingImpl<T> createBinding(InjectorImpl injector) {
163: Key<T> key = Key.get(type, annotationStrategy);
164: ConstantFactory<T> factory = new ConstantFactory<T>(value);
165: return BindingImpl.newInstance(injector, key, source,
166: factory);
167: }
168: }
169: }
|