void validate(Binder binder) { // TODO: Set source from Struts XML. if (hasScope(interceptorClass)) { binder.addError( "Scoping interceptors is not currently supported." + " Please remove the scope annotation from " + interceptorClass.getName() + "."); } // Make sure it implements Interceptor. if (!Interceptor.class.isAssignableFrom(interceptorClass)) { binder.addError( interceptorClass.getName() + " must implement " + Interceptor.class.getName() + "."); } }
private static void checkTypeAndAnnotations(Binder binder, Class<?> type) { if (!type.isInterface()) { binder.addError("Type %s must be an interface", type); } if (!Finders.class.isAssignableFrom(type)) { binder.addError("Type %s must be annotated with %s", type, Finders.class); } for (Method method : type.getMethods()) { if (!method.isAnnotationPresent(Finder.class)) { binder.addError("Method %s must be annotated with %s", method, Finder.class); } if (method.getReturnType() != Iterator.class) { binder.addError("Method %s must return an %s", method, Iterator.class); } else if (!resultType(method).isInterface()) { binder.addError("%s must be an interface on method %s", resultType(method), method); } } }
public List<ProviderMethod<?>> getProviderMethods(Binder binder) { System.out.println("end"); List<ProviderMethod<?>> result = Lists.newArrayList(); Multimap<Signature, Method> methodsBySignature = HashMultimap.create(); for (Class<?> c = delegate.getClass(); c != Object.class; c = c.getSuperclass()) { for (Method method : c.getDeclaredMethods()) { // private/static methods cannot override or be overridden by other methods, so there is no // point in indexing them. // Skip synthetic methods and bridge methods since java will automatically generate // synthetic overrides in some cases where we don't want to generate an error (e.g. // increasing visibility of a subclass). if (((method.getModifiers() & (Modifier.PRIVATE | Modifier.STATIC)) == 0) && !method.isBridge() && !method.isSynthetic()) { methodsBySignature.put(new Signature(method), method); } Optional<Annotation> annotation = isProvider(binder, method); if (annotation.isPresent()) { result.add(createProviderMethod(binder, method, annotation.get())); } } } // we have found all the providers and now need to identify if any were overridden // In the worst case this will have O(n^2) in the number of @Provides methods, but that is only // assuming that every method is an override, in general it should be very quick. for (ProviderMethod<?> provider : result) { Method method = provider.getMethod(); for (Method matchingSignature : methodsBySignature.get(new Signature(method))) { // matching signature is in the same class or a super class, therefore method cannot be // overridding it. if (matchingSignature.getDeclaringClass().isAssignableFrom(method.getDeclaringClass())) { continue; } // now we know matching signature is in a subtype of method.getDeclaringClass() if (overrides(matchingSignature, method)) { String annotationString = provider.getAnnotation().annotationType() == Provides.class ? "@Provides" : "@" + provider.getAnnotation().annotationType().getCanonicalName(); binder.addError( "Overriding " + annotationString + " methods is not allowed." + "\n\t" + annotationString + " method: %s\n\toverridden by: %s", method, matchingSignature); break; } } } return result; }
private static <T> void bind(Binder binder, Class<T> type) { ImmutableMap.Builder<Method, Call> methods = ImmutableMap.builder(); for (Method method : type.getMethods()) { try { Call call = new Call(method, binder.getProvider(Storage.class)); methods.put(method, call); } catch (ParseException e) { binder.addError("%s\n%s", method, e.getMessage()); } } binder.bind(type).toInstance(proxy(type, methods.build())); }
private <T> ProviderMethod<T> createProviderMethod( Binder binder, Method method, Annotation annotation) { binder = binder.withSource(method); Errors errors = new Errors(method); // prepare the parameter providers InjectionPoint point = InjectionPoint.forMethod(method, typeLiteral); List<Dependency<?>> dependencies = point.getDependencies(); List<Provider<?>> parameterProviders = Lists.newArrayList(); for (Dependency<?> dependency : point.getDependencies()) { parameterProviders.add(binder.getProvider(dependency)); } @SuppressWarnings("unchecked") // Define T as the method's return type. TypeLiteral<T> returnType = (TypeLiteral<T>) typeLiteral.getReturnType(method); Key<T> key = getKey(errors, returnType, method, method.getAnnotations()); try { key = scanner.prepareMethod(binder, annotation, key, point); } catch (Throwable t) { binder.addError(t); } Class<? extends Annotation> scopeAnnotation = Annotations.findScopeAnnotation(errors, method.getAnnotations()); for (Message message : errors.getMessages()) { binder.addError(message); } return ProviderMethod.create( key, method, delegate, ImmutableSet.copyOf(dependencies), parameterProviders, scopeAnnotation, skipFastClassGeneration, annotation); }
/** * Returns true if the method is a provider. * * <p>Synthetic bridge methods are excluded. Starting with JDK 8, javac copies annotations onto * bridge methods (which always have erased signatures). */ private Optional<Annotation> isProvider(Binder binder, Method method) { if (method.isBridge() || method.isSynthetic()) { return Optional.absent(); } Annotation annotation = null; for (Class<? extends Annotation> annotationClass : scanner.annotationClasses()) { Annotation foundAnnotation = method.getAnnotation(annotationClass); if (foundAnnotation != null) { if (annotation != null) { binder.addError( "More than one annotation claimed by %s on method %s." + " Methods can only have one annotation claimed per scanner.", scanner, method); return Optional.absent(); } annotation = foundAnnotation; } } return Optional.fromNullable(annotation); }
@Override protected void setup(Binder binder) { RecipeConfig recipes = buildConfigObject(RecipeConfig.class); Multibinder<HttpService> httpServices = Multibinder.newSetBinder(binder, HttpService.class); httpServices.addBinding().to(RecipeHttpService.class).in(Scopes.SINGLETON); if (recipes.getRecipes() == null) { return; } boolean set_default = false; for (String recipeConfig : recipes.getRecipes()) { URI recipeUri; try { recipeUri = new URI(recipeConfig); } catch (URISyntaxException e) { throw Throwables.propagate( new InvalidConfigurationException("The value of 'recipe' config must be an URI.")); } String path = "/" + recipeUri.getHost() + recipeUri.getPath(); InputStream stream; switch (recipeUri.getScheme()) { case "file": try { stream = new FileInputStream(path); } catch (FileNotFoundException e) { throw Throwables.propagate(e); } break; case "resources": stream = getClass().getResourceAsStream(path); if (stream == null) { throw new IllegalArgumentException("Recipe file couldn't found: " + recipeUri); } break; case "http": case "https": try { stream = recipeUri.toURL().openStream(); } catch (IOException e) { binder.addError("The value of 'recipe' property '%s' is not an URL"); return; } break; default: binder.addError( "The scheme of 'recipe' %s is not valid", recipeConfig, recipeUri.getScheme()); return; } ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); mapper.registerModule( new SimpleModule() { @Override public void setupModule(SetupContext context) { context.insertAnnotationIntrospector(new SwaggerAnnotationIntrospector_()); } }); Recipe recipe; try { recipe = mapper.readValue(stream, Recipe.class); } catch (IOException e) { binder.addError("'recipes' file %s couldn't parsed: %s", recipeConfig, e.getMessage()); return; } switch (recipe.getStrategy()) { case DEFAULT: if (set_default) { binder.addError("Only one recipe can use DEFAULT strategy."); return; } binder.bind(Recipe.class).toInstance(recipe); binder.bind(RecipeLoader.class).asEagerSingleton(); binder.bind(RecipeHandler.class).in(Scopes.SINGLETON); set_default = true; break; case SPECIFIC: Multibinder<InjectionHook> hooks = Multibinder.newSetBinder(binder, InjectionHook.class); hooks.addBinding().toInstance(new RecipeLoaderSingle(recipe)); break; default: throw new IllegalStateException(); } } }
@Override public void addError(Message message) { binder.addError(message); }
@Override public void addError(Throwable t) { binder.addError(t); }
@Override public void addError(String message, Object... arguments) { binder.addError(message, arguments); }