Skip to content

Commit

Permalink
Implement #33
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Oct 11, 2013
1 parent bafb6fb commit 85cc17a
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -125,20 +125,6 @@ public abstract class ProviderBase<
* View to use for writing if none defined for the end point.
*/
protected Class<?> _defaultWriteView;

/**
* Object used for handling possible {@link ObjectReader} injection.
*
* @since 2.3
*/
protected ObjectReaderInjector _readerInjector;

/**
* Object used for handling possible {@link ObjectWriter} injection.
*
* @since 2.3
*/
protected ObjectWriterInjector _writerInjector;

/*
/**********************************************************
Expand Down Expand Up @@ -190,8 +176,6 @@ public abstract class ProviderBase<

protected ProviderBase(MAPPER_CONFIG mconfig) {
_mapperConfig = mconfig;
_readerInjector = new ObjectReaderInjector();
_writerInjector = new ObjectWriterInjector();
}

/**
Expand Down Expand Up @@ -465,31 +449,25 @@ protected boolean hasMatchingMediaTypeForWriting(MediaType mediaType) {
protected EP_CONFIG _configForReading(MAPPER mapper,
Annotation[] annotations, Class<?> defaultView)
{
ObjectReader r = _readerInjector.getAndClear();
if (r == null) {
if (defaultView != null) {
r = mapper.readerWithView(defaultView);
} else {
r = mapper.reader();
}
// ObjectReaderModi r = _readerInjector.getAndClear();
ObjectReader r;
if (defaultView != null) {
r = mapper.readerWithView(defaultView);
} else {
r = r.withView(defaultView);
r = mapper.reader();
}
return _configForReading(r, annotations);
}

protected EP_CONFIG _configForWriting(MAPPER mapper,
Annotation[] annotations, Class<?> defaultView)
{
ObjectWriter w = _writerInjector.getAndClear();
if (w == null) {
if (defaultView != null) {
w = mapper.writerWithView(defaultView);
} else {
w = mapper.writer();
}
// ObjectWriter w = _writerInjector.getAndClear();
ObjectWriter w;
if (defaultView != null) {
w = mapper.writerWithView(defaultView);
} else {
w = w.withView(defaultView);
w = mapper.writer();
}
return _configForWriting(w, annotations);
}
Expand Down Expand Up @@ -634,6 +612,13 @@ public void writeTo(Object value, Class<?> type, Type genericType, Annotation[]
writer = writer.withType(rootType);
}
value = endpoint.modifyBeforeWrite(value);

// [Issue#32]: allow modification by filter-injectible thing
ObjectWriterModifier mod = ObjectWriterInjector.getAndClear();
if (mod != null) {
writer = mod.modify(endpoint, value, writer, g);
}

writer.writeValue(g, value);
} finally {
g.close();
Expand Down Expand Up @@ -758,6 +743,7 @@ public Object readFrom(Class<Object> type, Type genericType, Annotation[] annota
}
ObjectReader reader = endpoint.getReader();
JsonParser jp = _createParser(reader, entityStream);

// If null is returned, considered to be empty stream
if (jp == null || jp.nextToken() == null) {
return null;
Expand All @@ -766,7 +752,14 @@ public Object readFrom(Class<Object> type, Type genericType, Annotation[] annota
if (((Class<?>) type) == JsonParser.class) {
return jp;
}
return reader.withType(genericType).readValue(jp);
final JavaType resolvedType = reader.getTypeFactory().constructType(genericType);
reader = reader.withType(resolvedType);
// [Issue#32]: allow modification by filter-injectible thing
ObjectReaderModifier mod = ObjectReaderInjector.getAndClear();
if (mod != null) {
reader = mod.modify(endpoint, resolvedType, reader, jp);
}
return reader.readValue(jp);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,40 +5,41 @@
import com.fasterxml.jackson.databind.*;

/**
* Based on ideas from [Issue#32], this class allows "overriding" of {@link ObjectReader}
* that JAX-RS Resource will use; usually this is done from a Servlet or JAX-RS filter
* Based on ideas from [Issue#32], this class allows registering a
* modifier ({@link ObjectReaderModifier}) that can be used to
* reconfigure {@link ObjectReader}
* that JAX-RS Resource will use for reading input into Java Objects.
* Usually this class is accessed from a Servlet or JAX-RS filter
* before execution reaches resource.
*
* @author apemberton@github, Tatu Saloranta
*
* @since 2.3
*/
public class ObjectReaderInjector
{
protected static final ThreadLocal<ObjectReader> _threadLocal = new ThreadLocal<ObjectReader>();
protected static final ThreadLocal<ObjectReaderModifier> _threadLocal = new ThreadLocal<ObjectReaderModifier>();

/**
* Simple marker used to optimize out {@link ThreadLocal} access in cases
* where this feature is not being used
*/
protected final AtomicBoolean _hasBeenSet = new AtomicBoolean(false);
public ObjectReaderInjector() { }
protected static final AtomicBoolean _hasBeenSet = new AtomicBoolean(false);

private ObjectReaderInjector() { }

public void set(ObjectReader r) {
public static void set(ObjectReaderModifier mod) {
_hasBeenSet.set(true);
_threadLocal.set(r);
_threadLocal.set(mod);
}

public ObjectReader get() {
public static ObjectReaderModifier get() {
return _hasBeenSet.get() ? _threadLocal.get() : null;
}

public ObjectReader getAndClear() {
ObjectReader r = get();
if (r != null) {
public static ObjectReaderModifier getAndClear() {
ObjectReaderModifier mod = get();
if (mod != null) {
_threadLocal.remove();
}
return r;
return mod;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.fasterxml.jackson.jaxrs.cfg;

import java.io.IOException;

import com.fasterxml.jackson.core.*;

import com.fasterxml.jackson.databind.*;

/**
* @since 2.3
*/
public abstract class ObjectReaderModifier
{
/**
* Method called to let modifier make any changes it wants to to objects
* used for reading request objects for specified endpoint.
*
* @param endpoint End point for which reader is used
* @param resultType Type that input is to be bound to
* @param r ObjectReader as constructed for endpoint, type to handle
* @param p Parser to use for reading content
*/
public abstract ObjectReader modify(EndpointConfigBase<?> endpoint,
JavaType resultType, ObjectReader r, JsonParser p)
throws IOException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,34 @@
* that JAX-RS Resource will use; usually this is done from a Servlet or JAX-RS filter
* before execution reaches resource.
*
* @author apemberton@github, Tatu Saloranta
*
* @since 2.3
*/
public class ObjectWriterInjector
{
protected static final ThreadLocal<ObjectWriter> _threadLocal = new ThreadLocal<ObjectWriter>();
protected static final ThreadLocal<ObjectWriterModifier> _threadLocal = new ThreadLocal<ObjectWriterModifier>();

/**
* Simple marker used to optimize out {@link ThreadLocal} access in cases
* where this feature is not being used
*/
protected final AtomicBoolean _hasBeenSet = new AtomicBoolean(false);
protected static final AtomicBoolean _hasBeenSet = new AtomicBoolean(false);

public ObjectWriterInjector() { }
private ObjectWriterInjector() { }

public void set(ObjectWriter r) {
public static void set(ObjectWriterModifier mod) {
_hasBeenSet.set(true);
_threadLocal.set(r);
_threadLocal.set(mod);
}

public ObjectWriter get() {
public static ObjectWriterModifier get() {
return _hasBeenSet.get() ? _threadLocal.get() : null;
}

public ObjectWriter getAndClear() {
ObjectWriter w = get();
if (w != null) {
public static ObjectWriterModifier getAndClear() {
ObjectWriterModifier mod = get();
if (mod != null) {
_threadLocal.remove();
}
return w;
return mod;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.fasterxml.jackson.jaxrs.cfg;

import java.io.IOException;

import com.fasterxml.jackson.core.*;

import com.fasterxml.jackson.databind.*;

/**
* @since 2.3
*/
public abstract class ObjectWriterModifier
{
/**
* Method called to let modifier make any changes it wants to to objects
* used for writing response for specified endpoint.
*/
public abstract ObjectWriter modify(EndpointConfigBase<?> endpoint,
Object valueToWrite, ObjectWriter r, JsonGenerator g)
throws IOException;
}
1 change: 1 addition & 0 deletions release-notes/VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Sub-modules:
Version: 2.3.0 (xx-Oct-2013)

#24: Allow defining default view to use for endpoints without View annotation
#33: Provide a way to customize `ObjectReader` / `ObjectWriter` used by end points

------------------------------------------------------------------------
=== History: ===
Expand Down

0 comments on commit 85cc17a

Please sign in to comment.