private void removeLinksToProducedTypes(final InjectableImpl specialized, final Set<InjectableImpl> toBeRemoved) { final Collection<InjectableReference> producedReferences = new ArrayList<>(); for (final MetaMethod method : specialized.type.getDeclaredMethodsAnnotatedWith(Produces.class)) { producedReferences.add(lookupInjectableReference(method.getReturnType(), qualFactory.forSource(method))); } for (final MetaField field : specialized.type.getDeclaredFields()) { if (field.isAnnotationPresent(Produces.class)) { producedReferences.add(lookupInjectableReference(field.getType(), qualFactory.forSource(field))); } } for (final InjectableReference reference : producedReferences) { final Iterator<InjectableBase> linkIter = reference.linked.iterator(); while (linkIter.hasNext()) { final InjectableBase link = linkIter.next(); if (link instanceof InjectableImpl && ((InjectableImpl) link).injectableType.equals(InjectableType.Producer)) { final InjectableImpl concreteLink = (InjectableImpl) link; final ProducerInstanceDependencyImpl producerMemberDep = GraphUtil.findProducerInstanceDep(concreteLink); if (producerMemberDep.producingMember.getDeclaringClass().equals(specialized.type)) { linkIter.remove(); toBeRemoved.add(concreteLink); } } } } }
private void updateSpecializedReferenceLinks(final InjectableImpl specialization, final Set<InjectableImpl> toBeRemoved, final InjectableReference injectableReference) { assert injectableReference.linked.size() == 1 : "The injectable " + injectableReference + " should have one link but instead has:\n" + injectableReference.linked; final InjectableImpl specialized = (InjectableImpl) injectableReference.linked.iterator().next(); specialization.qualifier = qualFactory.combine(specialization.qualifier, specialized.qualifier); toBeRemoved.add(specialized); injectableReference.linked.clear(); injectableReference.linked.add(lookupInjectableReference(specialization.type, specialization.qualifier)); removeLinksToProducedTypes(specialized, toBeRemoved); }
private Collection<MetaMethod> getMatchingMethods(final MetaClassMember member, final Collection<MetaMethod> disposesMethods) { final Collection<MetaMethod> matching = new ArrayList<>(); final Qualifier memberQual = qualFactory.forSource(member); final MetaClass producedType = getProducedType(member); for (final MetaMethod candidate : disposesMethods) { final MetaParameter disposesParam = candidate.getParametersAnnotatedWith(Disposes.class).iterator().next(); if (producedType.isAssignableTo(disposesParam.getType())) { final Qualifier paramQual = qualFactory.forSink(disposesParam); if (paramQual.isSatisfiedBy(memberQual)) { matching.add(candidate); } } } return matching; }
final boolean enabled; if (isSimpleton(type)) { builder.addInjectable(type, qualFactory.forSource(type), ANY, Dependent.class, InjectableType.Type, WiringElementType.DependentBean, WiringElementType.Simpleton); maybeProcessAsStaticOnlyProducer(builder, type, problems); final Injectable typeInjectable = builder.addInjectable(type, qualFactory.forSource(type), getPathPredicate(type, problems), directScope, InjectableType.Type, getWiringTypes(type, directScope)); processInjectionPoints(typeInjectable, builder, problems); final Injectable typeInjectable = builder.addInjectable(type, qualFactory.forSource(type), getPathPredicate(type, problems), directScope, InjectableType.Disabled, getWiringTypes(type, directScope)); maybeProcessAsProducer(builder, type, typeInjectable, false, problems); final WiringElementType scopeWiringType = (type.isAnnotationPresent(SharedSingleton.class) ? WiringElementType.SharedSingleton : WiringElementType.DependentBean); builder.addInjectable(type, qualFactory.forUniversallyQualified(), ANY, Dependent.class, InjectableType.JsType, scopeWiringType);
@Override public void afterInitialization(final IOCProcessingContext context, final InjectionContext injectionContext) { if (DYNAMIC_VALIDATION_ENABLED) { injectionContext.registerExtensionTypeCallback(type -> { if (type.isConcrete() && type.isAssignableTo(ConstraintValidator.class) && !type.getFullyQualifiedName().equals(NullType.class.getName())) { logger.debug("Found ConstraintValidator, {}", type.getFullyQualifiedName()); validators.add(type); } }); final InjectableHandle handle = new InjectableHandle(MetaClassFactory.get(DynamicValidator.class), injectionContext.getQualifierFactory().forDefault()); injectionContext.registerInjectableProvider(handle, (injectionSite, nameGenerator) -> new DefaultCustomFactoryInjectable(handle.getType(), handle.getQualifier(), "DynamicValidatorFactory", Singleton.class, Arrays.asList(WiringElementType.NormalScopedBean), new DynamicValidatorBodyGenerator(validators))); } }
private void processProducerAndDisposerMethodsDependencies(final DependencyGraphBuilder builder, final Collection<MetaMethod> disposesMethods, final MetaMethod method, final Injectable producedInjectable) { final MetaParameter[] params = method.getParameters(); for (int i = 0; i < params.length; i++) { final MetaParameter param = params[i]; builder.addProducerParamDependency(producedInjectable, param.getType(), qualFactory.forSink(param), i, param); } final Collection<MetaMethod> matchingDisposes = getMatchingMethods(method, disposesMethods); if (matchingDisposes.size() > 1) { // TODO descriptive message with names of disposers found. throw new RuntimeException(); } else if (!matchingDisposes.isEmpty()) { addDisposerDependencies(producedInjectable, matchingDisposes.iterator().next(), builder); } }
private InjectableReference createStaticMemberInjectable(final MetaClass producerType, final MetaClassMember member) { final InjectableReference retVal = new InjectableReference(producerType, qualFactory.forUniversallyQualified()); retVal.resolution = new InjectableImpl(producerType, qualFactory.forUniversallyQualified(), IOCProcessor.ANY, "", ApplicationScoped.class, InjectableType.Static, Collections.<WiringElementType> emptyList()); return retVal; }
private void addProviderForWidgetType(final InjectionContext injectionContext, final MetaClass widgetType) { if (widgetType.isPublic() && widgetType.isDefaultInstantiable()) { final InjectableHandle handle = new InjectableHandle(widgetType, injectionContext.getQualifierFactory().forDefault()); injectionContext.registerExactTypeInjectableProvider(handle, new InjectableProvider() {
private void addConstructorInjectionPoints(final Injectable concreteInjectable, final MetaConstructor injectableConstructor, final DependencyGraphBuilder builder) { final MetaParameter[] params = injectableConstructor.getParameters(); for (int i = 0; i < params.length; i++) { final MetaParameter param = params[i]; builder.addConstructorDependency(concreteInjectable, param.getType(), qualFactory.forSink(param), i, param); } }
@Override public void afterInitialization(final IOCProcessingContext context, final InjectionContext injectionContext) { final InjectableHandle handle = new InjectableHandle(MetaClassFactory.get(Logger.class), injectionContext.getQualifierFactory().forUniversallyQualified()); final Map<String, CustomFactoryInjectable> injectablesByLoggerName = new HashMap<String, CustomFactoryInjectable>();
@Override public void afterInitialization(final IOCProcessingContext context, final InjectionContext injectionContext) { final QualifierFactory qualifierFactory = injectionContext.getQualifierFactory(); final InjectableHandle transitionToHandle = new InjectableHandle(MetaClassFactory.get(Anchor.class), qualifierFactory.forSource(() -> new Annotation[] { TRANSITION_TO })); final InjectableHandle transitionToRoleHandle = new InjectableHandle(MetaClassFactory.get(Anchor.class), qualifierFactory.forSource(() -> new Annotation[] { TRANSITION_TO_ROLE })); scanForUniquePageRoles(context.getGeneratorContext()); registerProvider(injectionContext, transitionToHandle); registerProvider(injectionContext, transitionToRoleHandle); }
private void addDisposerDependencies(final Injectable producedInjectable, final MetaMethod disposer, final DependencyGraphBuilder builder) { for (final MetaParameter param : disposer.getParameters()) { if (param.isAnnotationPresent(Disposes.class)) { builder.addDisposesMethodDependency(producedInjectable, disposer.getDeclaringClass(), qualFactory.forSink(disposer.getDeclaringClass()), disposer); } else { builder.addDisposesParamDependency(producedInjectable, param.getType(), qualFactory.forSink(param), param.getIndex(), param); } } }
private void addContextualProviderInjectable(final Injectable providerInjectable, final DependencyGraphBuilder builder, final boolean enabled) { final MetaClass providerImpl = providerInjectable.getInjectedType(); final MetaMethod providerMethod = providerImpl.getMethod("provide", Class[].class, Annotation[].class); // Do not get generic return type for contextual providers final MetaClass providedType = providerMethod.getReturnType(); final InjectableType injectableType = (enabled ? InjectableType.ContextualProvider : InjectableType.Disabled); final Injectable providedInjectable = builder.addInjectable(providedType, qualFactory.forUniversallyQualified(), EXACT_TYPE, Dependent.class, injectableType, WiringElementType.Provider, WiringElementType.DependentBean); builder.addProducerMemberDependency(providedInjectable, providerImpl, providerInjectable.getQualifier(), providerMethod); }
private void removeSpecializedAndSpecializingLinks(final InjectableImpl specialization, final Set<InjectableImpl> toBeRemoved, final MetaClass specializingType, final MetaClass enclosingType, final Iterator<InjectableBase> linkedIter, final InjectableImpl linkedInjectable) { if (linkedInjectable.injectableType.equals(InjectableType.Producer)) { final MetaClass foundProducerType = GraphUtil.findProducerInstanceDep(linkedInjectable).injectable.type.getErased(); if (foundProducerType.equals(enclosingType.getErased()) || foundProducerType.equals(specializingType.getErased())) { linkedIter.remove(); } if (foundProducerType.equals(enclosingType.getErased())) { toBeRemoved.add(linkedInjectable); specialization.qualifier = qualFactory.combine(specialization.qualifier, linkedInjectable.qualifier); } } }
@Override public void afterInitialization(final IOCProcessingContext context, final InjectionContext injectionContext) { final QualifierFactory qualifierFactory = injectionContext.getQualifierFactory(); final InjectableHandle transitionToHandle = new InjectableHandle(MetaClassFactory.get(Anchor.class), qualifierFactory.forSource(() -> new Annotation[] { TRANSITION_TO })); final InjectableHandle transitionToRoleHandle = new InjectableHandle(MetaClassFactory.get(Anchor.class), qualifierFactory.forSource(() -> new Annotation[] { TRANSITION_TO_ROLE })); scanForUniquePageRoles(context.getGeneratorContext()); registerProvider(injectionContext, transitionToHandle); registerProvider(injectionContext, transitionToRoleHandle); }
private void addFieldInjectionPoints(final Injectable typeInjectable, final DependencyGraphBuilder builder, final List<String> problems) { final boolean noPublicFieldsAllowed = typeInjectable.getWiringElementTypes().contains(WiringElementType.NormalScopedBean); final MetaClass type = typeInjectable.getInjectedType(); final Collection<Class<? extends Annotation>> injectAnnotations = injectionContext.getAnnotationsForElementType(WiringElementType.InjectionPoint); for (final Class<? extends Annotation> inject : injectAnnotations) { for (final MetaField field : type.getFieldsAnnotatedWith(inject)) { if (noPublicFieldsAllowed && field.isPublic()) { problems.add("The normal scoped bean " + type.getFullyQualifiedName() + " has a public field " + field.getName()); } builder.addFieldDependency(typeInjectable, field.getType(), qualFactory.forSink(field), field); } } }
@Override public CustomFactoryInjectable getInjectable(final InjectionSite injectionSite, final FactoryNameGenerator nameGenerator) { final String loggerName; if (injectionSite.isAnnotationPresent(NamedLogger.class)) { loggerName = injectionSite.getAnnotation(NamedLogger.class).value(); } else { loggerName = injectionSite.getEnclosingType().getFullyQualifiedName(); } if (!injectablesByLoggerName.containsKey(loggerName)) { final Statement loggerValue = invokeStatic(LoggerFactory.class, "getLogger", loggerName); final FactoryBodyGenerator generator = new AbstractBodyGenerator() { @Override protected List<Statement> generateCreateInstanceStatements(final ClassStructureBuilder<?> bodyBlockBuilder, final Injectable injectable, final DependencyGraph graph, final InjectionContext injectionContext) { return Collections.singletonList(Stmt.nestedCall(loggerValue).returnValue()); } }; final MetaClass type = MetaClassFactory.get(Logger.class); final Qualifier qualifier = injectionContext.getQualifierFactory().forUniversallyQualified(); injectablesByLoggerName.put(loggerName, new DefaultCustomFactoryInjectable(type, qualifier, nameGenerator.generateFor(type, qualifier, InjectableType.ExtensionProvided), Dependent.class, Collections.singletonList(WiringElementType.DependentBean), generator)); } return injectablesByLoggerName.get(loggerName); } });
@Test public void typeWithCustomQualifier() throws Exception { final Qualifier customQualifier = qualFactory.forSource(() -> new Annotation[] { new CustomQualifier() { @Override public Class<? extends Annotation> annotationType() { return CustomQualifier.class; } }}); final String generated = generator.generateFor(object, customQualifier, Type); assertEquals("Type_factory__j_l_Object__quals__j_e_i_Any_o_j_e_i_u_r_CustomQualifier", generated); }
private void addMethodInjectionPoints(final Injectable typeInjectable, final DependencyGraphBuilder builder, final List<String> problems) { final MetaClass type = typeInjectable.getInjectedType(); final Collection<Class<? extends Annotation>> injectAnnotations = injectionContext.getAnnotationsForElementType(WiringElementType.InjectionPoint); for (final Class<? extends Annotation> inject : injectAnnotations) { for (final MetaMethod setter : type.getMethodsAnnotatedWith(inject)) { if (setter.getParameters().length != 1) { problems.add("The method injection point " + setter.getName() + " in " + setter.getDeclaringClass().getFullyQualifiedName() + " should have exactly one parameter, not " + setter.getParameters().length + "."); } else { final MetaParameter metaParam = setter.getParameters()[0]; builder.addSetterMethodDependency(typeInjectable, metaParam.getType(), qualFactory.forSink(setter.getParameters()[0]), setter); } } } }
private void addProviderInjectable(final Injectable providerImplInjectable, final DependencyGraphBuilder builder, final boolean enabled) { final MetaClass providerImpl = providerImplInjectable.getInjectedType(); final MetaMethod providerMethod = providerImpl.getMethod("get", new Class[0]); final MetaClass providedType = getMethodReturnType(providerMethod); final InjectableType injectableType = (enabled ? InjectableType.Provider : InjectableType.Disabled); final Injectable providedInjectable = builder.addInjectable(providedType, qualFactory.forSource(providerMethod), EXACT_TYPE, Dependent.class, injectableType, WiringElementType.Provider, WiringElementType.DependentBean); builder.addProducerMemberDependency(providedInjectable, providerImplInjectable.getInjectedType(), providerImplInjectable.getQualifier(), providerMethod); }