private Descriptor buildCollectionResourceDescriptor(
      Class<?> type,
      RootResourceInformation resourceInformation,
      Descriptor representationDescriptor,
      HttpMethod method) {

    ResourceMetadata metadata = mappings.getMetadataFor(type);

    List<Descriptor> nestedDescriptors = new ArrayList<Descriptor>();
    nestedDescriptors.addAll(getPaginationDescriptors(type, method));
    nestedDescriptors.addAll(getProjectionDescriptor(type, method));

    Type descriptorType = getType(method);
    return descriptor()
        . //
        id(prefix(method).concat(metadata.getRel()))
        . //
        name(metadata.getRel())
        . //
        type(descriptorType)
        . //
        doc(getDocFor(metadata.getDescription()))
        . //
        rt("#" + representationDescriptor.getId())
        . //
        descriptors(nestedDescriptors)
        .build();
  }
  /** @see DATAREST-791 */
  @Test
  public void usesRepositoryInvokerToLookupRelatedInstance() throws Exception {

    KeyValuePersistentEntity<?> entity = mappingContext.getPersistentEntity(Sample.class);

    ResourceMappings mappings =
        new PersistentEntitiesResourceMappings(
            new PersistentEntities(Collections.singleton(mappingContext)));
    ResourceMetadata metadata = spy(mappings.getMetadataFor(Sample.class));
    when(metadata.getSupportedHttpMethods()).thenReturn(AllSupportedHttpMethods.INSTANCE);

    RepositoryPropertyReferenceController controller =
        new RepositoryPropertyReferenceController(repositories, invokerFactory, assembler);
    controller.setApplicationEventPublisher(publisher);

    doReturn(invoker).when(invokerFactory).getInvokerFor(Reference.class);
    doReturn(new Sample()).when(invoker).invokeFindOne(4711);
    doReturn(new Reference()).when(invoker).invokeFindOne("some-id");
    doReturn(new Sample()).when(invoker).invokeSave(any(Object.class));

    RootResourceInformation information = new RootResourceInformation(metadata, entity, invoker);
    Resources<Object> request =
        new Resources<Object>(Collections.emptySet(), new Link("/reference/some-id"));

    controller.createPropertyReference(information, HttpMethod.POST, request, 4711, "references");

    verify(invokerFactory).getInvokerFor(Reference.class);
    verify(invoker).invokeFindOne("some-id");
  }
  private Descriptor buildRepresentationDescriptor(Class<?> type) {

    ResourceMetadata metadata = mappings.getMetadataFor(type);

    return descriptor()
        . //
        id(getRepresentationDescriptorId(metadata))
        . //
        href(entityLinks.linkFor(type).slash("schema").toString())
        . //
        doc(getDocFor(metadata.getItemResourceDescription()))
        . //
        descriptors(buildPropertyDescriptors(type, metadata.getItemResourceRel()))
        . //
        build();
  }
  @Before
  public void setUp() {

    when(metadata.isExported()).thenReturn(true);
    this.invoker = mock(RepositoryInvoker.class, new DefaultBooleanToTrue());
    this.information = new RootResourceInformation(metadata, entity, invoker);
  }
  /**
   * Builds a descriptor for the projection parameter of the given resource.
   *
   * @param metadata
   * @param projectionConfiguration
   * @return
   */
  private Descriptor buildProjectionDescriptor(ResourceMetadata metadata) {

    ProjectionDefinitionConfiguration projectionConfiguration =
        configuration.projectionConfiguration();
    String projectionParameterName = projectionConfiguration.getParameterName();

    Map<String, Class<?>> projections =
        projectionConfiguration.getProjectionsFor(metadata.getDomainType());
    List<Descriptor> projectionDescriptors = new ArrayList<Descriptor>(projections.size());

    for (Entry<String, Class<?>> projection : projections.entrySet()) {

      Class<?> type = projection.getValue();
      String key =
          String.format(
              "%s.%s.%s", metadata.getRel(), projectionParameterName, projection.getKey());
      ResourceDescription fallback = SimpleResourceDescription.defaultFor(key);
      AnnotationBasedResourceDescription projectionDescription =
          new AnnotationBasedResourceDescription(type, fallback);

      projectionDescriptors.add( //
          descriptor()
              . //
              type(Type.SEMANTIC)
              . //
              name(projection.getKey())
              . //
              doc(getDocFor(projectionDescription))
              . //
              descriptors(createJacksonDescriptor(projection.getKey(), type))
              . //
              build());
    }

    return descriptor()
        . //
        type(Type.SEMANTIC)
        . //
        name(projectionParameterName)
        . //
        doc(getDocFor(SimpleResourceDescription.defaultFor(projectionParameterName)))
        . //
        descriptors(projectionDescriptors)
        .build();
  }
  @RequestMapping(value = MASTER_ROOT_MAPPING, method = RequestMethod.GET)
  public Resources<Resource<TreeNode>> getTableList() {

    List<Resource<TreeNode>> content = new ArrayList<Resource<TreeNode>>();
    Link link = new Link(getRootPath(this.configuration)).withSelfRel();
    for (Class<?> domainType : this.repositories) {
      ResourceMetadata mapping = this.mappings.getMetadataFor(domainType);
      if (mapping.isExported()) {
        TreeNode treeNode = new TreeNode();
        treeNode.setId(mapping.getRel());
        String text = tableProperties.getProperty(mapping.getRel(), mapping.getRel());
        treeNode.setText(text);
        treeNode.setState("open");
        treeNode.setChecked(false);
        treeNode.setChildren(null);
        Resource<TreeNode> resource =
            new Resource<TreeNode>(
                treeNode, new Link(getPath(this.configuration, mapping), mapping.getRel()));
        content.add(resource);
      }
    }
    content.sort(
        new Comparator<Resource<TreeNode>>() {

          @Override
          public int compare(Resource<TreeNode> o1, Resource<TreeNode> o2) {
            return o1.getContent().getId().compareTo(o2.getContent().getId());
          }
        });
    Resources<Resource<TreeNode>> resources = new Resources<Resource<TreeNode>>(content, link);
    return resources;
  }
  private Collection<Descriptor> buildSearchResourceDescriptors(PersistentEntity<?, ?> entity) {

    ResourceMetadata metadata = mappings.getMetadataFor(entity.getType());
    List<Descriptor> descriptors = new ArrayList<Descriptor>();

    for (MethodResourceMapping methodMapping : metadata.getSearchResourceMappings()) {

      List<Descriptor> parameterDescriptors = new ArrayList<Descriptor>();

      for (ParameterMetadata parameterMetadata : methodMapping.getParametersMetadata()) {

        parameterDescriptors.add( //
            descriptor()
                . //
                name(parameterMetadata.getName())
                . //
                doc(getDocFor(parameterMetadata.getDescription()))
                . //
                type(Type.SEMANTIC) //
                .build());
      }

      descriptors.add(
          descriptor()
              . //
              type(Type.SAFE)
              . //
              name(methodMapping.getRel())
              . //
              descriptors(parameterDescriptors)
              . //
              build());
    }

    return descriptors;
  }
  private Descriptor buildItemResourceDescriptor(
      RootResourceInformation resourceInformation,
      Descriptor representationDescriptor,
      HttpMethod method) {

    PersistentEntity<?, ?> entity = resourceInformation.getPersistentEntity();
    ResourceMetadata metadata = mappings.getMetadataFor(entity.getType());

    return descriptor()
        . //
        id(prefix(method).concat(metadata.getItemResourceRel()))
        . //
        name(metadata.getItemResourceRel())
        . //
        type(getType(method))
        . //
        doc(getDocFor(metadata.getItemResourceDescription()))
        . //
        rt("#".concat(representationDescriptor.getId()))
        . //
        descriptors(getProjectionDescriptor(entity.getType(), method))
        . //
        build();
  }
  /*
   * (non-Javadoc)
   * @see org.springframework.core.convert.converter.GenericConverter#convert(java.lang.Object, org.springframework.core.convert.TypeDescriptor, org.springframework.core.convert.TypeDescriptor)
   */
  @Override
  public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {

    PersistentEntity<?, ?> persistentEntity = repositories.getPersistentEntity((Class<?>) source);
    final ResourceMetadata metadata = mappings.getMappingFor(persistentEntity.getType());
    final JsonSchema jsonSchema =
        new JsonSchema(
            persistentEntity.getName(), accessor.getMessage(metadata.getItemResourceDescription()));

    persistentEntity.doWithProperties(
        new SimplePropertyHandler() {

          /*
           * (non-Javadoc)
           * @see org.springframework.data.mapping.PropertyHandler#doWithPersistentProperty(org.springframework.data.mapping.PersistentProperty)
           */
          @Override
          public void doWithPersistentProperty(PersistentProperty<?> persistentProperty) {

            Class<?> propertyType = persistentProperty.getType();
            String type = uncapitalize(propertyType.getSimpleName());

            ResourceMapping propertyMapping = metadata.getMappingFor(persistentProperty);
            ResourceDescription description = propertyMapping.getDescription();
            String message = accessor.getMessage(description);

            Property property =
                persistentProperty.isCollectionLike()
                    ? //
                    new ArrayProperty("array", message, false)
                    : new Property(type, message, false);

            jsonSchema.addProperty(persistentProperty.getName(), property);
          }
        });

    final List<Link> links = new ArrayList<Link>();

    persistentEntity.doWithAssociations(
        new SimpleAssociationHandler() {

          /*
           * (non-Javadoc)
           * @see org.springframework.data.mapping.AssociationHandler#doWithAssociation(org.springframework.data.mapping.Association)
           */
          @Override
          public void doWithAssociation(Association<? extends PersistentProperty<?>> association) {

            PersistentProperty<?> persistentProperty = association.getInverse();

            if (!metadata.isExported(persistentProperty)) {
              return;
            }

            RepositoryLinkBuilder builder =
                new RepositoryLinkBuilder(metadata, config.getBaseUri()).slash("{id}");
            maybeAddAssociationLink(builder, mappings, persistentProperty, links);
          }
        });

    jsonSchema.add(links);

    return jsonSchema;
  }
 private static String getRepresentationDescriptorId(ResourceMetadata metadata) {
   return metadata.getItemResourceRel().concat("-representation");
 }