All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javax.ws.rs.core.GenericEntity Maven / Gradle / Ivy

package javax.ws.rs.core;

/*
 * The contents of this file are subject to the terms
 * of the Common Development and Distribution License
 * (the "License").  You may not use this file except
 * in compliance with the License.
 *
 * You can obtain a copy of the license at
 * http://www.opensource.org/licenses/cddl1.php
 * See the License for the specific language governing
 * permissions and limitations under the License.
 *
 * This file incorporates work covered by the following copyright and
 * permission notice:
 *
 * Copyright (C) 2006 Google Inc.
 *
 * 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.
 */
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import javax.ws.rs.ext.MessageBodyWriter;

/**
 * Represents a response entity of a generic type {@code T}.
 * 
 * 

Normally type erasure removes generic type information such that a * {@link Response} instance that contains, e.g., an entity of type * {@code List} appears to contain a raw {@code List} at runtime. * When the generic type is required to select a suitable * {@link MessageBodyWriter}, this class may be used to wrap the entity and * capture its generic type.

* *

There are two ways to create an instance:

*
    *
  1. Create a (typically anonymous) subclass of this * class which enables retrieval of the type information at runtime despite * type erasure. For example, the following code shows how to create a * {@link Response} containing an entity of type {@code List} whose * generic type will be available at runtime for selection of a suitable * {@link MessageBodyWriter}: * *
    List<String> list = new ArrayList<String>();
     *GenericEntity<List<String>> entity = new GenericEntity<List<String>>(list) {};
     *Response response = Response.ok(entity).build();
    * *

    where list is the instance of List<String> * that will form the response body and entity is an instance of an anonymous * subclass of {@code GenericEntity}.

  2. *
  3. Create an instance directly by supplying the generic type information * with the entity. For example the following code shows how to create * a response containing the result of a method invoked via reflection: *
    Method method = ...;
     *GenericEntity<Object> entity = new GenericEntity<Object>(
     *    method.invoke(...), method.getGenericReturnType());
     *Response response = Response.ok(entity).build();
  4. *

    The above obtains the generic type from the return type of the method, * the raw type is the class of entity.

    *
*/ public class GenericEntity { final Class rawType; final Type type; final T entity; /** * Constructs a new generic entity. Derives represented class from type * parameter. Note that this constructor is protected, users should create * a (usually anonymous) subclass as shown above. * * @param entity the entity instance, must not be null * @throws IllegalArgumentException if entity is null */ protected GenericEntity(T entity) { if (entity == null) { throw new IllegalArgumentException("The entity must not be null"); } this.entity = entity; this.type = getSuperclassTypeParameter(getClass()); this.rawType = entity.getClass(); } /** * Create a new instance of GenericEntity, supplying the generic type * information. The entity must be assignable to a variable of the * supplied generic type, e.g. if {@code entity} is an instance of * {@code ArrayList} then {@code genericType} could * be the same or a superclass of {@code ArrayList} with the same generic * type like {@code List}. * @param entity the entity instance, must not be null * @param genericType the generic type, must not be null * @throws IllegalArgumentException if the entity is not assignable to * a variable of the supplied generic type or if entity or genericType * is null. */ public GenericEntity(T entity, Type genericType) { if (entity == null || genericType==null) { throw new IllegalArgumentException("Arguments must not be null"); } this.entity = entity; this.rawType = entity.getClass(); checkTypeCompatibility(this.rawType, genericType); this.type = genericType; } private void checkTypeCompatibility(Class c, Type t) { if (t instanceof Class) { Class ct = (Class)t; if (ct.isAssignableFrom(c)) return; } else if (t instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType)t; Type rt = pt.getRawType(); checkTypeCompatibility(c, rt); return; } else if (c.isArray() && (t instanceof GenericArrayType)) { GenericArrayType at = (GenericArrayType)t; Type rt = at.getGenericComponentType(); checkTypeCompatibility(c.getComponentType(), rt); return; } throw new IllegalArgumentException("The type is incompatible with the class of the entity"); } /** * Returns the type from super class's type parameter. */ private static Type getSuperclassTypeParameter(Class subclass) { Type superclass = subclass.getGenericSuperclass(); if (!(superclass instanceof ParameterizedType)) { throw new RuntimeException("Missing type parameter."); } ParameterizedType parameterized = (ParameterizedType) superclass; return parameterized.getActualTypeArguments()[0]; } /** * Gets the raw type of the enclosed entity. Note that this is the raw type of * the instance, not the raw type of the type parameter. I.e. in the example * in the introduction, the raw type is {@code ArrayList} not {@code List}. * @return the raw type */ public final Class getRawType() { return rawType; } /** * Gets underlying {@code Type} instance. Note that this is derived from the * type parameter, not the enclosed instance. I.e. in the example * in the introduction, the type is {@code List} not * {@code ArrayList}. * @return the type */ public final Type getType() { return type; } /** * Get the enclosed entity * @return the enclosed entity */ public final T getEntity() { return entity; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy