diff --git a/pom.xml b/pom.xml
index 0eca2f42b5..95c8d31a31 100644
--- a/pom.xml
+++ b/pom.xml
@@ -69,7 +69,7 @@ javax.xml.datatype, javax.xml.namespace, javax.xml.parsers
com.fasterxml.jackson.core
jackson-annotations
- 2.5.0
+ 2.6.0-SNAPSHOT
com.fasterxml.jackson.core
diff --git a/release-notes/VERSION b/release-notes/VERSION
index ce72b88be8..9b9f2bc324 100644
--- a/release-notes/VERSION
+++ b/release-notes/VERSION
@@ -6,6 +6,7 @@ Project: jackson-databind
2.6.0 (not yet released)
+#95: Allow read-only properties with `@JsonIgnoreProperties(allowGetters=true)`
#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/AnnotationIntrospector.java b/src/main/java/com/fasterxml/jackson/databind/AnnotationIntrospector.java
index cc1f85ca00..c0973f4e07 100644
--- a/src/main/java/com/fasterxml/jackson/databind/AnnotationIntrospector.java
+++ b/src/main/java/com/fasterxml/jackson/databind/AnnotationIntrospector.java
@@ -223,11 +223,23 @@ public PropertyName findRootName(AnnotatedClass ac) {
* List of property names is applied
* after other detection mechanisms, to filter out these specific
* properties from being serialized and deserialized.
+ *
+ * @param forSerialization True if requesting properties to ignore for serialization;
+ * false if for deserialization
+ */
+ public String[] findPropertiesToIgnore(Annotated ac, boolean forSerialization) {
+ // !!! Change direction in 2.7 or later
+ return findPropertiesToIgnore(ac);
+ }
+
+ /**
+ * @deprecated Since 2.6, use variant that takes second argument.
*/
+ @Deprecated
public String[] findPropertiesToIgnore(Annotated ac) {
return null;
}
-
+
/**
* Method for checking whether an annotation indicates that all unknown properties
*/
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/BasicDeserializerFactory.java b/src/main/java/com/fasterxml/jackson/databind/deser/BasicDeserializerFactory.java
index d70f9fca4e..1ade8b9131 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/BasicDeserializerFactory.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/BasicDeserializerFactory.java
@@ -1164,7 +1164,8 @@ public JsonDeserializer> createMapDeserializer(DeserializationContext ctxt,
if (deser == null) {
ValueInstantiator inst = findValueInstantiator(ctxt, beanDesc);
MapDeserializer md = new MapDeserializer(type, inst, keyDes, contentDeser, contentTypeDeser);
- md.setIgnorableProperties(config.getAnnotationIntrospector().findPropertiesToIgnore(beanDesc.getClassInfo()));
+ AnnotationIntrospector ai = config.getAnnotationIntrospector();
+ md.setIgnorableProperties(ai.findPropertiesToIgnore(beanDesc.getClassInfo(), false));
deser = md;
}
}
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java
index eb38dde46d..8e8c48fa5a 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java
@@ -618,7 +618,7 @@ public JsonDeserializer> createContextual(DeserializationContext ctxt,
}
// And possibly add more properties to ignore
if (accessor != null) {
- String[] ignorals = intr.findPropertiesToIgnore(accessor);
+ String[] ignorals = intr.findPropertiesToIgnore(accessor, false);
if (ignorals != null && ignorals.length != 0) {
HashSet newIgnored = ArrayBuilders.setAndArray(contextual._ignorableProps, ignorals);
contextual = contextual.withIgnorableProperties(newIgnored);
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java
index 8b0b6f0c55..89914835a1 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java
@@ -451,7 +451,7 @@ protected void addBeanProps(DeserializationContext ctxt,
}
}
// Or explicit/implicit definitions?
- Set ignored = ArrayBuilders.arrayToSet(intr.findPropertiesToIgnore(beanDesc.getClassInfo()));
+ Set ignored = ArrayBuilders.arrayToSet(intr.findPropertiesToIgnore(beanDesc.getClassInfo(), false));
for (String propName : ignored) {
builder.addIgnorable(propName);
}
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/std/MapDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/std/MapDeserializer.java
index aaec054fb4..69c0d3febd 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/std/MapDeserializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/std/MapDeserializer.java
@@ -254,7 +254,7 @@ public JsonDeserializer> createContextual(DeserializationContext ctxt,
if (intr != null && property != null) {
AnnotatedMember member = property.getMember();
if (member != null) {
- String[] moreToIgnore = intr.findPropertiesToIgnore(member);
+ String[] moreToIgnore = intr.findPropertiesToIgnore(member, false);
if (moreToIgnore != null) {
ignored = (ignored == null) ? new HashSet() : new HashSet(ignored);
for (String str : moreToIgnore) {
diff --git a/src/main/java/com/fasterxml/jackson/databind/introspect/AnnotationIntrospectorPair.java b/src/main/java/com/fasterxml/jackson/databind/introspect/AnnotationIntrospectorPair.java
index 13e8603cbe..c1c9d2c7ae 100644
--- a/src/main/java/com/fasterxml/jackson/databind/introspect/AnnotationIntrospectorPair.java
+++ b/src/main/java/com/fasterxml/jackson/databind/introspect/AnnotationIntrospectorPair.java
@@ -113,8 +113,8 @@ public PropertyName findRootName(AnnotatedClass ac)
}
@Override
- public String[] findPropertiesToIgnore(Annotated ac)
- {
+ @Deprecated // since 2.6
+ public String[] findPropertiesToIgnore(Annotated ac) {
String[] result = _primary.findPropertiesToIgnore(ac);
if (result == null) {
result = _secondary.findPropertiesToIgnore(ac);
@@ -122,6 +122,15 @@ public String[] findPropertiesToIgnore(Annotated ac)
return result;
}
+ @Override
+ public String[] findPropertiesToIgnore(Annotated ac, boolean forSerialization) {
+ String[] result = _primary.findPropertiesToIgnore(ac, forSerialization);
+ if (result == null) {
+ result = _secondary.findPropertiesToIgnore(ac, forSerialization);
+ }
+ return result;
+ }
+
@Override
public Boolean findIgnoreUnknownProperties(AnnotatedClass ac)
{
diff --git a/src/main/java/com/fasterxml/jackson/databind/introspect/JacksonAnnotationIntrospector.java b/src/main/java/com/fasterxml/jackson/databind/introspect/JacksonAnnotationIntrospector.java
index fe37b17328..73f3ce2981 100644
--- a/src/main/java/com/fasterxml/jackson/databind/introspect/JacksonAnnotationIntrospector.java
+++ b/src/main/java/com/fasterxml/jackson/databind/introspect/JacksonAnnotationIntrospector.java
@@ -81,11 +81,31 @@ public PropertyName findRootName(AnnotatedClass ac)
}
@Override
+ @Deprecated // since 2.6, remove from 2.7 or later
public String[] findPropertiesToIgnore(Annotated ac) {
JsonIgnoreProperties ignore = _findAnnotation(ac, JsonIgnoreProperties.class);
return (ignore == null) ? null : ignore.value();
}
+ @Override // since 2.6
+ public String[] findPropertiesToIgnore(Annotated ac, boolean forSerialization) {
+ JsonIgnoreProperties ignore = _findAnnotation(ac, JsonIgnoreProperties.class);
+ if (ignore == null) {
+ return null;
+ }
+ // 13-May-2015, tatu: As per [databind#95], allow read-only/write-only props
+ if (forSerialization) {
+ if (ignore.allowGetters()) {
+ return null;
+ }
+ } else {
+ if (ignore.allowSetters()) {
+ return null;
+ }
+ }
+ return ignore.value();
+ }
+
@Override
public Boolean findIgnoreUnknownProperties(AnnotatedClass ac) {
JsonIgnoreProperties ignore = _findAnnotation(ac, JsonIgnoreProperties.class);
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/BasicSerializerFactory.java b/src/main/java/com/fasterxml/jackson/databind/ser/BasicSerializerFactory.java
index 7938d6aab3..69a515d0c6 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/BasicSerializerFactory.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/BasicSerializerFactory.java
@@ -761,7 +761,8 @@ protected JsonSerializer> buildMapSerializer(SerializationConfig config,
} else {
*/
Object filterId = findFilterId(config, beanDesc);
- MapSerializer mapSer = MapSerializer.construct(config.getAnnotationIntrospector().findPropertiesToIgnore(beanDesc.getClassInfo()),
+ AnnotationIntrospector ai = config.getAnnotationIntrospector();
+ MapSerializer mapSer = MapSerializer.construct(ai.findPropertiesToIgnore(beanDesc.getClassInfo(), true),
type, staticTyping, elementTypeSerializer,
keySerializer, elementValueSerializer, filterId);
Object suppressableValue = findSuppressableContentValue(config,
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/BeanSerializerFactory.java b/src/main/java/com/fasterxml/jackson/databind/ser/BeanSerializerFactory.java
index 2bbf2d613c..f32a47c2f8 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/BeanSerializerFactory.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/BeanSerializerFactory.java
@@ -587,7 +587,7 @@ protected List filterBeanProperties(SerializationConfig conf
{
AnnotationIntrospector intr = config.getAnnotationIntrospector();
AnnotatedClass ac = beanDesc.getClassInfo();
- String[] ignored = intr.findPropertiesToIgnore(ac);
+ String[] ignored = intr.findPropertiesToIgnore(ac, true);
if (ignored != null && ignored.length > 0) {
HashSet ignoredSet = ArrayBuilders.arrayToSet(ignored);
Iterator it = props.iterator();
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/BeanSerializerBase.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/BeanSerializerBase.java
index 53e1de8553..1d40930bd8 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/BeanSerializerBase.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/BeanSerializerBase.java
@@ -420,7 +420,7 @@ public JsonSerializer> createContextual(SerializerProvider provider,
// Then we may have an override for Object Id
if (accessor != null) {
- ignorals = intr.findPropertiesToIgnore(accessor);
+ ignorals = intr.findPropertiesToIgnore(accessor, true);
ObjectIdInfo objectIdInfo = intr.findObjectIdInfo(accessor);
if (objectIdInfo == null) {
// no ObjectId override, but maybe ObjectIdRef?
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/MapSerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/MapSerializer.java
index 722bfde1a8..9dd181000a 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/MapSerializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/MapSerializer.java
@@ -356,7 +356,7 @@ public JsonSerializer> createContextual(SerializerProvider provider,
HashSet ignored = _ignoredEntries;
boolean sortKeys = false;
if (intr != null && propertyAcc != null) {
- String[] moreToIgnore = intr.findPropertiesToIgnore(propertyAcc);
+ String[] moreToIgnore = intr.findPropertiesToIgnore(propertyAcc, true);
if (moreToIgnore != null) {
ignored = (ignored == null) ? new HashSet() : new HashSet(ignored);
for (String str : moreToIgnore) {
diff --git a/src/test/java/com/fasterxml/jackson/databind/filter/TestIgnorePropsForSerialization.java b/src/test/java/com/fasterxml/jackson/databind/filter/IgnorePropsTest.java
similarity index 98%
rename from src/test/java/com/fasterxml/jackson/databind/filter/TestIgnorePropsForSerialization.java
rename to src/test/java/com/fasterxml/jackson/databind/filter/IgnorePropsTest.java
index 9c1c757271..035976ffd7 100644
--- a/src/test/java/com/fasterxml/jackson/databind/filter/TestIgnorePropsForSerialization.java
+++ b/src/test/java/com/fasterxml/jackson/databind/filter/IgnorePropsTest.java
@@ -6,7 +6,7 @@
import com.fasterxml.jackson.databind.*;
-public class TestIgnorePropsForSerialization
+public class IgnorePropsTest
extends BaseMapTest
{
@JsonIgnoreProperties({"b", "c"})
@@ -63,7 +63,7 @@ static class MapWrapper {
value.put("b", 2);
}
}
-
+
/*
/****************************************************************
/* Unit tests
diff --git a/src/test/java/com/fasterxml/jackson/databind/filter/ReadOnlyProperties95Test.java b/src/test/java/com/fasterxml/jackson/databind/filter/ReadOnlyProperties95Test.java
new file mode 100644
index 0000000000..a00b5c69f6
--- /dev/null
+++ b/src/test/java/com/fasterxml/jackson/databind/filter/ReadOnlyProperties95Test.java
@@ -0,0 +1,29 @@
+package com.fasterxml.jackson.databind.filter;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.databind.*;
+
+/**
+ * Failing test related to [databind#95]
+ */
+public class ReadOnlyProperties95Test extends BaseMapTest
+{
+ @JsonIgnoreProperties(value={ "computed" }, allowGetters=true)
+ static class ReadOnlyBean
+ {
+ public int value = 3;
+
+ public int getComputed() { return 32; }
+ }
+
+ public void testReadOnlyProp() throws Exception
+ {
+ ObjectMapper m = new ObjectMapper();
+ String json = m.writeValueAsString(new ReadOnlyBean());
+ if (json.indexOf("computed") < 0) {
+ fail("Should have property 'computed', didn't: "+json);
+ }
+ ReadOnlyBean bean = m.readValue(json, ReadOnlyBean.class);
+ assertNotNull(bean);
+ }
+}