aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml13
-rw-r--r--pom.xml52
-rw-r--r--release-notes/VERSION-2.x8
-rw-r--r--src/main/java/com/fasterxml/jackson/annotation/JsonIncludeProperties.java164
-rw-r--r--src/main/java/com/fasterxml/jackson/annotation/JsonSubTypes.java17
-rw-r--r--src/test/java/com/fasterxml/jackson/annotation/JsonIncludePropertiesTest.java68
6 files changed, 300 insertions, 22 deletions
diff --git a/.travis.yml b/.travis.yml
index cc6344e..9b7656c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,16 +9,9 @@ jdk:
# Below this line is configuration for deploying to the Sonatype OSS repo
# http://blog.xeiam.com/2013/05/configure-travis-ci-to-deploy-snapshots.html
before_install: "git clone -b travis `git config --get remote.origin.url` target/travis"
-after_success: "mvn deploy --settings target/travis/settings.xml"
-
-# whitelist
-branches:
- only:
- - master
- - 2.11
+script: "[ ${TRAVIS_PULL_REQUEST} = 'false' ] && mvn -B source:jar deploy --settings target/travis/settings.xml || mvn clean verify --settings target/travis/settings.xml"
env:
global:
- - secure: "a2T/bJVacCzBKfGW7ycW2aVLxupCUenLpRX6Neh/WLFf5wbIjTtKZpB94sxbVGTKNT+HQmwFynWhz7Dh3251fSZ4lfGcHBnUr5lpq1vo10aMBTJaMpk5vrTLn0AxGESxqOjQQkDhasdLpoXlv1EtVn7HqHLepAr0AIUl41XggfA="
- - secure: "Gdl5m/gEm4FrCxOVnvCM13dipEhjaL4IXbEL2dsNhxwZ+lqD+8OAwObbPrTLuUZ+KTWctfsNauGTin1bDhi8m/Gh6jm71U+hGuA7/8cqgprZDhdARxG7fSOdr9Syp24JL7h5u5X43+a7m2KiC/iUcErIiVKPBcAisOj286GcFhc="
-
+ - secure: "BmDMUlS07UDn3zGHra90YOT+U2QpTRmb02GIJmvfykmOie2q8hP6XwxKehsYBtnMHp6+5xm+bF+dA4BhjJ9l+bzXIH2FVkFTfJEo1GJJiVGq8B1DptqGGl404Eb4vD4c+cbb4GP2zKgNMc05oNsKTThE3wHdxZDbh2hjATz/b0M="
+ - secure: "XcMnwfSjRNVHs3HEutOIIGyYiHUZQZx2+DynlzkiBZ3IKpiVT0LfeIElJfWKJkwtJxGIIJghNZArylKvJXeZguB4s0XieOHxzarE1BgfcYU+vK/0pla0x66mgGEPjD/99arrGTTvZUH//jmRPc95fZJqytdIOJ7Erb4GpGLo/hM="
diff --git a/pom.xml b/pom.xml
index 63ee586..be2c8c7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,17 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <!-- This module was also published with a richer model, Gradle metadata, -->
+ <!-- which should be used instead. Do not delete the following line which -->
+ <!-- is to indicate to Gradle or any Gradle module metadata file consumer -->
+ <!-- that they should prefer consuming it instead. -->
+ <!-- do_not_remove: published-with-gradle-metadata -->
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.fasterxml.jackson</groupId>
<!-- this is one of few Jackson modules that depends on parent and NOT jackson-bom -->
<artifactId>jackson-parent</artifactId>
- <version>2.11</version>
+ <version>2.12-SNAPSHOT</version>
</parent>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<name>Jackson-annotations</name>
- <version>2.11.2-SNAPSHOT</version>
+ <version>2.12.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<description>Core annotations used for value types, used by Jackson data binding package.
</description>
@@ -43,12 +48,6 @@
<maven.compiler.target>1.6</maven.compiler.target>
<osgi.export>com.fasterxml.jackson.annotation.*;version=${project.version}</osgi.export>
-
- <!-- 31-Jul-2020, tatu: will go in `oss-parent` for 2.12, but for 2.11 need to bump
- bundle-plugin version to make work in JDK 15+
- (see https://github.com/FasterXML/jackson-databind/issues/2806)
- -->
- <version.plugin.bundle>5.1.1</version.plugin.bundle>
</properties>
<dependencies>
@@ -59,6 +58,18 @@
</dependency>
</dependencies>
+ <!-- Alas, need to include snapshot reference since otherwise can not find
+ snapshot of parent... -->
+ <repositories>
+ <repository>
+ <id>sonatype-nexus-snapshots</id>
+ <name>Sonatype Nexus Snapshots</name>
+ <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+ <releases><enabled>false</enabled></releases>
+ <snapshots><enabled>true</enabled></snapshots>
+ </repository>
+ </repositories>
+
<build>
<plugins>
<plugin>
@@ -98,6 +109,31 @@
<stagingProfileId>b34f19b9cc6224</stagingProfileId>
</configuration>
</plugin>
+
+ <!-- 11-Jun-2020, tatu: As per [annotations#173], add gradle module metadata
+ -->
+ <plugin>
+ <groupId>de.jjohannes</groupId>
+ <artifactId>gradle-module-metadata-maven-plugin</artifactId>
+ <version>0.2.0</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>gmm</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <platformDependencies>
+ <dependency>
+ <groupId>com.fasterxml.jackson</groupId>
+ <artifactId>jackson-bom</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </platformDependencies>
+ </configuration>
+ </plugin>
+
</plugins>
</build>
diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x
index 43b508f..74e64de 100644
--- a/release-notes/VERSION-2.x
+++ b/release-notes/VERSION-2.x
@@ -11,6 +11,14 @@ NOTE: Annotations module will never contain changes in patch versions,
=== Releases ===
------------------------------------------------------------------------
+2.12.0 (not yet released)
+
+#171: `JsonSubType.Type` should accept array of names
+ (contributed by Swayam R)
+#173: Jackson version alignment with Gradle 6
+#174: Add `@JsonIncludeProperties`
+ (contributed by Baptiste P)
+
2.11.0 (26-Apr-2020)
- `JsonPattern.Value.pattern` retained as "", never (accidentally) exposed
diff --git a/src/main/java/com/fasterxml/jackson/annotation/JsonIncludeProperties.java b/src/main/java/com/fasterxml/jackson/annotation/JsonIncludeProperties.java
new file mode 100644
index 0000000..a1f5fcd
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/annotation/JsonIncludeProperties.java
@@ -0,0 +1,164 @@
+package com.fasterxml.jackson.annotation;
+
+import java.lang.annotation.*;
+import java.util.*;
+
+/**
+ * Annotation that can be used to either only include serialization of
+ * properties (during serialization), or only include processing of
+ * JSON properties read (during deserialization).
+ * <p>
+ * Example:
+ * <pre>
+ * // to only include specified fields from being serialized or deserialized
+ * // (i.e. only include in JSON output; or being set even if they were included)
+ * &#064;JsonIncludeProperties({ "internalId", "secretKey" })
+ * </pre>
+ * <p>
+ * Annotation can be applied both to classes and
+ * to properties. If used for both, actual set will be union of all
+ * includes: that is, you can only add properties to include, not remove
+ * or override. So you can not remove properties to include using
+ * per-property annotation.
+ *
+ * @since 2.12
+ */
+@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE,
+ ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+@JacksonAnnotation
+public @interface JsonIncludeProperties
+{
+ /**
+ * Names of properties to include.
+ */
+ public String[] value() default {};
+
+ /*
+ /**********************************************************
+ /* Value class used to enclose information, allow for
+ /* merging of layered configuration settings.
+ /**********************************************************
+ */
+
+ /**
+ * Helper class used to contain information from a single {@link JsonIncludeProperties}
+ * annotation, as well as to provide possible overrides from non-annotation sources.
+ *
+ * @since 2.12
+ */
+ public static class Value implements JacksonAnnotationValue<JsonIncludeProperties>, java.io.Serializable
+ {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Default instance has no explicitly included fields
+ */
+ protected final static JsonIncludeProperties.Value ALL = new JsonIncludeProperties.Value(null);
+
+ /**
+ * Name of the properties to include.
+ * Null means that all properties are included, empty means none.
+ */
+ protected final Set<String> _included;
+
+ protected Value(Set<String> included)
+ {
+ _included = included;
+ }
+
+ public static JsonIncludeProperties.Value from(JsonIncludeProperties src)
+ {
+ if (src == null) {
+ return ALL;
+ }
+ return new Value(_asSet(src.value()));
+ }
+
+ public static JsonIncludeProperties.Value all()
+ {
+ return ALL;
+ }
+
+ @Override
+ public Class<JsonIncludeProperties> valueFor()
+ {
+ return JsonIncludeProperties.class;
+ }
+
+ /**
+ * @return Names included, if any, possibly empty; {@code null} for "not defined"
+ */
+ public Set<String> getIncluded()
+ {
+ return _included;
+ }
+
+ /**
+ * Mutant factory method to override the current value with an another,
+ * merging the included fields so that only entries that exist in both original
+ * and override set are included, taking into account that "undefined" {@link Value}s
+ * do not count ("undefined" meaning that {@code getIncluded()} returns {@code null}).
+ * So: overriding with "undefined" returns original {@code Value} as-is; overriding an
+ * "undefined" {@code Value} returns override {@code Value} as-is.
+ */
+ public JsonIncludeProperties.Value withOverrides(JsonIncludeProperties.Value overrides)
+ {
+ final Set<String> otherIncluded;
+
+ if (overrides == null || (otherIncluded = overrides.getIncluded()) == null) {
+ return this;
+ }
+
+ if (_included == null) {
+ return overrides;
+ }
+
+ HashSet<String> toInclude = new HashSet<String>();
+ for (String incl : otherIncluded) {
+ if (_included.contains(incl)) {
+ toInclude.add(incl);
+ }
+ }
+
+ return new JsonIncludeProperties.Value(toInclude);
+ }
+
+ @Override
+ public String toString() {
+ return String.format("JsonIncludeProperties.Value(included=%s)",
+ _included);
+ }
+
+ @Override
+ public int hashCode() {
+ return (_included == null) ? 0 : _included.size();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == this) return true;
+ if (o == null) return false;
+ return (o.getClass() == getClass()) && _equals(_included, ((Value) o)._included);
+ }
+
+ private static boolean _equals(Set<String> a, Set<String> b)
+ {
+ return a == null ? (b == null)
+ // keep this last just because it can be expensive
+ : a.equals(b);
+ }
+
+ private static Set<String> _asSet(String[] v)
+ {
+ if (v == null || v.length == 0) {
+ return Collections.emptySet();
+ }
+ Set<String> s = new HashSet<String>(v.length);
+ for (String str : v) {
+ s.add(str);
+ }
+ return s;
+ }
+ }
+}
diff --git a/src/main/java/com/fasterxml/jackson/annotation/JsonSubTypes.java b/src/main/java/com/fasterxml/jackson/annotation/JsonSubTypes.java
index 8263038..9771bba 100644
--- a/src/main/java/com/fasterxml/jackson/annotation/JsonSubTypes.java
+++ b/src/main/java/com/fasterxml/jackson/annotation/JsonSubTypes.java
@@ -28,9 +28,9 @@ public @interface JsonSubTypes {
public Type[] value();
/**
- * Definition of a subtype, along with optional name. If name is missing, class
- * of the type will be checked for {@link JsonTypeName} annotation; and if that
- * is also missing or empty, a default
+ * Definition of a subtype, along with optional name(s). If no name is defined
+ * (empty Strings are ignored), class of the type will be checked for {@link JsonTypeName}
+ * annotation; and if that is also missing or empty, a default
* name will be constructed by type id mechanism.
* Default name is usually based on class name.
*/
@@ -41,8 +41,17 @@ public @interface JsonSubTypes {
public Class<?> value();
/**
- * Logical type name used as the type identifier for the class
+ * Logical type name used as the type identifier for the class, if defined; empty
+ * String means "not defined". Used unless {@link #names} is defined as non-empty.
*/
public String name() default "";
+
+ /**
+ * (optional) Logical type names used as the type identifier for the class: used if
+ * more than one type name should be associated with the same type.
+ *
+ * @since 2.12
+ */
+ public String[] names() default {};
}
}
diff --git a/src/test/java/com/fasterxml/jackson/annotation/JsonIncludePropertiesTest.java b/src/test/java/com/fasterxml/jackson/annotation/JsonIncludePropertiesTest.java
new file mode 100644
index 0000000..55ae738
--- /dev/null
+++ b/src/test/java/com/fasterxml/jackson/annotation/JsonIncludePropertiesTest.java
@@ -0,0 +1,68 @@
+package com.fasterxml.jackson.annotation;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+/**
+ * Tests to verify that it is possibly to merge {@link JsonIncludeProperties.Value}
+ * instances for overrides
+ */
+public class JsonIncludePropertiesTest extends TestBase
+{
+ @JsonIncludeProperties(value = {"foo", "bar"})
+ private final static class Bogus
+ {
+ }
+
+ private final JsonIncludeProperties.Value ALL = JsonIncludeProperties.Value.all();
+
+ public void testAll()
+ {
+ assertSame(ALL, JsonIncludeProperties.Value.from(null));
+ assertNull(ALL.getIncluded());
+ assertEquals(ALL, ALL);
+ assertEquals("JsonIncludeProperties.Value(included=null)", ALL.toString());
+ assertEquals(0, ALL.hashCode());
+ }
+
+ public void testFromAnnotation()
+ {
+ JsonIncludeProperties.Value v = JsonIncludeProperties.Value.from(Bogus.class.getAnnotation(JsonIncludeProperties.class));
+ assertNotNull(v);
+ Set<String> included = v.getIncluded();
+ assertEquals(2, v.getIncluded().size());
+ assertEquals(_set("foo", "bar"), included);
+ assertEquals("JsonIncludeProperties.Value(included=[bar, foo])", v.toString());
+ assertEquals(v, JsonIncludeProperties.Value.from(Bogus.class.getAnnotation(JsonIncludeProperties.class)));
+ }
+
+ public void testWithOverridesAll() {
+ JsonIncludeProperties.Value v = JsonIncludeProperties.Value.from(Bogus.class.getAnnotation(JsonIncludeProperties.class));
+ v = v.withOverrides(ALL);
+ Set<String> included = v.getIncluded();
+ assertEquals(2, included.size());
+ assertEquals(_set("foo", "bar"), included);
+ }
+
+ public void testWithOverridesEmpty() {
+ JsonIncludeProperties.Value v = JsonIncludeProperties.Value.from(Bogus.class.getAnnotation(JsonIncludeProperties.class));
+ v = v.withOverrides(new JsonIncludeProperties.Value(Collections.<String>emptySet()));
+ Set<String> included = v.getIncluded();
+ assertEquals(0, included.size());
+ }
+
+ public void testWithOverridesMerge() {
+ JsonIncludeProperties.Value v = JsonIncludeProperties.Value.from(Bogus.class.getAnnotation(JsonIncludeProperties.class));
+ v = v.withOverrides(new JsonIncludeProperties.Value(_set("foo")));
+ Set<String> included = v.getIncluded();
+ assertEquals(1, included.size());
+ assertEquals(_set("foo"), included);
+ }
+
+ private Set<String> _set(String... args)
+ {
+ return new LinkedHashSet<String>(Arrays.asList(args));
+ }
+}