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