001: /**
002: * Copyright (C) 2006 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: */package com.bm.ejb3guice.inject;
016:
017: import com.bm.ejb3guice.internal.StackTraceElements;
018:
019: import java.lang.reflect.Constructor;
020: import java.lang.reflect.Field;
021: import java.lang.reflect.Member;
022: import java.lang.reflect.Method;
023: import java.util.Arrays;
024: import java.util.Collection;
025: import java.util.List;
026:
027: /**
028: * Error message templates.
029: *
030: * @author crazybob@google.com (Bob Lee)
031: */
032: class ErrorMessages {
033:
034: private static final String MISSING_BINDING = "Binding to %s not found. No bindings to that"
035: + " type were found.";
036:
037: private static final String MISSING_BINDING_BUT_OTHERS_EXIST = "Binding to %s not found. Annotations on other"
038: + " bindings to that type include: %s";
039:
040: static void handleMissingBinding(InjectorImpl injector,
041: Object source, Key<?> key) {
042: ErrorHandler errorHandler = injector.errorHandler;
043: List<String> otherNames = injector
044: .getNamesOfBindingAnnotations(key.getTypeLiteral());
045:
046: if (source instanceof Member) {
047: source = StackTraceElements.forMember((Member) source);
048: }
049:
050: if (otherNames.isEmpty()) {
051: errorHandler.handle(source, MISSING_BINDING, key);
052: } else {
053: errorHandler.handle(source,
054: MISSING_BINDING_BUT_OTHERS_EXIST, key, otherNames);
055: }
056: }
057:
058: static final String SUBTYPE_NOT_PROVIDED = "%s doesn't provide instances of %s.";
059:
060: static final String NOT_A_SUBTYPE = "%s doesn't extend %s.";
061:
062: static final String RECURSIVE_IMPLEMENTATION_TYPE = "@DefaultImplementation"
063: + " points to the same class it annotates.";
064:
065: static final String RECURSIVE_PROVIDER_TYPE = "@DefaultProvider"
066: + " points to the same class it annotates.";
067:
068: static final String ERROR_INJECTING_MEMBERS = "An error occurred"
069: + " while injecting members of %s. Error message: %s";
070:
071: static final String ERROR_INJECTING_MEMBERS_SEE_LOG = "An error of type %s"
072: + " occurred while injecting members of %s. See log for details. Error"
073: + " message: %s";
074:
075: static final String EXCEPTION_REPORTED_BY_MODULE = "An exception was"
076: + " caught and reported. Message: %s";
077:
078: static final String EXCEPTION_REPORTED_BY_MODULE_SEE_LOG = "An exception"
079: + " was caught and reported. See log for details. Message: %s";
080:
081: static final String MISSING_BINDING_ANNOTATION = "Please annotate with"
082: + " @BindingAnnotation. Bound at %s.";
083:
084: static final String MISSING_RUNTIME_RETENTION = "Please annotate with"
085: + " @Retention(RUNTIME). Bound at %s.";
086:
087: static final String MISSING_SCOPE_ANNOTATION = "Please annotate with"
088: + " @ScopeAnnotation.";
089:
090: static final String OPTIONAL_CONSTRUCTOR = "@Inject(optional=true) is"
091: + " not allowed on constructors.";
092:
093: static final String CONSTANT_CONVERSION_ERROR = "Error converting String"
094: + " constant bound at %s to %s: %s";
095:
096: static final String CANNOT_BIND_TO_GUICE_TYPE = "Binding to core guice"
097: + " framework type is not allowed: %s.";
098:
099: static final String SCOPE_NOT_FOUND = "No scope is bound to %s.";
100:
101: static final String SINGLE_INSTANCE_AND_SCOPE = "Setting the scope is not"
102: + " permitted when binding to a single instance.";
103:
104: static final String CONSTRUCTOR_RULES = "Classes must have either one (and"
105: + " only one) constructor annotated with @Inject or a zero-argument"
106: + " constructor.";
107:
108: static final String MISSING_CONSTRUCTOR = "Could not find a suitable"
109: + " constructor in %s. " + CONSTRUCTOR_RULES;
110:
111: static final String TOO_MANY_CONSTRUCTORS = "Found more than one constructor"
112: + " annotated with @Inject. " + CONSTRUCTOR_RULES;
113:
114: static final String DUPLICATE_SCOPES = "Scope %s is already bound to %s."
115: + " Cannot bind %s.";
116:
117: static final String MISSING_CONSTANT_VALUE = "Missing constant value. Please"
118: + " call to(...).";
119:
120: static final String CANNOT_INJECT_ABSTRACT_TYPE = "Injecting into abstract"
121: + " types is not supported. Please use a concrete type instead of %s.";
122:
123: static final String CANNOT_INJECT_INNER_CLASS = "Injecting into inner"
124: + " classes is not supported. Please use a static class (top-level or"
125: + " nested) instead.";
126:
127: static final String ANNOTATION_ALREADY_SPECIFIED = "More than one annotation"
128: + " is specified for this binding.";
129:
130: static final String IMPLEMENTATION_ALREADY_SET = "Implementation is set more"
131: + " than once.";
132:
133: static final String SCOPE_ALREADY_SET = "Scope is set more than once.";
134:
135: static final String DUPLICATE_BINDING_ANNOTATIONS = "Found more than one annotation annotated with @BindingAnnotation:"
136: + " %s and %s";
137:
138: static final String DUPLICATE_SCOPE_ANNOTATIONS = "More than one scope"
139: + " annotation was found: %s and %s";
140:
141: static final String CONSTANT_VALUE_ALREADY_SET = "Constant value is set more"
142: + " than once.";
143:
144: static final String RECURSIVE_BINDING = "Binding points to itself.";
145:
146: static final String BINDING_ALREADY_SET = "A binding to %s was already"
147: + " configured at %s.";
148:
149: static final String PRELOAD_NOT_ALLOWED = "Preloading is only supported for"
150: + " singleton-scoped bindings.";
151:
152: static final String EXCEPTION_WHILE_CREATING = "Error while locating"
153: + " instance%n bound to %s%n for member at %s";
154:
155: static final String NULL_PROVIDED = "Null value returned by custom provider"
156: + " bound at %s";
157:
158: static String getRootMessage(Throwable t) {
159: Throwable cause = t.getCause();
160: return cause == null ? t.toString() : getRootMessage(cause);
161: }
162:
163: static Object convert(Object o) {
164: for (Converter<?> converter : converters) {
165: if (converter.appliesTo(o)) {
166: return converter.convert(o);
167: }
168: }
169: return o;
170: }
171:
172: @SuppressWarnings("unchecked")
173: static final Collection<Converter<?>> converters = Arrays.asList(
174: new Converter<Method>(Method.class) {
175: public String toString(Method m) {
176: return "method " + m.getDeclaringClass().getName()
177: + "." + m.getName() + "()";
178: }
179: }, new Converter<Constructor>(Constructor.class) {
180: public String toString(Constructor c) {
181: return "constructor "
182: + c.getDeclaringClass().getName() + "()";
183: }
184: }, new Converter<Field>(Field.class) {
185: public String toString(Field f) {
186: return "field " + f.getDeclaringClass().getName()
187: + "." + f.getName();
188: }
189: }, new Converter<Class>(Class.class) {
190: public String toString(Class c) {
191: return c.getName();
192: }
193: }, new Converter<Key>(Key.class) {
194: public String toString(Key k) {
195: return k.hasAnnotationType() ? k.getTypeLiteral()
196: + " annotated with "
197: + k.getAnnotationName() : k
198: .getTypeLiteral().toString();
199: }
200: });
201:
202: static abstract class Converter<T> {
203:
204: final Class<T> type;
205:
206: Converter(Class<T> type) {
207: this .type = type;
208: }
209:
210: boolean appliesTo(Object o) {
211: return type.isAssignableFrom(o.getClass());
212: }
213:
214: String convert(Object o) {
215: return toString(type.cast(o));
216: }
217:
218: abstract String toString(T t);
219: }
220: }
|