/******************************************************************************* * Copyright (c) 2012-2016 Codenvy, S.A. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.everrest.core.impl; import org.everrest.core.impl.header.AcceptLanguageHeaderDelegate; import org.everrest.core.impl.header.AcceptMediaTypeHeaderDelegate; import org.everrest.core.impl.header.CacheControlHeaderDelegate; import org.everrest.core.impl.header.CookieHeaderDelegate; import org.everrest.core.impl.header.DateHeaderDelegate; import org.everrest.core.impl.header.EntityTagHeaderDelegate; import org.everrest.core.impl.header.LinkHeaderDelegate; import org.everrest.core.impl.header.LocaleHeaderDelegate; import org.everrest.core.impl.header.MediaTypeHeaderDelegate; import org.everrest.core.impl.header.NewCookieHeaderDelegate; import org.everrest.core.impl.header.RangesHeaderDelegate; import org.everrest.core.impl.header.StringHeaderDelegate; import org.everrest.core.impl.header.URIHeaderDelegate; import org.everrest.core.impl.uri.LinkBuilderImpl; import org.everrest.core.impl.uri.UriBuilderImpl; import javax.ws.rs.core.Application; import javax.ws.rs.core.Link; import javax.ws.rs.core.Response.ResponseBuilder; import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.Variant.VariantListBuilder; import javax.ws.rs.ext.RuntimeDelegate; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.HashMap; import java.util.Map; import static com.google.common.base.Preconditions.checkArgument; /** * @author andrew00x */ public class RuntimeDelegateImpl extends RuntimeDelegate { /** HeaderDelegate cache. */ private final Map<Class<?>, HeaderDelegate> headerDelegates = new HashMap<>(); /** * Should be used only once for initialize. * * @see RuntimeDelegate#setInstance(RuntimeDelegate) * @see RuntimeDelegate#getInstance() */ public RuntimeDelegateImpl() { init(); } private void init() { addHeaderDelegate(new MediaTypeHeaderDelegate()); addHeaderDelegate(new CacheControlHeaderDelegate()); addHeaderDelegate(new CookieHeaderDelegate()); addHeaderDelegate(new NewCookieHeaderDelegate()); addHeaderDelegate(new EntityTagHeaderDelegate()); addHeaderDelegate(new DateHeaderDelegate()); addHeaderDelegate(new AcceptLanguageHeaderDelegate()); addHeaderDelegate(new AcceptMediaTypeHeaderDelegate()); addHeaderDelegate(new StringHeaderDelegate()); addHeaderDelegate(new URIHeaderDelegate()); addHeaderDelegate(new LocaleHeaderDelegate()); addHeaderDelegate(new RangesHeaderDelegate()); addHeaderDelegate(new LinkHeaderDelegate()); } public void addHeaderDelegate(HeaderDelegate<?> headerDelegate) { headerDelegates.put(getHeaderType(headerDelegate), headerDelegate); } private Class<?> getHeaderType(HeaderDelegate<?> headerDelegate) { Class<?> typeSupportedByHeaderDelegate = null; Class<?> headerDelegateClass = headerDelegate.getClass(); while (headerDelegateClass != null && typeSupportedByHeaderDelegate == null) { for (Type genericType : headerDelegateClass.getGenericInterfaces()) { if (genericType instanceof ParameterizedType) { final ParameterizedType parameterizedType = (ParameterizedType)genericType; final Type rawType = parameterizedType.getRawType(); if (HeaderDelegate.class == rawType) { final Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); if (actualTypeArguments.length == 1) { if (actualTypeArguments[0] instanceof Class) { typeSupportedByHeaderDelegate = (Class)actualTypeArguments[0]; } } } } } headerDelegateClass = headerDelegateClass.getSuperclass(); } if (typeSupportedByHeaderDelegate == null) { throw new IllegalArgumentException(String.format("Unable determine type of headers processed by %s", headerDelegate)); } return typeSupportedByHeaderDelegate; } /** End Points is not supported. {@inheritDoc} */ @Override public <T> T createEndpoint(Application applicationConfig, Class<T> type) { throw new UnsupportedOperationException("End Points is not supported"); } @SuppressWarnings("unchecked") @Override public <T> HeaderDelegate<T> createHeaderDelegate(Class<T> type) { checkArgument(type != null, "Null type is not supported"); return headerDelegates.get(type); } @Override public Link.Builder createLinkBuilder() { return new LinkBuilderImpl(); } @Override public ResponseBuilder createResponseBuilder() { return new ResponseImpl.ResponseBuilderImpl(); } @Override public UriBuilder createUriBuilder() { return new UriBuilderImpl(); } @Override public VariantListBuilder createVariantListBuilder() { return new VariantListBuilderImpl(); } }