GraphFilter implements Cloneable, Serializable { public void setEdgeFilter(final Traversal<Vertex, Edge> edgeFilter) { if (!TraversalHelper.isLocalStarGraph(edgeFilter.asAdmin())) throw GraphComputer.Exceptions.edgeFilterAccessesAdjacentVertices(edgeFilter); this.edgeFilter = edgeFilter.asAdmin().clone(); this.edgeLegality = new EnumMap<>(Direction.class); this.edgeLegality.put(Direction.OUT, new HashMap<>()); this.edgeLegality.put(Direction.IN, new HashMap<>()); this.edgeLegality.put(Direction.BOTH, new HashMap<>()); if (this.edgeFilter.getEndStep() instanceof RangeGlobalStep && 0 == ((RangeGlobalStep) this.edgeFilter.getEndStep()).getHighRange()) this.allowNoEdges = true; if (this.edgeFilter.getStartStep() instanceof VertexStep) { final VertexStep step = (VertexStep) this.edgeFilter.getStartStep(); final Map<String, Legal> map = this.edgeLegality.get(step.getDirection()); if (step.returnsEdge()) { if (step.getEdgeLabels().length == 0) map.put(null, 1 == this.edgeFilter.getSteps().size() ? Legal.YES : Legal.MAYBE); else { for (final String label : step.getEdgeLabels()) { map.put(label, 1 == this.edgeFilter.getSteps().size() ? Legal.YES : Legal.MAYBE); } } } } else if (this.edgeFilter.getStartStep() instanceof UnionStep) { final UnionStep<?, ?> step = (UnionStep) this.edgeFilter.getStartStep(); for (final Traversal.Admin<?, ?> union : step.getGlobalChildren()) { if (union.getStartStep() instanceof VertexStep) { final VertexStep vertexStep = (VertexStep) union.getStartStep(); final Map<String, Legal> map = this.edgeLegality.get(vertexStep.getDirection()); if (vertexStep.returnsEdge()) { if (vertexStep.getEdgeLabels().length == 0) map.put(null, 2 == union.getSteps().size() ? Legal.YES : Legal.MAYBE); else { for (final String label : vertexStep.getEdgeLabels()) { map.put(label, 2 == union.getSteps().size() ? Legal.YES : Legal.MAYBE); } } } } } } final Map<String, Legal> outMap = this.edgeLegality.get(Direction.OUT); final Map<String, Legal> inMap = this.edgeLegality.get(Direction.IN); final Map<String, Legal> bothMap = this.edgeLegality.get(Direction.BOTH); for (final Map.Entry<String, Legal> entry : bothMap.entrySet()) { final Legal legal = inMap.get(entry.getKey()); if (null == legal || legal.compareTo(entry.getValue()) > 0) inMap.put(entry.getKey(), entry.getValue()); } for (final Map.Entry<String, Legal> entry : bothMap.entrySet()) { final Legal legal = outMap.get(entry.getKey()); if (null == legal || legal.compareTo(entry.getValue()) > 0) outMap.put(entry.getKey(), entry.getValue()); } for (final Map.Entry<String, Legal> entry : outMap.entrySet()) { final Legal legal = inMap.get(entry.getKey()); if (null != legal) bothMap.put(entry.getKey(), legal.compareTo(entry.getValue()) > 0 ? legal : entry.getValue()); } if (outMap.isEmpty() && inMap.isEmpty() && bothMap.isEmpty()) { outMap.put(null, Legal.MAYBE); inMap.put(null, Legal.MAYBE); bothMap.put(null, Legal.MAYBE); } } GraphFilter();  GraphFilter(final Computer computer); void setVertexFilter(final Traversal<Vertex, Vertex> vertexFilter); void setEdgeFilter(final Traversal<Vertex, Edge> edgeFilter); boolean legalVertex(final Vertex vertex); Iterator<Edge> legalEdges(final Vertex vertex); final Traversal.Admin<Vertex, Vertex> getVertexFilter(); final Traversal.Admin<Vertex, Edge> getEdgeFilter(); boolean hasFilter(); boolean hasEdgeFilter(); boolean hasVertexFilter(); Set<String> getLegallyPositiveEdgeLabels(final Direction direction); Legal checkEdgeLegality(final Direction direction, final String label); Legal checkEdgeLegality(final Direction direction); @Override int hashCode(); @Override boolean equals(final Object object); @Override GraphFilter clone(); @Override String toString();  }
@Test public void shouldOnlyAllowEdgeFilterToTraverseLocalStarGraph() { GraphFilter graphFilter = new GraphFilter(); graphFilter.setEdgeFilter(__.outE()); try { graphFilter.setEdgeFilter(__.<Vertex>outE().inV().outE()); fail("Should not allow traversals past the star graph"); } catch (final IllegalArgumentException e) { assertEquals(e.getMessage(), GraphComputer.Exceptions.edgeFilterAccessesAdjacentVertices(__.<Vertex>outE().inV().outE()).getMessage()); } }