/* * Copyright 2014-2015 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; import static org.springframework.util.StringUtils.*; import java.net.URI; import java.util.Collections; import java.util.List; import javax.servlet.http.HttpServletRequest; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UrlPathHelper; /** * Value object to be able to extract the lookup path within a configured base URI that forms a URI namespace. * * @author Oliver Gierke */ public class BaseUri { public static final BaseUri NONE = new BaseUri(URI.create("")); private static final UrlPathHelper URL_PATH_HELPER = new UrlPathHelper(); private final URI baseUri; /** * Creates a new {@link BaseUri} with the given URI as base. * * @param uri must not be {@literal null}. */ public BaseUri(URI uri) { Assert.notNull(uri, "Base URI must not be null!"); String uriString = uri.toString(); this.baseUri = URI.create(trimTrailingCharacter(trimTrailingCharacter(uriString, '/'), '/')); } /** * Creates a new {@link BaseUri} with the given URI as base. * * @param uri must not be {@literal null}. */ public BaseUri(String uri) { this(URI.create(uri)); } /** * Returns the base URI. * * @return */ public URI getUri() { return baseUri; } /** * Extracts the actual lookup path within the Spring Data REST managed URI space. This includes stripping the * necessary parts of the base URI from the source lookup path. * * @param request must not be {@literal null}. * @return the stripped lookup path with then the repository URI space or {@literal null} in case the lookup path is * not pointing into the repository URI space. */ public String getRepositoryLookupPath(NativeWebRequest request) { return getRepositoryLookupPath(request.getNativeRequest(HttpServletRequest.class)); } /** * Extracts the actual lookup path within the Spring Data REST managed URI space. This includes stripping the * necessary parts of the base URI from the source lookup path. * * @param request must not be {@literal null}. * @return the stripped lookup path with then the repository URI space or {@literal null} in case the lookup path is * not pointing into the repository URI space. */ private String getRepositoryLookupPath(HttpServletRequest request) { String lookupPath = URL_PATH_HELPER.getLookupPathForRequest(request); return getRepositoryLookupPath(lookupPath); } /** * Extracts the actual lookup path within the Spring Data REST managed URI space. This includes stripping the * necessary parts of the base URI from the source lookup path. * * @param lookupPath must not be {@literal null}. * @return the stripped lookup path with then the repository URI space or {@literal null} in case the lookup path is * not pointing into the repository URI space. */ public String getRepositoryLookupPath(String lookupPath) { Assert.notNull(lookupPath, "Lookup path must not be null!"); // Temporary fix for SPR-13455 lookupPath = lookupPath.replaceAll("//", "/"); lookupPath = trimTrailingCharacter(lookupPath, '/'); if (!baseUri.isAbsolute()) { String uri = baseUri.toString(); if (!StringUtils.hasText(uri)) { return lookupPath; } uri = uri.startsWith("/") ? uri : "/".concat(uri); return lookupPath.startsWith(uri) ? lookupPath.substring(uri.length(), lookupPath.length()) : null; } List<String> baseUriSegments = UriComponentsBuilder.fromUri(baseUri).build().getPathSegments(); Collections.reverse(baseUriSegments); String tail = ""; for (String tailSegment : baseUriSegments) { tail = "/".concat(tailSegment).concat(tail); if (lookupPath.startsWith(tail)) { return lookupPath.substring(tail.length(), lookupPath.length()); } } return null; } /** * Returns a new {@link UriComponentsBuilder} for the base URI. If the base URI is not absolute, it'll lokup the URI * for the current servlet mapping and extend it accordingly. * * @return */ public UriComponentsBuilder getUriComponentsBuilder() { if (baseUri.isAbsolute()) { return UriComponentsBuilder.fromUri(baseUri); } return ServletUriComponentsBuilder.fromCurrentServletMapping().path(baseUri.toString()); } }