import java.net.*; import java.security.*; import java.util.*; import java.util.concurrent.*; import javax.ws.rs.core.*; /** * JAX-RS Utilities. */ public abstract class RESTUtil { public static class ConcurrentMultivaluedMapWrapper extends AbstractMap> implements MultivaluedMap { protected final Map> multivaluedMap; public ConcurrentMultivaluedMapWrapper(final MultivaluedMap multivaluedMap) throws IllegalArgumentException { if (multivaluedMap == null) throw new IllegalArgumentException("null multivaluedMap"); this.multivaluedMap = Collections.unmodifiableMap(new ConcurrentHashMap>(multivaluedMap)); return; } @Override public Set>> entrySet() { final Set>> entrySet = multivaluedMap.entrySet(); if (entrySet == null) return null; final List>> concurrentEntries = new ArrayList>>(entrySet.size()); for (Map.Entry> entry : entrySet) { concurrentEntries.add(new AbstractMap.SimpleEntry>(entry.getKey(), (entry.getValue() != null) ? Collections.unmodifiableList(new CopyOnWriteArrayList(entry.getValue())) : null)); } return Collections.unmodifiableSet(new CopyOnWriteArraySet>>(concurrentEntries)); } @Override public void clear() { throw new UnsupportedOperationException(); } @Override public boolean containsKey(final Object key) { return multivaluedMap.containsKey(key); } @Override public boolean containsValue(final Object value) { return multivaluedMap.containsValue(value); } @Override public List get(final Object key) { final List value = multivaluedMap.get(key); return (value != null) ? Collections.unmodifiableList(new CopyOnWriteArrayList(value)) : null; } @Override public boolean isEmpty() { return multivaluedMap.isEmpty(); } @Override public Set keySet() { final Set keySet = multivaluedMap.keySet(); return (keySet != null) ? Collections.unmodifiableSet(new CopyOnWriteArraySet(keySet)) : null; } @Override public List remove(final Object key) { throw new UnsupportedOperationException(); } @Override public int size() { return multivaluedMap.size(); } @Override public void add(final K key, final V value) { throw new UnsupportedOperationException(); } @Override public V getFirst(final K key) { final List values = multivaluedMap.get(key); return ((values != null) && (!values.isEmpty())) ? values.get(0) : null; } @Override public void putSingle(final K key, final V value) { throw new UnsupportedOperationException(); } @Override public List put(final K key, final List value) { throw new UnsupportedOperationException(); } @Override public void putAll(final Map> m) { throw new UnsupportedOperationException(); } } // ConcurrentMultivaluedMapWrapper public static class ConcurrentRequestWrapper implements Request { protected final Request request; public ConcurrentRequestWrapper(final Request request) throws IllegalArgumentException { if (request == null) throw new IllegalArgumentException("null request"); this.request = request; return; } @Override public Response.ResponseBuilder evaluatePreconditions() { synchronized (request) { return request.evaluatePreconditions(); } } @Override public Response.ResponseBuilder evaluatePreconditions(final EntityTag eTag) { synchronized (request) { return request.evaluatePreconditions(eTag); } } @Override public Response.ResponseBuilder evaluatePreconditions(final Date lastModified) { synchronized (request) { return request.evaluatePreconditions(lastModified); } } @Override public Response.ResponseBuilder evaluatePreconditions(final Date lastModified, final EntityTag eTag) { synchronized (request) { return request.evaluatePreconditions(lastModified, eTag); } } @Override public String getMethod() { synchronized (request) { return request.getMethod(); } } @Override public Variant selectVariant(final List variants) throws IllegalArgumentException { synchronized (request) { return request.selectVariant(variants); } } } // ConcurrentRequestWrapper public static class ConcurrentUriInfoWrapper implements UriInfo { protected final UriInfo uriInfo; public ConcurrentUriInfoWrapper(final UriInfo uriInfo) throws IllegalArgumentException { if (uriInfo == null) throw new IllegalArgumentException("null uriInfo"); this.uriInfo = uriInfo; return; } @Override public URI getAbsolutePath() { synchronized (uriInfo) { return uriInfo.getAbsolutePath(); } } @Override public UriBuilder getAbsolutePathBuilder() { synchronized (uriInfo) { return uriInfo.getAbsolutePathBuilder(); } } @Override public URI getBaseUri() { synchronized (uriInfo) { return uriInfo.getBaseUri(); } } @Override public UriBuilder getBaseUriBuilder() { synchronized (uriInfo) { return uriInfo.getBaseUriBuilder(); } } @Override public List getMatchedResources() { synchronized (uriInfo) { final List matchedResources = uriInfo.getMatchedResources(); return (matchedResources != null) ? Collections.unmodifiableList(new CopyOnWriteArrayList(matchedResources)) : null; } } @Override public List getMatchedURIs() { synchronized (uriInfo) { final List matchedURIs = uriInfo.getMatchedURIs(); return (matchedURIs != null) ? Collections.unmodifiableList(new CopyOnWriteArrayList(matchedURIs)) : null; } } @Override public List getMatchedURIs(boolean decode) { synchronized (uriInfo) { final List matchedURIs = uriInfo.getMatchedURIs(decode); return (matchedURIs != null) ? Collections.unmodifiableList(new CopyOnWriteArrayList(matchedURIs)) : null; } } @Override public String getPath() { synchronized (uriInfo) { return uriInfo.getPath(); } } @Override public String getPath(boolean decode) { synchronized (uriInfo) { return uriInfo.getPath(decode); } } @Override public MultivaluedMap getPathParameters() { synchronized (uriInfo) { final MultivaluedMap pathParameters = uriInfo.getPathParameters(); return (pathParameters != null) ? new ConcurrentMultivaluedMapWrapper(pathParameters) : null; } } @Override public MultivaluedMap getPathParameters(boolean decode) { synchronized (uriInfo) { final MultivaluedMap pathParameters = uriInfo.getPathParameters(decode); return (pathParameters != null) ? new ConcurrentMultivaluedMapWrapper(pathParameters) : null; } } @Override public List getPathSegments() { synchronized (uriInfo) { final List pathSegments = uriInfo.getPathSegments(); return (pathSegments != null) ? Collections.unmodifiableList(new CopyOnWriteArrayList(pathSegments)) : null; } } @Override public List getPathSegments(boolean decode) { synchronized (uriInfo) { final List pathSegments = uriInfo.getPathSegments(decode); return (pathSegments != null) ? Collections.unmodifiableList(new CopyOnWriteArrayList(pathSegments)) : null; } } @Override public MultivaluedMap getQueryParameters() { synchronized (uriInfo) { final MultivaluedMap queryParameters = uriInfo.getQueryParameters(); return (queryParameters != null) ? new ConcurrentMultivaluedMapWrapper(queryParameters) : null; } } @Override public MultivaluedMap getQueryParameters(boolean decode) { synchronized (uriInfo) { final MultivaluedMap queryParameters = uriInfo.getQueryParameters(decode); return (queryParameters != null) ? new ConcurrentMultivaluedMapWrapper(queryParameters) : null; } } @Override public URI getRequestUri() { synchronized (uriInfo) { return uriInfo.getRequestUri(); } } @Override public UriBuilder getRequestUriBuilder() { synchronized (uriInfo) { return uriInfo.getRequestUriBuilder(); } } } // ConcurrentUriInfoWrapper public static class ConcurrentSecurityContextWrapper implements SecurityContext { protected final SecurityContext securityContext; public ConcurrentSecurityContextWrapper(final SecurityContext securityContext) throws IllegalArgumentException { if (securityContext == null) throw new IllegalArgumentException("null securityContext"); this.securityContext = securityContext; return; } @Override public String getAuthenticationScheme() { synchronized (securityContext) { return securityContext.getAuthenticationScheme(); } } @Override public Principal getUserPrincipal() { synchronized (securityContext) { return securityContext.getUserPrincipal(); } } @Override public boolean isSecure() { synchronized (securityContext) { return securityContext.isSecure(); } } @Override public boolean isUserInRole(final String role) { synchronized (securityContext) { return securityContext.isUserInRole(role); } } } // ConcurrentSecurityContextWrapper public static class ConcurrentHttpHeadersWrapper implements HttpHeaders { protected final HttpHeaders httpHeaders; public ConcurrentHttpHeadersWrapper(final HttpHeaders httpHeaders) throws IllegalArgumentException { if (httpHeaders == null) throw new IllegalArgumentException("null httpHeaders"); this.httpHeaders = httpHeaders; return; } @Override public List getAcceptableLanguages() { synchronized (httpHeaders) { final List acceptableLanguages = httpHeaders.getAcceptableLanguages(); return (acceptableLanguages != null) ? Collections.unmodifiableList(new CopyOnWriteArrayList(acceptableLanguages)) : null; } } @Override public List getAcceptableMediaTypes() { synchronized (httpHeaders) { final List acceptableMediaTypes = httpHeaders.getAcceptableMediaTypes(); return (acceptableMediaTypes != null) ? Collections.unmodifiableList(new CopyOnWriteArrayList(acceptableMediaTypes)) : null; } } @Override public Map getCookies() { synchronized (httpHeaders) { final Map cookies = httpHeaders.getCookies(); return (cookies != null) ? Collections.unmodifiableMap(new ConcurrentHashMap(cookies)) : null; } } @Override public Locale getLanguage() { synchronized (httpHeaders) { return httpHeaders.getLanguage(); } } @Override public MediaType getMediaType() { synchronized (httpHeaders) { return httpHeaders.getMediaType(); } } @Override public List getRequestHeader(final String name) { synchronized (httpHeaders) { final List requestHeader = httpHeaders.getRequestHeader(name); return (requestHeader != null) ? Collections.unmodifiableList(new CopyOnWriteArrayList(requestHeader)) : null; } } @Override public MultivaluedMap getRequestHeaders() { synchronized (httpHeaders) { final MultivaluedMap requestHeaders = httpHeaders.getRequestHeaders(); return (requestHeaders != null) ? new ConcurrentMultivaluedMapWrapper(requestHeaders) : null; } } } // ConcurrentHttpHeadersWrapper }