/* * Copyright 2014-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.data.rest.webmvc.mapping; import lombok.Getter; import lombok.NonNull; import lombok.RequiredArgsConstructor; import java.util.Collections; import java.util.List; import org.springframework.data.mapping.Association; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.rest.core.Path; import org.springframework.data.rest.core.config.RepositoryRestConfiguration; import org.springframework.data.rest.core.mapping.ResourceMapping; import org.springframework.data.rest.core.mapping.ResourceMappings; import org.springframework.data.rest.core.mapping.ResourceMetadata; import org.springframework.hateoas.Link; import org.springframework.util.Assert; /** * A value object to for {@link Link}s representing associations. * * @author Oliver Gierke * @author Greg Turnquist * @since 2.1 */ @RequiredArgsConstructor public class Associations { private final @NonNull @Getter ResourceMappings mappings; private final @NonNull RepositoryRestConfiguration config; /** * Returns the links to render for the given {@link Association}. * * @param association must not be {@literal null}. * @param path must not be {@literal null}. * @return */ public List<Link> getLinksFor(Association<? extends PersistentProperty<?>> association, Path path) { Assert.notNull(association, "Association must not be null!"); Assert.notNull(path, "Base path must not be null!"); if (isLinkableAssociation(association)) { PersistentProperty<?> property = association.getInverse(); ResourceMetadata metadata = mappings.getMetadataFor(property.getOwner().getType()); ResourceMapping propertyMapping = metadata.getMappingFor(property); String href = path.slash(propertyMapping.getPath()).toString(); String rel = propertyMapping.getRel(); return Collections.singletonList(new Link(href, rel)); } return Collections.emptyList(); } /** * Returns the {@link ResourceMetadata} for the given type. * * @param type must not be {@literal null}. * @return */ public ResourceMetadata getMetadataFor(Class<?> type) { Assert.notNull(type, "Type must not be null!"); return mappings.getMetadataFor(type); } /** * Returns whether the type of the given {@link PersistentProperty} is configured as lookup type. * * @param property must not be {@literal null}. * @return */ public boolean isLookupType(PersistentProperty<?> property) { Assert.notNull(property, "Persistent property must not be null!"); return config.isLookupType(property.getActualType()); } public boolean isIdExposed(PersistentEntity<?, ?> entity) { return config.isIdExposedFor(entity.getType()); } /** * Returns whether the given {@link Association} is linkable. * * @param association must not be {@literal null}. * @return */ public boolean isLinkableAssociation(Association<? extends PersistentProperty<?>> association) { Assert.notNull(association, "Association must not be null!"); return isLinkableAssociation(association.getInverse()); } /** * Returns whether the given property is an association that is linkable. * * @param property must not be {@literal null}. * @return */ public boolean isLinkableAssociation(PersistentProperty<?> property) { Assert.notNull(property, "PersistentProperty must not be null!"); if (!property.isAssociation() || config.isLookupType(property.getActualType())) { return false; } ResourceMetadata metadata = mappings.getMetadataFor(property.getOwner().getType()); if (metadata != null && !metadata.isExported(property)) { return false; } metadata = mappings.getMetadataFor(property.getActualType()); return metadata == null ? false : metadata.isExported(); } }