From cb6dddd8303e247a4787f4136e1d37f502946ecd Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Wed, 13 May 2015 23:20:43 -0700 Subject: [PATCH] Fix #296 --- release-notes/CREDITS | 5 ++ release-notes/VERSION | 3 + .../jackson/databind/MapperFeature.java | 15 +++- .../databind/introspect/AnnotatedClass.java | 7 +- .../databind/introspect/AnnotatedField.java | 6 ++ .../introspect/POJOPropertiesCollector.java | 15 +++- .../introspect/POJOPropertyBuilder.java | 89 ------------------- .../introspect/TransientFieldTest.java | 32 +++++++ ...ation.java => FieldSerializationTest.java} | 2 +- 9 files changed, 76 insertions(+), 98 deletions(-) create mode 100644 src/test/java/com/fasterxml/jackson/databind/introspect/TransientFieldTest.java rename src/test/java/com/fasterxml/jackson/databind/ser/{TestFieldSerialization.java => FieldSerializationTest.java} (99%) diff --git a/release-notes/CREDITS b/release-notes/CREDITS index f755ec2154..55a7b01f2f 100644 --- a/release-notes/CREDITS +++ b/release-notes/CREDITS @@ -266,3 +266,8 @@ Laird Nelson (ljnelson@github) Derk Norton (derknorton@github) * Suggested #689: Add `ObjectMapper.setDefaultPrettyPrinter(PrettyPrinter)` (2.6.0) + +Michal Letynski (mletynski@github) + * Suggested #296: Serialization of transient fields with public getters (add + MapperFeature.PROPAGATE_TRANSIENT_MARKER) + (2.6.0) diff --git a/release-notes/VERSION b/release-notes/VERSION index 9b9f2bc324..684d4e781b 100644 --- a/release-notes/VERSION +++ b/release-notes/VERSION @@ -7,6 +7,9 @@ Project: jackson-databind 2.6.0 (not yet released) #95: Allow read-only properties with `@JsonIgnoreProperties(allowGetters=true)` +#296: Serialization of transient fields with public getters (add + MapperFeature.PROPAGATE_TRANSIENT_MARKER) + (suggested by Michal L) #312: Support Type Id mappings where two ids map to same Class #348: ObjectMapper.valueToTree does not work with @JsonRawValue (reported by Chris P, pimlottc@github) diff --git a/src/main/java/com/fasterxml/jackson/databind/MapperFeature.java b/src/main/java/com/fasterxml/jackson/databind/MapperFeature.java index 74f3d61465..0a9a0f61d5 100644 --- a/src/main/java/com/fasterxml/jackson/databind/MapperFeature.java +++ b/src/main/java/com/fasterxml/jackson/databind/MapperFeature.java @@ -18,7 +18,7 @@ public enum MapperFeature implements ConfigFeature { /* /****************************************************** - /* Introspection features + /* Introspection features /****************************************************** */ @@ -198,7 +198,18 @@ public enum MapperFeature implements ConfigFeature * @since 2.2 */ ALLOW_FINAL_FIELDS_AS_MUTATORS(true), - + + /** + * Feature that determines for transient modifier for fields + * is handled: if disabled, it is only taken to mean exclusion of + *

