private String getBeanName(final Injectable injectable) { final Named named = injectable.getInjectedType().getAnnotation(Named.class); return (named != null) ? named.value() : null; }
private static void traceConstituentHashContents(final Injectable injectable, final String name) { log.trace("Begin trace of hashContent for {}", name); log.trace("Combined content: {}", injectable.hashContent()); log.trace("HashContent for injectable type: {}", injectable.getInjectedType().hashContent()); for (final Dependency dep : injectable.getDependencies()) { log.trace("HashContent for {} dep of type {}: {}", dep.getDependencyType().toString(), dep.getInjectable().getInjectedType(), dep.getInjectable().getInjectedType().hashContent()); } log.trace("End trace of hashContent for {}", name); }
public static AbstractStatementBuilder getAssignableTypesArrayStmt(final Injectable injectable) { final Object[] assignableTypes = injectable.getAnnotatedObject() .flatMap(annotated -> Optional.ofNullable(annotated.getAnnotation(Typed.class))) .map(typedAnno -> typedAnno.value()) // Ensure that Object is an assignable type .map(beanTypes -> { if (Arrays.stream(beanTypes).anyMatch(type -> Object.class.equals(type))) { return (Object[]) beanTypes; } else { final Class<?>[] copyWithObject = Arrays.copyOf(beanTypes, beanTypes.length+1); copyWithObject[beanTypes.length] = Object.class; return (Object[]) copyWithObject; } }) .orElseGet(() -> getAllAssignableTypes(injectable.getInjectedType()).stream().filter(MetaClass::isPublic).toArray()); return newArray(Class.class).initialize(assignableTypes); }
@Override public boolean matches(final Injectable injectable) { return matchingTypes.contains(injectable.getInjectableType()) && !injectable.getWiringElementTypes().contains(WiringElementType.Simpleton); } },
private MetaClass addFactoryDeclaration(final Injectable injectable, final IOCProcessingContext processingContext) { final String factoryName = injectable.getFactoryName(); final MetaClass typeCreatedByFactory = injectable.getInjectedType(); return addFactoryDeclaration(factoryName, typeCreatedByFactory, processingContext); }
protected Statement generateFactoryHandleStatement(final Injectable injectable) { final Statement newObject; if (injectable.getInjectedType().isAnnotationPresent(ActivatedBy.class)) { final Class<? extends BeanActivator> activatorType = injectable.getInjectedType().getAnnotation(ActivatedBy.class).value(); newObject = newObject(FactoryHandleImpl.class, loadLiteral(injectable.getInjectedType()), injectable.getFactoryName(), injectable.getScope(), isEager(injectable.getInjectedType()), injectable.getBeanName(), !injectable.isContextual(), loadLiteral(activatorType)); } else { newObject = newObject(FactoryHandleImpl.class, loadLiteral(injectable.getInjectedType()), injectable.getFactoryName(), injectable.getScope(), isEager(injectable.getInjectedType()), injectable.getBeanName(), !injectable.isContextual()); } return newObject; }
private List<Statement> fieldCreateInstanceStatements(final MetaField producingMember, final Injectable producerInjectable, final Injectable producedInjectable, final ClassStructureBuilder<?> bodyBlockBuilder) { final List<Statement> stmts = new ArrayList<>(); controller.ensureMemberExposed(producingMember); if (!producingMember.isStatic()) { final Statement producerInstanceValue = loadVariable("contextManager").invoke("getInstance", producerInjectable.getFactoryName()); stmts.add(declareVariable(PRODUCER_INSTANCE, producerInjectable.getInjectedType(), producerInstanceValue)); stmts.add(loadVariable(PRODUCER_INSTANCE).assignValue(Stmt.castTo(producerInjectable.getInjectedType(), invokeStatic(Factory.class, "maybeUnwrapProxy", loadVariable(PRODUCER_INSTANCE))))); } final Statement invocation = controller.exposedFieldStmt(loadVariable(PRODUCER_INSTANCE), producingMember); stmts.add(declareFinalVariable("instance", producedInjectable.getInjectedType(), invocation)); if (!producingMember.isStatic()) { stmts.add(setProducerInstanceReference()); if (producerInjectable.getWiringElementTypes().contains(WiringElementType.DependentBean)) { stmts.add(loadVariable("this").invoke("registerDependentScopedReference", loadVariable("instance"), loadVariable(PRODUCER_INSTANCE))); } } stmts.add(loadVariable("instance").returnValue()); return stmts; }
if (depInjectable.isContextual()) { final MetaClass[] typeArgsClasses = getTypeArguments(field.getType()); final Annotation[] qualifiers = getQualifiers(field).toArray(new Annotation[0]); injectedValue = castTo(depInjectable.getInjectedType(), loadVariable("contextManager").invoke("getContextualInstance", loadLiteral(depInjectable.getFactoryName()), typeArgsClasses, qualifiers)); } else { injectedValue = castTo(depInjectable.getInjectedType(), loadVariable("contextManager").invoke("getInstance", loadLiteral(depInjectable.getFactoryName()))); createInstanceStatements.add(declareFinalVariable(fieldDepVarName, depInjectable.getInjectedType(), injectedValue)); if (depInjectable.getWiringElementTypes().contains(WiringElementType.DependentBean)) { createInstanceStatements .add(loadVariable("this").invoke("registerDependentScopedReference", loadVariable("instance"), loadVariable(fieldDepVarName)));
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); }
protected Injectable getProviderInjectable(final Injectable depInjectable) { for (final Dependency dep : depInjectable.getDependencies()) { if (dep.getDependencyType().equals(DependencyType.ProducerMember)) { final MetaClass providerType = dep.getInjectable().getInjectedType(); if (providerType.isAssignableTo(getProviderRawType())) { return dep.getInjectable(); } else { throw new RuntimeException("Unrecognized contextual provider type " + providerType.getFullyQualifiedName()); } } } throw new RuntimeException(); }
private ContextualStatementBuilder getInjectedValue(final Injectable depInjectable, final ParamDependency paramDep) { final ContextualStatementBuilder injectedValue; if (depInjectable.isContextual()) { final MetaClass[] typeArgsClasses = getTypeArguments(paramDep.getParameter().getType()); final Annotation[] qualifiers = getQualifiers(paramDep.getParameter()).toArray(new Annotation[0]); injectedValue = castTo(depInjectable.getInjectedType(), loadVariable("contextManager").invoke("getContextualInstance", loadLiteral(depInjectable.getFactoryName()), typeArgsClasses, qualifiers)); } else { injectedValue = castTo(depInjectable.getInjectedType(), loadVariable("contextManager").invoke("getInstance", loadLiteral(depInjectable.getFactoryName()))); } return injectedValue; } }
private Injectable maybeProcessAsExtension(final BaseDependency dep, final Injectable depOwner, final Map<String, Injectable> customProvidedInjectables, final Multimap<ResolutionPriority, InjectableImpl> resolvedByPriority, final Collection<InjectableImpl> resolved) { Injectable injectable = resolved.iterator().next(); if (injectable.isExtension()) { final ExtensionInjectable providedInjectable = (ExtensionInjectable) injectable; final Collection<Injectable> otherResolvedInjectables = new ArrayList<>(resolvedByPriority.values()); otherResolvedInjectables.remove(injectable); final InjectionSite site = new InjectionSite(depOwner.getInjectedType(), dep, otherResolvedInjectables); injectable = providedInjectable.provider.getInjectable(site, nameGenerator); customProvidedInjectables.put(injectable.getFactoryName(), injectable); dep.injectable = GraphUtil.copyInjectableReference(dep.injectable); } return injectable; }
private static String createCycleMessage(final Set<Injectable> visiting, final Injectable injectable) { final StringBuilder builder = new StringBuilder(); boolean cycleStarted = false; boolean hasProducer = false; for (final Injectable visitingInjectable : visiting) { if (visitingInjectable.equals(injectable)) { cycleStarted = true; } if (cycleStarted) { builder.append("\t"); visitingInjectable.getQualifier().stream() .forEach(anno -> builder.append(anno.toString()).append(' ')); builder.append(visitingInjectable.getInjectedType().getFullyQualifiedName()) .append("\n"); if (visitingInjectable.getInjectableType().equals(InjectableType.Producer)) { hasProducer = true; } } } if (hasProducer) { builder.insert(0, "A cycle was found containing a producer and no other normal scoped types:\n"); } else { builder.insert(0, "A cycle of only pseudo-scoped beans was found:\n"); } return builder.toString(); } }
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); } } }
private Statement createJsTypeProviderFor(final Injectable injectable) { final MetaClass type = injectable.getInjectedType(); final AnonymousClassStructureBuilder jsTypeProvider = newInstanceOf(parameterizedAs(JsTypeProvider.class, typeParametersOf(type))).extend(); jsTypeProvider .publicOverridesMethod("getInstance") .append(Stmt.castTo(type, loadVariable("contextManager").invoke("getInstance", injectable.getFactoryName())) .returnValue()).finish() .publicOverridesMethod("getName") .append(Stmt.loadLiteral(getBeanName(injectable)).returnValue()) .finish() .publicOverridesMethod("getFactoryName") .append(Stmt.loadLiteral(injectable.getFactoryName()).returnValue()) .finish() .publicOverridesMethod("getQualifiers") .append(Stmt.nestedCall(Stmt.newObject(parameterizedAs(JsArray.class, typeParametersOf(String.class)), Stmt.loadLiteral(AnnotationSerializer.serialize(injectable.getQualifier().iterator())))).returnValue()) .finish(); return jsTypeProvider.finish(); }
private void registerFactoryWithContext(final Injectable injectable, final MetaClass factoryClass, final Map<Class<? extends Annotation>, MetaClass> scopeContexts, @SuppressWarnings("rawtypes") final BlockBuilder registerFactoriesBody) { final Class<? extends Annotation> scope = injectable.getScope(); final MetaClass injectedType = injectable.getInjectedType(); final MetaClass scopeContextImpl = Assert.notNull("No scope context for " + scope.getSimpleName(), scopeContexts.get(scope)); final String contextVarName = getContextVarName(scopeContextImpl); registerFactoriesBody.append(loadVariable(contextVarName).invoke("registerFactory", Stmt.castTo(parameterizedAs(Factory.class, typeParametersOf(injectedType)), invokeStatic(GWT.class, "create", factoryClass)))); }
protected void implementCreateInstance(final ClassStructureBuilder<?> bodyBlockBuilder, final Injectable injectable, final List<Statement> createInstanceStatements) { String createInstanceMethodName; Parameter[] params; if (injectable.isContextual()) { createInstanceMethodName = "createContextualInstance"; params = new Parameter[] { finalOf(ContextManager.class, "contextManager"), finalOf(Class[].class, "typeArgs"), finalOf(Annotation[].class, "qualifiers") }; } else { createInstanceMethodName = "createInstance"; params = new Parameter[] { finalOf(ContextManager.class, "contextManager") }; } bodyBlockBuilder.publicMethod(injectable.getInjectedType(), createInstanceMethodName, params) .appendAll(createInstanceStatements) .finish(); }
final InjectionContext injectionContext = assertInjectionContextSet(); final Injectable injectable = graph.getConcreteInjectable(typeName.substring(typeName.lastIndexOf('.')+1)); final InjectableType factoryType = injectable.getInjectableType(); parameterizedAs(Factory.class, typeParametersOf(injectable.getInjectedType()))).publicScope().body(); final FactoryBodyGenerator generator = selectBodyGenerator(factoryType, typeName, injectable);
private void resolveDependencies() { logger.debug("Resolving dependencies for {} injectables...", injectablesByName.size()); final Set<Injectable> visited = new HashSet<>(); final Set<String> transientInjectableNames = new HashSet<>(); final List<String> dependencyProblems = new ArrayList<>(); final Map<String, Injectable> customProvidedInjectables = new IdentityHashMap<>(); for (final Injectable injectable : injectablesByName.values()) { if (injectable.isExtension()) { transientInjectableNames.add(injectable.getFactoryName()); } if (!visited.contains(injectable)) { logger.debug("Resolving {} dependencies for: {}", injectable.getDependencies().size(), injectable); for (final Dependency dep : injectable.getDependencies()) { resolveDependency(BaseDependency.as(dep), injectable, dependencyProblems, customProvidedInjectables); } } } injectablesByName.keySet().removeAll(transientInjectableNames); injectablesByName.putAll(customProvidedInjectables); if (!dependencyProblems.isEmpty()) { throw new RuntimeException(GraphUtil.buildMessageFromProblems(dependencyProblems)); } }
private void removeUnreachableInjectables(final ReachabilityStrategy strategy) { logger.debug("Removing unreachable injectables from dependency graph using {} strategy.", strategy); final Set<String> reachableNames = new HashSet<>(); final Queue<Injectable> processingQueue = new LinkedList<>(); final Predicate<Injectable> reachabilityRoot = reachabilityRootPredicate(strategy); for (final Injectable injectable : injectablesByName.values()) { if (reachabilityRoot.test(injectable) && !reachableNames.contains(injectable.getFactoryName()) && !InjectableType.Disabled.equals(injectable.getInjectableType())) { processingQueue.add(injectable); do { final Injectable processedInjectable = processingQueue.poll(); reachableNames.add(processedInjectable.getFactoryName()); logger.trace("Marked as reachable: {}", processedInjectable); for (final Dependency dep : processedInjectable.getDependencies()) { final Injectable resolvedDep = GraphUtil.getResolvedDependency(dep, processedInjectable); if (!reachableNames.contains(resolvedDep.getFactoryName())) { processingQueue.add(resolvedDep); } } } while (processingQueue.size() > 0); } } final int initialSize = injectablesByName.size(); injectablesByName.keySet().retainAll(reachableNames); logger.debug("Removed {} unreachable injectables.", initialSize - injectablesByName.size()); }