NeighborVisitor extends ShapeVisitor.Default<List<Relationship>> implements NeighborProvider { @Override public List<Relationship> resourceShape(ResourceShape shape) { List<Relationship> result = new ArrayList<>(); shape.getIdentifiers().forEach((k, v) -> result.add(relationship(shape, RelationshipType.IDENTIFIER, v))); shape.getResources().forEach(id -> addBinding(result, shape, id, RelationshipType.RESOURCE)); shape.getAllOperations().forEach(id -> addBinding(result, shape, id, RelationshipType.OPERATION)); shape.getRead().ifPresent(id -> { result.add(relationship(shape, RelationshipType.READ, id)); result.add(relationship(shape, RelationshipType.INSTANCE_OPERATION, id)); }); shape.getUpdate().ifPresent(id -> { result.add(relationship(shape, RelationshipType.UPDATE, id)); result.add(relationship(shape, RelationshipType.INSTANCE_OPERATION, id)); }); shape.getDelete().ifPresent(id -> { result.add(relationship(shape, RelationshipType.DELETE, id)); result.add(relationship(shape, RelationshipType.INSTANCE_OPERATION, id)); }); shape.getPut().ifPresent(id -> { result.add(relationship(shape, RelationshipType.PUT, id)); result.add(relationship(shape, RelationshipType.INSTANCE_OPERATION, id)); }); shape.getCreate().ifPresent(id -> { result.add(relationship(shape, RelationshipType.CREATE, id)); result.add(relationship(shape, RelationshipType.COLLECTION_OPERATION, id)); }); shape.getList().ifPresent(id -> { result.add(relationship(shape, RelationshipType.LIST, id)); result.add(relationship(shape, RelationshipType.COLLECTION_OPERATION, id)); }); shape.getCollectionOperations().forEach(id -> result.add( relationship(shape, RelationshipType.COLLECTION_OPERATION, id))); shape.getOperations().forEach(id -> result.add( relationship(shape, RelationshipType.INSTANCE_OPERATION, id))); Stream.concat(model.shapes(ResourceShape.class), model.shapes(ServiceShape.class)) .filter(parent -> parent.getResources().contains(shape.getId())) .forEach(parent -> addBinding(result, parent, shape.getId(), RelationshipType.RESOURCE)); return result; } NeighborVisitor(Model model); @Override List<Relationship> getNeighbors(Shape shape); @Override List<Relationship> getDefault(Shape shape); @Override List<Relationship> serviceShape(ServiceShape shape); @Override List<Relationship> resourceShape(ResourceShape shape); @Override List<Relationship> operationShape(OperationShape shape); @Override List<Relationship> memberShape(MemberShape shape); @Override List<Relationship> listShape(ListShape shape); @Override List<Relationship> setShape(SetShape shape); @Override List<Relationship> mapShape(MapShape shape); @Override List<Relationship> structureShape(StructureShape shape); @Override List<Relationship> unionShape(UnionShape shape);  }
@Test public void resourceShape() { ServiceShape parent = ServiceShape.builder() .id("ns.foo#Svc") .version("2017-01-17") .addResource("ns.foo#Resource") .build(); ResourceShape resource = ResourceShape.builder() .id("ns.foo#Resource") .addIdentifier("id", "ns.foo#ResourceIdentifier") .put(ShapeId.from("ns.foo#Put")) .create(ShapeId.from("ns.foo#Create")) .read(ShapeId.from("ns.foo#Get")) .update(ShapeId.from("ns.foo#Update")) .delete(ShapeId.from("ns.foo#Delete")) .list(ShapeId.from("ns.foo#List")) .addOperation("ns.foo#Named") .addCollectionOperation("ns.foo#GenericCollection") .addResource("ns.foo#Child1") .build(); StringShape identifier = StringShape.builder().id("ns.foo#ResourceIdentifier").build(); OperationShape createOperation = OperationShape.builder().id("ns.foo#Create").build(); OperationShape getOperation = OperationShape.builder() .id("ns.foo#Get") .addTrait(new ReadonlyTrait()) .build(); OperationShape updateOperation = OperationShape.builder().id("ns.foo#Update").build(); OperationShape deleteOperation = OperationShape.builder() .id("ns.foo#Delete") .addTrait(new IdempotentTrait()) .build(); OperationShape listOperation = OperationShape.builder() .id("ns.foo#List") .addTrait(new ReadonlyTrait()) .build(); OperationShape namedOperation = OperationShape.builder() .id("ns.foo#Named") .build(); OperationShape collectionOperation = OperationShape.builder() .id("ns.foo#GenericCollection") .build(); OperationShape putOperation = OperationShape.builder() .id("ns.foo#Put") .build(); ResourceShape child1 = ResourceShape.builder().id("ns.foo#Child1").addResource("ns.foo#Child2").build(); ResourceShape child2 = ResourceShape.builder().id("ns.foo#Child2").build(); Model model = Model.builder() .addShapes(parent, resource, identifier, child1, child2) .addShapes(createOperation, getOperation, updateOperation, deleteOperation, listOperation) .addShapes(namedOperation, collectionOperation, putOperation) .build(); NeighborVisitor neighborVisitor = new NeighborVisitor(model); List<Relationship> relationships = resource.accept(neighborVisitor); assertThat(relationships, containsInAnyOrder( Relationship.create(parent, RelationshipType.RESOURCE, resource), Relationship.create(resource, RelationshipType.BOUND, parent), Relationship.create(resource, RelationshipType.IDENTIFIER, identifier), Relationship.create(resource, RelationshipType.CREATE, createOperation), Relationship.create(resource, RelationshipType.READ, getOperation), Relationship.create(resource, RelationshipType.UPDATE, updateOperation), Relationship.create(resource, RelationshipType.DELETE, deleteOperation), Relationship.create(resource, RelationshipType.LIST, listOperation), Relationship.create(resource, RelationshipType.PUT, putOperation), Relationship.create(resource, RelationshipType.COLLECTION_OPERATION, createOperation), Relationship.create(resource, RelationshipType.COLLECTION_OPERATION, listOperation), Relationship.create(resource, RelationshipType.COLLECTION_OPERATION, collectionOperation), Relationship.create(resource, RelationshipType.INSTANCE_OPERATION, getOperation), Relationship.create(resource, RelationshipType.INSTANCE_OPERATION, updateOperation), Relationship.create(resource, RelationshipType.INSTANCE_OPERATION, deleteOperation), Relationship.create(resource, RelationshipType.INSTANCE_OPERATION, namedOperation), Relationship.create(resource, RelationshipType.INSTANCE_OPERATION, putOperation), Relationship.create(resource, RelationshipType.OPERATION, createOperation), Relationship.create(resource, RelationshipType.OPERATION, getOperation), Relationship.create(resource, RelationshipType.OPERATION, updateOperation), Relationship.create(resource, RelationshipType.OPERATION, deleteOperation), Relationship.create(resource, RelationshipType.OPERATION, listOperation), Relationship.create(resource, RelationshipType.OPERATION, namedOperation), Relationship.create(resource, RelationshipType.OPERATION, putOperation), Relationship.create(resource, RelationshipType.OPERATION, collectionOperation), Relationship.create(resource, RelationshipType.RESOURCE, child1), Relationship.create(namedOperation, RelationshipType.BOUND, resource), Relationship.create(createOperation, RelationshipType.BOUND, resource), Relationship.create(getOperation, RelationshipType.BOUND, resource), Relationship.create(updateOperation, RelationshipType.BOUND, resource), Relationship.create(deleteOperation, RelationshipType.BOUND, resource), Relationship.create(listOperation, RelationshipType.BOUND, resource), Relationship.create(putOperation, RelationshipType.BOUND, resource), Relationship.create(collectionOperation, RelationshipType.BOUND, resource), Relationship.create(child1, RelationshipType.BOUND, resource) )); }