+ * Feature is disabled by default, meaning that existence of `transient` + * for a field does not necessarily lead to ignoral of getters or setters. + * + * @since 2.6 + */ + PROPAGATE_TRANSIENT_MARKER(false), + /* /****************************************************** /* Type-handling features diff --git a/src/main/java/com/fasterxml/jackson/databind/introspect/AnnotatedClass.java b/src/main/java/com/fasterxml/jackson/databind/introspect/AnnotatedClass.java index 019b7be334..d548f7c1fe 100644 --- a/src/main/java/com/fasterxml/jackson/databind/introspect/AnnotatedClass.java +++ b/src/main/java/com/fasterxml/jackson/databind/introspect/AnnotatedClass.java @@ -688,7 +688,7 @@ protected Map _findFields(Class c, Map Linked merge(Linked chain1, Linked chain2) return chain1.append(chain2); } - // // Deprecated variants that do not take 'explName': to be removed in a later version - // // (but are used at least by 2.3 and earlier versions of Scala module at least so - // // need to be careful with phasing out if before 3.0) - - /** - * @deprecated Since 2.4 call method that takes additional 'explName' argument, to indicate - * whether name of property was provided by annotation (and not derived from accessor name); - * this method assumes the name is explicit if it is non-null. - */ - @Deprecated - public void addField(AnnotatedField a, String name, boolean visible, boolean ignored) { - addField(a, _propName(name), name != null, visible, ignored); - } - - @Deprecated - public void addField(AnnotatedField a, String name, boolean explName, boolean visible, boolean ignored) { - addField(a, _propName(name), explName, visible, ignored); - } - - /** - * @deprecated Since 2.4 call method that takes additional 'explName' argument, to indicate - * whether name of property was provided by annotation (and not derived from accessor name); - * this method assumes the name is explicit if it is non-null. - */ - @Deprecated - public void addCtor(AnnotatedParameter a, String name, boolean visible, boolean ignored) { - addCtor(a, _propName(name), name != null, visible, ignored); - } - @Deprecated - public void addCtor(AnnotatedParameter a, String name, boolean explName, boolean visible, boolean ignored) { - addCtor(a, _propName(name), explName, visible, ignored); - } - - /** - * @deprecated Since 2.4 call method that takes additional 'explName' argument, to indicate - * whether name of property was provided by annotation (and not derived from accessor name); - * this method assumes the name is explicit if it is non-null. - */ - @Deprecated - public void addGetter(AnnotatedMethod a, String name, boolean visible, boolean ignored) { - addGetter(a, _propName(name), name != null, visible, ignored); - } - @Deprecated - public void addGetter(AnnotatedMethod a, String name, boolean explName, boolean visible, boolean ignored) { - addGetter(a, _propName(name), explName, visible, ignored); - } - - /** - * @deprecated Since 2.4 call method that takes additional 'explName' argument, to indicate - * whether name of property was provided by annotation (and not derived from accessor name); - * this method assumes the name is explicit if it is non-null. - */ - @Deprecated - public void addSetter(AnnotatedMethod a, String name, boolean visible, boolean ignored) { - addSetter(a, _propName(name), name != null, visible, ignored); - } - @Deprecated - public void addSetter(AnnotatedMethod a, String name, boolean explName, boolean visible, boolean ignored) { - addSetter(a, _propName(name), explName, visible, ignored); - } - - private PropertyName _propName(String simple) { - return PropertyName.construct(simple, null); - } - /* /********************************************************** /* Modifications @@ -831,30 +766,6 @@ private boolean _anyIgnorals(Linked n) return false; } - /** - * @since 2.4 Use {@link #findExplicitNames} instead - */ - @Deprecated - public String findNewName() - { - Collection l = findExplicitNames(); - if (l == null) { - return null; - } - - // 13-Apr-2014, tatu: Start with code similar to existing conflict checks - if (l.size() > 1) { - throw new IllegalStateException("Conflicting/ambiguous property name definitions (implicit name '" - +_name+"'): found more than one explicit name: " - +l); - } - PropertyName first = l.iterator().next(); - if (first.equals(_name)) { - return null; - } - return first.getSimpleName(); - } - /** * Method called to find out set of explicit names for accessors * bound together due to implicit name. diff --git a/src/test/java/com/fasterxml/jackson/databind/introspect/TransientFieldTest.java b/src/test/java/com/fasterxml/jackson/databind/introspect/TransientFieldTest.java new file mode 100644 index 0000000000..7c58ce0476 --- /dev/null +++ b/src/test/java/com/fasterxml/jackson/databind/introspect/TransientFieldTest.java @@ -0,0 +1,32 @@ +package com.fasterxml.jackson.databind.introspect; + +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.databind.*; + +// tests for [databind#296] +public class TransientFieldTest extends BaseMapTest +{ + @JsonPropertyOrder({ "x" }) + static class ClassyTransient + { + public transient int value = 3; + + public int getValue() { return value; } + + public int getX() { return 42; } + } + + public void testTransientFieldHandling() throws Exception + { + // default handling: remove transient field but do not propagate + ObjectMapper m = objectMapper(); + assertEquals(aposToQuotes("{'x':42,'value':3}"), + m.writeValueAsString(new ClassyTransient())); + + // but may change that + m = new ObjectMapper() + .enable(MapperFeature.PROPAGATE_TRANSIENT_MARKER); + assertEquals(aposToQuotes("{'x':42}"), + m.writeValueAsString(new ClassyTransient())); + } +} diff --git a/src/test/java/com/fasterxml/jackson/databind/ser/TestFieldSerialization.java b/src/test/java/com/fasterxml/jackson/databind/ser/FieldSerializationTest.java similarity index 99% rename from src/test/java/com/fasterxml/jackson/databind/ser/TestFieldSerialization.java rename to src/test/java/com/fasterxml/jackson/databind/ser/FieldSerializationTest.java index 3e3ed3d5b5..ee4068c9db 100644 --- a/src/test/java/com/fasterxml/jackson/databind/ser/TestFieldSerialization.java +++ b/src/test/java/com/fasterxml/jackson/databind/ser/FieldSerializationTest.java @@ -12,7 +12,7 @@ * Unit tests for verifying that field-backed properties can also be serialized * (since version 1.1) as well as getter-accessible properties. */ -public class TestFieldSerialization +public class FieldSerializationTest extends BaseMapTest { /*