2
* Copyright 2005-2012 Restlet S.A.S.
4
* The contents of this file are subject to the terms of one of the following
5
* open source licenses: Apache 2.0 or LGPL 3.0 or LGPL 2.1 or CDDL 1.0 or EPL
6
* 1.0 (the "Licenses"). You can select the license that you prefer but you may
7
* not use this file except in compliance with one of these Licenses.
9
* You can obtain a copy of the Apache 2.0 license at
10
* http://www.opensource.org/licenses/apache-2.0
12
* You can obtain a copy of the LGPL 3.0 license at
13
* http://www.opensource.org/licenses/lgpl-3.0
15
* You can obtain a copy of the LGPL 2.1 license at
16
* http://www.opensource.org/licenses/lgpl-2.1
18
* You can obtain a copy of the CDDL 1.0 license at
19
* http://www.opensource.org/licenses/cddl1
21
* You can obtain a copy of the EPL 1.0 license at
22
* http://www.opensource.org/licenses/eclipse-1.0
24
* See the Licenses for the specific language governing permissions and
25
* limitations under the Licenses.
27
* Alternatively, you can obtain a royalty free commercial license with less
28
* limitations, transferable or non-transferable, directly at
29
* http://www.restlet.com/products/restlet-framework
31
* Restlet is a registered trademark of Restlet S.A.S.
34
package org.restlet.ext.jaxrs.internal.wrappers.provider;
36
import java.io.IOException;
37
import java.io.InputStream;
38
import java.io.OutputStream;
39
import java.lang.annotation.Annotation;
40
import java.lang.reflect.InvocationTargetException;
41
import java.lang.reflect.Type;
42
import java.util.logging.Logger;
44
import javax.ws.rs.WebApplicationException;
45
import javax.ws.rs.core.Context;
46
import javax.ws.rs.core.MultivaluedMap;
47
import javax.ws.rs.ext.ExceptionMapper;
48
import javax.ws.rs.ext.Providers;
50
import org.restlet.data.CharacterSet;
51
import org.restlet.data.MediaType;
52
import org.restlet.ext.jaxrs.internal.core.CallContext;
53
import org.restlet.ext.jaxrs.internal.core.ThreadLocalizedContext;
54
import org.restlet.ext.jaxrs.internal.exceptions.IllegalTypeException;
55
import org.restlet.ext.jaxrs.internal.exceptions.InjectException;
56
import org.restlet.ext.jaxrs.internal.util.Converter;
57
import org.restlet.ext.jaxrs.internal.util.Util;
63
public class SingletonProvider extends AbstractProviderWrapper implements
64
MessageBodyReader, MessageBodyWriter, ContextResolver {
67
* the {@link ContextResolver}, if this providers is a
68
* {@link ContextResolver}
70
private final javax.ws.rs.ext.ContextResolver<?> contextResolver;
72
private final javax.ws.rs.ext.ExceptionMapper<? extends Throwable> excMapper;
74
private final Object jaxRsProvider;
77
* The JAX-RS {@link javax.ws.rs.ext.MessageBodyReader} this wrapper
80
private final javax.ws.rs.ext.MessageBodyReader<?> reader;
82
private final javax.ws.rs.ext.MessageBodyWriter<Object> writer;
85
* Creates a new wrapper for a ProviderWrapper and initializes the provider.
86
* If the given class is not a provider, an {@link IllegalArgumentException}
89
* @param jaxRsProvider
90
* the JAX-RS provider class.
93
* @throws IllegalArgumentException
94
* if the class is not a valid provider, may not be instantiated
96
* @throws WebApplicationException
97
* @see javax.ws.rs.ext.MessageBodyReader
98
* @see javax.ws.rs.ext.MessageBodyWriter
99
* @see javax.ws.rs.ext.ContextResolver
102
* @param jaxRsProvider
104
* needed, if the provider implements no provider interface
105
* @throws IllegalArgumentException
106
* @throws WebApplicationException
108
@SuppressWarnings("unchecked")
109
public SingletonProvider(Object jaxRsProvider, Logger logger)
110
throws IllegalArgumentException, WebApplicationException {
111
super((jaxRsProvider == null) ? null : jaxRsProvider.getClass());
112
if (jaxRsProvider == null) {
113
throw new IllegalArgumentException(
114
"The JAX-RS provider class must not be null");
116
this.jaxRsProvider = jaxRsProvider;
117
boolean isProvider = false;
118
if (jaxRsProvider instanceof javax.ws.rs.ext.MessageBodyWriter) {
119
this.writer = (javax.ws.rs.ext.MessageBodyWriter<Object>) jaxRsProvider;
124
if (jaxRsProvider instanceof javax.ws.rs.ext.MessageBodyReader) {
125
this.reader = (javax.ws.rs.ext.MessageBodyReader<?>) jaxRsProvider;
130
if (jaxRsProvider instanceof javax.ws.rs.ext.ExceptionMapper) {
131
this.excMapper = (javax.ws.rs.ext.ExceptionMapper<? extends Throwable>) jaxRsProvider;
134
this.excMapper = null;
136
if (jaxRsProvider instanceof javax.ws.rs.ext.ContextResolver) {
137
this.contextResolver = (javax.ws.rs.ext.ContextResolver<?>) jaxRsProvider;
140
this.contextResolver = null;
143
logger.config("The provider "
144
+ jaxRsProvider.getClass()
145
+ " is neither a MessageBodyWriter nor a MessageBodyReader nor a ContextResolver nor an ExceptionMapper");
150
* Checks, if this MessageBodyReader could read the given type.
155
* @return true, if the wrapped message body reader supports reading for the
156
* given class with the given parameters.
157
* @see javax.ws.rs.ext.MessageBodyReader#isReadable(Class, Type,
160
public boolean isReadable(Class<?> type, Type genericType,
161
Annotation[] annotations, javax.ws.rs.core.MediaType mediaType) {
163
return this.getJaxRsReader().isReadable(type, genericType,
164
annotations, mediaType);
165
} catch (NullPointerException e) {
166
if (genericType == null || annotations == null) {
167
// interpreted as not readable for the given combination
171
} catch (IllegalArgumentException e) {
172
if (genericType == null || annotations == null) {
173
// interpreted as not readable for the given combination
181
* Checks, if the given class could be written by this MessageBodyWriter.
186
* @return true, if the wrapped message writer reader supports writing for
187
* the given class with the given parameters.
188
* @see javax.ws.rs.ext.MessageBodyWriter#isWriteable(Class)
190
public boolean isWriteable(Class<?> type, Type genericType,
191
Annotation[] annotations, javax.ws.rs.core.MediaType mediaType) {
193
return this.getJaxRsWriter().isWriteable(type, genericType,
194
annotations, mediaType);
195
} catch (NullPointerException e) {
196
if (genericType == null || annotations == null) {
197
// interpreted as not writable for the given combination
201
} catch (IllegalArgumentException e) {
202
if (genericType == null || annotations == null) {
203
// interpreted as not writable for the given combination
211
public final boolean equals(Object otherProvider) {
212
if (this == otherProvider) {
215
if (!(otherProvider instanceof SingletonProvider)) {
218
return this.jaxRsProvider.getClass().equals(
219
((SingletonProvider) otherProvider).getClass());
223
* @return the JAX-RS provider class name
226
public String getClassName() {
227
return jaxRsProvider.getClass().getName();
231
* @return the contextResolver
233
public javax.ws.rs.ext.ContextResolver<?> getContextResolver() {
234
return this.contextResolver;
238
* Returns the {@link ExceptionMapper}, or null, if this provider is not an
239
* {@link ExceptionMapper}.
241
* @return the {@link ExceptionMapper}, or null, if this provider is not an
242
* {@link ExceptionMapper}.
244
public javax.ws.rs.ext.ExceptionMapper<? extends Throwable> getExcMapper() {
245
return this.excMapper;
249
* @see org.restlet.ext.jaxrs.internal.wrappers.provider.ProviderWrapper#getInitializedReader()
251
public MessageBodyReader getInitializedReader() {
256
* @see org.restlet.ext.jaxrs.internal.wrappers.provider.ProviderWrapper#getInitializedWriter()
258
public MessageBodyWriter getInitializedWriter() {
263
* @see org.restlet.ext.jaxrs.internal.wrappers.provider.MessageBodyReader#getJaxRsReader()
265
public javax.ws.rs.ext.MessageBodyReader<?> getJaxRsReader() {
270
* @see org.restlet.ext.jaxrs.internal.wrappers.provider.MessageBodyWriter#getJaxRsWriter()
272
public javax.ws.rs.ext.MessageBodyWriter<Object> getJaxRsWriter() {
277
public final int hashCode() {
278
return this.jaxRsProvider.hashCode();
285
* The generic {@link Type} to convert to.
287
* the annotations of the artifact to convert to
290
* @param entityStream
291
* @return the read object
292
* @throws IOException
293
* @see javax.ws.rs.ext.MessageBodyReader#readFrom(Class, Type,
294
* javax.ws.rs.core.MediaType, Annotation[], MultivaluedMap,
297
@SuppressWarnings({ "unchecked", "rawtypes" })
298
public Object readFrom(Class<?> type, Type genericType,
299
Annotation[] annotations, MediaType mediaType,
300
CharacterSet characterSet,
301
MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
302
throws IOException, InvocationTargetException {
304
return this.getJaxRsReader().readFrom((Class) type, genericType,
305
annotations, Converter.toJaxRsMediaType(mediaType),
306
httpHeaders, entityStream);
307
} catch (Throwable t) {
308
if (t instanceof IOException)
309
throw (IOException) t;
310
if (t instanceof WebApplicationException)
311
throw (WebApplicationException) t;
313
throw new InvocationTargetException(t);
318
* Write a type to an HTTP response. The response header map is mutable but
319
* any changes must be made before writing to the output stream since the
320
* headers will be flushed prior to writing the response body.
323
* The generic {@link Type} to convert to.
325
* the annotations of the artifact to convert to
327
* the media type of the HTTP entity.
329
* a mutable map of the HTTP response headers.
330
* @param entityStream
331
* the {@link OutputStream} for the HTTP entity.
333
* the object to write.
335
* @throws java.io.IOException
336
* if an IO error arises
337
* @see javax.ws.rs.ext.MessageBodyWriter#writeTo(Object, Type,
338
* Annotation[], javax.ws.rs.core.MediaType, MultivaluedMap,
341
public void writeTo(Object object, Class<?> type, Type genericType,
342
Annotation[] annotations, MediaType mediaType,
343
MultivaluedMap<String, Object> httpHeaders,
344
OutputStream entityStream) throws IOException {
345
this.getJaxRsWriter().writeTo(object, type, genericType, annotations,
346
Converter.toJaxRsMediaType(mediaType), httpHeaders,
351
* Injects the supported dependencies into this provider and calls the
352
* method annotated with @{@link PostConstruct}.
355
* The thread local wrapped {@link CallContext}
356
* @param allProviders
358
* @param extensionBackwardMapping
359
* the extension backward mapping
360
* @throws InjectException
361
* @throws InvocationTargetException
362
* if a bean setter throws an exception
363
* @throws IllegalTypeException
364
* if the given class is not valid to be annotated with @
366
* @see ProviderWrapper#initAtAppStartUp(ThreadLocalizedContext, Providers,
367
* ExtensionBackwardMapping)
369
public void initAtAppStartUp(ThreadLocalizedContext tlContext,
370
Providers allProviders,
371
ExtensionBackwardMapping extensionBackwardMapping)
372
throws InjectException, InvocationTargetException,
373
IllegalTypeException {
374
initProvider(this.jaxRsProvider, tlContext, allProviders,
375
extensionBackwardMapping);
379
* Returns true, if this ProviderWrapper is also a
380
* {@link javax.ws.rs.ext.ContextResolver}, otherwise false.
382
* @return true, if this ProviderWrapper is also a
383
* {@link javax.ws.rs.ext.ContextResolver}, otherwise false.
386
public final boolean isContextResolver() {
387
return this.contextResolver != null;
391
* Checks, if this provider represents an {@link ExceptionMapper}.
393
* @return true, if this provider is an {@link ExceptionMapper}, or false if
397
public final boolean isExceptionMapper() {
398
return this.excMapper != null;
402
* Returns true, if this ProviderWrapper is also a
403
* {@link javax.ws.rs.ext.MessageBodyReader}, otherwise false.
405
* @return true, if this ProviderWrapper is also a
406
* {@link javax.ws.rs.ext.MessageBodyReader}, otherwise false.
409
public final boolean isReader() {
410
return this.reader != null;
414
* Returns true, if this ProviderWrapper is also a
415
* {@link javax.ws.rs.ext.MessageBodyWriter}, otherwise false.
417
* @return true, if this ProviderWrapper is also a
418
* {@link javax.ws.rs.ext.MessageBodyWriter}, otherwise false.
421
public final boolean isWriter() {
422
return this.writer != null;
426
* @see org.restlet.ext.jaxrs.internal.wrappers.provider.MessageBodyWriter#getSize(java.lang.Object,
427
* Class, Type, Annotation[], MediaType)
429
public long getSize(Object t, Class<?> type, Type genericType,
430
Annotation[] annotations, MediaType mediaType) {
431
return this.writer.getSize(t, type, genericType, annotations,
432
Converter.toJaxRsMediaType(mediaType));
436
* @see org.restlet.ext.jaxrs.internal.wrappers.provider.ProviderWrapper#getInitializedCtxResolver()
438
public ContextResolver getInitializedCtxResolver() {
443
* @see org.restlet.ext.jaxrs.internal.wrappers.provider.ProviderWrapper#getInitializedExcMapper()
445
public ExceptionMapper<? extends Throwable> getInitializedExcMapper() {
450
* @see org.restlet.ext.jaxrs.internal.wrappers.provider.ProviderWrapper#getExcMapperType()
452
public Class<?> getExcMapperType() {
453
return Util.getGenericClass(jaxRsProvider.getClass(),
454
ExceptionMapper.class);