/** * Variant of {@link #bindInterceptor(Class, Class...) bindInterceptor} that * allows constructor-injection of interceptors described by class, each * wrapped by a method interceptor wrapper. * @param classMatcher matches classes the interception should apply to. * For example: {@code only(Runnable.class)}. * @param methodMatcher matches methods the interception should apply to. * For example: {@code annotatedWith(Transactional.class)}. * @param methodInterceptorWrapper a wrapper applied to each of the specified interceptors. * @param methodInterceptorClasses chain of * {@link org.aopalliance.intercept.MethodInterceptor MethodInterceptor}s * used to intercept calls, specified by class. */ public void bindInterceptor(Matcher<? super Class<?>> classMatcher, Matcher<? super Method> methodMatcher, MethodInterceptorWrapper methodInterceptorWrapper, Class<?>... methodInterceptorClasses) { if (methodInterceptorClasses != null) { MethodInterceptor[] interceptors = new MethodInterceptor[methodInterceptorClasses.length]; int i = 0; for (Class<?> cls : methodInterceptorClasses) { if (!MethodInterceptor.class.isAssignableFrom(cls)) { addError("bindInterceptor: %s does not implement MethodInterceptor", cls.getName()); } else { @SuppressWarnings("unchecked") Class<? extends MethodInterceptor> c = (Class<? extends MethodInterceptor>) cls; interceptors[i++] = wrap(methodInterceptorWrapper, c); } } bindInterceptor(classMatcher, methodMatcher, interceptors); } }
/** * Creates a matcher that will match methods of an interface, optionally excluding inherited * methods. * * @param matchInterface The interface to match. * @param declaredMethodsOnly if {@code true} only methods directly declared in the interface * will be matched, otherwise all methods on the interface are matched. * @return A new matcher instance. */ public static Matcher<Method> interfaceMatcher( Class<?> matchInterface, boolean declaredMethodsOnly) { Method[] methods = declaredMethodsOnly ? matchInterface.getDeclaredMethods() : matchInterface.getMethods(); final Set<Pair<String, Class<?>[]>> interfaceMethods = ImmutableSet.copyOf(Iterables.transform(ImmutableList.copyOf(methods), CANONICALIZE)); final LoadingCache<Method, Pair<String, Class<?>[]>> cache = CacheBuilder.newBuilder() .build(CacheLoader.from(CANONICALIZE)); return new AbstractMatcher<Method>() { @Override public boolean matches(Method method) { return interfaceMethods.contains(cache.getUnchecked(method)); } }; }
/** * Binds an exception trap on all interface methods of all classes bound against an interface. * Individual methods may opt out of trapping by annotating with {@link AllowUnchecked}. * Only void methods are allowed, any non-void interface methods must explicitly opt out. * * @param binder The binder to register an interceptor with. * @param wrapInterface Interface whose methods should be wrapped. * @throws IllegalArgumentException If any of the non-whitelisted interface methods are non-void. */ public static void bindExceptionTrap(Binder binder, Class<?> wrapInterface) throws IllegalArgumentException { Set<Method> disallowed = ImmutableSet.copyOf(Iterables.filter( ImmutableList.copyOf(wrapInterface.getMethods()), Predicates.and(Predicates.not(IS_WHITELISTED), Predicates.not(VOID_METHOD)))); Preconditions.checkArgument(disallowed.isEmpty(), "Non-void methods must be explicitly whitelisted with @AllowUnchecked: " + disallowed); Matcher<Method> matcher = Matchers.not(WHITELIST_MATCHER).and(interfaceMatcher(wrapInterface, false)); binder.bindInterceptor(Matchers.subclassesOf(wrapInterface), matcher, new MethodInterceptor() { @Override public Object invoke(MethodInvocation invocation) throws Throwable { try { return invocation.proceed(); } catch (RuntimeException e) { LOG.warn("Trapped uncaught exception: " + e, e); return null; } } }); }
/** * Returns a collection of all instances matching the given matcher * * @param matcher * matches the types to return instances * @return a set of objects returned from this injector */ public static <T> Set<T> getInstancesOf(Injector injector, Matcher<Class> matcher) { Set<T> answer = Sets.newHashSet(); Set<Entry<Key<?>, Binding<?>>> entries = injector.getBindings() .entrySet(); for (Entry<Key<?>, Binding<?>> entry : entries) { Key<?> key = entry.getKey(); Class<?> keyType = getKeyType(key); if (keyType != null && matcher.matches(keyType)) { Binding<?> binding = entry.getValue(); Object value = binding.getProvider().get(); answer.add((T) value); } } return answer; }
/** * Returns a collection of all of the providers matching the given matcher * * @param matcher * matches the types to return instances * @return a set of objects returned from this injector */ public static <T> Set<Provider<T>> getProvidersOf(Injector injector, Matcher<Class> matcher) { Set<Provider<T>> answer = Sets.newHashSet(); Set<Entry<Key<?>, Binding<?>>> entries = injector.getBindings() .entrySet(); for (Entry<Key<?>, Binding<?>> entry : entries) { Key<?> key = entry.getKey(); Class<?> keyType = getKeyType(key); if (keyType != null && matcher.matches(keyType)) { Binding<?> binding = entry.getValue(); answer.add((Provider<T>) binding.getProvider()); } } return answer; }
private static void convertToClasses( InjectorImpl injector, final Matcher<? super Class<?>> typeMatcher, TypeConverter converter) { internalConvertToTypes( injector, new AbstractMatcher<TypeLiteral<?>>() { @Override public boolean matches(TypeLiteral<?> typeLiteral) { Type type = typeLiteral.getType(); if (!(type instanceof Class)) { return false; } Class<?> clazz = (Class<?>) type; return typeMatcher.matches(clazz); } @Override public String toString() { return typeMatcher.toString(); } }, converter); }
public void testBindListener() { final Matcher<Object> typeMatcher = Matchers.only(TypeLiteral.get(String.class)); final TypeListener listener = new TypeListener() { @Override public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) { throw new UnsupportedOperationException(); } }; checkModule( new AbstractModule() { @Override protected void configure() { bindListener(typeMatcher, listener); } }, new FailingElementVisitor() { @Override public Void visit(TypeListenerBinding binding) { assertSame(typeMatcher, binding.getTypeMatcher()); assertSame(listener, binding.getListener()); return null; } }); }
private static void convertToClasses(InjectorImpl injector, final Matcher<? super Class<?>> typeMatcher, TypeConverter converter) { internalConvertToTypes(injector, new AbstractMatcher<TypeLiteral<?>>() { public boolean matches(TypeLiteral<?> typeLiteral) { Type type = typeLiteral.getType(); if (!(type instanceof Class)) { return false; } Class<?> clazz = (Class<?>) type; return typeMatcher.matches(clazz); } @Override public String toString() { return typeMatcher.toString(); } }, converter); }
public void testBindListener() { final Matcher<Object> typeMatcher = Matchers.only(TypeLiteral.get(String.class)); final TypeListener listener = new TypeListener() { public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) { throw new UnsupportedOperationException(); } }; checkModule( new AbstractModule() { protected void configure() { bindListener(typeMatcher, listener); } }, new FailingElementVisitor() { @Override public Void visit(TypeListenerBinding binding) { assertSame(typeMatcher, binding.getTypeMatcher()); assertSame(listener, binding.getListener()); return null; } } ); }
public void testAddingInterceptors() throws NoSuchMethodException { final Matcher<Object> buzz = only(C.class.getMethod("buzz")); Injector injector = Guice.createInjector(new AbstractModule() { @Override protected void configure() { bindInterceptor(any(), buzz, prefixInterceptor("ka")); bindInterceptor(any(), any(), prefixInterceptor("fe")); bindListener(onlyAbcd, new TypeListener() { public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) { encounter.bindInterceptor(any(), prefixInterceptor("li")); encounter.bindInterceptor(buzz, prefixInterceptor("no")); } }); } }); // interceptors must be invoked in the order they're bound. C c = injector.getInstance(C.class); assertEquals("kafelinobuzz", c.buzz()); assertEquals("felibeep", c.beep()); }
@Override protected void configure() { // Use interceptor that checks CurrentUser and calls AccessRefuser to deny access final MethodInterceptor interceptor = new AuthConstraintMethodInterceptor(getProvider(CurrentUser.class), config, calls, granted, denied, authenticatedDenied); // Collect all REST service interfaces we implement Set<Class<?>> restIfaces = RestResourceRegistry.getResources().stream().map(RestResource:: getResourceClass).collect( Collectors.toSet()); Matcher<Method> matcher = new WebMethodMatcher(restIfaces); bindInterceptor(Matchers.any(), matcher, interceptor); }
private void convertToClasses(final Matcher<? super Class<?>> typeMatcher, TypeConverter converter) { internalConvertToTypes(new AbstractMatcher<TypeLiteral<?>>() { public boolean matches(TypeLiteral<?> typeLiteral) { Type type = typeLiteral.getType(); if (!(type instanceof Class)) { return false; } Class<?> clazz = (Class<?>) type; return typeMatcher.matches(clazz); } @Override public String toString() { return typeMatcher.toString(); } }, converter); }
public void testAddingInterceptors() throws NoSuchMethodException { final Matcher<Object> buzz = only(C.class.getMethod("buzz")); Injector injector = Guice.createInjector(new AbstractModule() { protected void configure() { bindInterceptor(any(), buzz, prefixInterceptor("ka")); bindInterceptor(any(), any(), prefixInterceptor("fe")); bindListener(onlyAbcd, new TypeListener() { public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) { encounter.bindInterceptor(any(), prefixInterceptor("li")); encounter.bindInterceptor(buzz, prefixInterceptor("no")); } }); } }); // interceptors must be invoked in the order they're bound. C c = injector.getInstance(C.class); assertEquals("kafelinobuzz", c.buzz()); assertEquals("felibeep", c.beep()); }
private static Set<Class<?>> getTransactionClasses(InjectorConfig config) { Set<Class<?>> ret = new HashSet<>(); { Set<String> packages = getPackageNames(config.getTransactionPackages()); if (isNotNoSize(packages)) { final Filter<Class<?>> filter = config.getTransactionClassFilter(); for (String pkg : packages) { final String regex = getPackageRegex(pkg); ret.addAll(ResolverUtils.find(new com.brightgenerous.resolver.Matcher() { @Override public boolean matches(Class<?> arg0) { if (arg0.isAnnotation() || arg0.isEnum()) { return false; } if ((filter != null) && !filter.filter(arg0)) { return false; } return arg0.getName().matches(regex); } }, pkg)); } } } return ret; }
private static Set<Class<?>> getMapperClasses(InjectorConfig config) { Set<Class<?>> ret = new HashSet<>(); { Set<String> packages = getPackageNames(config.getMapperPackages()); if (isNotNoSize(packages)) { final Filter<Class<?>> filter = config.getMapperClassFilter(); for (String pkg : packages) { final String regex = getPackageRegex(pkg); ret.addAll(ResolverUtils.find(new com.brightgenerous.resolver.Matcher() { @Override public boolean matches(Class<?> arg0) { if (arg0.isAnnotation() || arg0.isEnum()) { return false; } if ((filter != null) && !filter.filter(arg0)) { return false; } return arg0.getName().matches(regex); } }, pkg)); } } } return ret; }
/** * Create a Matcher which matches against a service method. * * @return Matcher matching a service method */ Matcher<Method> matchServiceMethod() { return new AbstractMatcher<Method>() { @Override public boolean matches(Method method) { return isServiceMethod(method); } }; }
@Override default Matcher<T> and(com.google.inject.matcher.Matcher<? super T> other) { return new AbstractMatcher<T>() { @Override public boolean matches(T t) { return FunctionalMatcher.this.matches(t) && other.matches(t); } }; }
@Override default Matcher<T> or(com.google.inject.matcher.Matcher<? super T> other) { return new AbstractMatcher<T>() { @Override public boolean matches(T t) { return FunctionalMatcher.this.matches(t) || other.matches(t); } }; }
/** * Variant of {@link #bindInterceptor(Class, Class...) bindInterceptor} that * allows constructor-injection of interceptors described by Key, each * wrapped by a method interceptor wrapper. * @param classMatcher matches classes the interception should apply to. * For example: {@code only(Runnable.class)}. * @param methodMatcher matches methods the interception should apply to. * For example: {@code annotatedWith(Transactional.class)}. * @param methodInterceptorWrapper a wrapper applied to each of the specified interceptors. * @param methodInterceptorKeys chain of * {@link org.aopalliance.intercept.MethodInterceptor MethodInterceptor}s * used to intercept calls, specified by {@link com.google.inject.Key Key}. */ public void bindInterceptor(Matcher<? super Class<?>> classMatcher, Matcher<? super Method> methodMatcher, MethodInterceptorWrapper methodInterceptorWrapper, Key<?>... methodInterceptorKeys) { if (methodInterceptorKeys != null) { MethodInterceptor[] interceptors = new MethodInterceptor[methodInterceptorKeys.length]; int i = 0; for (Key<?> key : methodInterceptorKeys) { Type type = key.getTypeLiteral().getType(); if (!(type instanceof Class)) { addError("bindInterceptor: %s is not a Key for a MethodInterceptor subtype", key); } else // type instanceof Class { Class<?> cls = (Class<?>) type; if (!MethodInterceptor.class.isAssignableFrom(cls)) { addError("bindInterceptor: %s does not implement MethodInterceptor", cls.getName()); } else { @SuppressWarnings("unchecked") Key<? extends MethodInterceptor> k = (Key<? extends MethodInterceptor>) key; interceptors[i++] = wrap(methodInterceptorWrapper, k); } } } bindInterceptor(classMatcher, methodMatcher, interceptors); } }
@VisibleForTesting static void bindThriftDecorator( Binder binder, Matcher<? super Class<?>> classMatcher, MethodInterceptor interceptor) { binder.bindInterceptor( classMatcher, Matchers.returns(Matchers.subclassesOf(Response.class)), interceptor); binder.requestInjection(interceptor); }
@Override protected void configureServlets() { final Matcher<AnnotatedElement> jaxrsMethods = Matchers.annotatedWith(LogCall.class) .or(Matchers.annotatedWith(GET.class)) .or(Matchers.annotatedWith(POST.class)) .or(Matchers.annotatedWith(PUT.class)) .or(Matchers.annotatedWith(DELETE.class)) .or(Matchers.annotatedWith(OPTIONS.class)) .or(Matchers.annotatedWith(HEAD.class)); bindInterceptor(Matchers.any(), jaxrsMethods, new LogCallInterceptor()); bind(ObjectMapperContextResolver.class); filter(prefix + "/*").through(GuiceResteasyFilterDispatcher.class); }
/** * Returns a collection of all of the bindings matching the given matcher * * @param matcher * matches the types to return instances * @return a set of objects returned from this injector */ public static Set<Binding<?>> getBindingsOf(Injector injector, Matcher<Class> matcher) { Set<Binding<?>> answer = Sets.newHashSet(); Set<Entry<Key<?>, Binding<?>>> entries = injector.getBindings() .entrySet(); for (Entry<Key<?>, Binding<?>> entry : entries) { Key<?> key = entry.getKey(); Class<?> keyType = getKeyType(key); if (keyType != null && matcher.matches(keyType)) { answer.add(entry.getValue()); } } return answer; }
@Override protected void bindInterceptor(final Matcher<? super Class<?>> classMatcher, final Matcher<? super Method> methodMatcher, final MethodInterceptor... interceptors) { if (!bound) { // Explicitly bind module instance under a specific sub-type (not Module as Guice forbids that) bind(Key.get(AbstractInterceptorModule.class, Names.named(getClass().getName()))).toInstance(this); bound = true; } super.bindInterceptor(classMatcher, methodMatcher, interceptors); }
private static Matcher<Binding<?>> keyMatcher(final Class<?> clazz) { return new AbstractMatcher<Binding<?>>() { @Override public boolean matches(Binding<?> t) { return t.getKey().equals(Key.get(clazz)); } }; }
@Override protected void setup() { bind(BasicAuthenticationHandler.class); bind(FormAuthenticationHandler.class); Matcher<Class> controllers = subclassesOf(Controller.class); Matcher<Class> notControllers = not(controllers); /* * The grand ControllerInterceptor. */ ControllerInterceptor controllerInterceptor = new ControllerInterceptor(getProvider(SecurityManager.class)); bindInterceptor(controllers, any(), controllerInterceptor); /* * Individual method interceptors for annotating non-controllers. */ RequireTokenInterceptor tokenInterceptor = new RequireTokenInterceptor(getProvider(SecurityManager.class)); bindInterceptor(notControllers, annotatedWith(RequireToken.class), tokenInterceptor); RequireAuthenticatedInterceptor authenticatedInterceptor = new RequireAuthenticatedInterceptor(); bindInterceptor(notControllers, annotatedWith(RequireAuthenticated.class), authenticatedInterceptor); RequireAdministratorInterceptor administratorInterceptor = new RequireAdministratorInterceptor(); bindInterceptor(notControllers, annotatedWith(RequireAdministrator.class), administratorInterceptor); RequireRoleInterceptor roleInterceptor = new RequireRoleInterceptor(); bindInterceptor(notControllers, annotatedWith(RequireRole.class), roleInterceptor); RequirePermissionInterceptor permissionInterceptor = new RequirePermissionInterceptor(); bindInterceptor(notControllers, annotatedWith(RequirePermission.class), permissionInterceptor); RequireRolesInterceptor rolesInterceptor = new RequireRolesInterceptor(); bindInterceptor(notControllers, annotatedWith(RequireRoles.class), rolesInterceptor); RequirePermissionsInterceptor permissionsInterceptor = new RequirePermissionsInterceptor(); bindInterceptor(notControllers, annotatedWith(RequirePermissions.class), permissionsInterceptor); }
@Override protected void configure() { JdbcAdapter.newInstance(configs.values(), poolType, this.getClass()); JdbcTransactionalMethodInterceptor interceptor = new JdbcTransactionalMethodInterceptor(); requestInjection(interceptor); Matcher<AnnotatedElement> annotatedElement = annotatedWith(JdbcTransactional.class); bindInterceptor(any(), annotatedElement, interceptor); bindInterceptor(annotatedElement, not(annotatedElement), interceptor); }
@Override protected void configure() { final MultiTransactionalMethodInterceptor interceptor = new MultiTransactionalMethodInterceptor(); requestInjection(interceptor); final Matcher<AnnotatedElement> annotatedElement = annotatedWith(MultiTransactional.class); bindInterceptor(any(), annotatedElement, interceptor); bindInterceptor(annotatedElement, not(annotatedElement), interceptor); }
public static Matcher<? super Class<?>> newClassOrSuperclassAnnotatedWithMatcher( final Class<? extends Annotation> annotationClass) { return new AbstractMatcher<Class<?>>() { @Override public boolean matches(Class<?> clazz) { return isClassOrSuperclassAnnotatedWith(clazz, annotationClass); } }; }
public static Matcher<? super Method> newComponentActionMethodMatcher() { return new AbstractMatcher<Method>() { @Override public boolean matches(Method method) { return "action".equals(method.getName()) || "validate".equals(method.getName()) || "invalid".equals(method.getName()) || method.isAnnotationPresent(Action.class) || method.isAnnotationPresent(Validate.class) || method.isAnnotationPresent(Invalid.class); } }; }
@Override protected void bindInterceptor(final Matcher<? super Class<?>> classMatcher, final Matcher<? super Method> methodMatcher, final MethodInterceptor... interceptors) { // hack to correctly bind @Transactional annotation for java8: // aop tries to intercept synthetic methods which cause a lot of warnings // (and generally not correct) super.bindInterceptor(classMatcher, new AbstractMatcher<Method>() { @Override public boolean matches(final Method method) { return !method.isSynthetic() && !method.isBridge() && methodMatcher.matches(method); } }, interceptors); }
protected AbstractObjectInitializer(final Provider<OObjectDatabaseTx> dbProvider, final ObjectSchemeInitializer schemeInitializer, final Matcher<? super Class<?>> classMatcher, final String... packages) { this.schemeInitializer = schemeInitializer; this.dbProvider = dbProvider; this.classMatcher = classMatcher; this.packages = packages.length == 0 ? new String[]{""} : packages; }
/** * @see Binder#bindInterceptor(com.google.inject.matcher.Matcher, * com.google.inject.matcher.Matcher, org.aopalliance.intercept.MethodInterceptor[]) */ protected final void bindInterceptor( Matcher<? super Class<?>> classMatcher, Matcher<? super Method> methodMatcher, org.aopalliance.intercept.MethodInterceptor... interceptors) { binder().bindInterceptor(classMatcher, methodMatcher, interceptors); }
@Override public void bindInterceptor( Matcher<? super Class<?>> classMatcher, Matcher<? super Method> methodMatcher, org.aopalliance.intercept.MethodInterceptor... interceptors) { elements.add( new InterceptorBinding(getElementSource(), classMatcher, methodMatcher, interceptors)); }
/** @since 3.0 */ public TypeConverterBinding( Object source, Matcher<? super TypeLiteral<?>> typeMatcher, TypeConverter typeConverter) { this.source = checkNotNull(source, "source"); this.typeMatcher = checkNotNull(typeMatcher, "typeMatcher"); this.typeConverter = checkNotNull(typeConverter, "typeConverter"); }
InterceptorBinding( Object source, Matcher<? super Class<?>> classMatcher, Matcher<? super Method> methodMatcher, MethodInterceptor[] interceptors) { this.source = checkNotNull(source, "source"); this.classMatcher = checkNotNull(classMatcher, "classMatcher"); this.methodMatcher = checkNotNull(methodMatcher, "methodMatcher"); this.interceptors = ImmutableList.copyOf(interceptors); }
@Override public void bindInterceptor( Matcher<? super Method> methodMatcher, org.aopalliance.intercept.MethodInterceptor... interceptors) { checkState(valid, "Encounters may not be used after hear() returns."); // make sure the applicable aspects is mutable if (aspects == null) { aspects = Lists.newArrayList(); } aspects.add(new MethodAspect(Matchers.any(), methodMatcher, interceptors)); }
/** * @param classMatcher matches classes the interceptor should apply to. For example: {@code * only(Runnable.class)}. * @param methodMatcher matches methods the interceptor should apply to. For example: {@code * annotatedWith(Transactional.class)}. * @param interceptors to apply */ MethodAspect( Matcher<? super Class<?>> classMatcher, Matcher<? super Method> methodMatcher, List<MethodInterceptor> interceptors) { this.classMatcher = checkNotNull(classMatcher, "class matcher"); this.methodMatcher = checkNotNull(methodMatcher, "method matcher"); this.interceptors = checkNotNull(interceptors, "interceptors"); }
/** * @see Binder#bindInterceptor(com.google.inject.matcher.Matcher, * com.google.inject.matcher.Matcher, org.aopalliance.intercept.MethodInterceptor[]) */ protected void bindInterceptor( Matcher<? super Class<?>> classMatcher, Matcher<? super Method> methodMatcher, org.aopalliance.intercept.MethodInterceptor... interceptors) { binder().bindInterceptor(classMatcher, methodMatcher, interceptors); }
public void testBindIntercepor() { final Matcher<Class> classMatcher = Matchers.subclassesOf(List.class); final Matcher<Object> methodMatcher = Matchers.any(); final org.aopalliance.intercept.MethodInterceptor methodInterceptor = new org.aopalliance.intercept.MethodInterceptor() { @Override public Object invoke(org.aopalliance.intercept.MethodInvocation methodInvocation) { return null; } }; checkModule( new AbstractModule() { @Override protected void configure() { bindInterceptor(classMatcher, methodMatcher, methodInterceptor); } }, new FailingElementVisitor() { @Override public Void visit(InterceptorBinding command) { assertSame(classMatcher, command.getClassMatcher()); assertSame(methodMatcher, command.getMethodMatcher()); assertEquals(Arrays.asList(methodInterceptor), command.getInterceptors()); return null; } }); }