private GVNode componentNode(Class<?> type, String pid) { String id = pid == null ? nodeId : pid; ComponentNodeBuilder bld = ComponentNodeBuilder.create(id, type); bld.setShareable(pid == null && GraphtUtils.isShareable(currentNode)) .setShared(!unsharedNodes.contains(currentNode)) .setIsProvider(pid != null); eb.set("arrowtail", "crow"); if (GraphtUtils.desireIsTransient(dep)) { eb.set("style", "dashed");
if (!edgeIsTransient(edge)) { boolean es = shared.contains(edge.getTail()); isShared &= es;
/** * Replace shareable nodes in a graph. * * @param replace A replacement function. For each shareable node, this function will * be called; if it returns a node different from its input node, the * new node will be used as a replacement for the old. */ private DAGNode<Component,Dependency> replaceShareableNodes(NodeProcessor replace) throws InjectionException { logger.debug("replacing nodes in graph with {} nodes", graph.getReachableNodes().size()); Set<DAGNode<Component,Dependency>> toReplace = GraphtUtils.getShareableNodes(graph); logger.debug("found {} shared nodes", toReplace.size()); DAGNode<Component, Dependency> result = NodeProcessors.processNodes(graph, toReplace, replace); logger.debug("final graph has {} nodes", result.getReachableNodes().size()); return result; } }
switch (validationMode) { case IMMEDIATE: GraphtUtils.checkForPlaceholders(graph, logger); break; case DEFERRED: instantiable = GraphtUtils.getPlaceholderNodes(graph).isEmpty(); break; case NONE:
logger.debug("resolving node {}", node); if (!GraphtUtils.isShareable(node)) { logger.debug("node {} is not shareable", node); return node; if (!GraphtUtils.edgeIsTransient(edge)) { bld.addEdge(edge.getTail(), edge.getLabel());
public static boolean edgeIsTransient(DAGEdge<?, Dependency> input) { Desire desire = input.getLabel().getInitialDesire(); return desireIsTransient(desire); }
public <T> T tryGetInstance(QualifierMatcher qmatch, Class<T> type) throws InjectionException { DAGNode<Component, Dependency> node = GraphtUtils.findSatisfyingNode(graph, qmatch, type); return node != null ? type.cast(instantiator.instantiate(node)) : null; }
/** * Build the recommender engine. * * @param dao The data access object to use. Can be `null` to build without a DAO, but this is only useful in * special cases. * @return The built recommender engine, with {@linkplain ModelDisposition#EXCLUDED excluded} * components removed. * @throws RecommenderBuildException if there is an error building the engine. */ public LenskitRecommenderEngine build(DataAccessObject dao) throws RecommenderBuildException { DAGNode<Component, Dependency> graph = buildRecommenderGraph(dao); graph = instantiateGraph(graph); graph = rewriteExcludedComponents(graph, dao); boolean instantiable = GraphtUtils.getPlaceholderNodes(graph).isEmpty(); return new LenskitRecommenderEngine(graph, instantiable); }
private DAGNode<Component, Dependency> createRecommenderGraph(LenskitConfiguration config) throws RecommenderConfigurationException { Preconditions.checkNotNull(config, "extra configuration"); final DAGNode<Component, Dependency> toBuild; RecommenderGraphBuilder rgb = new RecommenderGraphBuilder(); rgb.addBindings(config.getBindings()); DependencySolver solver = rgb.buildDependencySolver(); try { toBuild = solver.rewrite(graph); } catch (ResolutionException ex) { throw new RecommenderConfigurationException("error reconfiguring recommender", ex); } GraphtUtils.checkForPlaceholders(toBuild, logger); return toBuild; }
/** * Create a provided node from the current node, and queue an edge for it. * * @param pid The ID of the provider node for targeting the provision edge. * @return The provided node and the edge connect it to the provider node. */ private Pair<GVNode, GVEdge> providedNode(String pid) { GVNode pNode = ComponentNodeBuilder.create(nodeId, satisfaction.getErasedType()) .setShareable(GraphtUtils.isShareable(currentNode)) .setShared(!unsharedNodes.contains(currentNode)) .setIsProvided(true) .build(); GVEdge pEdge = EdgeBuilder.create(pNode.getTarget() + ":e", pid) .set("style", "dotted") .set("dir", "back") .set("arrowhead", "vee") .build(); return Pair.of(pNode, pEdge); }
@Nonnull DAGNode<Component, Dependency> original) throws InjectionException { if (!GraphtUtils.isShareable(node)) { return node; if (!GraphtUtils.edgeIsTransient(edge)) { bld.addEdge(edge.getTail(), edge.getLabel());
public static boolean edgeIsTransient(DAGEdge<?, Dependency> input) { Desire desire = input.getLabel().getInitialDesire(); return desireIsTransient(desire); }
switch (validationMode) { case IMMEDIATE: GraphtUtils.checkForPlaceholders(graph, logger); break; case DEFERRED: instantiable = GraphtUtils.getPlaceholderNodes(graph).isEmpty(); break; case NONE:
/** * Get the component of a particular type, if one is already instantiated. This is useful to extract pre-built * models from serialized recommender engines, for example. * @param type The required component type. * @param <T> The required component type. * @return The component instance, or {@code null} if no instance can be retreived (either because no such * component is configured, or it is not yet instantiated). */ @Nullable public <T> T getComponent(Class<T> type) { DAGNode<Component, Dependency> node = GraphtUtils.findSatisfyingNode(graph, Qualifiers.matchDefault(), type); if (node == null) { return null; } Satisfaction sat = node.getLabel().getSatisfaction(); if (sat instanceof InstanceSatisfaction) { return type.cast(((InstanceSatisfaction) sat).getInstance()); } else { return null; } }
/** * Check a graph for placeholder satisfactions. * * @param graph The graph to check. * @throws RecommenderConfigurationException if the graph has a placeholder satisfaction. */ public static void checkForPlaceholders(DAGNode<Component, Dependency> graph, Logger logger) throws RecommenderConfigurationException { Set<DAGNode<Component, Dependency>> placeholders = getPlaceholderNodes(graph); Satisfaction sat = null; for (DAGNode<Component,Dependency> node: placeholders) { Component csat = node.getLabel(); // special-case DAOs for non-checking if (DataAccessObject.class.isAssignableFrom(csat.getSatisfaction().getErasedType())) { logger.debug("found DAO placeholder {}", csat.getSatisfaction()); } else { // all other placeholders are bad if (sat == null) { sat = csat.getSatisfaction(); } logger.error("placeholder {} not removed", csat.getSatisfaction()); } } if (sat != null) { throw new RecommenderConfigurationException("placeholder " + sat + " not removed"); } }
private DAGNode<Component, Dependency> createRecommenderGraph(LenskitConfiguration config) throws RecommenderConfigurationException { Preconditions.checkNotNull(config, "extra configuration"); final DAGNode<Component, Dependency> toBuild; RecommenderGraphBuilder rgb = new RecommenderGraphBuilder(); rgb.addBindings(config.getBindings()); DependencySolver solver = rgb.buildDependencySolver(); try { toBuild = solver.rewrite(graph); } catch (ResolutionException ex) { throw new RecommenderConfigurationException("error reconfiguring recommender", ex); } GraphtUtils.checkForPlaceholders(toBuild, logger); return toBuild; }
/** * Create a provided node from the current node, and queue an edge for it. * * @param pid The ID of the provider node for targeting the provision edge. * @return The provided node and the edge connect it to the provider node. */ private Pair<GVNode, GVEdge> providedNode(String pid) { GVNode pNode = ComponentNodeBuilder.create(nodeId, satisfaction.getErasedType()) .setShareable(GraphtUtils.isShareable(currentNode)) .setShared(!unsharedNodes.contains(currentNode)) .setIsProvided(true) .build(); GVEdge pEdge = EdgeBuilder.create(pNode.getTarget() + ":e", pid) .set("style", "dotted") .set("dir", "back") .set("arrowhead", "vee") .build(); return Pair.of(pNode, pEdge); }
public DAGNode<Component, Dependency> processNode(@Nonnull DAGNode<Component, Dependency> node, @Nonnull DAGNode<Component, Dependency> original) { Component label = node.getLabel(); if (!label.getSatisfaction().hasInstance()) { Satisfaction instanceSat = Satisfactions.nullOfType(label.getSatisfaction().getErasedType()); Component newLbl = Component.create(instanceSat, label.getCachePolicy()); // build new node with replacement label DAGNodeBuilder<Component,Dependency> bld = DAGNode.newBuilder(newLbl); // retain all non-transient edges for (DAGEdge<Component,Dependency> edge: node.getOutgoingEdges()) { if (!GraphtUtils.edgeIsTransient(edge)) { bld.addEdge(edge.getTail(), edge.getLabel()); } } DAGNode<Component,Dependency> repl = bld.build(); logger.debug("simulating instantiation of {}", node); return repl; } else { return node; } } }
private GVNode componentNode(Class<?> type, String pid) { String id = pid == null ? nodeId : pid; ComponentNodeBuilder bld = ComponentNodeBuilder.create(id, type); bld.setShareable(pid == null && GraphtUtils.isShareable(currentNode)) .setShared(!unsharedNodes.contains(currentNode)) .setIsProvider(pid != null); eb.set("arrowtail", "crow"); if (GraphtUtils.desireIsTransient(dep)) { eb.set("style", "dashed");
@Override protected DAGNode<Component, Dependency> instantiateGraph(DAGNode<Component, Dependency> graph) { if (cache == null) { logger.debug("Building directly without a cache"); return super.instantiateGraph(graph); } else { logger.debug("Instantiating graph with a cache"); try { Set<DAGNode<Component, Dependency>> nodes = GraphtUtils.getShareableNodes(graph); logger.debug("resolving {} nodes", nodes.size()); DAGNode<Component, Dependency> newGraph = NodeProcessors.processNodes(graph, nodes, cache); logger.debug("newGraph went from {} to {} nodes", newGraph.getReachableNodes().size(), newGraph.getReachableNodes().size()); return newGraph; } catch (InjectionException e) { logger.error("Error instantiating recommender nodes with cache", e); throw new RecommenderBuildException("Cached instantiation failed", e); } } } }