From 8b22cd8aeaef3f80eafe7de5b2054bf4532e8f98 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Wed, 9 Oct 2013 20:14:56 -0700 Subject: [PATCH] Implement #24 --- base/pom.xml | 2 +- .../jackson/jaxrs/base/ProviderBase.java | 130 ++++++++++++------ .../jackson/jaxrs/cfg/EndpointConfigBase.java | 38 ++++- json/pom.xml | 17 +-- .../jaxrs/json/JacksonJsonProvider.java | 12 +- .../jaxrs/json/JsonEndpointConfig.java | 10 +- .../jackson/jaxrs/json/TestJsonView.java | 17 ++- pom.xml | 6 +- release-notes/VERSION | 14 +- smile/pom.xml | 17 +-- .../jaxrs/smile/JacksonSmileProvider.java | 10 +- .../jaxrs/smile/SmileEndpointConfig.java | 13 +- xml/pom.xml | 17 +-- .../jackson/jaxrs/xml/JacksonXMLProvider.java | 11 +- .../jackson/jaxrs/xml/XMLEndpointConfig.java | 10 +- 15 files changed, 190 insertions(+), 134 deletions(-) diff --git a/base/pom.xml b/base/pom.xml index 5e650df5..91411a73 100644 --- a/base/pom.xml +++ b/base/pom.xml @@ -6,7 +6,7 @@ com.fasterxml.jackson.jaxrs jackson-jaxrs-providers - 2.2.4-SNAPSHOT + 2.3.0-SNAPSHOT jackson-jaxrs-base Jackson-JAXRS-base diff --git a/base/src/main/java/com/fasterxml/jackson/jaxrs/base/ProviderBase.java b/base/src/main/java/com/fasterxml/jackson/jaxrs/base/ProviderBase.java index 0742bf00..16d5694a 100644 --- a/base/src/main/java/com/fasterxml/jackson/jaxrs/base/ProviderBase.java +++ b/base/src/main/java/com/fasterxml/jackson/jaxrs/base/ProviderBase.java @@ -116,6 +116,16 @@ public abstract class ProviderBase< */ protected int _jaxRSFeatures; + /** + * View to use for reading if none defined for the end point. + */ + protected Class _defaultReadView; + + /** + * View to use for writing if none defined for the end point. + */ + protected Class _defaultWriteView; + /* /********************************************************** /* Excluded types @@ -175,7 +185,7 @@ protected ProviderBase(MAPPER_CONFIG mconfig) { * Should NOT be used by any code explicitly; only exists * for proxy support. */ - @Deprecated + @Deprecated // just to denote it should NOT be directly called; will not be removed protected ProviderBase() { _mapperConfig = null; } @@ -252,23 +262,61 @@ public void setMapper(MAPPER m) { _mapperConfig.setMapper(m); } + /** + * Method for specifying JSON View to use for reading content + * when end point does not have explicit View annotations. + * + * @since 2.3 + */ + public THIS setDefaultReadView(Class view) { + _defaultReadView = view; + return _this(); + } + + /** + * Method for specifying JSON View to use for reading content + * when end point does not have explicit View annotations. + * + * @since 2.3 + */ + public THIS setDefaultWriteView(Class view) { + _defaultWriteView = view; + return _this(); + } + + /** + * Method for specifying JSON View to use for reading and writing content + * when end point does not have explicit View annotations. + * Functionally equivalent to: + * + * setDefaultReadView(view); + * setDefaultWriteView(view); + * + * + * @since 2.3 + */ + public THIS setDefaultView(Class view) { + _defaultReadView = _defaultWriteView = view; + return _this(); + } + // // // JaxRSFeature config public THIS configure(JaxRSFeature feature, boolean state) { - _jaxRSFeatures |= feature.getMask(); + _jaxRSFeatures |= feature.getMask(); return _this(); } public THIS enable(JaxRSFeature feature) { - _jaxRSFeatures |= feature.getMask(); + _jaxRSFeatures |= feature.getMask(); return _this(); } public THIS enable(JaxRSFeature first, JaxRSFeature... f2) { - _jaxRSFeatures |= first.getMask(); - for (JaxRSFeature f : f2) { - _jaxRSFeatures |= f.getMask(); - } + _jaxRSFeatures |= first.getMask(); + for (JaxRSFeature f : f2) { + _jaxRSFeatures |= f.getMask(); + } return _this(); } @@ -278,10 +326,10 @@ public THIS disable(JaxRSFeature feature) { } public THIS disable(JaxRSFeature first, JaxRSFeature... f2) { - _jaxRSFeatures &= ~first.getMask(); - for (JaxRSFeature f : f2) { - _jaxRSFeatures &= ~f.getMask(); - } + _jaxRSFeatures &= ~first.getMask(); + for (JaxRSFeature f : f2) { + _jaxRSFeatures &= ~f.getMask(); + } return _this(); } @@ -398,10 +446,12 @@ protected boolean hasMatchingMediaTypeForWriting(MediaType mediaType) { protected abstract MAPPER _locateMapperViaProvider(Class type, MediaType mediaType); - protected abstract EP_CONFIG _configForReading(MAPPER mapper, Annotation[] annotations); + protected abstract EP_CONFIG _configForReading(MAPPER mapper, + Annotation[] annotations, Class defaultView); + + protected abstract EP_CONFIG _configForWriting(MAPPER mapper, + Annotation[] annotations, Class defaultView); - protected abstract EP_CONFIG _configForWriting(MAPPER mapper, Annotation[] annotations); - /* /********************************************************** /* Partial MessageBodyWriter impl @@ -444,22 +494,20 @@ public boolean isWriteable(Class type, Type genericType, Annotation[] annotat } Boolean customUntouchable = _findCustomUntouchable(type); if (customUntouchable != null) { - // negation: Boolean.TRUE means untouchable -> can not write - return !customUntouchable.booleanValue(); + // negation: Boolean.TRUE means untouchable -> can not write + return !customUntouchable.booleanValue(); } - if (customUntouchable == null) { - /* Ok: looks like we must weed out some core types here; ones that - * make no sense to try to bind from JSON: - */ - if (_untouchables.contains(new ClassKey(type))) { + /* Ok: looks like we must weed out some core types here; ones that + * make no sense to try to bind from JSON: + */ + if (_untouchables.contains(new ClassKey(type))) { + return false; + } + // but some are interface/abstract classes, so + for (Class cls : _unwritableClasses) { + if (cls.isAssignableFrom(type)) { return false; } - // but some are interface/abstract classes, so - for (Class cls : _unwritableClasses) { - if (cls.isAssignableFrom(type)) { - return false; - } - } } // Also: if we really want to verify that we can deserialize, we'll check: if (_cfgCheckCanSerialize) { @@ -487,7 +535,7 @@ public void writeTo(Object value, Class type, Type genericType, Annotation[] // not yet resolved (or not cached any more)? Resolve! if (endpoint == null) { MAPPER mapper = locateMapper(type, mediaType); - endpoint = _configForWriting(mapper, annotations); + endpoint = _configForWriting(mapper, annotations, _defaultWriteView); // and cache for future reuse synchronized (_writers) { _writers.put(key.immutableKey(), endpoint); @@ -596,22 +644,20 @@ public boolean isReadable(Class type, Type genericType, Annotation[] annotati Boolean customUntouchable = _findCustomUntouchable(type); if (customUntouchable != null) { - // negation: Boolean.TRUE means untouchable -> can not write - return !customUntouchable.booleanValue(); + // negation: Boolean.TRUE means untouchable -> can not write + return !customUntouchable.booleanValue(); } - if (customUntouchable == null) { - /* Ok: looks like we must weed out some core types here; ones that - * make no sense to try to bind from JSON: - */ - if (_untouchables.contains(new ClassKey(type))) { + /* Ok: looks like we must weed out some core types here; ones that + * make no sense to try to bind from JSON: + */ + if (_untouchables.contains(new ClassKey(type))) { + return false; + } + // and there are some other abstract/interface types to exclude too: + for (Class cls : _unreadableClasses) { + if (cls.isAssignableFrom(type)) { return false; } - // and there are some other abstract/interface types to exclude too: - for (Class cls : _unreadableClasses) { - if (cls.isAssignableFrom(type)) { - return false; - } - } } // Finally: if we really want to verify that we can serialize, we'll check: if (_cfgCheckCanSerialize) { @@ -641,7 +687,7 @@ public Object readFrom(Class type, Type genericType, Annotation[] annota // not yet resolved (or not cached any more)? Resolve! if (endpoint == null) { MAPPER mapper = locateMapper(type, mediaType); - endpoint = _configForReading(mapper, annotations); + endpoint = _configForReading(mapper, annotations, _defaultReadView); // and cache for future reuse synchronized (_readers) { _readers.put(key.immutableKey(), endpoint); diff --git a/base/src/main/java/com/fasterxml/jackson/jaxrs/cfg/EndpointConfigBase.java b/base/src/main/java/com/fasterxml/jackson/jaxrs/cfg/EndpointConfigBase.java index a5ef5d3e..0dab1280 100644 --- a/base/src/main/java/com/fasterxml/jackson/jaxrs/cfg/EndpointConfigBase.java +++ b/base/src/main/java/com/fasterxml/jackson/jaxrs/cfg/EndpointConfigBase.java @@ -18,7 +18,7 @@ public abstract class EndpointConfigBase> { // // General configuration - protected Class _activeView; + protected Class _activeView; protected String _rootName; @@ -83,13 +83,25 @@ protected void addAnnotation(Class type, } } } + + /** + * @deprecated Since 2.3 + */ + @Deprecated + protected THIS initReader(ObjectMapper mapper) { + return initReader(mapper, null); + } @SuppressWarnings("unchecked") - protected THIS initReader(ObjectMapper mapper) + protected THIS initReader(ObjectMapper mapper, Class defaultView) { // first common config - if (_activeView != null) { - _reader = mapper.readerWithView(_activeView); + Class view = _activeView; + if (view == null) { + view = defaultView; + } + if (view != null) { + _reader = mapper.readerWithView(view); } else { _reader = mapper.reader(); } @@ -112,12 +124,24 @@ protected THIS initReader(ObjectMapper mapper) return (THIS) this; } + /** + * @deprecated Since 2.3 + */ + @Deprecated + protected THIS initWriter(ObjectMapper mapper) { + return initWriter(mapper, null); + } + @SuppressWarnings("unchecked") - protected THIS initWriter(ObjectMapper mapper) + protected THIS initWriter(ObjectMapper mapper, Class defaultView) { // first common config - if (_activeView != null) { - _writer = mapper.writerWithView(_activeView); + Class view = _activeView; + if (view == null) { + view = defaultView; + } + if (view != null) { + _writer = mapper.writerWithView(view); } else { _writer = mapper.writer(); } diff --git a/json/pom.xml b/json/pom.xml index b8b2ea17..8d4abc1d 100644 --- a/json/pom.xml +++ b/json/pom.xml @@ -1,19 +1,4 @@ - 4.0.0 @@ -21,7 +6,7 @@ com.fasterxml.jackson.jaxrs jackson-jaxrs-providers - 2.2.4-SNAPSHOT + 2.3.0-SNAPSHOT jackson-jaxrs-json-provider Jackson-JAXRS-JSON diff --git a/json/src/main/java/com/fasterxml/jackson/jaxrs/json/JacksonJsonProvider.java b/json/src/main/java/com/fasterxml/jackson/jaxrs/json/JacksonJsonProvider.java index b54f88fc..4724d301 100644 --- a/json/src/main/java/com/fasterxml/jackson/jaxrs/json/JacksonJsonProvider.java +++ b/json/src/main/java/com/fasterxml/jackson/jaxrs/json/JacksonJsonProvider.java @@ -8,7 +8,6 @@ import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.*; - import com.fasterxml.jackson.jaxrs.base.ProviderBase; import com.fasterxml.jackson.jaxrs.cfg.Annotations; @@ -218,12 +217,15 @@ protected ObjectMapper _locateMapperViaProvider(Class type, MediaType mediaTy } @Override - protected JsonEndpointConfig _configForReading(ObjectMapper mapper, Annotation[] annotations) { - return JsonEndpointConfig.forReading(mapper, annotations); + protected JsonEndpointConfig _configForReading(ObjectMapper mapper, + Annotation[] annotations, Class defaultView) { + return JsonEndpointConfig.forReading(mapper, annotations, defaultView); } @Override - protected JsonEndpointConfig _configForWriting(ObjectMapper mapper, Annotation[] annotations) { - return JsonEndpointConfig.forWriting(mapper, annotations, _jsonpFunctionName); + protected JsonEndpointConfig _configForWriting(ObjectMapper mapper, + Annotation[] annotations, Class defaultView) { + return JsonEndpointConfig.forWriting(mapper, annotations, defaultView, + _jsonpFunctionName); } } diff --git a/json/src/main/java/com/fasterxml/jackson/jaxrs/json/JsonEndpointConfig.java b/json/src/main/java/com/fasterxml/jackson/jaxrs/json/JsonEndpointConfig.java index 149e089d..8a000de5 100644 --- a/json/src/main/java/com/fasterxml/jackson/jaxrs/json/JsonEndpointConfig.java +++ b/json/src/main/java/com/fasterxml/jackson/jaxrs/json/JsonEndpointConfig.java @@ -28,14 +28,16 @@ public class JsonEndpointConfig protected JsonEndpointConfig() { } - public static JsonEndpointConfig forReading(ObjectMapper mapper, Annotation[] annotations) + public static JsonEndpointConfig forReading(ObjectMapper mapper, + Annotation[] annotations, Class defaultView) { return new JsonEndpointConfig() .add(annotations, false) - .initReader(mapper); + .initReader(mapper, defaultView); } - public static JsonEndpointConfig forWriting(ObjectMapper mapper, Annotation[] annotations, + public static JsonEndpointConfig forWriting(ObjectMapper mapper, + Annotation[] annotations, Class defaultView, String defaultJsonpMethod) { JsonEndpointConfig config = new JsonEndpointConfig(); @@ -44,7 +46,7 @@ public static JsonEndpointConfig forWriting(ObjectMapper mapper, Annotation[] an } return config .add(annotations, true) - .initWriter(mapper) + .initWriter(mapper, defaultView) ; } diff --git a/json/src/test/java/com/fasterxml/jackson/jaxrs/json/TestJsonView.java b/json/src/test/java/com/fasterxml/jackson/jaxrs/json/TestJsonView.java index c5c0d16c..bd12b26c 100644 --- a/json/src/test/java/com/fasterxml/jackson/jaxrs/json/TestJsonView.java +++ b/json/src/test/java/com/fasterxml/jackson/jaxrs/json/TestJsonView.java @@ -22,7 +22,7 @@ static class Bean { } @JsonView({ MyView1.class }) - public void bogus() { } + public void bogus() { } /* /********************************************************** @@ -43,4 +43,19 @@ public void testViews() throws Exception MediaType.APPLICATION_JSON_TYPE, null, out); assertEquals("{\"value1\":1}", out.toString("UTF-8")); } + + // [Issue#24] + public void testDefaultView() throws Exception + { + JacksonJsonProvider prov = new JacksonJsonProvider(); + prov.setDefaultWriteView(MyView2.class); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Bean bean = new Bean(); + Method m = getClass().getDeclaredMethod("bogus"); + JsonView view = m.getAnnotation(JsonView.class); + assertNotNull(view); + prov.writeTo(bean, bean.getClass(), bean.getClass(), new Annotation[0], + MediaType.APPLICATION_JSON_TYPE, null, out); + assertEquals("{\"value2\":2}", out.toString("UTF-8")); + } } diff --git a/pom.xml b/pom.xml index da38565b..88c1ec19 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ com.fasterxml.jackson.jaxrs jackson-jaxrs-providers Jackson JAX-RS - 2.2.4-SNAPSHOT + 2.3.0-SNAPSHOT pom Parent for Jackson JAX-RS providers @@ -30,8 +30,8 @@ UTF-8 - 2.2.3 - 2.2.3 + 2.3.0-SNAPSHOT + 2.3.0-SNAPSHOT ${version.jackson.core} ${version.jackson.core} diff --git a/release-notes/VERSION b/release-notes/VERSION index 1151dac6..80f5ef3d 100644 --- a/release-notes/VERSION +++ b/release-notes/VERSION @@ -3,7 +3,15 @@ Sub-modules: jackson-jaxrs-json-provider jackson-jaxrs-smile-provider jackson-jaxrs-xml-provider -Version: 2.2.3 (24-Aug-2013) +Version: 2.3.0 (xx-Oct-2013) + +#24: Allow defining default view to use for endpoints without View annotation + +------------------------------------------------------------------------ +=== History: === +------------------------------------------------------------------------ + +2.2.3 (24-Aug-2013) #6: Add `JaxRSFeature.ADD_NO_SNIFF_HEADER` to automatically add X-Content-Type-Options header (works with IE) @@ -16,10 +24,6 @@ Version: 2.2.3 (24-Aug-2013) #26: Missing OSGi import for base, (c.f.j.databind.cfg) (reported by jerome-leclercq@github) ------------------------------------------------------------------------- -=== History: === ------------------------------------------------------------------------- - 2.2.2 (31-May-2013) #11: ContextResolvers don't work for ObjectMapper due over-aggressive caching diff --git a/smile/pom.xml b/smile/pom.xml index 0cbd6459..d5f877e0 100644 --- a/smile/pom.xml +++ b/smile/pom.xml @@ -1,19 +1,4 @@ - 4.0.0 @@ -21,7 +6,7 @@ com.fasterxml.jackson.jaxrs jackson-jaxrs-providers - 2.2.4-SNAPSHOT + 2.3.0-SNAPSHOT jackson-jaxrs-smile-provider Jackson-JAXRS-Smile diff --git a/smile/src/main/java/com/fasterxml/jackson/jaxrs/smile/JacksonSmileProvider.java b/smile/src/main/java/com/fasterxml/jackson/jaxrs/smile/JacksonSmileProvider.java index ba063841..68e82a91 100644 --- a/smile/src/main/java/com/fasterxml/jackson/jaxrs/smile/JacksonSmileProvider.java +++ b/smile/src/main/java/com/fasterxml/jackson/jaxrs/smile/JacksonSmileProvider.java @@ -207,12 +207,14 @@ protected ObjectMapper _locateMapperViaProvider(Class type, MediaType mediaTy } @Override - protected SmileEndpointConfig _configForReading(ObjectMapper mapper, Annotation[] annotations) { - return SmileEndpointConfig.forReading(mapper, annotations); + protected SmileEndpointConfig _configForReading(ObjectMapper mapper, + Annotation[] annotations, Class defaultView) { + return SmileEndpointConfig.forReading(mapper, annotations, defaultView); } @Override - protected SmileEndpointConfig _configForWriting(ObjectMapper mapper, Annotation[] annotations) { - return SmileEndpointConfig.forWriting(mapper, annotations); + protected SmileEndpointConfig _configForWriting(ObjectMapper mapper, + Annotation[] annotations, Class defaultView) { + return SmileEndpointConfig.forWriting(mapper, annotations, defaultView); } } diff --git a/smile/src/main/java/com/fasterxml/jackson/jaxrs/smile/SmileEndpointConfig.java b/smile/src/main/java/com/fasterxml/jackson/jaxrs/smile/SmileEndpointConfig.java index 4611c001..9688faca 100644 --- a/smile/src/main/java/com/fasterxml/jackson/jaxrs/smile/SmileEndpointConfig.java +++ b/smile/src/main/java/com/fasterxml/jackson/jaxrs/smile/SmileEndpointConfig.java @@ -20,20 +20,23 @@ public class SmileEndpointConfig protected SmileEndpointConfig() { } - public static SmileEndpointConfig forReading(ObjectMapper mapper, Annotation[] annotations) + public static SmileEndpointConfig forReading(ObjectMapper mapper, + Annotation[] annotations, Class defaultView) { return new SmileEndpointConfig() .add(annotations, false) - .initReader(mapper); + .initReader(mapper, defaultView) + ; } - public static SmileEndpointConfig forWriting(ObjectMapper mapper, Annotation[] annotations) + public static SmileEndpointConfig forWriting(ObjectMapper mapper, + Annotation[] annotations, Class defaultView) { SmileEndpointConfig config = new SmileEndpointConfig(); return config .add(annotations, true) - .initWriter(mapper) - ; + .initWriter(mapper, defaultView) + ; } @SuppressWarnings("deprecation") diff --git a/xml/pom.xml b/xml/pom.xml index 277dd18c..632e0cde 100644 --- a/xml/pom.xml +++ b/xml/pom.xml @@ -1,19 +1,4 @@ - 4.0.0 @@ -21,7 +6,7 @@ com.fasterxml.jackson.jaxrs jackson-jaxrs-providers - 2.2.4-SNAPSHOT + 2.3.0-SNAPSHOT jackson-jaxrs-xml-provider Jackson-JAXRS-XML diff --git a/xml/src/main/java/com/fasterxml/jackson/jaxrs/xml/JacksonXMLProvider.java b/xml/src/main/java/com/fasterxml/jackson/jaxrs/xml/JacksonXMLProvider.java index 0d2f0d49..fdcc6375 100644 --- a/xml/src/main/java/com/fasterxml/jackson/jaxrs/xml/JacksonXMLProvider.java +++ b/xml/src/main/java/com/fasterxml/jackson/jaxrs/xml/JacksonXMLProvider.java @@ -11,7 +11,6 @@ import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.dataformat.xml.XmlMapper; - import com.fasterxml.jackson.jaxrs.base.ProviderBase; import com.fasterxml.jackson.jaxrs.cfg.Annotations; @@ -133,13 +132,15 @@ public Version version() { */ @Override - protected XMLEndpointConfig _configForReading(XmlMapper mapper, Annotation[] annotations) { - return XMLEndpointConfig.forReading(mapper, annotations); + protected XMLEndpointConfig _configForReading(XmlMapper mapper, + Annotation[] annotations, Class defaultView) { + return XMLEndpointConfig.forReading(mapper, annotations, defaultView); } @Override - protected XMLEndpointConfig _configForWriting(XmlMapper mapper, Annotation[] annotations) { - return XMLEndpointConfig.forWriting(mapper, annotations); + protected XMLEndpointConfig _configForWriting(XmlMapper mapper, + Annotation[] annotations, Class defaultView) { + return XMLEndpointConfig.forWriting(mapper, annotations, defaultView); } /** diff --git a/xml/src/main/java/com/fasterxml/jackson/jaxrs/xml/XMLEndpointConfig.java b/xml/src/main/java/com/fasterxml/jackson/jaxrs/xml/XMLEndpointConfig.java index 2c177351..f00e3802 100644 --- a/xml/src/main/java/com/fasterxml/jackson/jaxrs/xml/XMLEndpointConfig.java +++ b/xml/src/main/java/com/fasterxml/jackson/jaxrs/xml/XMLEndpointConfig.java @@ -21,19 +21,21 @@ public class XMLEndpointConfig protected XMLEndpointConfig() { } - public static XMLEndpointConfig forReading(ObjectMapper mapper, Annotation[] annotations) + public static XMLEndpointConfig forReading(ObjectMapper mapper, + Annotation[] annotations, Class defaultView) { return new XMLEndpointConfig() .add(annotations, false) - .initReader(mapper); + .initReader(mapper, defaultView); } - public static XMLEndpointConfig forWriting(ObjectMapper mapper, Annotation[] annotations) + public static XMLEndpointConfig forWriting(ObjectMapper mapper, + Annotation[] annotations, Class defaultView) { XMLEndpointConfig config = new XMLEndpointConfig(); return config .add(annotations, true) - .initWriter(mapper) + .initWriter(mapper, defaultView) ; }