/*
* 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());
}
}