DS-3533 Drop embed/linkOptional properties from LinkRest

This commit is contained in:
Chris Wilper
2020-02-04 13:36:32 -05:00
parent 169cd502a2
commit 7d3885f939
15 changed files with 39 additions and 111 deletions

View File

@@ -64,16 +64,11 @@ public class DSpaceResourceHalLinkFactory extends HalLinkFactory<DSpaceResource,
.linkToSingleResource((RestAddressableModel) linkedObject, name);
}
if (linkedObject != null || !linkRest.linkOptional() || !linkRest.embedOptional()) {
if (linkRest.linkOptional() && linkRest.embedOptional()
&& !halResource.getContent().getProjection()
.allowLinking(halResource, linkRest)) {
continue; // projection disallows this optional method-level link
}
halResource.add(linkToSubResource);
if (!halResource.getContent().getProjection().allowLinking(halResource, linkRest)) {
continue; // projection disallows this optional method-level link
}
halResource.add(linkToSubResource);
}
} else if (RestModel.class.isAssignableFrom(readMethod.getReturnType())) {

View File

@@ -56,7 +56,7 @@ public class AuthenticationStatusRest extends BaseObjectRest<Integer> {
}
}
@LinkRest(linkClass = EPersonRest.class, name = "eperson", linkOptional = true)
@LinkRest(linkClass = EPersonRest.class, name = "eperson")
@JsonIgnore
public EPersonRest getEPersonRest() {
return ePersonRest;

View File

@@ -17,16 +17,12 @@ import org.dspace.app.rest.RestResourceController;
@LinksRest(links = {
@LinkRest(name = AuthorityRest.ENTRIES,
linkClass = AuthorityEntryRest.class,
method = "query",
embedOptional = true,
linkOptional = true
method = "query"
),
@LinkRest(
name = AuthorityRest.ENTRY,
linkClass = AuthorityEntryRest.class,
method = "getResource",
embedOptional = true,
linkOptional = true
method = "getResource"
)
})
public class AuthorityRest extends BaseObjectRest<String> {

View File

@@ -19,14 +19,12 @@ import com.fasterxml.jackson.annotation.JsonProperty.Access;
@LinkRest(
name = BitstreamRest.BUNDLE,
linkClass = BundleRest.class,
method = "getBundle",
embedOptional = true
method = "getBundle"
),
@LinkRest(
name = BitstreamRest.FORMAT,
linkClass = BitstreamFormatRest.class,
method = "getFormat",
embedOptional = true
method = "getFormat"
)
})
public class BitstreamRest extends DSpaceObjectRest {

View File

@@ -22,15 +22,12 @@ import org.dspace.app.rest.RestResourceController;
@LinkRest(
name = BrowseIndexRest.ITEMS,
linkClass = ItemRest.class,
method = "listBrowseItems",
embedOptional = true
method = "listBrowseItems"
),
@LinkRest(
name = BrowseIndexRest.ENTRIES,
linkClass = BrowseEntryRest.class,
method = "listBrowseEntries",
embedOptional = true,
linkOptional = true
method = "listBrowseEntries"
)
})
public class BrowseIndexRest extends BaseObjectRest<String> {

View File

@@ -19,14 +19,12 @@ import com.fasterxml.jackson.annotation.JsonProperty;
@LinkRest(
name = BundleRest.BITSTREAMS,
linkClass = BitstreamRest.class,
method = "getBitstreams",
embedOptional = true
method = "getBitstreams"
),
@LinkRest(
name = BundleRest.PRIMARY_BITSTREAM,
linkClass = BitstreamRest.class,
method = "getPrimaryBitstream",
embedOptional = true
method = "getPrimaryBitstream"
)
})
public class BundleRest extends DSpaceObjectRest {

View File

@@ -18,26 +18,22 @@ import com.fasterxml.jackson.annotation.JsonProperty;
@LinkRest(
name = CollectionRest.DEFAULT_ACCESS_CONDITIONS,
linkClass = ResourcePolicyRest.class,
method = "getDefaultAccessConditions",
embedOptional = true
method = "getDefaultAccessConditions"
),
@LinkRest(
name = CollectionRest.LICENSE,
linkClass = LicenseRest.class,
method = "getLicense",
embedOptional = true
method = "getLicense"
),
@LinkRest(
name = CollectionRest.LOGO,
linkClass = BitstreamRest.class,
method = "getLogo",
embedOptional = true
method = "getLogo"
),
@LinkRest(
name = CollectionRest.MAPPED_ITEMS,
linkClass = ItemRest.class,
method = "getMappedItems",
embedOptional = true
method = "getMappedItems"
)
})
public class CollectionRest extends DSpaceObjectRest {

View File

@@ -18,20 +18,17 @@ import com.fasterxml.jackson.annotation.JsonProperty;
@LinkRest(
name = CommunityRest.COLLECTIONS,
linkClass = CollectionRest.class,
method = "getCollections",
embedOptional = true
method = "getCollections"
),
@LinkRest(
name = CommunityRest.LOGO,
linkClass = BitstreamRest.class,
method = "getLogo",
embedOptional = true
method = "getLogo"
),
@LinkRest(
name = CommunityRest.SUBCOMMUNITIES,
linkClass = CommunityRest.class,
method = "getSubcommunities",
embedOptional = true
method = "getSubcommunities"
)
})
public class CommunityRest extends DSpaceObjectRest {

View File

@@ -23,8 +23,7 @@ import org.dspace.app.rest.RestResourceController;
@LinkRest(
name = EPersonRest.GROUPS,
linkClass = GroupRest.class,
method = "getGroups",
embedOptional = true
method = "getGroups"
)
})
public class EPersonRest extends DSpaceObjectRest {

View File

@@ -21,8 +21,7 @@ import org.dspace.app.rest.RestResourceController;
@LinkRest(
name = GroupRest.GROUPS,
linkClass = GroupRest.class,
method = "getGroups",
embedOptional = true
method = "getGroups"
)
})
public class GroupRest extends DSpaceObjectRest {

View File

@@ -156,7 +156,7 @@ public class HarvestedCollectionRest extends BaseObjectRest<Integer> {
this.lastHarvested = lastHarvested;
}
@LinkRest(linkClass = HarvesterMetadataRest.class, name = "harvestermetadata", linkOptional = true)
@LinkRest(linkClass = HarvesterMetadataRest.class, name = "harvestermetadata")
@JsonIgnore
public HarvesterMetadataRest getMetadataConfigs() {
return metadata_configs;

View File

@@ -20,32 +20,27 @@ import com.fasterxml.jackson.annotation.JsonProperty;
@LinkRest(
name = ItemRest.BUNDLES,
linkClass = BundleRest.class,
method = "getBundles",
embedOptional = true
method = "getBundles"
),
@LinkRest(
name = ItemRest.MAPPED_COLLECTIONS,
linkClass = CollectionRest.class,
method = "getMappedCollections",
embedOptional = true
method = "getMappedCollections"
),
@LinkRest(
name = ItemRest.OWNING_COLLECTION,
linkClass = CollectionRest.class,
method = "getOwningCollection",
embedOptional = true
method = "getOwningCollection"
),
@LinkRest(
name = ItemRest.RELATIONSHIPS,
linkClass = RelationshipRest.class,
method = "getRelationships",
embedOptional = true
method = "getRelationships"
),
@LinkRest(
name = ItemRest.TEMPLATE_ITEM_OF,
linkClass = CollectionRest.class,
method = "getTemplateItemOf",
embedOptional = true
method = "getTemplateItemOf"
)
})
public class ItemRest extends DSpaceObjectRest {

View File

@@ -14,7 +14,6 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.dspace.app.rest.model.hateoas.HALResource;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.repository.LinkRestRepository;
import org.dspace.app.rest.utils.Utils;
import org.springframework.stereotype.Component;
@@ -63,37 +62,4 @@ public @interface LinkRest {
* @return the class.
*/
Class linkClass();
/**
* Tells whether embedding the resource indicated by this link is optional.
* <p>
* If false (the default), it means the resource will always be embedded unless the {@link LinkRestRepository}
* forbids it via {@link LinkRestRepository#isEmbeddableRelation(Object, String)}.
* </p>
* <p>
* If true, it means the resource will be embedded normally, unless forbidden by the {@link LinkRestRepository}
* or the projection, in use, via {@link Projection#allowOptionalEmbed(HALResource, LinkRest)}.
* </p>
*
* @return whether embedding is optional.
*/
boolean embedOptional() default false;
/**
* Tells whether linking the resource indicated by this link is optional.
* <p>
* If false (the default), it means the resource will always be linked.
* </p>
* <p>
* If true, it means the resource will only be linked if:
* <ul>
* <li> The resource is embedded, or</li>
* <li> The value returned by the link method is not null and linking is not forbidden by the
* projection in use, via {@link Projection#allowOptionalLink(HALResource, LinkRest)}</li>
* </ul>
* </p>
*
* @return whether linking is optional.
*/
boolean linkOptional() default false;
}

View File

@@ -445,10 +445,10 @@ public class Utils {
Projection projection = halResource.getContent().getProjection();
getLinkRests(halResource.getContent().getClass()).stream().forEach((linkRest) -> {
Link link = linkToSubResource(halResource.getContent(), linkRest.name());
if (!linkRest.embedOptional() || projection.allowEmbedding(halResource, linkRest)) {
if (projection.allowEmbedding(halResource, linkRest)) {
embedRelFromRepository(halResource, linkRest.name(), link, linkRest);
halResource.add(link); // unconditionally link if embedding was allowed
} else if (!linkRest.linkOptional() || projection.allowLinking(halResource, linkRest)) {
} else if (projection.allowLinking(halResource, linkRest)) {
halResource.add(link);
}
});
@@ -492,9 +492,7 @@ public class Utils {
Object contentId = getContentIdForLinkMethod(resource.getContent(), method);
try {
Object linkedObject = method.invoke(linkRepository, null, contentId, null, projection);
if (linkedObject != null || !linkRest.embedOptional()) {
resource.embedResource(rel, wrapForEmbedding(linkedObject, link));
}
resource.embedResource(rel, wrapForEmbedding(linkedObject, link));
} catch (InvocationTargetException e) {
if (e.getTargetException() instanceof RuntimeException) {
throw (RuntimeException) e.getTargetException();
@@ -559,8 +557,7 @@ public class Utils {
LinkRest linkRest = findLinkAnnotation(readMethod);
try {
if (linkRest != null) {
if (linkRest.embedOptional()
&& !resource.getContent().getProjection().allowEmbedding(resource, linkRest)) {
if (!resource.getContent().getProjection().allowEmbedding(resource, linkRest)) {
return; // projection disallows this optional method-level embed
}
if (StringUtils.isNotBlank(linkRest.name())) {
@@ -569,9 +566,7 @@ public class Utils {
Link link = linkToSubResource(resource.getContent(), rel);
if (StringUtils.isBlank(linkRest.method())) {
Object linkedObject = readMethod.invoke(resource.getContent());
if (linkedObject != null || !linkRest.embedOptional()) {
resource.embedResource(rel, wrapForEmbedding(linkedObject, link));
}
resource.embedResource(rel, wrapForEmbedding(linkedObject, link));
} else {
embedRelFromRepository(resource, rel, link, linkRest);
}

View File

@@ -17,15 +17,12 @@ import org.dspace.app.rest.projection.Projection;
@LinkRest(
name = MockObjectRest.O_CHILDREN,
linkClass = MockObjectRest.class,
method = "getMockObjectChildren",
embedOptional = true,
linkOptional = true
method = "getMockObjectChildren"
),
@LinkRest(
name = MockObjectRest.A_CHILDREN,
linkClass = MockObjectRest.class,
method = "getMockObjectChildren",
linkOptional = true
method = "getMockObjectChildren"
),
@LinkRest(
name = MockObjectRest.N_CHILDREN,
@@ -90,7 +87,7 @@ public class MockObjectRest extends BaseObjectRest<Long> {
this.value = value;
}
@LinkRest(linkClass = MockObjectRest.class, linkOptional = true)
@LinkRest(linkClass = MockObjectRest.class)
public MockObjectRest getRestProp1() {
return restProp1;
}
@@ -99,7 +96,7 @@ public class MockObjectRest extends BaseObjectRest<Long> {
this.restProp1 = restProp1;
}
@LinkRest(linkClass = MockObjectRest.class, embedOptional = true, linkOptional = true)
@LinkRest(linkClass = MockObjectRest.class)
public MockObjectRest getRestProp2() {
return restProp2;
}
@@ -108,7 +105,7 @@ public class MockObjectRest extends BaseObjectRest<Long> {
this.restProp2 = restProp2;
}
@LinkRest(linkClass = MockObjectRest.class, embedOptional = true, linkOptional = true)
@LinkRest(linkClass = MockObjectRest.class)
public MockObjectRest getRestProp3() {
return restProp3;
}
@@ -117,7 +114,7 @@ public class MockObjectRest extends BaseObjectRest<Long> {
this.restProp3 = restProp3;
}
@LinkRest(linkClass = MockObjectRest.class, embedOptional = true)
@LinkRest(linkClass = MockObjectRest.class)
public MockObjectRest getRestProp4() {
return restProp4;
}