internal.org.springframework.content.rest.controllers.ResourceHandlerMethodArgumentResolver Maven / Gradle / Ivy
package internal.org.springframework.content.rest.controllers;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.springframework.content.commons.mappingcontext.MappingContext;
import org.springframework.content.commons.repository.AssociativeStore;
import org.springframework.content.commons.repository.Store;
import org.springframework.content.commons.storeservice.StoreInfo;
import org.springframework.content.commons.storeservice.Stores;
import org.springframework.content.rest.config.RestConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.core.MethodParameter;
import org.springframework.core.io.Resource;
import org.springframework.data.repository.support.Repositories;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.util.UriTemplate;
import org.springframework.web.util.UrlPathHelper;
import internal.org.springframework.content.rest.controllers.resolvers.AssociativeStoreResourceResolver;
import internal.org.springframework.content.rest.controllers.resolvers.EntityResolution;
import internal.org.springframework.content.rest.controllers.resolvers.EntityResolvers;
import internal.org.springframework.content.rest.controllers.resolvers.ResourceResolver;
import internal.org.springframework.content.rest.controllers.resolvers.StoreResourceResolver;
import internal.org.springframework.content.rest.io.StoreResourceImpl;
import internal.org.springframework.content.rest.utils.StoreUtils;
public class ResourceHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
private UriTemplate entityUriTemplate = new UriTemplate("/{repository}/{id}");
private UriTemplate entityPropertyUriTemplate = new UriTemplate("/{repository}/{id}/{property}");
private UriTemplate entityPropertyWithIdUriTemplate = new UriTemplate("/{repository}/{id}/{property}/**");
private UriTemplate revisionPropertyUriTemplate = new UriTemplate("/{repository}/{id}/revisions/{revisionId}/{property}");
private UriTemplate revisionPropertyWithIdUriTemplate = new UriTemplate("/{repository}/{id}/revisions/{revisionId}/{property}/{contentId}");
private EntityResolvers entityResolvers;
private List resolvers = new ArrayList<>();
private ApplicationContext context;
private final RestConfiguration config;
private final Repositories repositories;
private final Stores stores;
private final MappingContext mappingContext;
public ResourceHandlerMethodArgumentResolver(ApplicationContext context, RestConfiguration config, Repositories repositories, Stores stores, MappingContext mappingContext, EntityResolvers entityResolvers) {
this.context = context;
this.config = config;
this.repositories = repositories;
this.stores = stores;
this.mappingContext = mappingContext;
this.entityResolvers = entityResolvers;
resolvers.add(new StoreResourceResolver(this.mappingContext));
resolvers.add(new AssociativeStoreResourceResolver(this.mappingContext));
}
RestConfiguration getConfig() {
return config;
}
protected Repositories getRepositories() {
return repositories;
}
protected Stores getStores() {
return stores;
}
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
return Resource.class.isAssignableFrom(methodParameter.getParameterType());
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
String pathInfo = webRequest.getNativeRequest(HttpServletRequest.class).getRequestURI();
pathInfo = new UrlPathHelper().getPathWithinApplication(webRequest.getNativeRequest(HttpServletRequest.class));
pathInfo = StoreUtils.storeLookupPath(pathInfo, this.getConfig().getBaseUri());
String[] pathSegments = pathInfo.split("/");
if (pathSegments.length < 2) {
return null;
}
String store = pathSegments[1];
StoreInfo info = this.getStores().getStore(Store.class, StoreUtils.withStorePath(store));
if (info == null) {
throw new IllegalArgumentException(String.format("Store for path %s not found", store));
}
if (AssociativeStore.class.isAssignableFrom(info.getInterface())) {
EntityResolution result = this.entityResolvers.resolve(pathInfo);
AntPathMatcher matcher = new AntPathMatcher();
Comparator patternComparator = matcher.getPatternComparator(pathInfo);
List uriTemplates = new ArrayList<>();
for (ResourceResolver resolver : resolvers) {
if (matcher.match(resolver.getMapping(), pathInfo)) {
uriTemplates.add(resolver.getMapping());
}
}
String bestMatch = null;
if (uriTemplates.size() > 1) {
uriTemplates.sort(patternComparator);
}
bestMatch = uriTemplates.get(0);
ResourceResolver matchedResolver = null;
for (ResourceResolver resolver : resolvers) {
if (bestMatch.equals(resolver.getMapping())) {
matchedResolver = resolver;
}
}
return matchedResolver.resolve(webRequest, info, result.getEntity(), result.getProperty());
} else if (Store.class.isAssignableFrom(info.getInterface())) {
return resolveStoreArgument(webRequest, info);
}
throw new IllegalArgumentException();
}
protected Object resolveStoreArgument(NativeWebRequest nativeWebRequest, StoreInfo info) {
String path = new UrlPathHelper().getPathWithinApplication(nativeWebRequest.getNativeRequest(HttpServletRequest.class));
String pathToUse = path.substring(StoreUtils.storePath(info).length() + 1);
return new StoreResourceImpl(info, info.getImplementation(Store.class).getResource(pathToUse));
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy