package org.etk.core.rest.impl;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.PathSegment;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import org.etk.core.rest.GenericContainerRequest;
import org.etk.core.rest.GenericContainerResponse;
import org.etk.core.rest.impl.uri.UriComponent;
public class ApplicationContextImpl implements ApplicationContext {
/**
* {@link ThreadLocal} ApplicationContext.
*/
private static ThreadLocal<ApplicationContext> current = new ThreadLocal<ApplicationContext>();
/**
* Set ApplicationContext for current thread.
*
* @param context the ApplicationContext.
*/
public static void setCurrent(ApplicationContext context) {
current.set(context);
}
/**
* @return current ApplicationContext.
*/
public static ApplicationContext getCurrent() {
return current.get();
}
/**
* Values of template parameters.
*/
private List<String> parameterValues = new ArrayList<String>();
/**
* List of matched resources.
*/
private List<Object> matchedResources = new ArrayList<Object>();
/**
* List of not decoded matched URIs.
*/
private List<String> encodedMatchedURIs = new ArrayList<String>();
/**
* List of decoded matched URIs.
*/
private List<String> matchedURIs = new ArrayList<String>();
/**
* Mutable runtime attributes.
*/
private Map<String, Object> attributes;
/**
* See {@link GenericContainerRequest}.
*/
protected GenericContainerRequest request;
/**
* See {@link ContainerResponse}.
*/
protected GenericContainerResponse response;
/**
* Providers.
*/
protected ProviderBinder providers;
/**
* Constructs new instance of ApplicationContext.
*
* @param request See {@link GenricContainerRequest}
* @param response See {@link GenericContainerResponse}
* @param providers See {@link ProviderBinder}
*/
public ApplicationContextImpl(GenericContainerRequest request,
GenericContainerResponse response,
ProviderBinder providers) {
this.request = request;
this.response = response;
this.providers = providers;
}
/**
* {@inheritDoc}
*/
public List<String> getParameterValues() {
return parameterValues;
}
/**
* {@inheritDoc}
*/
public void setParameterNames(List<String> parameterNames) {
if (encodedPathParameters == null)
encodedPathParameters = new MultivaluedMapImpl();
for (int i = 0; i < parameterNames.size(); i++)
encodedPathParameters.add(parameterNames.get(i), parameterValues.get(i));
}
/**
* {@inheritDoc}
*/
public void addMatchedResource(Object resource) {
matchedResources.add(0, resource);
}
/**
* {@inheritDoc}
*/
public void addMatchedURI(String uri) {
encodedMatchedURIs.add(0, uri);
matchedURIs.add(0, UriComponent.decode(uri, UriComponent.PATH_SEGMENT));
}
/**
* {@inheritDoc}
*/
public Map<String, Object> getAttributes() {
return attributes == null ? attributes = new HashMap<String, Object>() : attributes;
}
/**
* {@inheritDoc}
*/
public Request getRequest() {
return request;
}
/**
* {@inheritDoc}
*/
public HttpHeaders getHttpHeaders() {
return request;
}
/**
* {@inheritDoc}
*/
public SecurityContext getSecurityContext() {
return request;
}
/**
* {@inheritDoc}
*/
public GenericContainerRequest getContainerRequest() {
return request;
}
/**
* {@inheritDoc}
*/
public UriInfo getUriInfo() {
return this;
}
/**
* {@inheritDoc}
*/
public GenericContainerResponse getContainerResponse() {
return response;
}
// UriInfo
/**
* Absolute path, full requested URI without query string and fragment.
*/
private URI absolutePath;
/**
* Decoded relative path.
*/
private String path;
/**
* Not decoded relative path.
*/
private String encodedPath;
/**
* Not decoded path template parameters.
*/
private MultivaluedMap<String, String> encodedPathParameters;
/**
* Decoded path template parameters.
*/
private MultivaluedMap<String, String> pathParameters;
/**
* List of not decoded path segments.
*/
private List<PathSegment> encodedPathSegments;
/**
* Decoded path segments.
*/
private List<PathSegment> pathSegments;
/**
* Not decoded query parameters.
*/
private MultivaluedMap<String, String> encodedQueryParameters;
/**
* Decoded query parameters.
*/
private MultivaluedMap<String, String> queryParameters;
/**
* {@inheritDoc}
*/
public URI getAbsolutePath() {
if (absolutePath != null)
return absolutePath;
return absolutePath = getRequestUriBuilder().replaceQuery(null).fragment(null).build();
}
/**
* {@inheritDoc}
*/
public UriBuilder getAbsolutePathBuilder() {
return UriBuilder.fromUri(getAbsolutePath());
}
/**
* {@inheritDoc}
*/
public List<Object> getMatchedResources() {
return matchedResources;
}
/**
* {@inheritDoc}
*/
public List<String> getMatchedURIs() {
return getMatchedURIs(true);
}
/**
* {@inheritDoc}
*/
public List<String> getMatchedURIs(boolean decode) {
return decode ? matchedURIs : encodedMatchedURIs;
}
/**
* {@inheritDoc}
*/
public URI getBaseUri() {
return request.getBaseUri();
}
/**
* {@inheritDoc}
*/
public UriBuilder getBaseUriBuilder() {
return UriBuilder.fromUri(getBaseUri());
}
/**
* {@inheritDoc}
*/
public String getPath() {
return getPath(true);
}
/**
* {@inheritDoc}
*/
public String getPath(boolean decode) {
if (encodedPath == null)
encodedPath = getAbsolutePath().getRawPath().substring(getBaseUri().getRawPath().length());
if (decode) {
if (path != null)
return path;
return path = UriComponent.decode(encodedPath, UriComponent.PATH);
}
return encodedPath;
}
/**
* {@inheritDoc}
*/
public MultivaluedMap<String, String> getPathParameters() {
return getPathParameters(true);
}
/**
* {@inheritDoc}
*/
public MultivaluedMap<String, String> getPathParameters(boolean decode) {
if (encodedPathParameters == null)
throw new IllegalStateException("Path template variables not initialized yet.");
if (decode) {
if (pathParameters == null) {
pathParameters = new MultivaluedMapImpl();
}
if (pathParameters.size() != encodedPathParameters.size()) {
for (String key : encodedPathParameters.keySet()) {
if (!pathParameters.containsKey(key)) {
pathParameters.putSingle(UriComponent.decode(key, UriComponent.PATH_SEGMENT),
UriComponent.decode(encodedPathParameters.getFirst(key),
UriComponent.PATH));
}
}
}
return pathParameters;
}
return encodedPathParameters;
}
/**
* {@inheritDoc}
*/
public List<PathSegment> getPathSegments() {
return getPathSegments(true);
}
/**
* {@inheritDoc}
*/
public List<PathSegment> getPathSegments(boolean decode) {
if (decode) {
return pathSegments != null ? pathSegments
: (pathSegments = UriComponent.parsePathSegments(getPath(), true));
}
return encodedPathSegments != null ? encodedPathSegments
: (encodedPathSegments = UriComponent.parsePathSegments(getPath(),
false));
}
/**
* {@inheritDoc}
*/
public MultivaluedMap<String, String> getQueryParameters() {
return getQueryParameters(true);
}
/**
* {@inheritDoc}
*/
public MultivaluedMap<String, String> getQueryParameters(boolean decode) {
if (decode)
return queryParameters != null ? queryParameters
: (queryParameters = UriComponent.parseQueryString(getRequestUri().getRawQuery(),
true));
return encodedQueryParameters != null ? encodedQueryParameters
: (encodedQueryParameters = UriComponent.parseQueryString(getRequestUri().getRawQuery(),
false));
}
/**
* {@inheritDoc}
*/
public URI getRequestUri() {
return request.getRequestUri();
}
/**
* {@inheritDoc}
*/
public UriBuilder getRequestUriBuilder() {
return UriBuilder.fromUri(getRequestUri());
}
/**
* {@inheritDoc}
*/
public ProviderBinder getProviders() {
return providers;
}
}