├── .gitignore
├── .travis.yml
├── README.md
├── pom.xml
├── profile.sh
├── release-notes
├── CREDITS
└── VERSION
├── run.sh
└── src
├── main
├── java
│ └── com
│ │ └── fasterxml
│ │ └── jackson
│ │ └── module
│ │ └── afterburner
│ │ ├── AfterburnerModule.java
│ │ ├── PackageVersion.java.in
│ │ ├── deser
│ │ ├── BeanPropertyMutator.java
│ │ ├── CreatorOptimizer.java
│ │ ├── DeserializerModifier.java
│ │ ├── OptimizedSettableBeanProperty.java
│ │ ├── OptimizedValueInstantiator.java
│ │ ├── PropertyMutatorCollector.java
│ │ ├── SettableBooleanFieldProperty.java
│ │ ├── SettableBooleanMethodProperty.java
│ │ ├── SettableIntFieldProperty.java
│ │ ├── SettableIntMethodProperty.java
│ │ ├── SettableLongFieldProperty.java
│ │ ├── SettableLongMethodProperty.java
│ │ ├── SettableObjectFieldProperty.java
│ │ ├── SettableObjectMethodProperty.java
│ │ ├── SettableStringFieldProperty.java
│ │ ├── SettableStringMethodProperty.java
│ │ ├── SuperSonicBeanDeserializer.java
│ │ └── SuperSonicDeserializerBuilder.java
│ │ ├── ser
│ │ ├── BeanPropertyAccessor.java
│ │ ├── BooleanFieldPropertyWriter.java
│ │ ├── BooleanMethodPropertyWriter.java
│ │ ├── IntFieldPropertyWriter.java
│ │ ├── IntMethodPropertyWriter.java
│ │ ├── LongFieldPropertyWriter.java
│ │ ├── LongMethodPropertyWriter.java
│ │ ├── ObjectFieldPropertyWriter.java
│ │ ├── ObjectMethodPropertyWriter.java
│ │ ├── OptimizedBeanPropertyWriter.java
│ │ ├── PropertyAccessorCollector.java
│ │ ├── SerializerModifier.java
│ │ ├── StringFieldPropertyWriter.java
│ │ └── StringMethodPropertyWriter.java
│ │ └── util
│ │ ├── ClassName.java
│ │ ├── DynamicPropertyAccessorBase.java
│ │ └── MyClassLoader.java
└── resources
│ └── META-INF
│ ├── LICENSE
│ └── services
│ └── com.fasterxml.jackson.databind.Module
└── test
├── java
├── com
│ └── fasterxml
│ │ └── jackson
│ │ └── module
│ │ └── afterburner
│ │ ├── AfterburnerTestBase.java
│ │ ├── TestAccessFallback.java
│ │ ├── TestSealedPackages.java
│ │ ├── TestUnwrapped.java
│ │ ├── TestVersions.java
│ │ ├── codegen
│ │ └── GenerateWithMixinsTest.java
│ │ ├── deser
│ │ ├── TestBuilders.java
│ │ ├── TestCollectionDeser.java
│ │ ├── TestConstructors.java
│ │ ├── TestCreators.java
│ │ ├── TestCreators2.java
│ │ ├── TestCreatorsDelegating.java
│ │ ├── TestFinalFields.java
│ │ ├── TestIssue14.java
│ │ ├── TestNonStaticInner.java
│ │ ├── TestPolymorphic.java
│ │ ├── TestPolymorphicCreators.java
│ │ ├── TestSimpleDeserialize.java
│ │ ├── TestSingleArgCtors.java
│ │ ├── TestStdDeserializerOverrides.java
│ │ └── TestTreeConversions.java
│ │ ├── roundtrip
│ │ ├── AbstractSettersTest.java
│ │ ├── BiggerDataTest.java
│ │ ├── JavaxTypesTest.java
│ │ ├── MediaItem.java
│ │ ├── MediaItemRoundtripTest.java
│ │ └── POJOAsArrayTest.java
│ │ ├── ser
│ │ ├── CustomBeanPropertyWriterTest.java
│ │ ├── JsonAppendTest.java
│ │ ├── JsonIncludeTest.java
│ │ ├── SerializeWithViewTest.java
│ │ ├── TestAccessorGeneration.java
│ │ ├── TestInclusionAnnotations.java
│ │ ├── TestInterfaceSerialize.java
│ │ ├── TestJsonFilter.java
│ │ ├── TestJsonSerializeAnnotationBug.java
│ │ ├── TestRawValues.java
│ │ ├── TestSimpleSerialize.java
│ │ └── TestStdSerializerOverrides.java
│ │ └── util
│ │ └── MyClassLoaderTest.java
├── perf
│ ├── ManualDatabindPerf.java
│ ├── MediaItem.java
│ ├── NopOutputStream.java
│ ├── TestPojo.java
│ └── Value.java
└── perftest
│ ├── MediaItem.java
│ ├── TestDeserializePerf.java
│ ├── TestJvmDeserPerf.java
│ ├── TestJvmSerPerf.java
│ └── TestSerializePerf.java
└── resources
└── data
└── citm_catalog.json
/.gitignore:
--------------------------------------------------------------------------------
1 | # Skip maven 'target' directory
2 | target
3 | *~
4 |
5 | # plus eclipse crap
6 | .classpath
7 | .project
8 | .settings
9 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 |
3 | jdk:
4 | - oraclejdk7
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | **NOTE**: This module has moved under [jackson-modules-base](../../../jackson-modules-base) as of Jackson 2.7.1.
2 |
3 | This repo only exists for 2.6 patch releases.
4 |
5 | -----
6 |
7 | Module that will add dynamic bytecode generation for standard Jackson POJO serializers and deserializers, eliminating majority of remaining data binding overhead.
8 |
9 | Plugs in using standard Module interface (requiring Jackson 2.0.0 or above).
10 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 |
4 | com.fasterxml.jackson
5 | jackson-parent
6 | 2.7
7 |
8 | com.fasterxml.jackson.module
9 | jackson-module-afterburner
10 | Jackson-module-Afterburner
11 | 2.7.2-SNAPSHOT
12 | bundle
13 | Jackson (https://github.com/FasterXML/jackson) extension module
14 | used to enhance access functionality using bytecode generation.
15 |
16 | http://wiki.fasterxml.com/JacksonHome
17 |
18 | scm:git:git@github.com:FasterXML/jackson-module-afterburner.git
19 | scm:git:git@github.com:FasterXML/jackson-module-afterburner.git
20 | http://github.com/FasterXML/jackson-module-afterburner
21 | HEAD
22 |
23 |
24 |
25 | 2.7.1
26 |
27 |
28 | com/fasterxml/jackson/module/afterburner
29 | ${project.groupId}.afterburner
30 |
31 |
33 |
34 |
39 | org.objectweb.asm;resolution:=optional,
40 | *
41 |
42 |
45 |
46 |
47 |
48 |
51 |
52 | com.fasterxml.jackson.core
53 | jackson-core
54 | ${jackson.core.version}
55 |
56 |
57 | com.fasterxml.jackson.core
58 | jackson-databind
59 | ${jackson.core.version}
60 |
61 |
62 | org.ow2.asm
63 | asm
64 | 5.0.3
65 | compile
66 |
67 |
68 | com.fasterxml.jackson.core
69 | jackson-annotations
70 | test
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | com.google.code.maven-replacer-plugin
79 | replacer
80 |
81 |
82 | process-packageVersion
83 | generate-sources
84 |
85 |
86 |
87 |
88 |
89 |
90 | org.apache.maven.plugins
91 | maven-surefire-plugin
92 | ${version.plugin.surefire}
93 |
94 |
95 | com/fasterxml/jackson/**/failing/*.java
96 |
97 |
98 |
99 |
100 |
101 |
102 | org.apache.maven.plugins
103 | maven-shade-plugin
104 | 2.3
105 |
106 |
107 | package
108 |
109 | shade
110 |
111 |
112 |
113 |
114 | org.ow2.asm:asm
115 |
116 |
117 |
118 |
119 | org.objectweb.asm
120 | com.fasterxml.jackson.module.afterburner.asm
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
--------------------------------------------------------------------------------
/profile.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | java -Xmx64m -server -cp lib/\*:target/\*:target/test-classes \
4 | -Xrunhprof:cpu=samples,depth=10,verbose=n,interval=2 \
5 | $*
6 |
--------------------------------------------------------------------------------
/release-notes/CREDITS:
--------------------------------------------------------------------------------
1 | Here are people who have contributed to development Jackson JSON processor
2 | Afterburner component, version 2.x
3 | (version numbers in brackets indicate release in which the problem was fixed)
4 |
5 | (note: for older credits, check out release notes for 1.x versions)
6 |
7 | Tatu Saloranta, tatu.saloranta@iki.fi: author
8 | Steven Schlansker, co-author (numerous fixes, patches)
9 |
10 | celkings@github:
11 |
12 | * Reported [#22]: Problems with Builder-style deserialization
13 | (2.2.2)
14 |
15 | R.W Bergstom (rwbergstom@github)
16 |
17 | * Reported, contributed [#29]: NON_DEFAULT inclusion setting ignored by primitive
18 | writers
19 | (2.2.3)
20 |
21 | Nándor István Krácser (bonifaido@github)
22 |
23 | * Contributed #27/#23: ability to deserialize interface types
24 | (2.2.3)
25 |
26 | Joost van de Wijgerd (jwijgerd@github)
27 |
28 | * Contributed fix to #48: Problem passing custom `JsonSerializer`, causing an NPE
29 | (2.4.5)
30 |
31 | Jörn Huxhorn (huxi@github)
32 |
33 | * Reported #47: java.lang.VerifyError (Illegal type in constant pool ...)
34 | (2.5.1)
35 |
36 | natnan@github
37 |
38 | * Reported #52: Invalidating SerializationInclusion.NON_NULL of other modules
39 | (2.5.2)
40 |
41 | Steve Metcalfe (steveme@github)
42 | * Reported #58: Specific ordering of type information for polymorphic deserialization
43 | (2.6.2)
44 |
45 | Lucas Pouzac (lucaspouzac@github)
46 |
47 | * Reported, constributed fix to #63: Revert back expansion of NON_EMPTY handling
48 | (2.7.1)
49 |
--------------------------------------------------------------------------------
/release-notes/VERSION:
--------------------------------------------------------------------------------
1 | Project: jackson-module-afterburner
2 |
3 | ------------------------------------------------------------------------
4 | === Releases ===
5 | ------------------------------------------------------------------------
6 |
7 | 2.7.1 (02-Feb-2016)
8 |
9 | #63: Revert back expansion of NON_EMPTY handling
10 | (reported by Lucas P)
11 |
12 | 2.7.0 (10-Jan-2016)
13 |
14 | No changes since 2.6.
15 |
16 | 2.6.7.1 (not yet released)
17 |
18 | (modules-base#7): Afterburner excludes serialization of some `null`-valued
19 | Object properties
20 |
21 | 2.6.7 (05-Jun-2016)
22 | 2.6.6 (05-Apr-2016)
23 | 2.6.5 (19-Jan-2016)
24 | 2.6.4 (07-Dec-2015)
25 |
26 | No changes since 2.6.3
27 |
28 | 2.6.3 (12-Oct-2015)
29 |
30 | #59: Cannot customize String deserialization behavior
31 | (reported by brianwyantora@github)
32 | #60: Cannot read some "pretty" documents (NOTE: actually fixed by [jackson-core#220] in 2.6.3)
33 | (reported by lehcim@github)
34 |
35 | 2.6.2 (15-Sep-2015)
36 |
37 | #56: Afterburner does not respect DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS
38 | (reported by shollander@github)
39 | #57: `@JsonAppend` causes `NullPointerException`
40 | (reported by cleiner@github)
41 | #58: Specific ordering of type information for polymorphic deserialization
42 | (reported by Steve M)
43 |
44 | 2.6.1 (09-Aug-2015)
45 |
46 | No changes since 2.6.0
47 |
48 | 2.6.0 (19-Jul-2015)
49 |
50 | #46: Log-warning "Disabling Afterburner deserialization for type" using wrong logger-name
51 | #53: Include checksum in generated class names (to resolve #52)
52 |
53 | 2.5.4 (09-Jun-2015)
54 | 2.5.3 (24-Apr-2015)
55 | 2.5.2 (29-Mar-2015)
56 |
57 | No changes since 2.5.1
58 |
59 | 2.5.1 (06-Feb-2015)
60 |
61 | #47: java.lang.VerifyError (Illegal type in constant pool ...)
62 | (reported by huxi@github)
63 | #52: Invalidating SerializationInclusion.NON_NULL of other modules
64 | (reported by natnan@github)
65 |
66 | 2.5.0 (01-Jan-2015)
67 |
68 | - Remove coupling of `_name` field of `BeanPropertyWriter`
69 |
70 | 2.4.5 (not yet released)
71 |
72 | #48: Problem passing custom `JsonSerializer`, causing an NPE
73 | (reported, fix contributed by Joost v-d-W)
74 |
75 | 2.4.4 (24-Nov-2014)
76 |
77 | No changes since 2.4.3.
78 |
79 | 2.4.3 (03-Oct-2014)
80 |
81 | #42: Problems trying to deserialize final fields
82 | #43: Problem deserializing type with one polymorphic property that
83 | uses inclusion of `As.EXTERNAL_PROPERTY`
84 | (reported by steveme@github)
85 | #44: Optimize `boolean` property access (read/write)
86 | - Upgrade to ASM 5.0
87 | - Change AfterburnerModule to directly extend Module, not SimpleModule
88 |
89 | 2.4.2 (14-Aug-2014)
90 |
91 | #40: Failure to deserialize non-static inner classes
92 | (reported by nigelzor@github)
93 | #41: Serialization of `javax.security.auth.AuthPermission` fails
94 |
95 | 2.4.1 (17-Jun-2014)
96 |
97 | - Make accessor class 'final'
98 |
99 | 2.4.0 (02-Jun-2014)
100 |
101 | #13: Upgrade to ASM5
102 |
103 | 2.3.2 (01-Mar-2014)
104 |
105 | #39: Afterburner does not respect JsonInclude.Include.NON_EMPTY
106 | (reported by mahileeb@github)
107 |
108 | 2.3.1 (28-Dec-2013)
109 |
110 | #38: Handling of @JsonRawValue broken (require 2.3.1 of jackson-databind for fix)
111 | (reported by willcheck@github)
112 |
113 | 2.3.0 (14-Nov-2013)
114 |
115 | #33: `SuperSonicBeanDeserializer` not working (missing optimization)
116 | #34: Needs to skip private creators, can not access even from sub-class.
117 |
118 |
119 | 2.2.3 (23-Aug-2013)
120 |
121 | #9: Ensure that `@JsonUnwrapped` handling still works
122 | #23: Support deserialization of interface types
123 | (contributed by bonifaido@github)
124 | #26: Use `java.util.logging` for logging warnings: it sucks, but is
125 | overridable, does not require a new dependency
126 | #29: NON_DEFAULT inclusion setting ignored by primitive writers
127 | (reported by rwbergstrom@github)
128 |
129 | 2.2.2 (27-May-2013)
130 |
131 | #20: Protect Afterburner against IllegalAccessError and SecurityException
132 | (contributed by Steven S)
133 | #22: Problems with Builder-style deserialization (actual bug in jackson-databind;
134 | requires 2.2.2 of databind)
135 | (reported by celkings@github)
136 | #24: Disable handling of interface types (for now)
137 |
138 | 2.2.1 (03-May-2013)
139 |
140 | #16: Problems with non-void setters, part 2
141 | (contributed by Steven S)
142 | #21: Prevent attempts to generate classes in sealed packages
143 | (contributed by Steven S)
144 |
145 | 2.2.0 (22-Apr-2013)
146 |
147 | #14: Problems deserializing a complex POJO with serialization inclusion of
148 | NotNull.
149 |
150 | 2.1.2 (04-Dec-2012)
151 |
152 | #11: problems with property-based @JsonCreator
153 |
154 | 2.1.1 (11-Nov-2012)
155 |
156 | #10: null String got coerced to "null" on deserialization
157 |
158 | 2.1.0 (08-Oct-2012)
159 |
160 | New minor version. No functional changes, but has to be updated to
161 | ensure that 2.1 core methods are covered.
162 |
163 | 2.0.6 (22-Sep-2012)
164 |
165 | Fixes:
166 |
167 | * [Issue-5] Failed to use setters that return something (non-void setters)
168 | (reported by chillenious@GH)
169 | * [Issue-6] Annotation-indicated (de)serializers were being overridden
170 | by Afterburner optimizer.
171 |
172 | 2.0.5 (27-Jul-2012)
173 |
174 | No fixes, just dependency updates.
175 |
176 | 2.0.4 (28-Jun-2012)
177 |
178 | No fixes, just dependency updates.
179 |
180 | 2.0.3: skipped
181 |
182 | 2.0.2 (14-May-2012)
183 |
184 | - No changes, updated dependencies.
185 |
186 | 2.0.0 (25-Mar-2012)
187 |
188 | - No new features; upgraded to work with core 2.0.0.
189 |
190 | [entries for versions 1.x and earlier not retained; refer to earlier releases)
191 |
--------------------------------------------------------------------------------
/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | java -Xmx64m -server -cp lib/\*:target/\*:target/test-classes $*
4 |
5 |
--------------------------------------------------------------------------------
/src/main/java/com/fasterxml/jackson/module/afterburner/AfterburnerModule.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner;
2 |
3 | import com.fasterxml.jackson.core.Version;
4 | import com.fasterxml.jackson.databind.Module;
5 | import com.fasterxml.jackson.module.afterburner.ser.SerializerModifier;
6 | import com.fasterxml.jackson.module.afterburner.deser.DeserializerModifier;
7 |
8 | public class AfterburnerModule extends Module
9 | implements java.io.Serializable // is this necessary?
10 | {
11 | private static final long serialVersionUID = 1L;
12 |
13 | /*
14 | /**********************************************************************
15 | /* Configuration settings
16 | /**********************************************************************
17 | */
18 |
19 | /**
20 | * Flag to indicate whether we will try to load generated classes using
21 | * same class loader as one that loaded class being accessed or not.
22 | * If not, we will use class loader that loaded this module.
23 | * Benefit of using value class loader is that 'protected' and 'package access'
24 | * properties can be accessed; otherwise only 'public' properties can
25 | * be accessed.
26 | *
27 | * By default this feature is enabled.
28 | */
29 | protected boolean _cfgUseValueClassLoader = true;
30 |
31 | /**
32 | * Flag to indicate whether we should use an optimized sub-class of
33 | * {@link com.fasterxml.jackson.databind.deser.BeanDeserializer} or not.
34 | * Use of optimized version should further improve performance, but
35 | * it can be disabled in case it causes issues.
36 | *
37 | * By default this feature is enabled.
38 | */
39 | protected boolean _cfgUseOptimizedBeanDeserializer = true;
40 |
41 | /*
42 | /**********************************************************************
43 | /* Basic life-cycle
44 | /**********************************************************************
45 | */
46 |
47 | public AfterburnerModule() { }
48 |
49 | @Override
50 | public void setupModule(SetupContext context)
51 | {
52 | ClassLoader cl = _cfgUseValueClassLoader ? null : getClass().getClassLoader();
53 | context.addBeanDeserializerModifier(new DeserializerModifier(cl,
54 | _cfgUseOptimizedBeanDeserializer));
55 | context.addBeanSerializerModifier(new SerializerModifier(cl));
56 | }
57 |
58 | @Override
59 | public String getModuleName() {
60 | return getClass().getSimpleName();
61 | }
62 |
63 | @Override
64 | public Version version() {
65 | return PackageVersion.VERSION;
66 | }
67 |
68 | /*
69 | /**********************************************************************
70 | /* Config methods
71 | /**********************************************************************
72 | */
73 |
74 | /**
75 | * Flag to indicate whether we will try to load generated classes using
76 | * same class loader as one that loaded class being accessed or not.
77 | * If not, we will use class loader that loaded this module.
78 | * Benefit of using value class loader is that 'protected' and 'package access'
79 | * properties can be accessed; otherwise only 'public' properties can
80 | * be accessed.
81 | *
82 | * By default this feature is enabled.
83 | */
84 | public AfterburnerModule setUseValueClassLoader(boolean state) {
85 | _cfgUseValueClassLoader = state;
86 | return this;
87 | }
88 |
89 | public AfterburnerModule setUseOptimizedBeanDeserializer(boolean state) {
90 | _cfgUseOptimizedBeanDeserializer = state;
91 | return this;
92 | }
93 | }
94 |
95 |
--------------------------------------------------------------------------------
/src/main/java/com/fasterxml/jackson/module/afterburner/PackageVersion.java.in:
--------------------------------------------------------------------------------
1 | package @package@;
2 |
3 | import com.fasterxml.jackson.core.Version;
4 | import com.fasterxml.jackson.core.Versioned;
5 | import com.fasterxml.jackson.core.util.VersionUtil;
6 |
7 | /**
8 | * Automatically generated from PackageVersion.java.in during
9 | * packageVersion-generate execution of maven-replacer-plugin in
10 | * pom.xml.
11 | */
12 | public final class PackageVersion implements Versioned {
13 | public final static Version VERSION = VersionUtil.parseVersion(
14 | "@projectversion@", "@projectgroupid@", "@projectartifactid@");
15 |
16 | @Override
17 | public Version version() {
18 | return VERSION;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/fasterxml/jackson/module/afterburner/deser/OptimizedValueInstantiator.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.deser;
2 |
3 | import java.io.IOException;
4 |
5 | import com.fasterxml.jackson.core.JsonProcessingException;
6 | import com.fasterxml.jackson.databind.DeserializationContext;
7 | import com.fasterxml.jackson.databind.deser.std.StdValueInstantiator;
8 |
9 | /**
10 | * Base class for concrete bytecode-generated value instantiators.
11 | */
12 | public abstract class OptimizedValueInstantiator
13 | extends StdValueInstantiator
14 | {
15 | private static final long serialVersionUID = 1L;
16 |
17 | /**
18 | * Default constructor which is only used when creating
19 | * dummy instance to call factory method.
20 | */
21 | protected OptimizedValueInstantiator() {
22 | super(/*DeserializationConfig*/null, (Class>)String.class);
23 | }
24 |
25 | /**
26 | * Copy-constructor to use for creating actual optimized instances.
27 | */
28 | protected OptimizedValueInstantiator(StdValueInstantiator src) {
29 | super(src);
30 | }
31 |
32 | /**
33 | * Need to override this, now that we have installed default creator.
34 | */
35 | @Override
36 | public boolean canCreateUsingDefault() {
37 | return true;
38 | }
39 |
40 | protected abstract OptimizedValueInstantiator with(StdValueInstantiator src);
41 |
42 | /* Define as abstract to ensure that it gets reimplemented; or if not,
43 | * we get a specific error (too easy to break, and get cryptic error)
44 | */
45 | @Override
46 | public abstract Object createUsingDefault(DeserializationContext ctxt)
47 | throws IOException, JsonProcessingException;
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableBooleanFieldProperty.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.deser;
2 |
3 | import java.io.IOException;
4 |
5 | import com.fasterxml.jackson.core.*;
6 | import com.fasterxml.jackson.databind.*;
7 | import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
8 |
9 | public final class SettableBooleanFieldProperty
10 | extends OptimizedSettableBeanProperty
11 | {
12 | private static final long serialVersionUID = 1L;
13 |
14 | public SettableBooleanFieldProperty(SettableBeanProperty src,
15 | BeanPropertyMutator mutator, int index)
16 | {
17 | super(src, mutator, index);
18 | }
19 |
20 | public SettableBooleanFieldProperty(SettableBooleanFieldProperty src,
21 | JsonDeserializer> deser)
22 | {
23 | super(src, deser);
24 | }
25 |
26 | public SettableBooleanFieldProperty(SettableBooleanFieldProperty src, PropertyName name) {
27 | super(src, name);
28 | }
29 |
30 | @Override
31 | public SettableBeanProperty withName(PropertyName name) {
32 | return new SettableBooleanFieldProperty(this, name);
33 | }
34 |
35 | @Override
36 | public SettableBeanProperty withValueDeserializer(JsonDeserializer> deser) {
37 | if (!_isDefaultDeserializer(deser)) {
38 | return _originalSettable.withValueDeserializer(deser);
39 | }
40 | return new SettableBooleanFieldProperty(this, deser);
41 | }
42 |
43 | @Override
44 | public SettableBeanProperty withMutator(BeanPropertyMutator mut) {
45 | return new SettableBooleanFieldProperty(_originalSettable, mut, _optimizedIndex);
46 | }
47 |
48 | /*
49 | /**********************************************************************
50 | /* Deserialization
51 | /**********************************************************************
52 | */
53 |
54 | @Override
55 | public void deserializeAndSet(JsonParser p, DeserializationContext ctxt, Object bean) throws IOException {
56 | boolean b;
57 | JsonToken t = p.getCurrentToken();
58 | if (t == JsonToken.VALUE_TRUE) {
59 | b = true;
60 | } else if (t == JsonToken.VALUE_FALSE) {
61 | b = false;
62 | } else {
63 | b = _deserializeBoolean(p, ctxt);
64 | }
65 | _propertyMutator.booleanField(bean, b);
66 | }
67 |
68 | @Override
69 | public void set(Object bean, Object value) throws IOException {
70 | // not optimal (due to boxing), but better than using reflection:
71 | _propertyMutator.booleanField(bean, ((Boolean) value).booleanValue());
72 | }
73 |
74 | @Override
75 | public Object deserializeSetAndReturn(JsonParser p,
76 | DeserializationContext ctxt, Object instance) throws IOException
77 | {
78 | boolean b;
79 | JsonToken t = p.getCurrentToken();
80 | if (t == JsonToken.VALUE_TRUE) {
81 | b = true;
82 | } else if (t == JsonToken.VALUE_FALSE) {
83 | b = false;
84 | } else {
85 | b = _deserializeBoolean(p, ctxt);
86 | }
87 | return setAndReturn(instance, b);
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableBooleanMethodProperty.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.deser;
2 |
3 | import java.io.IOException;
4 |
5 | import com.fasterxml.jackson.core.*;
6 | import com.fasterxml.jackson.databind.*;
7 | import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
8 |
9 | public final class SettableBooleanMethodProperty
10 | extends OptimizedSettableBeanProperty
11 | {
12 | private static final long serialVersionUID = 1L;
13 |
14 | public SettableBooleanMethodProperty(SettableBeanProperty src,
15 | BeanPropertyMutator mutator, int index)
16 | {
17 | super(src, mutator, index);
18 | }
19 |
20 | public SettableBooleanMethodProperty(SettableBooleanMethodProperty src, JsonDeserializer> deser) {
21 | super(src, deser);
22 | }
23 |
24 | public SettableBooleanMethodProperty(SettableBooleanMethodProperty src, PropertyName name) {
25 | super(src, name);
26 | }
27 |
28 | @Override
29 | public SettableBeanProperty withName(PropertyName name) {
30 | return new SettableBooleanMethodProperty(this, name);
31 | }
32 |
33 | @Override
34 | public SettableBeanProperty withValueDeserializer(JsonDeserializer> deser) {
35 | if (!_isDefaultDeserializer(deser)) {
36 | return _originalSettable.withValueDeserializer(deser);
37 | }
38 | return new SettableBooleanMethodProperty(this, deser);
39 | }
40 |
41 | @Override
42 | public SettableBeanProperty withMutator(BeanPropertyMutator mut) {
43 | return new SettableBooleanMethodProperty(_originalSettable, mut, _optimizedIndex);
44 | }
45 |
46 | /*
47 | /**********************************************************************
48 | /* Deserialization
49 | /**********************************************************************
50 | */
51 |
52 | @Override
53 | public void deserializeAndSet(JsonParser p, DeserializationContext ctxt, Object bean) throws IOException {
54 | boolean b;
55 | JsonToken t = p.getCurrentToken();
56 | if (t == JsonToken.VALUE_TRUE) {
57 | b = true;
58 | } else if (t == JsonToken.VALUE_FALSE) {
59 | b = false;
60 | } else {
61 | b = _deserializeBoolean(p, ctxt);
62 | }
63 | _propertyMutator.booleanSetter(bean, b);
64 | }
65 |
66 | @Override
67 | public void set(Object bean, Object value) throws IOException {
68 | // not optimal (due to boxing), but better than using reflection:
69 | _propertyMutator.booleanSetter(bean, ((Boolean) value).booleanValue());
70 | }
71 |
72 | @Override
73 | public Object deserializeSetAndReturn(JsonParser p,
74 | DeserializationContext ctxt, Object instance) throws IOException
75 | {
76 | boolean b;
77 | JsonToken t = p.getCurrentToken();
78 | if (t == JsonToken.VALUE_TRUE) {
79 | b = true;
80 | } else if (t == JsonToken.VALUE_FALSE) {
81 | b = false;
82 | } else {
83 | b = _deserializeBoolean(p, ctxt);
84 | }
85 | return setAndReturn(instance, b);
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableIntFieldProperty.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.deser;
2 |
3 | import java.io.IOException;
4 |
5 | import com.fasterxml.jackson.core.*;
6 | import com.fasterxml.jackson.databind.*;
7 | import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
8 |
9 | public final class SettableIntFieldProperty
10 | extends OptimizedSettableBeanProperty
11 | {
12 | private static final long serialVersionUID = 1L;
13 |
14 | public SettableIntFieldProperty(SettableBeanProperty src,
15 | BeanPropertyMutator mutator, int index)
16 | {
17 | super(src, mutator, index);
18 | }
19 |
20 | public SettableIntFieldProperty(SettableIntFieldProperty src,
21 | JsonDeserializer> deser)
22 | {
23 | super(src, deser);
24 | }
25 |
26 | public SettableIntFieldProperty(SettableIntFieldProperty src, PropertyName name) {
27 | super(src, name);
28 | }
29 |
30 | @Override
31 | public SettableBeanProperty withName(PropertyName name) {
32 | return new SettableIntFieldProperty(this, name);
33 | }
34 |
35 | @Override
36 | public SettableBeanProperty withValueDeserializer(JsonDeserializer> deser) {
37 | if (!_isDefaultDeserializer(deser)) {
38 | return _originalSettable.withValueDeserializer(deser);
39 | }
40 | return new SettableIntFieldProperty(this, deser);
41 | }
42 |
43 | @Override
44 | public SettableBeanProperty withMutator(BeanPropertyMutator mut) {
45 | return new SettableIntFieldProperty(_originalSettable, mut, _optimizedIndex);
46 | }
47 |
48 | /*
49 | /**********************************************************************
50 | /* Deserialization
51 | /**********************************************************************
52 | */
53 |
54 | @Override
55 | public void deserializeAndSet(JsonParser p, DeserializationContext ctxt,
56 | Object bean) throws IOException
57 | {
58 | int v = p.hasToken(JsonToken.VALUE_NUMBER_INT) ? p.getIntValue() : _deserializeInt(p, ctxt);
59 | _propertyMutator.intField(bean, v);
60 | }
61 |
62 | @Override
63 | public void set(Object bean, Object value) throws IOException {
64 | // not optimal (due to boxing), but better than using reflection:
65 | _propertyMutator.intField(bean, ((Number) value).intValue());
66 | }
67 |
68 | @Override
69 | public Object deserializeSetAndReturn(JsonParser p,
70 | DeserializationContext ctxt, Object instance) throws IOException
71 | {
72 | int v = p.hasToken(JsonToken.VALUE_NUMBER_INT) ? p.getIntValue() : _deserializeInt(p, ctxt);
73 | return setAndReturn(instance, v);
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableIntMethodProperty.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.deser;
2 |
3 | import java.io.IOException;
4 |
5 | import com.fasterxml.jackson.core.*;
6 | import com.fasterxml.jackson.databind.*;
7 | import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
8 |
9 | public final class SettableIntMethodProperty
10 | extends OptimizedSettableBeanProperty
11 | {
12 | private static final long serialVersionUID = 1L;
13 |
14 | public SettableIntMethodProperty(SettableBeanProperty src,
15 | BeanPropertyMutator mutator, int index)
16 | {
17 | super(src, mutator, index);
18 | }
19 |
20 | public SettableIntMethodProperty(SettableIntMethodProperty src, JsonDeserializer> deser) {
21 | super(src, deser);
22 | }
23 |
24 | public SettableIntMethodProperty(SettableIntMethodProperty src, PropertyName name) {
25 | super(src, name);
26 | }
27 |
28 | @Override
29 | public SettableBeanProperty withName(PropertyName name) {
30 | return new SettableIntMethodProperty(this, name);
31 | }
32 |
33 | @Override
34 | public SettableBeanProperty withValueDeserializer(JsonDeserializer> deser) {
35 | if (!_isDefaultDeserializer(deser)) {
36 | return _originalSettable.withValueDeserializer(deser);
37 | }
38 | return new SettableIntMethodProperty(this, deser);
39 | }
40 |
41 | @Override
42 | public SettableBeanProperty withMutator(BeanPropertyMutator mut) {
43 | return new SettableIntMethodProperty(_originalSettable, mut, _optimizedIndex);
44 | }
45 |
46 | /*
47 | /**********************************************************************
48 | /* Deserialization
49 | /**********************************************************************
50 | */
51 |
52 | @Override
53 | public void deserializeAndSet(JsonParser p, DeserializationContext ctxt,
54 | Object bean) throws IOException
55 | {
56 | int v = p.hasToken(JsonToken.VALUE_NUMBER_INT) ? p.getIntValue() : _deserializeInt(p, ctxt);
57 | _propertyMutator.intSetter(bean, v);
58 | }
59 |
60 | @Override
61 | public void set(Object bean, Object value) throws IOException {
62 | // not optimal (due to boxing), but better than using reflection:
63 | _propertyMutator.intSetter(bean, ((Number) value).intValue());
64 | }
65 |
66 | @Override
67 | public Object deserializeSetAndReturn(JsonParser p,
68 | DeserializationContext ctxt, Object instance)
69 | throws IOException
70 | {
71 | int v = p.hasToken(JsonToken.VALUE_NUMBER_INT) ? p.getIntValue() : _deserializeInt(p, ctxt);
72 | return setAndReturn(instance, v);
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableLongFieldProperty.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.deser;
2 |
3 | import java.io.IOException;
4 |
5 | import com.fasterxml.jackson.core.*;
6 | import com.fasterxml.jackson.databind.*;
7 | import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
8 |
9 | public final class SettableLongFieldProperty
10 | extends OptimizedSettableBeanProperty
11 | {
12 | private static final long serialVersionUID = 1L;
13 |
14 | public SettableLongFieldProperty(SettableBeanProperty src,
15 | BeanPropertyMutator mutator, int index)
16 | {
17 | super(src, mutator, index);
18 | }
19 |
20 | public SettableLongFieldProperty(SettableLongFieldProperty src, JsonDeserializer> deser) {
21 | super(src, deser);
22 | }
23 |
24 | public SettableLongFieldProperty(SettableLongFieldProperty src, PropertyName name) {
25 | super(src, name);
26 | }
27 |
28 | @Override
29 | public SettableBeanProperty withName(PropertyName name) {
30 | return new SettableLongFieldProperty(this, name);
31 | }
32 |
33 | @Override
34 | public SettableBeanProperty withValueDeserializer(JsonDeserializer> deser) {
35 | if (!_isDefaultDeserializer(deser)) {
36 | return _originalSettable.withValueDeserializer(deser);
37 | }
38 | return new SettableLongFieldProperty(this, deser);
39 | }
40 |
41 | @Override
42 | public SettableBeanProperty withMutator(BeanPropertyMutator mut) {
43 | return new SettableLongFieldProperty(_originalSettable, mut, _optimizedIndex);
44 | }
45 |
46 | /*
47 | /**********************************************************************
48 | /* Deserialization
49 | /**********************************************************************
50 | */
51 |
52 | @Override
53 | public void deserializeAndSet(JsonParser p, DeserializationContext ctxt,
54 | Object bean) throws IOException
55 | {
56 | long l = p.hasToken(JsonToken.VALUE_NUMBER_INT) ? p.getLongValue() : _deserializeLong(p, ctxt);
57 | _propertyMutator.longField(bean, l);
58 | }
59 |
60 | @Override
61 | public void set(Object bean, Object value) throws IOException {
62 | // not optimal (due to boxing), but better than using reflection:
63 | _propertyMutator.longField(bean, ((Number) value).longValue());
64 | }
65 |
66 | @Override
67 | public Object deserializeSetAndReturn(JsonParser p,
68 | DeserializationContext ctxt, Object instance) throws IOException
69 | {
70 | long l = p.hasToken(JsonToken.VALUE_NUMBER_INT) ? p.getLongValue() : _deserializeLong(p, ctxt);
71 | return setAndReturn(instance, l);
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableLongMethodProperty.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.deser;
2 |
3 | import java.io.IOException;
4 |
5 | import com.fasterxml.jackson.core.*;
6 | import com.fasterxml.jackson.databind.*;
7 | import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
8 |
9 | public final class SettableLongMethodProperty
10 | extends OptimizedSettableBeanProperty
11 | {
12 | private static final long serialVersionUID = 1L;
13 |
14 | public SettableLongMethodProperty(SettableBeanProperty src,
15 | BeanPropertyMutator mutator, int index)
16 | {
17 | super(src, mutator, index);
18 | }
19 |
20 | public SettableLongMethodProperty(SettableLongMethodProperty src, JsonDeserializer> deser) {
21 | super(src, deser);
22 | }
23 |
24 | public SettableLongMethodProperty(SettableLongMethodProperty src, PropertyName name) {
25 | super(src, name);
26 | }
27 |
28 | @Override
29 | public SettableBeanProperty withName(PropertyName name) {
30 | return new SettableLongMethodProperty(this, name);
31 | }
32 |
33 | @Override
34 | public SettableBeanProperty withValueDeserializer(JsonDeserializer> deser) {
35 | if (!_isDefaultDeserializer(deser)) {
36 | return _originalSettable.withValueDeserializer(deser);
37 | }
38 | return new SettableLongMethodProperty(this, deser);
39 | }
40 |
41 | @Override
42 | public SettableBeanProperty withMutator(BeanPropertyMutator mut) {
43 | return new SettableLongMethodProperty(_originalSettable, mut, _optimizedIndex);
44 | }
45 |
46 | /*
47 | /**********************************************************************
48 | /* Deserialization
49 | /**********************************************************************
50 | */
51 |
52 | @Override
53 | public void deserializeAndSet(JsonParser p, DeserializationContext ctxt,
54 | Object bean) throws IOException
55 | {
56 | long l = p.hasToken(JsonToken.VALUE_NUMBER_INT) ? p.getLongValue() : _deserializeLong(p, ctxt);
57 | _propertyMutator.longSetter(bean, l);
58 | }
59 |
60 | @Override
61 | public void set(Object bean, Object value) throws IOException {
62 | // not optimal (due to boxing), but better than using reflection:
63 | _propertyMutator.longSetter(bean, ((Number) value).longValue());
64 | }
65 |
66 | @Override
67 | public Object deserializeSetAndReturn(JsonParser p,
68 | DeserializationContext ctxt, Object instance) throws IOException
69 | {
70 | long l = p.hasToken(JsonToken.VALUE_NUMBER_INT) ? p.getLongValue() : _deserializeLong(p, ctxt);
71 | return setAndReturn(instance, l);
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableObjectFieldProperty.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.deser;
2 |
3 | import java.io.IOException;
4 |
5 | import com.fasterxml.jackson.core.*;
6 | import com.fasterxml.jackson.databind.*;
7 | import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
8 |
9 | public final class SettableObjectFieldProperty
10 | extends OptimizedSettableBeanProperty
11 | {
12 | private static final long serialVersionUID = 1L;
13 |
14 | public SettableObjectFieldProperty(SettableBeanProperty src,
15 | BeanPropertyMutator mutator, int index)
16 | {
17 | super(src, mutator, index);
18 | }
19 |
20 | public SettableObjectFieldProperty(SettableObjectFieldProperty src, JsonDeserializer> deser) {
21 | super(src, deser);
22 | }
23 |
24 | public SettableObjectFieldProperty(SettableObjectFieldProperty src, PropertyName name) {
25 | super(src, name);
26 | }
27 |
28 | @Override
29 | public SettableBeanProperty withName(PropertyName name) {
30 | return new SettableObjectFieldProperty(this, name);
31 | }
32 |
33 | @Override
34 | public SettableBeanProperty withValueDeserializer(JsonDeserializer> deser) {
35 | if (!_isDefaultDeserializer(deser)) {
36 | return _originalSettable.withValueDeserializer(deser);
37 | }
38 | return new SettableObjectFieldProperty(this, deser);
39 | }
40 |
41 | @Override
42 | public SettableBeanProperty withMutator(BeanPropertyMutator mut) {
43 | return new SettableObjectFieldProperty(_originalSettable, mut, _optimizedIndex);
44 | }
45 |
46 | /*
47 | /**********************************************************************
48 | /* Deserialization
49 | /**********************************************************************
50 | */
51 |
52 | @Override
53 | public void deserializeAndSet(JsonParser p, DeserializationContext ctxt,
54 | Object bean) throws IOException
55 | {
56 | set(bean, deserialize(p, ctxt));
57 | }
58 |
59 | @Override
60 | public void set(Object bean, Object value) throws IOException {
61 | _propertyMutator.objectField(bean, value);
62 | }
63 |
64 | @Override
65 | public Object deserializeSetAndReturn(JsonParser p,
66 | DeserializationContext ctxt, Object instance) throws IOException
67 | {
68 | return setAndReturn(instance, deserialize(p, ctxt));
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableObjectMethodProperty.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.deser;
2 |
3 | import java.io.IOException;
4 |
5 | import com.fasterxml.jackson.core.*;
6 | import com.fasterxml.jackson.databind.*;
7 | import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
8 |
9 | public final class SettableObjectMethodProperty
10 | extends OptimizedSettableBeanProperty
11 | {
12 | private static final long serialVersionUID = 1L;
13 |
14 | public SettableObjectMethodProperty(SettableBeanProperty src,
15 | BeanPropertyMutator mutator, int index)
16 | {
17 | super(src, mutator, index);
18 | }
19 |
20 | public SettableObjectMethodProperty(SettableObjectMethodProperty src, JsonDeserializer> deser) {
21 | super(src, deser);
22 | }
23 |
24 | public SettableObjectMethodProperty(SettableObjectMethodProperty src, PropertyName name) {
25 | super(src, name);
26 | }
27 |
28 | @Override
29 | public SettableBeanProperty withName(PropertyName name) {
30 | return new SettableObjectMethodProperty(this, name);
31 | }
32 |
33 | @Override
34 | public SettableBeanProperty withValueDeserializer(JsonDeserializer> deser) {
35 | if (!_isDefaultDeserializer(deser)) {
36 | return _originalSettable.withValueDeserializer(deser);
37 | }
38 | return new SettableObjectMethodProperty(this, deser);
39 | }
40 |
41 | @Override
42 | public SettableBeanProperty withMutator(BeanPropertyMutator mut) {
43 | return new SettableObjectMethodProperty(_originalSettable, mut, _optimizedIndex);
44 | }
45 |
46 | /*
47 | /**********************************************************************
48 | /* Deserialization
49 | /**********************************************************************
50 | */
51 |
52 | @Override
53 | public void deserializeAndSet(JsonParser p, DeserializationContext ctxt,
54 | Object bean) throws IOException {
55 | set(bean, deserialize(p, ctxt));
56 | }
57 |
58 | @Override
59 | public void set(Object bean, Object value) throws IOException {
60 | _propertyMutator.objectSetter(bean, value);
61 | }
62 |
63 | @Override
64 | public Object deserializeSetAndReturn(JsonParser p,
65 | DeserializationContext ctxt, Object instance) throws IOException {
66 | return setAndReturn(instance, deserialize(p, ctxt));
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableStringFieldProperty.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.deser;
2 |
3 | import java.io.IOException;
4 |
5 | import com.fasterxml.jackson.core.*;
6 | import com.fasterxml.jackson.databind.*;
7 | import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
8 |
9 | public final class SettableStringFieldProperty
10 | extends OptimizedSettableBeanProperty
11 | {
12 | private static final long serialVersionUID = 1L;
13 |
14 | public SettableStringFieldProperty(SettableBeanProperty src,
15 | BeanPropertyMutator mutator, int index)
16 | {
17 | super(src, mutator, index);
18 | }
19 |
20 | public SettableStringFieldProperty(SettableStringFieldProperty src, JsonDeserializer> deser) {
21 | super(src, deser);
22 | }
23 |
24 | public SettableStringFieldProperty(SettableStringFieldProperty src, PropertyName name) {
25 | super(src, name);
26 | }
27 |
28 | @Override
29 | public SettableBeanProperty withName(PropertyName name) {
30 | return new SettableStringFieldProperty(this, name);
31 | }
32 |
33 | @Override
34 | public SettableBeanProperty withValueDeserializer(JsonDeserializer> deser) {
35 | if (!_isDefaultDeserializer(deser)) {
36 | return _originalSettable.withValueDeserializer(deser);
37 | }
38 | return new SettableStringFieldProperty(this, deser);
39 | }
40 |
41 | @Override
42 | public SettableBeanProperty withMutator(BeanPropertyMutator mut) {
43 | return new SettableStringFieldProperty(_originalSettable, mut, _optimizedIndex);
44 | }
45 |
46 | /*
47 | /**********************************************************************
48 | /* Deserialization
49 | /**********************************************************************
50 | */
51 |
52 | @Override
53 | public void deserializeAndSet(JsonParser p, DeserializationContext ctxt,
54 | Object bean) throws IOException
55 | {
56 | String text = p.getValueAsString();
57 | if (text == null) {
58 | text = _deserializeString(p, ctxt);
59 | }
60 | _propertyMutator.stringField(bean, text);
61 | }
62 |
63 | @Override
64 | public void set(Object bean, Object value) throws IOException {
65 | _propertyMutator.stringField(bean, (String) value);
66 | }
67 |
68 | @Override
69 | public Object deserializeSetAndReturn(JsonParser p, DeserializationContext ctxt, Object instance)
70 | throws IOException
71 | {
72 | String text = p.getValueAsString();
73 | if (text == null) {
74 | text = _deserializeString(p, ctxt);
75 | }
76 | return setAndReturn(instance, text);
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableStringMethodProperty.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.deser;
2 |
3 | import java.io.IOException;
4 |
5 | import com.fasterxml.jackson.core.*;
6 | import com.fasterxml.jackson.databind.*;
7 | import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
8 |
9 | public final class SettableStringMethodProperty
10 | extends OptimizedSettableBeanProperty
11 | {
12 | private static final long serialVersionUID = 1L;
13 |
14 | public SettableStringMethodProperty(SettableBeanProperty src,
15 | BeanPropertyMutator mutator, int index)
16 | {
17 | super(src, mutator, index);
18 | }
19 |
20 | public SettableStringMethodProperty(SettableStringMethodProperty src, JsonDeserializer> deser) {
21 | super(src, deser);
22 | }
23 |
24 | public SettableStringMethodProperty(SettableStringMethodProperty src, PropertyName name) {
25 | super(src, name);
26 | }
27 |
28 | @Override
29 | public SettableBeanProperty withName(PropertyName name) {
30 | return new SettableStringMethodProperty(this, name);
31 | }
32 |
33 | @Override
34 | public SettableBeanProperty withValueDeserializer(JsonDeserializer> deser) {
35 | if (!_isDefaultDeserializer(deser)) {
36 | return _originalSettable.withValueDeserializer(deser);
37 | }
38 | return new SettableStringMethodProperty(this, deser);
39 | }
40 |
41 | @Override
42 | public SettableBeanProperty withMutator(BeanPropertyMutator mut) {
43 | return new SettableStringMethodProperty(_originalSettable, mut, _optimizedIndex);
44 | }
45 |
46 | /*
47 | /**********************************************************************
48 | /* Deserialization
49 | /**********************************************************************
50 | */
51 |
52 | // Copied from StdDeserializer.StringDeserializer:
53 | @Override
54 | public void deserializeAndSet(JsonParser p, DeserializationContext ctxt, Object bean) throws IOException
55 | {
56 | String text = p.getValueAsString();
57 | if (text == null) {
58 | text = _deserializeString(p, ctxt);
59 | }
60 | _propertyMutator.stringSetter(bean, text);
61 | }
62 |
63 | @Override
64 | public void set(Object bean, Object value) throws IOException {
65 | _propertyMutator.stringSetter(bean, (String) value);
66 | }
67 |
68 | @Override
69 | public Object deserializeSetAndReturn(JsonParser p, DeserializationContext ctxt, Object instance) throws IOException
70 | {
71 | String text = p.getValueAsString();
72 | if (text == null) {
73 | text = _deserializeString(p, ctxt);
74 | }
75 | return setAndReturn(instance, text);
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SuperSonicDeserializerBuilder.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.deser;
2 |
3 | import java.util.*;
4 |
5 | import com.fasterxml.jackson.databind.JsonDeserializer;
6 | import com.fasterxml.jackson.databind.deser.*;
7 |
8 | public class SuperSonicDeserializerBuilder extends BeanDeserializerBuilder
9 | {
10 | public SuperSonicDeserializerBuilder(BeanDeserializerBuilder base) {
11 | super(base);
12 | }
13 |
14 | @Override
15 | public JsonDeserializer> build()
16 | {
17 | BeanDeserializer deser = (BeanDeserializer) super.build();
18 | // only create custom one, if existing one is standard deserializer;
19 | if (deser.getClass() == BeanDeserializer.class) {
20 | BeanDeserializer beanDeser = (BeanDeserializer) deser;
21 | Iterator it = getProperties();
22 | // also: only build custom one for non-empty beans:
23 | if (it.hasNext()) {
24 | // So let's find actual order of properties, necessary for optimal access
25 | ArrayList props = new ArrayList();
26 | do {
27 | props.add(it.next());
28 | } while (it.hasNext());
29 | return new SuperSonicBeanDeserializer(beanDeser, props);
30 | }
31 | }
32 | return deser;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/com/fasterxml/jackson/module/afterburner/ser/BeanPropertyAccessor.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.ser;
2 |
3 | /**
4 | * Abstract class that defines interface for implementations
5 | * that can be used for proxy-like access without using
6 | * Reflection.
7 | */
8 | public abstract class BeanPropertyAccessor
9 | {
10 | /** @since 2.5 */
11 | public boolean booleanGetter(Object bean, int property) {
12 | throw new UnsupportedOperationException("No booleanGetters defined");
13 | }
14 | public int intGetter(Object bean, int property) {
15 | throw new UnsupportedOperationException("No intGetters defined");
16 | }
17 | public long longGetter(Object bean, int property) {
18 | throw new UnsupportedOperationException("No longGetters defined");
19 | }
20 | public String stringGetter(Object bean, int property) {
21 | throw new UnsupportedOperationException("No stringGetters defined");
22 | }
23 | public Object objectGetter(Object bean, int property) {
24 | throw new UnsupportedOperationException("No objectGetters defined");
25 | }
26 |
27 | /** @since 2.5 */
28 | public boolean booleanField(Object bean, int property) {
29 | throw new UnsupportedOperationException("No booleanFields defined");
30 | }
31 | public int intField(Object bean, int property) {
32 | throw new UnsupportedOperationException("No intFields defined");
33 | }
34 | public long longField(Object bean, int property) {
35 | throw new UnsupportedOperationException("No longFields defined");
36 | }
37 | public String stringField(Object bean, int property) {
38 | throw new UnsupportedOperationException("No stringFields defined");
39 | }
40 | public Object objectField(Object bean, int property) {
41 | throw new UnsupportedOperationException("No objectFields defined");
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/com/fasterxml/jackson/module/afterburner/ser/BooleanFieldPropertyWriter.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.ser;
2 |
3 | import com.fasterxml.jackson.core.JsonGenerator;
4 | import com.fasterxml.jackson.databind.JsonSerializer;
5 | import com.fasterxml.jackson.databind.SerializerProvider;
6 | import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
7 |
8 | public final class BooleanFieldPropertyWriter
9 | extends OptimizedBeanPropertyWriter
10 | {
11 | private static final long serialVersionUID = 1L;
12 |
13 | private final boolean _suppressableSet;
14 | private final boolean _suppressableBoolean;
15 |
16 | public BooleanFieldPropertyWriter(BeanPropertyWriter src, BeanPropertyAccessor acc, int index,
17 | JsonSerializer ser) {
18 | super(src, acc, index, ser);
19 |
20 | if (_suppressableValue instanceof Boolean) {
21 | _suppressableBoolean = ((Boolean)_suppressableValue).booleanValue();
22 | _suppressableSet = true;
23 | } else {
24 | _suppressableBoolean = false;
25 | _suppressableSet = false;
26 | }
27 | }
28 |
29 | @Override
30 | public BeanPropertyWriter withSerializer(JsonSerializer ser) {
31 | return new BooleanFieldPropertyWriter(this, _propertyAccessor, _propertyIndex, ser);
32 | }
33 |
34 | @Override
35 | public BooleanFieldPropertyWriter withAccessor(BeanPropertyAccessor acc) {
36 | if (acc == null) throw new IllegalArgumentException();
37 | return new BooleanFieldPropertyWriter(this, acc, _propertyIndex, _serializer);
38 | }
39 |
40 | /*
41 | /**********************************************************
42 | /* Overrides
43 | /**********************************************************
44 | */
45 |
46 | @Override
47 | public final void serializeAsField(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception
48 | {
49 | if (broken) {
50 | fallbackWriter.serializeAsField(bean, gen, prov);
51 | return;
52 | }
53 | boolean value;
54 | try {
55 | value = _propertyAccessor.booleanField(bean, _propertyIndex);
56 | } catch (Throwable t) {
57 | _handleProblem(bean, gen, prov, t, false);
58 | return;
59 | }
60 | if (!_suppressableSet || _suppressableBoolean != value) {
61 | gen.writeFieldName(_fastName);
62 | gen.writeBoolean(value);
63 | }
64 | }
65 |
66 | @Override
67 | public final void serializeAsElement(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception
68 | {
69 | if (broken) {
70 | fallbackWriter.serializeAsElement(bean, gen, prov);
71 | return;
72 | }
73 | boolean value;
74 | try {
75 | value = _propertyAccessor.booleanField(bean, _propertyIndex);
76 | } catch (Throwable t) {
77 | _handleProblem(bean, gen, prov, t, true);
78 | return;
79 | }
80 | if (!_suppressableSet || _suppressableBoolean != value) {
81 | gen.writeBoolean(value);
82 | } else { // important: MUST output a placeholder
83 | serializeAsPlaceholder(bean, gen, prov);
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/main/java/com/fasterxml/jackson/module/afterburner/ser/BooleanMethodPropertyWriter.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.ser;
2 |
3 | import com.fasterxml.jackson.core.JsonGenerator;
4 | import com.fasterxml.jackson.databind.JsonSerializer;
5 | import com.fasterxml.jackson.databind.SerializerProvider;
6 | import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
7 |
8 | public final class BooleanMethodPropertyWriter
9 | extends OptimizedBeanPropertyWriter
10 | {
11 | private static final long serialVersionUID = 1L;
12 |
13 | private final boolean _suppressableSet;
14 | private final boolean _suppressableBoolean;
15 |
16 | public BooleanMethodPropertyWriter(BeanPropertyWriter src, BeanPropertyAccessor acc, int index,
17 | JsonSerializer ser) {
18 | super(src, acc, index, ser);
19 |
20 | if (_suppressableValue instanceof Boolean) {
21 | _suppressableBoolean = ((Boolean)_suppressableValue).booleanValue();
22 | _suppressableSet = true;
23 | } else {
24 | _suppressableBoolean = false;
25 | _suppressableSet = false;
26 | }
27 | }
28 |
29 | @Override
30 | public BeanPropertyWriter withSerializer(JsonSerializer ser) {
31 | return new BooleanMethodPropertyWriter(this, _propertyAccessor, _propertyIndex, ser);
32 | }
33 |
34 | @Override
35 | public BooleanMethodPropertyWriter withAccessor(BeanPropertyAccessor acc) {
36 | if (acc == null) throw new IllegalArgumentException();
37 | return new BooleanMethodPropertyWriter(this, acc, _propertyIndex, _serializer);
38 | }
39 |
40 | /*
41 | /**********************************************************
42 | /* Overrides
43 | /**********************************************************
44 | */
45 |
46 | @Override
47 | public final void serializeAsField(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception
48 | {
49 | if (broken) {
50 | fallbackWriter.serializeAsField(bean, gen, prov);
51 | return;
52 | }
53 | boolean value;
54 | try {
55 | value = _propertyAccessor.booleanGetter(bean, _propertyIndex);
56 | } catch (Throwable t) {
57 | _handleProblem(bean, gen, prov, t, false);
58 | return;
59 | }
60 | if (!_suppressableSet || _suppressableBoolean != value) {
61 | gen.writeFieldName(_fastName);
62 | gen.writeBoolean(value);
63 | }
64 | }
65 |
66 | @Override
67 | public final void serializeAsElement(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception
68 | {
69 | if (broken) {
70 | fallbackWriter.serializeAsElement(bean, gen, prov);
71 | return;
72 | }
73 | boolean value;
74 | try {
75 | value = _propertyAccessor.booleanGetter(bean, _propertyIndex);
76 | } catch (Throwable t) {
77 | _handleProblem(bean, gen, prov, t, true);
78 | return;
79 | }
80 | if (!_suppressableSet || _suppressableBoolean != value) {
81 | gen.writeBoolean(value);
82 | } else { // important: MUST output a placeholder
83 | serializeAsPlaceholder(bean, gen, prov);
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/main/java/com/fasterxml/jackson/module/afterburner/ser/IntFieldPropertyWriter.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.ser;
2 |
3 | import com.fasterxml.jackson.core.JsonGenerator;
4 | import com.fasterxml.jackson.databind.JsonSerializer;
5 | import com.fasterxml.jackson.databind.SerializerProvider;
6 | import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
7 |
8 | public final class IntFieldPropertyWriter
9 | extends OptimizedBeanPropertyWriter
10 | {
11 | private static final long serialVersionUID = 1L;
12 |
13 | private final int _suppressableInt;
14 | private final boolean _suppressableIntSet;
15 |
16 | public IntFieldPropertyWriter(BeanPropertyWriter src, BeanPropertyAccessor acc, int index,
17 | JsonSerializer ser) {
18 | super(src, acc, index, ser);
19 |
20 | if (_suppressableValue instanceof Integer) {
21 | _suppressableInt = ((Integer)_suppressableValue).intValue();
22 | _suppressableIntSet = true;
23 | } else {
24 | _suppressableInt = 0;
25 | _suppressableIntSet = false;
26 | }
27 | }
28 |
29 | @Override
30 | public BeanPropertyWriter withSerializer(JsonSerializer ser) {
31 | return new IntFieldPropertyWriter(this, _propertyAccessor, _propertyIndex, ser);
32 | }
33 |
34 | @Override
35 | public IntFieldPropertyWriter withAccessor(BeanPropertyAccessor acc) {
36 | if (acc == null) throw new IllegalArgumentException();
37 | return new IntFieldPropertyWriter(this, acc, _propertyIndex, _serializer);
38 | }
39 |
40 | /*
41 | /**********************************************************
42 | /* Overrides
43 | /**********************************************************
44 | */
45 |
46 | @Override
47 | public final void serializeAsField(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception
48 | {
49 | if (broken) {
50 | fallbackWriter.serializeAsField(bean, gen, prov);
51 | return;
52 | }
53 | int value;
54 | try {
55 | value = _propertyAccessor.intField(bean, _propertyIndex);
56 | } catch (Throwable t) {
57 | _handleProblem(bean, gen, prov, t, false);
58 | return;
59 | }
60 | if (!_suppressableIntSet || _suppressableInt != value) {
61 | gen.writeFieldName(_fastName);
62 | gen.writeNumber(value);
63 | }
64 | }
65 |
66 | @Override
67 | public final void serializeAsElement(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception
68 | {
69 | if (broken) {
70 | fallbackWriter.serializeAsElement(bean, gen, prov);
71 | return;
72 | }
73 | int value;
74 | try {
75 | value = _propertyAccessor.intField(bean, _propertyIndex);
76 | } catch (Throwable t) {
77 | _handleProblem(bean, gen, prov, t, true);
78 | return;
79 | }
80 | if (!_suppressableIntSet || _suppressableInt != value) {
81 | gen.writeNumber(value);
82 | } else { // important: MUST output a placeholder
83 | serializeAsPlaceholder(bean, gen, prov);
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/main/java/com/fasterxml/jackson/module/afterburner/ser/IntMethodPropertyWriter.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.ser;
2 |
3 | import com.fasterxml.jackson.core.JsonGenerator;
4 | import com.fasterxml.jackson.databind.JsonSerializer;
5 | import com.fasterxml.jackson.databind.SerializerProvider;
6 | import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
7 |
8 | public final class IntMethodPropertyWriter
9 | extends OptimizedBeanPropertyWriter
10 | {
11 | private static final long serialVersionUID = 1L;
12 |
13 | private final int _suppressableInt;
14 | private final boolean _suppressableIntSet;
15 |
16 | public IntMethodPropertyWriter(BeanPropertyWriter src, BeanPropertyAccessor acc, int index,
17 | JsonSerializer ser) {
18 | super(src, acc, index, ser);
19 |
20 | if (_suppressableValue instanceof Integer) {
21 | _suppressableInt = (Integer)_suppressableValue;
22 | _suppressableIntSet = true;
23 | } else {
24 | _suppressableInt = 0;
25 | _suppressableIntSet = false;
26 | }
27 | }
28 |
29 | @Override
30 | public BeanPropertyWriter withSerializer(JsonSerializer ser) {
31 | return new IntMethodPropertyWriter(this, _propertyAccessor, _propertyIndex, ser);
32 | }
33 |
34 | @Override
35 | public IntMethodPropertyWriter withAccessor(BeanPropertyAccessor acc) {
36 | if (acc == null) throw new IllegalArgumentException();
37 | return new IntMethodPropertyWriter(this, acc, _propertyIndex, _serializer);
38 | }
39 |
40 | /*
41 | /**********************************************************
42 | /* Overrides
43 | /**********************************************************
44 | */
45 |
46 | @Override
47 | public final void serializeAsField(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception
48 | {
49 | if (broken) {
50 | fallbackWriter.serializeAsField(bean, gen, prov);
51 | return;
52 | }
53 | int value;
54 | try {
55 | value = _propertyAccessor.intGetter(bean, _propertyIndex);
56 | } catch (Throwable t) {
57 | _handleProblem(bean, gen, prov, t, false);
58 | return;
59 | }
60 | if (!_suppressableIntSet || _suppressableInt != value) {
61 | gen.writeFieldName(_fastName);
62 | gen.writeNumber(value);
63 | }
64 | }
65 |
66 | @Override
67 | public final void serializeAsElement(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception
68 | {
69 | if (broken) {
70 | fallbackWriter.serializeAsElement(bean, gen, prov);
71 | return;
72 | }
73 | int value;
74 | try {
75 | value = _propertyAccessor.intGetter(bean, _propertyIndex);
76 | } catch (Throwable t) {
77 | _handleProblem(bean, gen, prov, t, true);
78 | return;
79 | }
80 | if (!_suppressableIntSet || _suppressableInt != value) {
81 | gen.writeNumber(value);
82 | } else { // important: MUST output a placeholder
83 | serializeAsPlaceholder(bean, gen, prov);
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/main/java/com/fasterxml/jackson/module/afterburner/ser/LongFieldPropertyWriter.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.ser;
2 |
3 | import com.fasterxml.jackson.core.JsonGenerator;
4 | import com.fasterxml.jackson.databind.JsonSerializer;
5 | import com.fasterxml.jackson.databind.SerializerProvider;
6 | import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
7 |
8 | public final class LongFieldPropertyWriter
9 | extends OptimizedBeanPropertyWriter
10 | {
11 | private static final long serialVersionUID = 1L;
12 |
13 | private final long _suppressableLong;
14 | private final boolean _suppressableLongSet;
15 |
16 | public LongFieldPropertyWriter(BeanPropertyWriter src, BeanPropertyAccessor acc, int index,
17 | JsonSerializer ser) {
18 | super(src, acc, index, ser);
19 |
20 | if (_suppressableValue instanceof Long) {
21 | _suppressableLong = (Long)_suppressableValue;
22 | _suppressableLongSet = true;
23 | } else {
24 | _suppressableLong = 0L;
25 | _suppressableLongSet = false;
26 | }
27 | }
28 |
29 | @Override
30 | public BeanPropertyWriter withSerializer(JsonSerializer ser) {
31 | return new LongFieldPropertyWriter(this, _propertyAccessor, _propertyIndex, ser);
32 | }
33 |
34 | @Override
35 | public LongFieldPropertyWriter withAccessor(BeanPropertyAccessor acc) {
36 | if (acc == null) throw new IllegalArgumentException();
37 | return new LongFieldPropertyWriter(this, acc, _propertyIndex, _serializer);
38 | }
39 |
40 | /*
41 | /**********************************************************
42 | /* Overrides
43 | /**********************************************************
44 | */
45 |
46 | @Override
47 | public final void serializeAsField(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception
48 | {
49 | if (broken) {
50 | fallbackWriter.serializeAsField(bean, gen, prov);
51 | return;
52 | }
53 | long value;
54 | try {
55 | value = _propertyAccessor.longField(bean, _propertyIndex);
56 | } catch (Throwable t) {
57 | _handleProblem(bean, gen, prov, t, false);
58 | return;
59 | }
60 | if (!_suppressableLongSet || _suppressableLong != value) {
61 | gen.writeFieldName(_fastName);
62 | gen.writeNumber(value);
63 | }
64 | }
65 |
66 | @Override
67 | public final void serializeAsElement(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception
68 | {
69 | if (broken) {
70 | fallbackWriter.serializeAsElement(bean, gen, prov);
71 | return;
72 | }
73 | long value;
74 | try {
75 | value = _propertyAccessor.longField(bean, _propertyIndex);
76 | } catch (Throwable t) {
77 | _handleProblem(bean, gen, prov, t, false);
78 | return;
79 | }
80 | if (!_suppressableLongSet || _suppressableLong != value) {
81 | gen.writeNumber(value);
82 | } else { // important: MUST output a placeholder
83 | serializeAsPlaceholder(bean, gen, prov);
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/main/java/com/fasterxml/jackson/module/afterburner/ser/LongMethodPropertyWriter.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.ser;
2 |
3 | import com.fasterxml.jackson.core.JsonGenerator;
4 | import com.fasterxml.jackson.databind.JsonSerializer;
5 | import com.fasterxml.jackson.databind.SerializerProvider;
6 | import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
7 |
8 | public final class LongMethodPropertyWriter
9 | extends OptimizedBeanPropertyWriter
10 | {
11 | private static final long serialVersionUID = 1L;
12 |
13 | private final long _suppressableLong;
14 | private final boolean _suppressableLongSet;
15 |
16 | public LongMethodPropertyWriter(BeanPropertyWriter src, BeanPropertyAccessor acc, int index,
17 | JsonSerializer ser) {
18 | super(src, acc, index, ser);
19 |
20 | if (_suppressableValue instanceof Long) {
21 | _suppressableLong = (Long)_suppressableValue;
22 | _suppressableLongSet = true;
23 | } else {
24 | _suppressableLong = 0L;
25 | _suppressableLongSet = false;
26 | }
27 | }
28 |
29 | @Override
30 | public BeanPropertyWriter withSerializer(JsonSerializer ser) {
31 | return new LongMethodPropertyWriter(this, _propertyAccessor, _propertyIndex, ser);
32 | }
33 |
34 | @Override
35 | public LongMethodPropertyWriter withAccessor(BeanPropertyAccessor acc) {
36 | if (acc == null) throw new IllegalArgumentException();
37 | return new LongMethodPropertyWriter(this, acc, _propertyIndex, _serializer);
38 | }
39 |
40 | /*
41 | /**********************************************************
42 | /* Overrides
43 | /**********************************************************
44 | */
45 |
46 | @Override
47 | public final void serializeAsField(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception
48 | {
49 | if (broken) {
50 | fallbackWriter.serializeAsField(bean, gen, prov);
51 | return;
52 | }
53 | long value;
54 | try {
55 | value = _propertyAccessor.longGetter(bean, _propertyIndex);
56 | } catch (Throwable t) {
57 | _handleProblem(bean, gen, prov, t, false);
58 | return;
59 | }
60 | if (!_suppressableLongSet || _suppressableLong != value) {
61 | gen.writeFieldName(_fastName);
62 | gen.writeNumber(value);
63 | }
64 | }
65 |
66 | @Override
67 | public final void serializeAsElement(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception
68 | {
69 | if (broken) {
70 | fallbackWriter.serializeAsElement(bean, gen, prov);
71 | return;
72 | }
73 | long value;
74 | try {
75 | value = _propertyAccessor.longGetter(bean, _propertyIndex);
76 | } catch (Throwable t) {
77 | _handleProblem(bean, gen, prov, t, true);
78 | return;
79 | }
80 | if (!_suppressableLongSet || _suppressableLong != value) {
81 | gen.writeNumber(value);
82 | } else { // important: MUST output a placeholder
83 | serializeAsPlaceholder(bean, gen, prov);
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/main/java/com/fasterxml/jackson/module/afterburner/ser/ObjectFieldPropertyWriter.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.ser;
2 |
3 | import com.fasterxml.jackson.core.JsonGenerator;
4 | import com.fasterxml.jackson.databind.JsonSerializer;
5 | import com.fasterxml.jackson.databind.SerializerProvider;
6 | import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
7 | import com.fasterxml.jackson.databind.ser.impl.PropertySerializerMap;
8 |
9 | public class ObjectFieldPropertyWriter
10 | extends OptimizedBeanPropertyWriter
11 | {
12 | private static final long serialVersionUID = 1L;
13 |
14 | public ObjectFieldPropertyWriter(BeanPropertyWriter src, BeanPropertyAccessor acc, int index,
15 | JsonSerializer ser) {
16 | super(src, acc, index, ser);
17 | }
18 |
19 | @Override
20 | public BeanPropertyWriter withSerializer(JsonSerializer ser) {
21 | return new ObjectFieldPropertyWriter(this, _propertyAccessor, _propertyIndex, ser);
22 | }
23 |
24 | @Override
25 | public ObjectFieldPropertyWriter withAccessor(BeanPropertyAccessor acc) {
26 | if (acc == null) throw new IllegalArgumentException();
27 | return new ObjectFieldPropertyWriter(this, acc, _propertyIndex, _serializer);
28 | }
29 |
30 | /*
31 | /**********************************************************
32 | /* Overrides
33 | /**********************************************************
34 | */
35 |
36 | @Override
37 | public final void serializeAsField(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception
38 | {
39 | if (broken) {
40 | fallbackWriter.serializeAsField(bean, gen, prov);
41 | return;
42 | }
43 | Object value;
44 | try {
45 | value = _propertyAccessor.objectField(bean, _propertyIndex);
46 | } catch (Throwable t) {
47 | _handleProblem(bean, gen, prov, t, false);
48 | return;
49 | }
50 | // Null (etc) handling; copied from super-class impl
51 | if (value == null) {
52 | if (_nullSerializer != null) {
53 | gen.writeFieldName(_fastName);
54 | _nullSerializer.serialize(null, gen, prov);
55 | } else if (!_suppressNulls) {
56 | gen.writeFieldName(_fastName);
57 | prov.defaultSerializeNull(gen);
58 | }
59 | return;
60 | }
61 | JsonSerializer ser = _serializer;
62 | if (ser == null) {
63 | Class> cls = value.getClass();
64 | PropertySerializerMap map = _dynamicSerializers;
65 | ser = map.serializerFor(cls);
66 | if (ser == null) {
67 | ser = _findAndAddDynamic(map, cls, prov);
68 | }
69 | }
70 | if (_suppressableValue != null) {
71 | if (MARKER_FOR_EMPTY == _suppressableValue) {
72 | if (ser.isEmpty(prov, value)) {
73 | return;
74 | }
75 | } else if (_suppressableValue.equals(value)) {
76 | return;
77 | }
78 | }
79 | if (value == bean) {
80 | // three choices: exception; handled by call; or pass-through
81 | if (_handleSelfReference(bean, gen, prov, ser)) {
82 | return;
83 | }
84 | }
85 | gen.writeFieldName(_fastName);
86 | if (_typeSerializer == null) {
87 | ser.serialize(value, gen, prov);
88 | } else {
89 | ser.serializeWithType(value, gen, prov, _typeSerializer);
90 | }
91 | }
92 |
93 | @Override
94 | public final void serializeAsElement(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception
95 | {
96 | if (broken) {
97 | fallbackWriter.serializeAsElement(bean, gen, prov);
98 | return;
99 | }
100 | Object value;
101 | try {
102 | value = _propertyAccessor.objectField(bean, _propertyIndex);
103 | } catch (Throwable t) {
104 | _handleProblem(bean, gen, prov, t, true);
105 | return;
106 | }
107 | if (value == null) {
108 | if (_nullSerializer != null) {
109 | _nullSerializer.serialize(null, gen, prov);
110 | } else if (_suppressNulls) {
111 | serializeAsPlaceholder(bean, gen, prov);
112 | } else {
113 | prov.defaultSerializeNull(gen);
114 | }
115 | return;
116 | }
117 | JsonSerializer ser = _serializer;
118 | if (ser == null) {
119 | Class> cls = value.getClass();
120 | PropertySerializerMap map = _dynamicSerializers;
121 | ser = map.serializerFor(cls);
122 | if (ser == null) {
123 | ser = _findAndAddDynamic(map, cls, prov);
124 | }
125 | }
126 | if (_suppressableValue != null) {
127 | if (MARKER_FOR_EMPTY == _suppressableValue) {
128 | if (ser.isEmpty(prov, value)) {
129 | serializeAsPlaceholder(bean, gen, prov);
130 | return;
131 | }
132 | } else if (_suppressableValue.equals(value)) {
133 | serializeAsPlaceholder(bean, gen, prov);
134 | return;
135 | }
136 | }
137 | if (value == bean) {
138 | // three choices: exception; handled by call; or pass-through
139 | if (_handleSelfReference(bean, gen, prov, ser)) {
140 | return;
141 | }
142 | }
143 | if (_typeSerializer == null) {
144 | ser.serialize(value, gen, prov);
145 | } else {
146 | ser.serializeWithType(value, gen, prov, _typeSerializer);
147 | }
148 | }
149 | }
150 |
--------------------------------------------------------------------------------
/src/main/java/com/fasterxml/jackson/module/afterburner/ser/ObjectMethodPropertyWriter.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.ser;
2 |
3 | import com.fasterxml.jackson.core.JsonGenerator;
4 | import com.fasterxml.jackson.databind.JsonSerializer;
5 | import com.fasterxml.jackson.databind.SerializerProvider;
6 | import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
7 | import com.fasterxml.jackson.databind.ser.impl.PropertySerializerMap;
8 |
9 | public class ObjectMethodPropertyWriter
10 | extends OptimizedBeanPropertyWriter
11 | {
12 | private static final long serialVersionUID = 1L;
13 |
14 | public ObjectMethodPropertyWriter(BeanPropertyWriter src, BeanPropertyAccessor acc, int index,
15 | JsonSerializer ser) {
16 | super(src, acc, index, ser);
17 | }
18 |
19 | @Override
20 | public BeanPropertyWriter withSerializer(JsonSerializer ser) {
21 | return new ObjectMethodPropertyWriter(this, _propertyAccessor, _propertyIndex, ser);
22 | }
23 |
24 | @Override
25 | public ObjectMethodPropertyWriter withAccessor(BeanPropertyAccessor acc) {
26 | if (acc == null) throw new IllegalArgumentException();
27 | return new ObjectMethodPropertyWriter(this, acc, _propertyIndex, _serializer);
28 | }
29 |
30 | /*
31 | /**********************************************************
32 | /* Overrides
33 | /**********************************************************
34 | */
35 |
36 | @Override
37 | public final void serializeAsField(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception
38 | {
39 | if (broken) {
40 | fallbackWriter.serializeAsField(bean, gen, prov);
41 | return;
42 | }
43 | Object value;
44 | try {
45 | value = _propertyAccessor.objectGetter(bean, _propertyIndex);
46 | } catch (Throwable t) {
47 | _handleProblem(bean, gen, prov, t, false);
48 | return;
49 | }
50 | // Null (etc) handling; copied from super-class impl
51 | if (value == null) {
52 | if (_nullSerializer != null) {
53 | gen.writeFieldName(_fastName);
54 | _nullSerializer.serialize(null, gen, prov);
55 | } else if (!_suppressNulls) {
56 | gen.writeFieldName(_fastName);
57 | prov.defaultSerializeNull(gen);
58 | }
59 | return;
60 | }
61 | JsonSerializer ser = _serializer;
62 | if (ser == null) {
63 | Class> cls = value.getClass();
64 | PropertySerializerMap map = _dynamicSerializers;
65 | ser = map.serializerFor(cls);
66 | if (ser == null) {
67 | ser = _findAndAddDynamic(map, cls, prov);
68 | }
69 | }
70 | if (_suppressableValue != null) {
71 | if (MARKER_FOR_EMPTY == _suppressableValue) {
72 | if (ser.isEmpty(prov, value)) {
73 | return;
74 | }
75 | } else if (_suppressableValue.equals(value)) {
76 | return;
77 | }
78 | }
79 | if (value == bean) {
80 | // three choices: exception; handled by call; or pass-through
81 | if (_handleSelfReference(bean, gen, prov, ser)) {
82 | return;
83 | }
84 | }
85 | gen.writeFieldName(_fastName);
86 | if (_typeSerializer == null) {
87 | ser.serialize(value, gen, prov);
88 | } else {
89 | ser.serializeWithType(value, gen, prov, _typeSerializer);
90 | }
91 | }
92 |
93 | @Override
94 | public final void serializeAsElement(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception
95 | {
96 | if (broken) {
97 | fallbackWriter.serializeAsElement(bean, gen, prov);
98 | return;
99 | }
100 | Object value;
101 | try {
102 | value = _propertyAccessor.objectGetter(bean, _propertyIndex);
103 | } catch (Throwable t) {
104 | _handleProblem(bean, gen, prov, t, true);
105 | return;
106 | }
107 | // Null (etc) handling; copied from super-class impl
108 | if (value == null) {
109 | if (_nullSerializer != null) {
110 | _nullSerializer.serialize(null, gen, prov);
111 | } else if (_suppressNulls) {
112 | serializeAsPlaceholder(bean, gen, prov);
113 | } else {
114 | prov.defaultSerializeNull(gen);
115 | }
116 | return;
117 | }
118 | JsonSerializer ser = _serializer;
119 | if (ser == null) {
120 | Class> cls = value.getClass();
121 | PropertySerializerMap map = _dynamicSerializers;
122 | ser = map.serializerFor(cls);
123 | if (ser == null) {
124 | ser = _findAndAddDynamic(map, cls, prov);
125 | }
126 | }
127 | if (_suppressableValue != null) {
128 | if (MARKER_FOR_EMPTY == _suppressableValue) {
129 | if (ser.isEmpty(prov, value)) {
130 | serializeAsPlaceholder(bean, gen, prov);
131 | return;
132 | }
133 | } else if (_suppressableValue.equals(value)) {
134 | serializeAsPlaceholder(bean, gen, prov);
135 | return;
136 | }
137 | }
138 | if (value == bean) {
139 | // three choices: exception; handled by call; or pass-through
140 | if (_handleSelfReference(bean, gen, prov, ser)) {
141 | return;
142 | }
143 | }
144 | if (_typeSerializer == null) {
145 | ser.serialize(value, gen, prov);
146 | } else {
147 | ser.serializeWithType(value, gen, prov, _typeSerializer);
148 | }
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/src/main/java/com/fasterxml/jackson/module/afterburner/ser/OptimizedBeanPropertyWriter.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.ser;
2 |
3 | import java.util.logging.Level;
4 | import java.util.logging.Logger;
5 |
6 | import com.fasterxml.jackson.core.JsonGenerator;
7 | import com.fasterxml.jackson.core.SerializableString;
8 |
9 | import com.fasterxml.jackson.databind.*;
10 | import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
11 | import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
12 | import com.fasterxml.jackson.databind.util.ClassUtil;
13 |
14 | /**
15 | * Intermediate base class that is used for concrete
16 | * per-type implementations
17 | */
18 | @SuppressWarnings("serial")
19 | abstract class OptimizedBeanPropertyWriter>
20 | extends BeanPropertyWriter
21 | {
22 | protected final BeanPropertyAccessor _propertyAccessor;
23 |
24 | /**
25 | * Locally stored version of efficiently serializable name.
26 | * Used to work around earlier problems with typing between
27 | * interface, implementation
28 | *
29 | * @since 2.5
30 | */
31 | protected final SerializableString _fastName;
32 | protected final int _propertyIndex;
33 |
34 | protected final BeanPropertyWriter fallbackWriter;
35 | // Not volatile to prevent overhead, worst case is we trip the exception a few extra times
36 | protected boolean broken = false;
37 |
38 | protected OptimizedBeanPropertyWriter(BeanPropertyWriter src,
39 | BeanPropertyAccessor propertyAccessor, int propertyIndex,
40 | JsonSerializer ser)
41 | {
42 | super(src);
43 | this.fallbackWriter = unwrapFallbackWriter(src);
44 | // either use the passed on serializer or the original one
45 | _serializer = (ser != null) ? ser : src.getSerializer();
46 | _propertyAccessor = propertyAccessor;
47 | _propertyIndex = propertyIndex;
48 | _fastName = src.getSerializedName();
49 | }
50 |
51 | private BeanPropertyWriter unwrapFallbackWriter(BeanPropertyWriter srcIn)
52 | {
53 | while (srcIn instanceof OptimizedBeanPropertyWriter) {
54 | srcIn = ((OptimizedBeanPropertyWriter>)srcIn).fallbackWriter;
55 | }
56 | return srcIn;
57 | }
58 |
59 | // Overridden since 2.6.3
60 | @Override
61 | public void assignTypeSerializer(TypeSerializer typeSer) {
62 | super.assignTypeSerializer(typeSer);
63 | if (fallbackWriter != null) {
64 | fallbackWriter.assignTypeSerializer(typeSer);
65 | }
66 | // 04-Oct-2015, tatu: Should we handle this wrt [module-afterburner#59]?
67 | // Seems unlikely, as String/long/int/boolean are final types; and for
68 | // basic 'Object' we delegate to deserializer as expected
69 | }
70 |
71 | // Overridden since 2.6.3
72 | @Override
73 | public void assignSerializer(JsonSerializer ser) {
74 | super.assignSerializer(ser);
75 | if (fallbackWriter != null) {
76 | fallbackWriter.assignSerializer(ser);
77 | }
78 | // 04-Oct-2015, tatu: To fix [module-afterburner#59], need to disable use of
79 | // fully optimized variant
80 | if (!isDefaultSerializer(ser)) {
81 | broken = true;
82 | }
83 | }
84 |
85 | @Override // since 2.7.6
86 | public void assignNullSerializer(JsonSerializer nullSer) {
87 | super.assignNullSerializer(nullSer);
88 | if (fallbackWriter != null) {
89 | fallbackWriter.assignNullSerializer(nullSer);
90 | }
91 | }
92 |
93 | public abstract T withAccessor(BeanPropertyAccessor acc);
94 |
95 | public abstract BeanPropertyWriter withSerializer(JsonSerializer ser);
96 |
97 | @Override
98 | public abstract void serializeAsField(Object bean, JsonGenerator jgen, SerializerProvider prov) throws Exception;
99 |
100 | // since 2.4.3
101 | @Override
102 | public abstract void serializeAsElement(Object bean, JsonGenerator jgen, SerializerProvider prov) throws Exception;
103 |
104 | // note: synchronized used to try to minimize race conditions; also, should NOT
105 | // be a performance problem
106 | protected synchronized void _handleProblem(Object bean, JsonGenerator gen, SerializerProvider prov,
107 | Throwable t, boolean element) throws Exception
108 | {
109 | if ((t instanceof IllegalAccessError)
110 | || (t instanceof SecurityException)) {
111 | _reportProblem(bean, t);
112 | if (element) {
113 | fallbackWriter.serializeAsElement(bean, gen, prov);
114 | } else {
115 | fallbackWriter.serializeAsField(bean, gen, prov);
116 | }
117 | return;
118 | }
119 | if (t instanceof Error) {
120 | throw (Error) t;
121 | }
122 | throw (Exception) t;
123 | }
124 |
125 | protected void _reportProblem(Object bean, Throwable e)
126 | {
127 | broken = true;
128 | String msg = String.format("Disabling Afterburner serialization for %s (field #%d; muator %s), due to access error (type %s, message=%s)%n",
129 | bean.getClass(), _propertyIndex, getClass().getName(),
130 | e.getClass().getName(), e.getMessage());
131 | Logger.getLogger(OptimizedBeanPropertyWriter.class.getName()).log(Level.WARNING, msg, e);
132 | }
133 |
134 | /**
135 | * Helper method used to check whether given serializer is the default
136 | * serializer implementation: this is necessary to avoid overriding other
137 | * kinds of deserializers.
138 | */
139 | protected boolean isDefaultSerializer(JsonSerializer> ser)
140 | {
141 | return (ser == null) || ClassUtil.isJacksonStdImpl(ser);
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/src/main/java/com/fasterxml/jackson/module/afterburner/ser/StringFieldPropertyWriter.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.ser;
2 |
3 | import com.fasterxml.jackson.core.JsonGenerator;
4 | import com.fasterxml.jackson.databind.JsonSerializer;
5 | import com.fasterxml.jackson.databind.SerializerProvider;
6 | import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
7 |
8 | public final class StringFieldPropertyWriter
9 | extends OptimizedBeanPropertyWriter
10 | {
11 | private static final long serialVersionUID = 1L;
12 |
13 | public StringFieldPropertyWriter(BeanPropertyWriter src, BeanPropertyAccessor acc, int index,
14 | JsonSerializer ser) {
15 | super(src, acc, index, ser);
16 | }
17 |
18 | @Override
19 | public BeanPropertyWriter withSerializer(JsonSerializer ser) {
20 | return new StringFieldPropertyWriter(this, _propertyAccessor, _propertyIndex, ser);
21 | }
22 |
23 | @Override
24 | public StringFieldPropertyWriter withAccessor(BeanPropertyAccessor acc) {
25 | if (acc == null) throw new IllegalArgumentException();
26 | return new StringFieldPropertyWriter(this, acc, _propertyIndex, _serializer);
27 | }
28 |
29 | /*
30 | /**********************************************************
31 | /* Overrides
32 | /**********************************************************
33 | */
34 |
35 | @Override
36 | public final void serializeAsField(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception
37 | {
38 | if (broken) {
39 | fallbackWriter.serializeAsField(bean, gen, prov);
40 | return;
41 | }
42 | String value;
43 | try {
44 | value = _propertyAccessor.stringField(bean, _propertyIndex);
45 | } catch (Throwable t) {
46 | _handleProblem(bean, gen, prov, t, false);
47 | return;
48 | }
49 | // Null (etc) handling; copied from super-class impl
50 | if (value == null) {
51 | if (!_suppressNulls) {
52 | gen.writeFieldName(_fastName);
53 | prov.defaultSerializeNull(gen);
54 | }
55 | return;
56 | }
57 | if (_suppressableValue != null) {
58 | if (MARKER_FOR_EMPTY == _suppressableValue) {
59 | if (value.length() == 0) {
60 | return;
61 | }
62 | } else if (_suppressableValue.equals(value)) {
63 | return;
64 | }
65 | }
66 | gen.writeFieldName(_fastName);
67 | gen.writeString(value);
68 | }
69 |
70 | @Override
71 | public final void serializeAsElement(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception
72 | {
73 | if (broken) {
74 | fallbackWriter.serializeAsElement(bean, gen, prov);
75 | return;
76 | }
77 | String value;
78 | try {
79 | value = _propertyAccessor.stringField(bean, _propertyIndex);
80 | } catch (Throwable t) {
81 | _handleProblem(bean, gen, prov, t, true);
82 | return;
83 | }
84 | if (_suppressableValue != null) {
85 | if (MARKER_FOR_EMPTY == _suppressableValue) {
86 | if (value.length() == 0) {
87 | serializeAsPlaceholder(bean, gen, prov);
88 | return;
89 | }
90 | } else if (_suppressableValue.equals(value)) {
91 | serializeAsPlaceholder(bean, gen, prov);
92 | return;
93 | }
94 | }
95 | gen.writeString(value);
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/src/main/java/com/fasterxml/jackson/module/afterburner/ser/StringMethodPropertyWriter.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.ser;
2 |
3 | import com.fasterxml.jackson.core.JsonGenerator;
4 | import com.fasterxml.jackson.databind.JsonSerializer;
5 | import com.fasterxml.jackson.databind.SerializerProvider;
6 | import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
7 |
8 | public class StringMethodPropertyWriter
9 | extends OptimizedBeanPropertyWriter
10 | {
11 | private static final long serialVersionUID = 1L;
12 |
13 | public StringMethodPropertyWriter(BeanPropertyWriter src, BeanPropertyAccessor acc, int index,
14 | JsonSerializer ser) {
15 | super(src, acc, index, ser);
16 | }
17 |
18 | @Override
19 | public BeanPropertyWriter withSerializer(JsonSerializer ser) {
20 | return new StringMethodPropertyWriter(this, _propertyAccessor, _propertyIndex, ser);
21 | }
22 |
23 | @Override
24 | public StringMethodPropertyWriter withAccessor(BeanPropertyAccessor acc) {
25 | if (acc == null) throw new IllegalArgumentException();
26 | return new StringMethodPropertyWriter(this, acc, _propertyIndex, _serializer);
27 | }
28 |
29 | /*
30 | /**********************************************************
31 | /* Overrides
32 | /**********************************************************
33 | */
34 |
35 | @Override
36 | public final void serializeAsField(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception
37 | {
38 | if (broken) {
39 | fallbackWriter.serializeAsField(bean, gen, prov);
40 | return;
41 | }
42 | String value;
43 | try {
44 | value = _propertyAccessor.stringGetter(bean, _propertyIndex);
45 | } catch (Throwable t) {
46 | _handleProblem(bean, gen, prov, t, false);
47 | return;
48 | }
49 | // Null (etc) handling; copied from super-class impl
50 | if (value == null) {
51 | if (!_suppressNulls) {
52 | gen.writeFieldName(_fastName);
53 | prov.defaultSerializeNull(gen);
54 | }
55 | return;
56 | }
57 | if (_suppressableValue != null) {
58 | if (MARKER_FOR_EMPTY == _suppressableValue) {
59 | if (value.length() == 0) {
60 | return;
61 | }
62 | } else if (_suppressableValue.equals(value)) {
63 | return;
64 | }
65 | }
66 | gen.writeFieldName(_fastName);
67 | gen.writeString(value);
68 | }
69 |
70 | @Override
71 | public final void serializeAsElement(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception
72 | {
73 | if (broken) {
74 | fallbackWriter.serializeAsElement(bean, gen, prov);
75 | return;
76 | }
77 |
78 | String value;
79 | try {
80 | value = _propertyAccessor.stringGetter(bean, _propertyIndex);
81 | } catch (Throwable t) {
82 | _handleProblem(bean, gen, prov, t, true);
83 | return;
84 | }
85 | // Null (etc) handling; copied from super-class impl
86 | if (value == null) {
87 | if (_suppressNulls) {
88 | serializeAsPlaceholder(bean, gen, prov);
89 | } else {
90 | prov.defaultSerializeNull(gen);
91 | }
92 | return;
93 | }
94 | if (_suppressableValue != null) {
95 | if (MARKER_FOR_EMPTY == _suppressableValue) {
96 | if (value.length() == 0) {
97 | serializeAsPlaceholder(bean, gen, prov);
98 | return;
99 | }
100 | } else if (_suppressableValue.equals(value)) {
101 | serializeAsPlaceholder(bean, gen, prov);
102 | return;
103 | }
104 | }
105 | gen.writeString(value);
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/src/main/java/com/fasterxml/jackson/module/afterburner/util/ClassName.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.util;
2 |
3 | import java.util.zip.Adler32;
4 |
5 | /**
6 | * Accessing various permutations of dotted/slashed representations gets
7 | * tiresome after a while, so here's an abstraction for hiding complexities,
8 | * and for performing lazy transformations as necessary.
9 | */
10 | public class ClassName
11 | {
12 | public final static String TEMPLATE_SUFFIX = actualClassName("", 0L);
13 |
14 | // Basenames with no checksum suffix
15 | protected final String _dottedBase;
16 |
17 | protected String _slashedBase;
18 |
19 | protected String _dottedName, _slashedName;
20 |
21 | protected long _checksum;
22 |
23 | private ClassName(String dottedBase) {
24 | _dottedBase = dottedBase;
25 | }
26 |
27 | public static ClassName constructFor(Class> baseClass, String suffix) {
28 | return new ClassName(baseClass.getName() + suffix);
29 | }
30 |
31 | public void assignChecksum(byte[] data) {
32 | long l = adler32(data);
33 | if (_checksum != 0L) {
34 | throw new IllegalStateException("Trying to re-assign checksum as 0x"+Long.toHexString(l)
35 | +" (had 0x"+Long.toHexString(_checksum)+")");
36 | }
37 | // Need to mask unlikely checksum of 0
38 | if (l == 0L) {
39 | l = 1;
40 | }
41 | _checksum = l;
42 | }
43 |
44 | public String getDottedTemplate() {
45 | return _dottedBase + TEMPLATE_SUFFIX;
46 | }
47 |
48 | public String getSlashedTemplate() {
49 | return getSlashedBase() + TEMPLATE_SUFFIX;
50 | }
51 |
52 | public String getDottedName() {
53 | if (_dottedName == null) {
54 | if (_checksum == 0) {
55 | throw new IllegalStateException("No checksum assigned yet");
56 | }
57 | _dottedName = String.format("%s%08x", getDottedBase(), (int) _checksum);
58 | }
59 | return _dottedName;
60 | }
61 |
62 | public String getSlashedName() {
63 | if (_slashedName == null) {
64 | if (_checksum == 0) {
65 | throw new IllegalStateException("No checksum assigned yet");
66 | }
67 | _slashedName = String.format("%s%08x", getSlashedBase(), (int) _checksum);
68 | }
69 | return _slashedName;
70 | }
71 |
72 | public String getSourceFilename() {
73 | return getSlashedBase() + ".java";
74 | }
75 |
76 | public String getDottedBase() {
77 | return _dottedBase;
78 | }
79 |
80 | public String getSlashedBase() {
81 | if (_slashedBase == null) {
82 | _slashedBase = dotsToSlashes(_dottedBase);
83 | }
84 | return _slashedBase;
85 | }
86 |
87 | @Override
88 | public String toString() {
89 | return getDottedName();
90 | }
91 |
92 | private static String actualClassName(String base, long checksum) {
93 | return String.format("%s%08x", base, (int) checksum);
94 | }
95 |
96 | protected static String dotsToSlashes(String className) {
97 | return className.replace(".", "/");
98 | }
99 |
100 | protected static long adler32(byte[] data)
101 | {
102 | Adler32 adler = new Adler32();
103 | adler.update(data);
104 | return adler.getValue();
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/src/main/java/com/fasterxml/jackson/module/afterburner/util/DynamicPropertyAccessorBase.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.util;
2 |
3 |
4 | import java.util.List;
5 |
6 | import org.objectweb.asm.MethodVisitor;
7 |
8 | import static org.objectweb.asm.Opcodes.*;
9 |
10 | public class DynamicPropertyAccessorBase
11 | {
12 | protected final static int[] ALL_INT_CONSTS = new int[] {
13 | ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4
14 | };
15 |
16 | protected int _accessorCount = 0;
17 |
18 | protected DynamicPropertyAccessorBase() {
19 | }
20 |
21 | public final boolean isEmpty() {
22 | return (_accessorCount == 0);
23 | }
24 |
25 | /*
26 | /**********************************************************
27 | /* Helper methods, generating common pieces
28 | /**********************************************************
29 | */
30 |
31 | protected static void generateException(MethodVisitor mv, String beanClass, int propertyCount)
32 | {
33 | mv.visitTypeInsn(NEW, "java/lang/IllegalArgumentException");
34 | mv.visitInsn(DUP);
35 | mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
36 | mv.visitInsn(DUP);
37 | mv.visitLdcInsn("Invalid field index (valid; 0 <= n < "+propertyCount+"): ");
38 | mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "", "(Ljava/lang/String;)V", false);
39 | mv.visitVarInsn(ILOAD, 2);
40 | mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;", false);
41 | mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false);
42 | mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalArgumentException", "", "(Ljava/lang/String;)V", false);
43 | mv.visitInsn(ATHROW);
44 | }
45 |
46 | /*
47 | /**********************************************************
48 | /* Helper methods, other
49 | /**********************************************************
50 | */
51 |
52 | protected static String internalClassName(String className) {
53 | return className.replace(".", "/");
54 | }
55 |
56 | protected T _add(List list, T value) {
57 | list.add(value);
58 | ++_accessorCount;
59 | return value;
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/src/main/java/com/fasterxml/jackson/module/afterburner/util/MyClassLoader.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.util;
2 |
3 | import java.lang.reflect.Method;
4 | import java.nio.charset.Charset;
5 |
6 | /**
7 | * Class loader that is needed to load generated classes.
8 | */
9 | public class MyClassLoader extends ClassLoader
10 | {
11 | private final static Charset UTF8 = Charset.forName("UTF-8");
12 |
13 | /**
14 | * Flag that determines if we should first try to load new class
15 | * using parent class loader or not; this may be done to try to
16 | * force access to protected/package-access properties.
17 | */
18 | protected final boolean _cfgUseParentLoader;
19 |
20 | public MyClassLoader(ClassLoader parent, boolean tryToUseParent)
21 | {
22 | super(parent);
23 | _cfgUseParentLoader = tryToUseParent;
24 | }
25 |
26 | /**
27 | * Helper method called to check whether it is acceptable to create a new
28 | * class in package that given class is part of.
29 | * This is used to prevent certain class of failures, related to access
30 | * limitations: for example, we can not add classes in sealed packages,
31 | * or core Java packages (java.*).
32 | *
33 | * @since 2.2.1
34 | */
35 | public static boolean canAddClassInPackageOf(Class> cls)
36 | {
37 | final Package beanPackage = cls.getPackage();
38 | if (beanPackage != null) {
39 | if (beanPackage.isSealed()) {
40 | return false;
41 | }
42 | String pname = beanPackage.getName();
43 | /* 14-Aug-2014, tatu: java.* we do not want to touch, but
44 | * javax is bit trickier. For now let's
45 | */
46 | if (pname.startsWith("java.")
47 | || pname.startsWith("javax.security.")) {
48 | return false;
49 | }
50 | }
51 | return true;
52 | }
53 |
54 | /**
55 | * @param className Interface or abstract class that class to load should extend or
56 | * implement
57 | */
58 | public Class> loadAndResolve(ClassName className, byte[] byteCode)
59 | throws IllegalArgumentException
60 | {
61 | // First things first: just to be sure; maybe we have already loaded it?
62 | Class> old = findLoadedClass(className.getDottedName());
63 | if (old != null) {
64 | return old;
65 | }
66 |
67 | Class> impl;
68 |
69 | // Important: bytecode is generated with a template name (since bytecode itself
70 | // is used for checksum calculation) -- must be replaced now, however
71 | replaceName(byteCode, className.getSlashedTemplate(), className.getSlashedName());
72 |
73 | // First: let's try calling it directly on parent, to be able to access protected/package-access stuff:
74 | if (_cfgUseParentLoader) {
75 | ClassLoader cl = getParent();
76 | // if we have parent, that is
77 | if (cl != null) {
78 | try {
79 | Method method = ClassLoader.class.getDeclaredMethod("defineClass",
80 | new Class[] {String.class, byte[].class, int.class,
81 | int.class});
82 | method.setAccessible(true);
83 | return (Class>)method.invoke(getParent(),
84 | className.getDottedName(), byteCode, 0, byteCode.length);
85 | } catch (Exception e) {
86 | // Should we handle this somehow?
87 | }
88 | }
89 | }
90 |
91 | // but if that doesn't fly, try to do it from our own class loader
92 |
93 | try {
94 | impl = defineClass(className.getDottedName(), byteCode, 0, byteCode.length);
95 | } catch (LinkageError e) {
96 | Throwable t = e;
97 | while (t.getCause() != null) {
98 | t = t.getCause();
99 | }
100 | throw new IllegalArgumentException("Failed to load class '"+className+"': "+t.getMessage(), t);
101 | }
102 | // important: must also resolve the class...
103 | resolveClass(impl);
104 | return impl;
105 | }
106 |
107 | public static int replaceName(byte[] byteCode,
108 | String from, String to)
109 | {
110 | byte[] fromB = from.getBytes(UTF8);
111 | byte[] toB = to.getBytes(UTF8);
112 |
113 | final int matchLength = fromB.length;
114 |
115 | // sanity check
116 | if (matchLength != toB.length) {
117 | throw new IllegalArgumentException("From String '"+from
118 | +"' has different length than To String '"+to+"'");
119 | }
120 |
121 | int i = 0;
122 | int count = 0;
123 |
124 | // naive; for now has to do
125 | main_loop:
126 | for (int end = byteCode.length - matchLength; i <= end; ) {
127 | if (byteCode[i++] == fromB[0]) {
128 | for (int j = 1; j < matchLength; ++j) {
129 | if (fromB[j] != byteCode[i+j-1]) {
130 | continue main_loop;
131 | }
132 | }
133 | ++count;
134 | System.arraycopy(toB, 0, byteCode, i-1, matchLength);
135 | i += (matchLength-1);
136 | }
137 | }
138 | return count;
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/src/main/resources/META-INF/LICENSE:
--------------------------------------------------------------------------------
1 | This copy of Jackson JSON processor databind module is licensed under the
2 | Apache (Software) License, version 2.0 ("the License").
3 | See the License for details about distribution rights, and the
4 | specific rights regarding derivate works.
5 |
6 | You may obtain a copy of the License at:
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
--------------------------------------------------------------------------------
/src/main/resources/META-INF/services/com.fasterxml.jackson.databind.Module:
--------------------------------------------------------------------------------
1 | com.fasterxml.jackson.module.afterburner.AfterburnerModule
2 |
3 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/TestAccessFallback.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner;
2 |
3 | import com.fasterxml.jackson.databind.ObjectMapper;
4 |
5 | public class TestAccessFallback extends AfterburnerTestBase
6 | {
7 | @SuppressWarnings("serial")
8 | static class BogusTestError extends IllegalAccessError {
9 | public BogusTestError(String msg) {
10 | super(msg);
11 | }
12 | }
13 |
14 | static class MyBean
15 | {
16 | private String e;
17 |
18 | public MyBean() { }
19 |
20 | MyBean(String e)
21 | {
22 | setE(e);
23 | }
24 |
25 | public void setE(String e)
26 | {
27 | /* 07-Mar-2015, tatu: This is bit tricky, as the exact stack trace varies
28 | * depending on how code is generated. So right now we must get the call
29 | * immediately from constructed class.
30 | */
31 |
32 | StackTraceElement[] elems = new Throwable().getStackTrace();
33 | StackTraceElement prev = elems[1];
34 | if (prev.getClassName().contains("Access4JacksonDeserializer")) {
35 | throw new BogusTestError("boom!");
36 | }
37 | this.e = e;
38 | }
39 |
40 | public String getE()
41 | {
42 | for (StackTraceElement elem : new Throwable().getStackTrace()) {
43 | if (elem.getClassName().contains("Access4JacksonSerializer")) {
44 | throw new BogusTestError("boom!");
45 | }
46 | }
47 | return e;
48 | }
49 | }
50 |
51 | private static final String BEAN_JSON = "{\"e\":\"a\"}";
52 |
53 | public void testSerializeAccess() throws Exception
54 | {
55 | ObjectMapper abMapper = mapperWithModule();
56 | assertEquals(BEAN_JSON, abMapper.writeValueAsString(new MyBean("a")));
57 | }
58 |
59 | public void testDeserializeAccess() throws Exception
60 | {
61 | ObjectMapper abMapper = mapperWithModule();
62 | MyBean bean = abMapper.readValue(BEAN_JSON, MyBean.class);
63 | assertEquals("a", bean.getE());
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/TestSealedPackages.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner;
2 |
3 | import com.fasterxml.jackson.databind.ObjectMapper;
4 |
5 | /**
6 | * Tests for [Issue#21]
7 | */
8 | public class TestSealedPackages extends AfterburnerTestBase
9 | {
10 | public void testJavaStdDeserialization() throws Exception
11 | {
12 | final ObjectMapper MAPPER = mapperWithModule();
13 | String json = "{}";
14 | Exception e = MAPPER.readValue(json, Exception.class);
15 | assertNotNull(e);
16 | }
17 |
18 | public void testJavaStdSerialization() throws Exception
19 | {
20 | final ObjectMapper MAPPER = mapperWithModule();
21 | String json = MAPPER.writeValueAsString(Thread.currentThread().getThreadGroup());
22 | assertNotNull(json);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/TestUnwrapped.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner;
2 |
3 | import com.fasterxml.jackson.annotation.JsonPropertyOrder;
4 | import com.fasterxml.jackson.annotation.JsonUnwrapped;
5 | import com.fasterxml.jackson.databind.ObjectMapper;
6 |
7 | public class TestUnwrapped extends AfterburnerTestBase
8 | {
9 | @JsonPropertyOrder({ "a", "b" })
10 | static class Wrapper
11 | {
12 | public int a;
13 |
14 | @JsonUnwrapped(prefix="foo.")
15 | public Unwrapped b;
16 |
17 | public Wrapper() { }
18 | public Wrapper(int a, int value) {
19 | this.a = a;
20 | b = new Unwrapped(value);
21 | }
22 | }
23 |
24 | static class Unwrapped {
25 | public int value;
26 |
27 | public Unwrapped() { }
28 | public Unwrapped(int v) { value = v; }
29 | }
30 |
31 | /*
32 | /**********************************************************
33 | /* Actual tests
34 | /**********************************************************
35 | */
36 |
37 | public void testSimpleSerialize() throws Exception
38 | {
39 | final ObjectMapper VANILLA = new ObjectMapper();
40 | final ObjectMapper BURNER = mapperWithModule();
41 | Wrapper input = new Wrapper(1, 3);
42 | String json = VANILLA.writeValueAsString(input);
43 | assertEquals(json, BURNER.writeValueAsString(input));
44 | }
45 |
46 | public void testUnwrappedDeserialize() throws Exception
47 | {
48 | final ObjectMapper VANILLA = new ObjectMapper();
49 | final ObjectMapper BURNER = mapperWithModule();
50 | String json = VANILLA.writeValueAsString(new Wrapper(2, 9));
51 | Wrapper out = BURNER.readValue(json, Wrapper.class);
52 | assertEquals(2, out.a);
53 | assertNotNull(out.b);
54 | assertEquals(9, out.b.value);
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/TestVersions.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner;
2 |
3 | import java.io.*;
4 |
5 | import com.fasterxml.jackson.core.Version;
6 | import com.fasterxml.jackson.core.Versioned;
7 |
8 | /**
9 | * Tests to verify that version information is properly accessible
10 | */
11 | public class TestVersions extends AfterburnerTestBase
12 | {
13 | public void testMapperVersions() throws IOException
14 | {
15 | AfterburnerModule module = new AfterburnerModule();
16 | assertVersion(module);
17 | }
18 |
19 | /*
20 | /**********************************************************
21 | /* Helper methods
22 | /**********************************************************
23 | */
24 |
25 | private void assertVersion(Versioned vers)
26 | {
27 | Version v = vers.version();
28 | assertFalse("Should find version information (got "+v+")", v.isUnknownVersion());
29 | Version exp = PackageVersion.VERSION;
30 | assertEquals(exp.toFullString(), v.toFullString());
31 | assertEquals(exp, v);
32 | }
33 | }
34 |
35 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/codegen/GenerateWithMixinsTest.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.codegen;
2 |
3 | import com.fasterxml.jackson.annotation.JsonIgnore;
4 | import com.fasterxml.jackson.core.JsonProcessingException;
5 | import com.fasterxml.jackson.databind.ObjectMapper;
6 | import com.fasterxml.jackson.module.afterburner.AfterburnerTestBase;
7 |
8 | // for [afterburner#51], where re-generation of classes does not work
9 | // as expected
10 | public class GenerateWithMixinsTest extends AfterburnerTestBase
11 | {
12 | static class SampleObject {
13 | private String field1;
14 | private int field2;
15 | private byte[] field3;
16 |
17 | public SampleObject(String field1, int field2, byte[] field3) {
18 | this.field1 = field1;
19 | this.field2 = field2;
20 | this.field3 = field3;
21 | }
22 |
23 | public String getField1() {
24 | return field1;
25 | }
26 |
27 | public void setField1(String field1) {
28 | this.field1 = field1;
29 | }
30 |
31 | public int getField2() {
32 | return field2;
33 | }
34 |
35 | public void setField2(int field2) {
36 | this.field2 = field2;
37 | }
38 |
39 | public byte[] getField3() {
40 | return field3;
41 | }
42 |
43 | public void setField3(byte[] field3) {
44 | this.field3 = field3;
45 | }
46 | }
47 |
48 | public abstract class IgnoreField3MixIn {
49 | @JsonIgnore
50 | public abstract byte[] getField3();
51 | }
52 |
53 | public void testIssue51() throws JsonProcessingException
54 | {
55 | SampleObject sampleObject = new SampleObject("field1", 2, "field3".getBytes());
56 |
57 | ObjectMapper objectMapper = mapperWithModule();
58 |
59 | ObjectMapper objectMapperCopy = objectMapper.copy();
60 | objectMapperCopy.addMixIn(SampleObject.class, IgnoreField3MixIn.class);
61 |
62 | objectMapperCopy.writeValueAsString(sampleObject);
63 |
64 | objectMapper.writeValueAsString(sampleObject);
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/deser/TestBuilders.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.deser;
2 |
3 | import com.fasterxml.jackson.databind.ObjectMapper;
4 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
5 | import com.fasterxml.jackson.module.afterburner.AfterburnerTestBase;
6 |
7 | public class TestBuilders extends AfterburnerTestBase
8 | {
9 | // [Issue#22]:
10 | static final class ThingBuilder
11 | {
12 | private String foo;
13 |
14 | public ThingBuilder withFoo(String str) {
15 | foo = str;
16 | return this;
17 | }
18 |
19 | public Thing build() {
20 | return new Thing(foo);
21 | }
22 | }
23 |
24 | @JsonDeserialize(builder=ThingBuilder.class)
25 | static class Thing {
26 | final String foo;
27 |
28 | private Thing(String foo) {
29 | this.foo = foo;
30 | }
31 | }
32 |
33 | /*
34 | /**********************************************************
35 | /* Test methods, valid cases, non-deferred, no-mixins
36 | /**********************************************************
37 | */
38 |
39 | private final ObjectMapper MAPPER = mapperWithModule();
40 |
41 | public void testSimpleBuilder() throws Exception
42 | {
43 | final Thing expected = new ThingBuilder().withFoo("bar").build();
44 | final Thing actual = MAPPER.readValue("{ \"foo\": \"bar\"}", Thing.class);
45 |
46 | assertNotNull(actual);
47 | assertNotNull(actual.foo);
48 | assertEquals(expected.foo, actual.foo);
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/deser/TestCollectionDeser.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.deser;
2 |
3 | import java.util.*;
4 |
5 | import com.fasterxml.jackson.databind.*;
6 | import com.fasterxml.jackson.module.afterburner.AfterburnerTestBase;
7 |
8 | public class TestCollectionDeser extends AfterburnerTestBase
9 | {
10 | // [module-afterburner#36]
11 | static class CollectionBean
12 | {
13 | private Collection x = new TreeSet();
14 |
15 | public Collection getStuff() { return x; }
16 | }
17 |
18 | static class IntBean {
19 | public int value;
20 | }
21 |
22 | /*
23 | /**********************************************************************
24 | /* Test methods
25 | /**********************************************************************
26 | */
27 |
28 | // [module-afterburner#36]
29 | public void testIntMethod() throws Exception
30 | {
31 | ObjectMapper mapper = mapperWithModule();
32 | mapper.configure(MapperFeature.USE_GETTERS_AS_SETTERS, true);
33 | CollectionBean bean = mapper.readValue("{\"stuff\":[\"a\",\"b\"]}",
34 | CollectionBean.class);
35 | assertEquals(2, bean.x.size());
36 | assertEquals(TreeSet.class, bean.x.getClass());
37 | }
38 |
39 | // [module-afterburner#56]
40 | public void testUnwrapSingleArray() throws Exception
41 | {
42 | final ObjectMapper mapper = mapperWithModule();
43 | mapper.enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
44 |
45 | /*
46 | final Integer intValue = mapper.readValue("[ 1 ]", Integer.class);
47 | assertEquals(Integer.valueOf(1), intValue);
48 |
49 | final String strValue = mapper.readValue("[ \"abc\" ]", String.class);
50 | assertEquals("abc", strValue);
51 |
52 | // and then via POJO. First, array of POJOs
53 | IntBean b1 = mapper.readValue(aposToQuotes("[{ 'value' : 123 }]"), IntBean.class);
54 | assertNotNull(b1);
55 | assertEquals(123, b1.value);
56 | */
57 |
58 | // and then array of ints within POJO
59 | IntBean b2 = mapper.readValue(aposToQuotes("{ 'value' : [ 123 ] }"), IntBean.class);
60 | assertNotNull(b2);
61 | assertEquals(123, b2.value);
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/deser/TestConstructors.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.deser;
2 |
3 | import com.fasterxml.jackson.annotation.JsonAutoDetect;
4 | import com.fasterxml.jackson.databind.ObjectMapper;
5 | import com.fasterxml.jackson.module.afterburner.AfterburnerTestBase;
6 |
7 | public class TestConstructors extends AfterburnerTestBase
8 | {
9 | // [Issue#34]
10 | @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
11 | private static class Row
12 | {
13 | private String id;
14 |
15 | public String _id() { return id; }
16 | }
17 |
18 | /*
19 | /**********************************************************************
20 | /* Test methods
21 | /**********************************************************************
22 | */
23 |
24 | // For [Issue#34]
25 | public void testPrivateConstructor() throws Exception
26 | {
27 | ObjectMapper mapper = mapperWithModule();
28 | Row row = mapper.readValue("{\"id\":\"x\"}", Row.class);
29 | assertNotNull(row);
30 | assertEquals("x", row._id());
31 |
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/deser/TestCreatorsDelegating.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.deser;
2 |
3 | import com.fasterxml.jackson.annotation.JsonCreator;
4 | import com.fasterxml.jackson.annotation.JacksonInject;
5 |
6 | import com.fasterxml.jackson.databind.*;
7 | import com.fasterxml.jackson.module.afterburner.AfterburnerTestBase;
8 |
9 | public class TestCreatorsDelegating extends AfterburnerTestBase
10 | {
11 | static class BooleanBean
12 | {
13 | protected Boolean value;
14 |
15 | public BooleanBean(Boolean v) { value = v; }
16 |
17 | @JsonCreator
18 | protected static BooleanBean create(Boolean value) {
19 | return new BooleanBean(value);
20 | }
21 | }
22 |
23 | // for [JACKSON-711]; should allow delegate-based one(s) too
24 | static class CtorBean711
25 | {
26 | protected String name;
27 | protected int age;
28 |
29 | @JsonCreator
30 | public CtorBean711(@JacksonInject String n, int a)
31 | {
32 | name = n;
33 | age = a;
34 | }
35 | }
36 |
37 | // for [JACKSON-711]; should allow delegate-based one(s) too
38 | static class FactoryBean711
39 | {
40 | protected String name1;
41 | protected String name2;
42 | protected int age;
43 |
44 | private FactoryBean711(int a, String n1, String n2) {
45 | age = a;
46 | name1 = n1;
47 | name2 = n2;
48 | }
49 |
50 | @JsonCreator
51 | public static FactoryBean711 create(@JacksonInject String n1, int a, @JacksonInject String n2) {
52 | return new FactoryBean711(a, n1, n2);
53 | }
54 | }
55 |
56 | /*
57 | /**********************************************************
58 | /* Unit tests
59 | /**********************************************************
60 | */
61 |
62 | public void testBooleanDelegate() throws Exception
63 | {
64 | ObjectMapper m = mapperWithModule();
65 | // should obviously work with booleans...
66 | BooleanBean bb = m.readValue("true", BooleanBean.class);
67 | assertEquals(Boolean.TRUE, bb.value);
68 |
69 | // but also with value conversion from String
70 | bb = m.readValue(quote("true"), BooleanBean.class);
71 | assertEquals(Boolean.TRUE, bb.value);
72 | }
73 |
74 | // As per [JACKSON-711]: should also work with delegate model (single non-annotated arg)
75 | public void testWithCtorAndDelegate() throws Exception
76 | {
77 | ObjectMapper mapper = mapperWithModule();
78 | mapper.setInjectableValues(new InjectableValues.Std()
79 | .addValue(String.class, "Pooka")
80 | );
81 | CtorBean711 bean = null;
82 | try {
83 | bean = mapper.readValue("38", CtorBean711.class);
84 | } catch (JsonMappingException e) {
85 | fail("Did not expect problems, got: "+e.getMessage());
86 | }
87 | assertEquals(38, bean.age);
88 | assertEquals("Pooka", bean.name);
89 | }
90 |
91 | public void testWithFactoryAndDelegate() throws Exception
92 | {
93 | ObjectMapper mapper = mapperWithModule();
94 | mapper.setInjectableValues(new InjectableValues.Std()
95 | .addValue(String.class, "Fygar")
96 | );
97 | FactoryBean711 bean = null;
98 | try {
99 | bean = mapper.readValue("38", FactoryBean711.class);
100 | } catch (JsonMappingException e) {
101 | fail("Did not expect problems, got: "+e.getMessage());
102 | }
103 | assertEquals(38, bean.age);
104 | assertEquals("Fygar", bean.name1);
105 | assertEquals("Fygar", bean.name2);
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/deser/TestFinalFields.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.deser;
2 |
3 | import com.fasterxml.jackson.annotation.*;
4 | import com.fasterxml.jackson.databind.*;
5 | import com.fasterxml.jackson.module.afterburner.AfterburnerTestBase;
6 |
7 | public class TestFinalFields extends AfterburnerTestBase
8 | {
9 | static class Address {
10 | public int zip1, zip2;
11 |
12 | public Address() { }
13 | public Address(int z1, int z2) {
14 | zip1 = z1;
15 | zip2 = z2;
16 | }
17 | }
18 |
19 | @JsonInclude(JsonInclude.Include.NON_NULL)
20 | static class Organization
21 | {
22 | public final long id;
23 | public final String name;
24 | public final Address address;
25 |
26 | @JsonCreator
27 | public Organization(@JsonProperty("id") long id,
28 | @JsonProperty("name") String name,
29 | @JsonProperty("address") Address address)
30 | {
31 | this.id = id;
32 | this.name = name;
33 | this.address = address;
34 | }
35 | }
36 |
37 | /*
38 | /**********************************************************
39 | /* Unit tests
40 | /**********************************************************
41 | */
42 |
43 | public void testFinalFields() throws Exception
44 | {
45 | ObjectMapper mapper = mapperWithModule();
46 | String json = mapper.writeValueAsString(new Organization[] {
47 | new Organization(123L, "Corp", new Address(98040, 98021))
48 | });
49 | Organization[] result = mapper.readValue(json, Organization[].class);
50 | assertNotNull(result);
51 | assertEquals(1, result.length);
52 | assertNotNull(result[0]);
53 | assertNotNull(result[0].address);
54 | assertEquals(98021, result[0].address.zip2);
55 | }
56 |
57 | // For [Afterburner#42]
58 |
59 | public void testFinalFields42() throws Exception
60 | {
61 | JsonAddress address = new JsonAddress(-1L, "line1", "line2", "city", "state", "zip", "locale", "timezone");
62 | JsonOrganization organization = new JsonOrganization(-1L, "name", address);
63 | ObjectMapper mapper = mapperWithModule();
64 | String json = mapper.writeValueAsString(organization);
65 | assertNotNull(json);
66 |
67 | JsonOrganization result = mapper.readValue(json, JsonOrganization.class);
68 | assertNotNull(result);
69 | }
70 |
71 | @JsonInclude(JsonInclude.Include.NON_NULL)
72 | static class JsonAddress extends Resource {
73 | public final long id;
74 | public final String state;
75 | public final String timezone;
76 | public final String locale;
77 | public final String line1;
78 | public final String line2;
79 | public final String city;
80 | public final String zipCode;
81 |
82 | // Note: missing last 2 fields, to trigger problem
83 | @JsonCreator
84 | public JsonAddress(@JsonProperty("id") long id,
85 | @JsonProperty("line1") String line1,
86 | @JsonProperty("line2") String line2,
87 | @JsonProperty("city") String city,
88 | @JsonProperty("state") String state,
89 | @JsonProperty("zipCode") String zipCode)
90 | {
91 | this.id = id;
92 | this.line1 = line1;
93 | this.line2 = line2;
94 | this.city = city;
95 | this.state = state;
96 | this.zipCode = zipCode;
97 | this.locale = null;
98 | this.timezone = null;
99 | }
100 |
101 | public JsonAddress(long id,
102 | String line1,
103 | String line2,
104 | String city,
105 | String state,
106 | String zipCode,
107 | String locale,
108 | String timezone)
109 | {
110 | this.id = id;
111 | this.line1 = line1;
112 | this.line2 = line2;
113 | this.city = city;
114 | this.state = state;
115 | this.zipCode = zipCode;
116 | this.locale = locale;
117 | this.timezone = timezone;
118 | }
119 | }
120 |
121 | @JsonInclude(JsonInclude.Include.NON_NULL)
122 | static class JsonOrganization extends Resource {
123 | public final long id;
124 | public final String name;
125 | public final JsonAddress address;
126 |
127 | @JsonCreator
128 | public JsonOrganization(@JsonProperty("id") long id,
129 | @JsonProperty("name") String name,
130 | @JsonProperty("address") JsonAddress address)
131 | {
132 | this.id = id;
133 | this.name = name;
134 | this.address = address;
135 | }
136 | }
137 |
138 | static class Resource { }
139 | }
140 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/deser/TestIssue14.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.deser;
2 |
3 | import java.util.*;
4 |
5 | import com.fasterxml.jackson.annotation.JsonInclude;
6 | import com.fasterxml.jackson.annotation.JsonInclude.Include;
7 | import com.fasterxml.jackson.annotation.JsonProperty;
8 |
9 | import com.fasterxml.jackson.databind.ObjectMapper;
10 |
11 | import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
12 | import com.fasterxml.jackson.module.afterburner.AfterburnerTestBase;
13 |
14 | public class TestIssue14 extends AfterburnerTestBase
15 | {
16 | public void testIssue() throws Exception
17 | {
18 | // create this ridiculously complicated object
19 | ItemData data = new ItemData();
20 | data.denomination = 100;
21 | Item item = new Item();
22 | item.data = data;
23 | item.productId = 123;
24 |
25 | List- itemList = new ArrayList
- ();
26 | itemList.add(item);
27 |
28 | PlaceOrderRequest order = new PlaceOrderRequest();
29 | order.orderId = 68723496;
30 | order.userId = "123489043";
31 | order.amount = 250;
32 | order.status = "placed";
33 | order.items = itemList;
34 |
35 | final Date now = new Date(999999L);
36 |
37 | order.createdAt = now;
38 | order.updatedAt = now;
39 |
40 | ObjectMapper vanillaMapper = new ObjectMapper();
41 | ObjectMapper abMapper = new ObjectMapper();
42 | abMapper.registerModule(new AfterburnerModule());
43 |
44 | // First: ensure that serialization produces identical output
45 |
46 | String origJson = vanillaMapper
47 | .writerWithDefaultPrettyPrinter()
48 | .writeValueAsString(order);
49 |
50 | String abJson = abMapper
51 | .writerWithDefaultPrettyPrinter()
52 | .writeValueAsString(order);
53 |
54 | assertEquals(origJson, abJson);
55 |
56 | // Then read the string and turn it back into an object
57 | // this will cause an exception unless the AfterburnerModule is commented out
58 | order = abMapper.readValue(abJson, PlaceOrderRequest.class);
59 | assertNotNull(order);
60 | assertEquals(250, order.amount);
61 | }
62 | }
63 |
64 | class PlaceOrderRequest {
65 | @JsonProperty("id") public long orderId;
66 | @JsonProperty("from") public String userId;
67 | public int amount;
68 | public String status;
69 | public List
- items;
70 | @JsonProperty("created_at") public Date createdAt;
71 | @JsonProperty("updated_at") public Date updatedAt;
72 | }
73 |
74 | class Item {
75 | @JsonProperty("product_id") public int productId;
76 | public int quantity;
77 | public ItemData data;
78 | }
79 |
80 | @JsonInclude(Include.NON_NULL)
81 | class ItemData {
82 | public int denomination;
83 | public List
bets;
84 | }
85 |
86 | class VLTBet {
87 | public int index;
88 | public String selection;
89 | public int stake;
90 | public int won;
91 | }
92 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/deser/TestNonStaticInner.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.deser;
2 |
3 | import com.fasterxml.jackson.databind.ObjectMapper;
4 | import com.fasterxml.jackson.module.afterburner.AfterburnerTestBase;
5 |
6 | public class TestNonStaticInner extends AfterburnerTestBase
7 | {
8 | static class Parent {
9 |
10 | private Child child;
11 |
12 | public Child getChild() {
13 | return child;
14 | }
15 |
16 | public void setChild(Child child) {
17 | this.child = child;
18 | }
19 |
20 | public /* not static */ class Child {
21 | private boolean value;
22 |
23 | public boolean isValue() {
24 | return value;
25 | }
26 |
27 | public void setValue(boolean value) {
28 | this.value = value;
29 | }
30 | }
31 | }
32 |
33 | public void testInnerClass() throws Exception {
34 | final ObjectMapper MAPPER = mapperWithModule();
35 | // final ObjectMapper MAPPER = new ObjectMapper();
36 |
37 | Parent parent = MAPPER.readValue("{\"child\":{\"value\":true}}", Parent.class);
38 |
39 | assertTrue(parent.getChild().isValue());
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/deser/TestPolymorphic.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.deser;
2 |
3 | import com.fasterxml.jackson.annotation.*;
4 |
5 | import com.fasterxml.jackson.databind.ObjectMapper;
6 |
7 | import com.fasterxml.jackson.module.afterburner.AfterburnerTestBase;
8 |
9 | public class TestPolymorphic extends AfterburnerTestBase
10 | {
11 | static class Envelope {
12 | @JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.EXTERNAL_PROPERTY, property="class")
13 | private Object payload;
14 |
15 | public Envelope(@JsonProperty("payload") Object payload) {
16 | this.payload = payload;
17 | }
18 | public Envelope() { }
19 |
20 | @JsonProperty
21 | public Object getPayload() {
22 | return payload;
23 | }
24 | }
25 |
26 | static class Payload {
27 | private String something;
28 |
29 | public Payload(@JsonProperty("something") String something) {
30 | this.something = something;
31 | }
32 | @JsonProperty
33 | public Object getSomething() {
34 | return something;
35 | }
36 | }
37 |
38 | public void testAfterburner() throws Exception {
39 | ObjectMapper mapper = mapperWithModule();
40 | Envelope envelope = new Envelope(new Payload("test"));
41 | String json = mapper.writeValueAsString(envelope);
42 | Envelope result = mapper.readValue(json, Envelope.class);
43 |
44 | assertNotNull(result);
45 | assertNotNull(result.payload);
46 | assertEquals(Payload.class, result.payload.getClass());
47 | }
48 |
49 | // for [module-afterburner#58]; although seems to be due to databind issue
50 | public void testPolymorphicIssue58() throws Exception
51 | {
52 | final String CLASS = Payload.class.getName();
53 |
54 | ObjectMapper mapper = mapperWithModule();
55 |
56 | // First, case that has been working always
57 | final String successCase = "{\"payload\":{\"something\":\"test\"},\"class\":\""+CLASS+"\"}";
58 | Envelope envelope1 = mapper.readValue(successCase, Envelope.class);
59 | assertNotNull(envelope1);
60 | assertEquals(Payload.class, envelope1.payload.getClass());
61 |
62 | // and then re-ordered case that was problematic
63 | final String failCase = "{\"class\":\""+CLASS+"\",\"payload\":{\"something\":\"test\"}}";
64 | Envelope envelope2 = mapper.readValue(failCase, Envelope.class);
65 | assertNotNull(envelope2);
66 | assertEquals(Payload.class, envelope2.payload.getClass());
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/deser/TestPolymorphicCreators.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.deser;
2 |
3 | import com.fasterxml.jackson.annotation.*;
4 |
5 | import com.fasterxml.jackson.databind.*;
6 | import com.fasterxml.jackson.module.afterburner.AfterburnerTestBase;
7 |
8 | /**
9 | * Unit tests for verifying that it is possible to annotate
10 | * various kinds of things with {@link JsonCreator} annotation.
11 | */
12 | public class TestPolymorphicCreators extends AfterburnerTestBase
13 | {
14 | static class Animal
15 | {
16 | // All animals have names, for our demo purposes...
17 | public String name;
18 |
19 | protected Animal() { }
20 |
21 | /**
22 | * Creator method that can instantiate instances of
23 | * appropriate polymoprphic type
24 | */
25 | @JsonCreator
26 | public static Animal create(@JsonProperty("type") String type)
27 | {
28 | if ("dog".equals(type)) {
29 | return new Dog();
30 | }
31 | if ("cat".equals(type)) {
32 | return new Cat();
33 | }
34 | throw new IllegalArgumentException("No such animal type ('"+type+"')");
35 | }
36 | }
37 |
38 | static class Dog extends Animal
39 | {
40 | double barkVolume; // in decibels
41 | public Dog() { }
42 | public void setBarkVolume(double v) { barkVolume = v; }
43 | }
44 |
45 | static class Cat extends Animal
46 | {
47 | boolean likesCream;
48 | public int lives;
49 | public Cat() { }
50 | public void setLikesCream(boolean likesCreamSurely) { likesCream = likesCreamSurely; }
51 | }
52 |
53 | abstract static class AbstractRoot
54 | {
55 | private final String opt;
56 |
57 | private AbstractRoot(String opt) {
58 | this.opt = opt;
59 | }
60 |
61 | @JsonCreator
62 | public static final AbstractRoot make(@JsonProperty("which") int which,
63 | @JsonProperty("opt") String opt) {
64 | if(1 == which) {
65 | return new One(opt);
66 | }
67 | throw new RuntimeException("cannot instantiate " + which);
68 | }
69 |
70 | abstract public int getWhich();
71 |
72 | public final String getOpt() {
73 | return opt;
74 | }
75 | }
76 |
77 | static final class One extends AbstractRoot {
78 | private One(String opt) {
79 | super(opt);
80 | }
81 |
82 | @Override public int getWhich() {
83 | return 1;
84 | }
85 | }
86 |
87 | /*
88 | /**********************************************************
89 | /* Actual tests
90 | /**********************************************************
91 | */
92 |
93 | private final ObjectMapper MAPPER = mapperWithModule();
94 |
95 | /**
96 | * Simple test to verify that it is possible to implement polymorphic
97 | * deserialization manually.
98 | */
99 | public void testManualPolymorphicDog() throws Exception
100 | {
101 | // first, a dog, start with type
102 | Animal animal = MAPPER.readValue("{ \"type\":\"dog\", \"name\":\"Fido\", \"barkVolume\" : 95.0 }", Animal.class);
103 | assertEquals(Dog.class, animal.getClass());
104 | assertEquals("Fido", animal.name);
105 | assertEquals(95.0, ((Dog) animal).barkVolume);
106 | }
107 |
108 | public void testManualPolymorphicCatBasic() throws Exception
109 | {
110 | // and finally, lactose-intolerant, but otherwise robust super-cat:
111 | Animal animal = MAPPER.readValue("{ \"name\" : \"Macavity\", \"type\":\"cat\", \"lives\":18, \"likesCream\":false }", Animal.class);
112 | assertEquals(Cat.class, animal.getClass());
113 | assertEquals("Macavity", animal.name); // ... there's no one like Macavity!
114 | Cat cat = (Cat) animal;
115 | assertEquals(18, cat.lives);
116 | // ok, he can't drink dairy products. Let's verify:
117 | assertEquals(false, cat.likesCream);
118 | }
119 |
120 | public void testManualPolymorphicCatWithReorder() throws Exception
121 | {
122 | // Then cat; shuffle order to mandate buffering
123 | Animal animal = MAPPER.readValue("{ \"likesCream\":true, \"name\" : \"Venla\", \"type\":\"cat\" }", Animal.class);
124 | assertEquals(Cat.class, animal.getClass());
125 | assertEquals("Venla", animal.name);
126 | // bah, of course cats like cream. But let's ensure Jackson won't mess with laws of nature!
127 | assertTrue(((Cat) animal).likesCream);
128 | }
129 |
130 | public void testManualPolymorphicWithNumbered() throws Exception
131 | {
132 | final ObjectWriter w = MAPPER.writerFor(AbstractRoot.class);
133 | final ObjectReader r = MAPPER.readerFor(AbstractRoot.class);
134 |
135 | AbstractRoot input = AbstractRoot.make(1, "oh hai!");
136 | String json = w.writeValueAsString(input);
137 | AbstractRoot result = r.readValue(json);
138 | assertNotNull(result);
139 | assertEquals("oh hai!", result.getOpt());
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/deser/TestSingleArgCtors.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.deser;
2 |
3 | import com.fasterxml.jackson.annotation.JsonCreator;
4 | import com.fasterxml.jackson.databind.ObjectMapper;
5 | import com.fasterxml.jackson.module.afterburner.AfterburnerTestBase;
6 |
7 | public class TestSingleArgCtors extends AfterburnerTestBase
8 | {
9 | static class Node {
10 | public String name;
11 |
12 | public int value;
13 |
14 | public Node() { }
15 |
16 | @JsonCreator
17 | public Node(String n) {
18 | name = n;
19 | value = -1;
20 | }
21 | }
22 |
23 | /*
24 | /**********************************************************
25 | /* Test methods
26 | /**********************************************************
27 | */
28 |
29 | private final ObjectMapper MAPPER = mapperWithModule();
30 |
31 | public void testSingleStringArgCtor() throws Exception
32 | {
33 | Node bean = MAPPER.readValue(quote("Foobar"), Node.class);
34 | assertNotNull(bean);
35 | assertEquals(-1, bean.value);
36 | assertEquals("Foobar", bean.name);
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/deser/TestStdDeserializerOverrides.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.deser;
2 |
3 | import java.io.IOException;
4 |
5 | import com.fasterxml.jackson.core.*;
6 | import com.fasterxml.jackson.databind.*;
7 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
8 | import com.fasterxml.jackson.databind.deser.Deserializers;
9 | import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
10 | import com.fasterxml.jackson.databind.module.SimpleModule;
11 | import com.fasterxml.jackson.module.afterburner.AfterburnerTestBase;
12 |
13 | @SuppressWarnings("serial")
14 | public class TestStdDeserializerOverrides extends AfterburnerTestBase
15 | {
16 | static class ClassWithPropOverrides
17 | {
18 | public String a;
19 |
20 | @JsonDeserialize(using=MyStringDeserializer.class)
21 | public String b;
22 | }
23 |
24 | static class MyStringDeserializer extends StdDeserializer
25 | {
26 | public MyStringDeserializer() { super(String.class); }
27 |
28 | @Override
29 | public String deserialize(JsonParser p, DeserializationContext ctxt)
30 | throws IOException, JsonProcessingException {
31 | return "Foo:"+p.getText();
32 | }
33 | }
34 |
35 | // for [module-afterburner#59]
36 | static class Issue59Bean {
37 | public String field;
38 | }
39 |
40 | static class DeAmpDeserializer extends StdDeserializer
41 | {
42 | public DeAmpDeserializer() { super(String.class); }
43 |
44 | @Override
45 | public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
46 | return p.getText().replaceAll("&", "&");
47 | }
48 | }
49 |
50 | /*
51 | /**********************************************************************
52 | /* Test methods
53 | /**********************************************************************
54 | */
55 |
56 | public void testFiveMinuteDoc() throws Exception
57 | {
58 | ObjectMapper plainMapper = new ObjectMapper();
59 | ObjectMapper abMapper = mapperWithModule();
60 | final String JSON = "{\"a\":\"a\",\"b\":\"b\"}";
61 |
62 | ClassWithPropOverrides vanilla = plainMapper.readValue(JSON, ClassWithPropOverrides.class);
63 | ClassWithPropOverrides burnt = abMapper.readValue(JSON, ClassWithPropOverrides.class);
64 |
65 | assertEquals("a", vanilla.a);
66 | assertEquals("Foo:b", vanilla.b);
67 |
68 | assertEquals("a", burnt.a);
69 | assertEquals("Foo:b", burnt.b);
70 | }
71 |
72 | public void testStringDeserOverideNoAfterburner() throws Exception
73 | {
74 | final String json = "{\"field\": \"value & value\"}";
75 | final String EXP = "value & value";
76 | Issue59Bean resultVanilla = new ObjectMapper()
77 | .registerModule(new SimpleModule("module", Version.unknownVersion())
78 | .addDeserializer(String.class, new DeAmpDeserializer()))
79 | .readValue(json, Issue59Bean.class);
80 | assertEquals(EXP, resultVanilla.field);
81 | }
82 |
83 | // for [module-afterburner#59]
84 | public void testStringDeserOverideWithAfterburner() throws Exception
85 | {
86 | final String json = "{\"field\": \"value & value\"}";
87 | final String EXP = "value & value";
88 |
89 | final Module module = new SimpleModule("module", Version.unknownVersion()) {
90 | @Override
91 | public void setupModule(SetupContext context) {
92 | context.addDeserializers(
93 | new Deserializers.Base() {
94 | @Override
95 | public JsonDeserializer> findBeanDeserializer(
96 | JavaType type,
97 | DeserializationConfig config,
98 | BeanDescription beanDesc)
99 | throws JsonMappingException {
100 | if (type.hasRawClass(String.class)) {
101 | return new DeAmpDeserializer();
102 | }
103 | return null;
104 | }
105 | });
106 | }
107 | };
108 |
109 | // but then fails with Afterburner
110 | Issue59Bean resultAB = mapperWithModule()
111 | .registerModule(module)
112 | .readValue(json, Issue59Bean.class);
113 | assertEquals(EXP, resultAB.field);
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/deser/TestTreeConversions.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.deser;
2 |
3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4 |
5 | import com.fasterxml.jackson.databind.JsonNode;
6 | import com.fasterxml.jackson.databind.ObjectMapper;
7 | import com.fasterxml.jackson.module.afterburner.AfterburnerTestBase;
8 |
9 | public class TestTreeConversions extends AfterburnerTestBase
10 | {
11 | @JsonIgnoreProperties(ignoreUnknown = true)
12 | public static class Occupancy {
13 | private Integer max;
14 | private Guests adults;
15 | private Guests children;
16 |
17 | public Occupancy() {
18 | }
19 |
20 | public Occupancy(Integer max, Guests adults, Guests children) {
21 | this.max = max;
22 | this.adults = adults;
23 | this.children = children;
24 | }
25 |
26 | public Integer getMax() {
27 | return max;
28 | }
29 |
30 | public Guests getAdults() {
31 | return adults;
32 | }
33 |
34 | public Guests getChildren() {
35 | return children;
36 | }
37 |
38 | }
39 |
40 | @JsonIgnoreProperties(ignoreUnknown = true)
41 | public static class Guests {
42 |
43 | private Integer min;
44 | private Integer max;
45 |
46 | public Guests() {
47 | }
48 |
49 | public Guests(Integer min, Integer max) {
50 | this.min = min;
51 | this.max = max;
52 | }
53 |
54 | public Integer getMin() {
55 | return min;
56 | }
57 |
58 | public Integer getMax() {
59 | return max;
60 | }
61 |
62 | }
63 | /*
64 | /**********************************************************
65 | /* Actual tests
66 | /**********************************************************
67 | */
68 |
69 | private final ObjectMapper MAPPER = mapperWithModule();
70 |
71 | public void testConversion() throws Exception
72 | {
73 | final JsonNode node = MAPPER.readTree("{" +
74 | "\"max\":3," +
75 | "\"adults\": {" +
76 | "\"min\":1" +
77 | "}," +
78 | "\"children\":{" +
79 | "\"min\":1," +
80 | "\"max\":2" +
81 | "}" +
82 | "}");
83 |
84 | final Occupancy occupancy = MAPPER.readerFor(Occupancy.class).readValue(node);
85 |
86 | assertNull(occupancy.getAdults().getMax());
87 | assertEquals(Integer.valueOf(2), occupancy.getChildren().getMax());
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/roundtrip/AbstractSettersTest.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.roundtrip;
2 |
3 | import com.fasterxml.jackson.annotation.*;
4 | import com.fasterxml.jackson.databind.*;
5 | import com.fasterxml.jackson.module.afterburner.AfterburnerTestBase;
6 |
7 | // for [issue#47]
8 | public class AbstractSettersTest extends AfterburnerTestBase
9 | {
10 | @JsonTypeInfo(
11 | use = JsonTypeInfo.Id.NAME,
12 | include = JsonTypeInfo.As.PROPERTY,
13 | property = "type")
14 | @JsonSubTypes({
15 | @JsonSubTypes.Type(value = FooImpl1.class, name = "impl1") })
16 | @JsonInclude(JsonInclude.Include.NON_NULL)
17 | public interface FooBase extends Cloneable
18 | {
19 | String getId();
20 | void setId(String id);
21 |
22 | FooBase clone() throws CloneNotSupportedException;
23 | }
24 |
25 | static class FooImpl1 implements FooBase {
26 | protected String id, revision, category;
27 |
28 | @Override
29 | public String getId() { return id; }
30 |
31 | @Override
32 | public void setId(String id) { this.id = id; }
33 |
34 | @Override
35 | public FooBase clone() throws CloneNotSupportedException {
36 | return this;
37 | }
38 | }
39 |
40 | /*
41 | /**********************************************************
42 | /* Test methods
43 | /**********************************************************
44 | */
45 |
46 | private final ObjectMapper MAPPER = mapperWithModule();
47 |
48 | public void testSimpleConstructor() throws Exception
49 | {
50 | FooImpl1 item = new FooImpl1();
51 | String string = MAPPER.writer()
52 | .without(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
53 | .writeValueAsString(item);
54 | FooBase read = MAPPER.readValue(string, FooBase.class);
55 | assertNotNull(read);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/roundtrip/BiggerDataTest.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.roundtrip;
2 |
3 | import java.util.*;
4 |
5 | import com.fasterxml.jackson.databind.*;
6 | import com.fasterxml.jackson.module.afterburner.AfterburnerTestBase;
7 |
8 | /**
9 | * Bigger test to try to do smoke-testing of overall functionality,
10 | * using more sizable (500k of JSON, 200k of encoded data) dataset.
11 | * Should tease out at least some of boundary conditions.
12 | */
13 | public class BiggerDataTest extends AfterburnerTestBase
14 | {
15 | static class Citm
16 | {
17 | public Map areaNames;
18 | public Map audienceSubCategoryNames;
19 | public Map blockNames;
20 | public Map seatCategoryNames;
21 | public Map subTopicNames;
22 | public Map subjectNames;
23 | public Map topicNames;
24 | public Map topicSubTopics;
25 | public Map venueNames;
26 |
27 | public Map events;
28 | public List performances;
29 | }
30 |
31 | static class Event
32 | {
33 | public int id;
34 | public String name;
35 | public String description;
36 | public String subtitle;
37 | public String logo;
38 | public int subjectCode;
39 | public int[] topicIds;
40 | public LinkedHashSet subTopicIds;
41 | }
42 |
43 | static class Performance
44 | {
45 | public int id;
46 | public int eventId;
47 | public String name;
48 | public String description;
49 | public String logo;
50 |
51 | public List prices;
52 | public List seatCategories;
53 |
54 | public long start;
55 | public String seatMapImage;
56 | public String venueCode;
57 | }
58 |
59 | static class Price {
60 | public int amount;
61 | public int audienceSubCategoryId;
62 | public int seatCategoryId;
63 | }
64 |
65 | static class SeatCategory {
66 | public int seatCategoryId;
67 | public List areas;
68 | }
69 |
70 | static class Area {
71 | public int areaId;
72 | public int[] blockIds;
73 | }
74 |
75 | /*
76 | /**********************************************************
77 | /* Test methods
78 | /**********************************************************
79 | */
80 |
81 | private final ObjectMapper MAPPER = mapperWithModule();
82 |
83 | public void testReading() throws Exception
84 | {
85 | Citm citm0 = MAPPER.readValue(getClass().getResourceAsStream("/data/citm_catalog.json"),
86 | Citm.class);
87 |
88 | byte[] cbor = MAPPER.writeValueAsBytes(citm0);
89 |
90 | Citm citm = MAPPER.readValue(cbor, Citm.class);
91 |
92 | assertNotNull(citm);
93 | assertNotNull(citm.areaNames);
94 | assertEquals(17, citm.areaNames.size());
95 | assertNotNull(citm.events);
96 | assertEquals(184, citm.events.size());
97 |
98 | assertNotNull(citm.seatCategoryNames);
99 | assertEquals(64, citm.seatCategoryNames.size());
100 | assertNotNull(citm.subTopicNames);
101 | assertEquals(19, citm.subTopicNames.size());
102 | assertNotNull(citm.subjectNames);
103 | assertEquals(0, citm.subjectNames.size());
104 | assertNotNull(citm.topicNames);
105 | assertEquals(4, citm.topicNames.size());
106 | assertNotNull(citm.topicSubTopics);
107 | assertEquals(4, citm.topicSubTopics.size());
108 | assertNotNull(citm.venueNames);
109 | assertEquals(1, citm.venueNames.size());
110 | }
111 |
112 | public void testRoundTrip() throws Exception
113 | {
114 | Citm citm0 = MAPPER.readValue(getClass().getResourceAsStream("/data/citm_catalog.json"),
115 | Citm.class);
116 |
117 | byte[] cbor = MAPPER.writeValueAsBytes(citm0);
118 | Citm citm = MAPPER.readValue(cbor, Citm.class);
119 |
120 | byte[] smile1 = MAPPER.writeValueAsBytes(citm);
121 | Citm citm2 = MAPPER.readValue(smile1, Citm.class);
122 | byte[] smile2 = MAPPER.writeValueAsBytes(citm2);
123 |
124 | assertEquals(smile1.length, smile2.length);
125 |
126 | assertNotNull(citm.areaNames);
127 | assertEquals(17, citm.areaNames.size());
128 | assertNotNull(citm.events);
129 | assertEquals(184, citm.events.size());
130 |
131 | assertEquals(citm.seatCategoryNames.size(), citm2.seatCategoryNames.size());
132 | assertEquals(citm.subTopicNames.size(), citm2.subTopicNames.size());
133 | assertEquals(citm.subjectNames.size(), citm2.subjectNames.size());
134 | assertEquals(citm.topicNames.size(), citm2.topicNames.size());
135 | assertEquals(citm.topicSubTopics.size(), citm2.topicSubTopics.size());
136 | assertEquals(citm.venueNames.size(), citm2.venueNames.size());
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/roundtrip/JavaxTypesTest.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.roundtrip;
2 |
3 | import javax.security.auth.AuthPermission;
4 | import javax.xml.datatype.DatatypeFactory;
5 | import javax.xml.datatype.XMLGregorianCalendar;
6 |
7 | import com.fasterxml.jackson.databind.ObjectMapper;
8 | import com.fasterxml.jackson.module.afterburner.AfterburnerTestBase;
9 |
10 | /**
11 | * Simple tests to try to see that handling of semi-standard types
12 | * from javax.* work.
13 | */
14 | public class JavaxTypesTest extends AfterburnerTestBase
15 | {
16 | final ObjectMapper MAPPER = mapperWithModule();
17 |
18 | public void testGregorianCalendar() throws Exception
19 | {
20 | DatatypeFactory f = DatatypeFactory.newInstance();
21 | XMLGregorianCalendar in = f.newXMLGregorianCalendar();
22 | in.setYear(2014);
23 | in.setMonth(3);
24 |
25 | String json = MAPPER.writeValueAsString(in);
26 | assertNotNull(json);
27 | XMLGregorianCalendar out = MAPPER.readValue(json, XMLGregorianCalendar.class);
28 | assertNotNull(out);
29 |
30 | // minor sanity check
31 | assertEquals(in.getYear(), out.getYear());
32 | }
33 |
34 | public void testAuthPermission() throws Exception
35 | {
36 | AuthPermission in = new AuthPermission("foo");
37 | String json = MAPPER.writeValueAsString(in);
38 | assertNotNull(json);
39 |
40 | // actually, deserialization won't work by default. So let's just check
41 | // some lexical aspects
42 | if (!json.contains("\"name\":")) {
43 | fail("Unexpected JSON, missing 'name' property: "+json);
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/roundtrip/MediaItem.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.roundtrip;
2 |
3 | import java.util.*;
4 |
5 | import com.fasterxml.jackson.annotation.JsonPropertyOrder;
6 |
7 | @JsonPropertyOrder({"content", "images", "bogus"})
8 | public class MediaItem
9 | {
10 | public enum Player { JAVA, FLASH; }
11 | public enum Size { SMALL, LARGE; }
12 |
13 | private List _photos;
14 | private Content _content;
15 |
16 | // just to exercise boolean access
17 | public boolean bogus = true;
18 |
19 | public MediaItem() { }
20 |
21 | public MediaItem(Content c)
22 | {
23 | _content = c;
24 | }
25 |
26 | public void addPhoto(Photo p) {
27 | if (_photos == null) {
28 | _photos = new ArrayList();
29 | }
30 | _photos.add(p);
31 | }
32 |
33 | public List getImages() { return _photos; }
34 | public void setImages(List p) { _photos = p; }
35 |
36 | public Content getContent() { return _content; }
37 | public void setContent(Content c) { _content = c; }
38 |
39 | /*
40 | /**********************************************************
41 | /* Helper types
42 | /**********************************************************
43 | */
44 |
45 | @JsonPropertyOrder({"uri","title","width","height","size"})
46 | public static class Photo
47 | {
48 | private String _uri;
49 | private String _title;
50 | private int _width;
51 | private int _height;
52 | private Size _size;
53 |
54 | public Photo() {}
55 | public Photo(String uri, String title, int w, int h, Size s)
56 | {
57 | _uri = uri;
58 | _title = title;
59 | _width = w;
60 | _height = h;
61 | _size = s;
62 | }
63 |
64 | public String getUri() { return _uri; }
65 | public String getTitle() { return _title; }
66 | public int getWidth() { return _width; }
67 | public int getHeight() { return _height; }
68 | public Size getSize() { return _size; }
69 |
70 | public void setUri(String u) { _uri = u; }
71 | public void setTitle(String t) { _title = t; }
72 | public void setWidth(int w) { _width = w; }
73 | public void setHeight(int h) { _height = h; }
74 | public void setSize(Size s) { _size = s; }
75 | }
76 |
77 | @JsonPropertyOrder({"uri","title","width","height","format","duration","size","bitrate","persons","player","copyright"})
78 | public static class Content
79 | {
80 | private Player _player;
81 | private String _uri;
82 | private String _title;
83 | private int _width;
84 | private int _height;
85 | private String _format;
86 | private long _duration;
87 | private long _size;
88 | private int _bitrate;
89 | private List _persons;
90 | private String _copyright;
91 |
92 | public Content() { }
93 |
94 | public void addPerson(String p) {
95 | if (_persons == null) {
96 | _persons = new ArrayList();
97 | }
98 | _persons.add(p);
99 | }
100 |
101 | public Player getPlayer() { return _player; }
102 | public String getUri() { return _uri; }
103 | public String getTitle() { return _title; }
104 | public int getWidth() { return _width; }
105 | public int getHeight() { return _height; }
106 | public String getFormat() { return _format; }
107 | public long getDuration() { return _duration; }
108 | public long getSize() { return _size; }
109 | public int getBitrate() { return _bitrate; }
110 | public List getPersons() { return _persons; }
111 | public String getCopyright() { return _copyright; }
112 |
113 | public void setPlayer(Player p) { _player = p; }
114 | public void setUri(String u) { _uri = u; }
115 | public void setTitle(String t) { _title = t; }
116 | public void setWidth(int w) { _width = w; }
117 | public void setHeight(int h) { _height = h; }
118 | public void setFormat(String f) { _format = f; }
119 | public void setDuration(long d) { _duration = d; }
120 | public void setSize(long s) { _size = s; }
121 | public void setBitrate(int b) { _bitrate = b; }
122 | public void setPersons(List p) { _persons = p; }
123 | public void setCopyright(String c) { _copyright = c; }
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/roundtrip/MediaItemRoundtripTest.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.roundtrip;
2 |
3 | import com.fasterxml.jackson.databind.ObjectMapper;
4 |
5 | import com.fasterxml.jackson.module.afterburner.AfterburnerTestBase;
6 |
7 | /**
8 | * Let's use a non-trivial POJO from "jvm-serializers" benchmark as
9 | * sort of sanity check.
10 | */
11 | public class MediaItemRoundtripTest extends AfterburnerTestBase
12 | {
13 | private final ObjectMapper MAPPER = mapperWithModule();
14 |
15 | public void testSimple() throws Exception
16 | {
17 | MediaItem input = buildItem();
18 |
19 | String json = MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(input);
20 | MediaItem result = MAPPER.readValue(json, MediaItem.class);
21 |
22 | String json2 = MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(result);
23 |
24 | assertEquals(json, json2);
25 | }
26 |
27 | private MediaItem buildItem() {
28 | MediaItem.Content content = new MediaItem.Content();
29 | content.setUri("http://javaone.com/keynote.mpg");
30 | content.setTitle("Javaone Keynote");
31 | content.setWidth(640);
32 | content.setHeight(480);
33 | content.setFormat("video/mpg4");
34 | content.setDuration(18000000);
35 | content.setSize(58982400L);
36 | content.setBitrate(262144);
37 | content.setPlayer(MediaItem.Player.JAVA);
38 | content.setCopyright("None");
39 | content.addPerson("Bill Gates");
40 | content.addPerson("Steve Jobs");
41 |
42 | MediaItem item = new MediaItem(content);
43 | item.addPhoto(new MediaItem.Photo("http://javaone.com/keynote_large.jpg", "Javaone Keynote",
44 | 1024, 768, MediaItem.Size.LARGE));
45 | item.addPhoto(new MediaItem.Photo("http://javaone.com/keynote_small.jpg", "Javaone Keynote",
46 | 320, 240, MediaItem.Size.SMALL));
47 | return item;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/roundtrip/POJOAsArrayTest.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.roundtrip;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import com.fasterxml.jackson.annotation.JsonPropertyOrder;
5 | import com.fasterxml.jackson.annotation.JsonFormat.Shape;
6 | import com.fasterxml.jackson.databind.ObjectMapper;
7 | import com.fasterxml.jackson.databind.SerializationFeature;
8 | import com.fasterxml.jackson.databind.introspect.Annotated;
9 | import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
10 | import com.fasterxml.jackson.module.afterburner.AfterburnerTestBase;
11 |
12 | // NOTE: copied almost verbatim from jackson-databind tests
13 | public class POJOAsArrayTest extends AfterburnerTestBase
14 | {
15 | static class Pojo
16 | {
17 | @JsonFormat(shape=JsonFormat.Shape.ARRAY)
18 | public PojoValue value;
19 |
20 | public Pojo() { }
21 | public Pojo(String name, int x, int y, boolean c) {
22 | value = new PojoValue(name, x, y, c);
23 | }
24 | }
25 |
26 | // note: must be serialized/deserialized alphabetically; fields NOT declared in that order
27 | @JsonPropertyOrder(alphabetic=true)
28 | static class PojoValue
29 | {
30 | public int x, y;
31 | public String name;
32 | public boolean complete;
33 |
34 | public PojoValue() { }
35 | public PojoValue(String name, int x, int y, boolean c) {
36 | this.name = name;
37 | this.x = x;
38 | this.y = y;
39 | this.complete = c;
40 | }
41 | }
42 |
43 | @JsonPropertyOrder(alphabetic=true)
44 | @JsonFormat(shape=JsonFormat.Shape.ARRAY)
45 | static class FlatPojo
46 | {
47 | public int x, y;
48 | public String name;
49 | public boolean complete;
50 |
51 | public FlatPojo() { }
52 | public FlatPojo(String name, int x, int y, boolean c) {
53 | this.name = name;
54 | this.x = x;
55 | this.y = y;
56 | this.complete = c;
57 | }
58 | }
59 |
60 | static class ForceArraysIntrospector extends JacksonAnnotationIntrospector
61 | {
62 | private static final long serialVersionUID = 1L;
63 |
64 | @Override
65 | public JsonFormat.Value findFormat(Annotated a) {
66 | return new JsonFormat.Value().withShape(JsonFormat.Shape.ARRAY);
67 | }
68 | }
69 |
70 | static class A {
71 | public B value = new B();
72 | }
73 |
74 | @JsonPropertyOrder(alphabetic=true)
75 | static class B {
76 | public int x = 1;
77 | public int y = 2;
78 | }
79 |
80 | // for [JACKSON-805]
81 | @JsonFormat(shape=Shape.ARRAY)
82 | static class SingleBean {
83 | public String name = "foo";
84 | }
85 |
86 | @JsonPropertyOrder(alphabetic=true)
87 | @JsonFormat(shape=Shape.ARRAY)
88 | static class TwoStringsBean {
89 | public String bar = null;
90 | public String foo = "bar";
91 | }
92 |
93 | /*
94 | /*****************************************************
95 | /* Basic tests
96 | /*****************************************************
97 | */
98 |
99 | final ObjectMapper MAPPER = mapperWithModule();
100 |
101 | /**
102 | * Test that verifies that property annotation works
103 | */
104 | public void testReadSimplePropertyValue() throws Exception
105 | {
106 | String json = "{\"value\":[true,\"Foobar\",42,13]}";
107 | Pojo p = MAPPER.readValue(json, Pojo.class);
108 | assertNotNull(p.value);
109 | assertTrue(p.value.complete);
110 | assertEquals("Foobar", p.value.name);
111 | assertEquals(42, p.value.x);
112 | assertEquals(13, p.value.y);
113 | }
114 |
115 | /**
116 | * Test that verifies that Class annotation works
117 | */
118 | public void testReadSimpleRootValue() throws Exception
119 | {
120 | String json = "[false,\"Bubba\",1,2]";
121 | FlatPojo p = MAPPER.readValue(json, FlatPojo.class);
122 | assertFalse(p.complete);
123 | assertEquals("Bubba", p.name);
124 | assertEquals(1, p.x);
125 | assertEquals(2, p.y);
126 | }
127 |
128 | /**
129 | * Test that verifies that property annotation works
130 | */
131 | public void testWriteSimplePropertyValue() throws Exception
132 | {
133 | String json = MAPPER.writeValueAsString(new Pojo("Foobar", 42, 13, true));
134 | // will have wrapper POJO, then POJO-as-array..
135 | assertEquals("{\"value\":[true,\"Foobar\",42,13]}", json);
136 | }
137 |
138 | /**
139 | * Test that verifies that Class annotation works
140 | */
141 | public void testWriteSimpleRootValue() throws Exception
142 | {
143 | String json = MAPPER.writeValueAsString(new FlatPojo("Bubba", 1, 2, false));
144 | // will have wrapper POJO, then POJO-as-array..
145 | assertEquals("[false,\"Bubba\",1,2]", json);
146 | }
147 |
148 | // [Issue#223]
149 | public void testNullColumn() throws Exception
150 | {
151 | assertEquals("[null,\"bar\"]", MAPPER.writeValueAsString(new TwoStringsBean()));
152 | }
153 |
154 | /*
155 | /*****************************************************
156 | /* Compatibility with "single-elem as array" feature
157 | /*****************************************************
158 | */
159 |
160 | public void testSerializeAsArrayWithSingleProperty() throws Exception {
161 | ObjectMapper mapper = mapperWithModule();
162 | mapper.enable(SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED);
163 | String json = mapper.writeValueAsString(new SingleBean());
164 | assertEquals("\"foo\"", json);
165 | }
166 | }
167 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/ser/CustomBeanPropertyWriterTest.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.ser;
2 |
3 | import java.util.List;
4 |
5 | import com.fasterxml.jackson.annotation.JsonInclude;
6 | import com.fasterxml.jackson.core.*;
7 | import com.fasterxml.jackson.databind.*;
8 | import com.fasterxml.jackson.databind.module.SimpleModule;
9 | import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
10 | import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
11 | import com.fasterxml.jackson.module.afterburner.AfterburnerTestBase;
12 |
13 | // for [afterburner#52]
14 | public class CustomBeanPropertyWriterTest extends AfterburnerTestBase
15 | {
16 | static class SampleObject {
17 | public String field1;
18 | public Integer field2;
19 | public Integer field3;
20 |
21 | protected SampleObject() { }
22 | public SampleObject(String field1, Integer field2, Integer field3) {
23 | this.field1 = field1;
24 | this.field2 = field2;
25 | this.field3 = field3;
26 | }
27 | }
28 |
29 | static class Only2BeanSerializerModifier extends BeanSerializerModifier {
30 | @Override
31 | public List changeProperties(SerializationConfig config, BeanDescription beanDesc, List props)
32 | {
33 | for (int i = 0, len = props.size(); i < len; ++i) {
34 | BeanPropertyWriter w = props.get(i);
35 | if (Integer.class.isAssignableFrom(w.getType().getRawClass())) {
36 | props.set(i, new Only2BeanPropertyWriter(w));
37 | }
38 | }
39 | return props;
40 | }
41 | }
42 |
43 | @SuppressWarnings("serial")
44 | static class Only2BeanPropertyWriter extends BeanPropertyWriter
45 | {
46 | protected Only2BeanPropertyWriter(BeanPropertyWriter base) {
47 | super(base);
48 | }
49 |
50 | @Override
51 | public void serializeAsField(Object bean, JsonGenerator jgen, SerializerProvider prov) throws Exception {
52 | Object val = get(bean);
53 | if((val == null || !val.equals(2)) && _nullSerializer == null) {
54 | return;
55 | }
56 | super.serializeAsField(bean, jgen, prov);
57 | }
58 | }
59 |
60 | public void testCustomPropertyWriter() throws Exception
61 | {
62 | ObjectMapper objectMapper = mapperWithModule();
63 | SimpleModule simpleModule = new SimpleModule();
64 | simpleModule.setSerializerModifier(new Only2BeanSerializerModifier());
65 | objectMapper.registerModule(simpleModule);
66 | objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
67 |
68 | SampleObject sampleObject = new SampleObject(null, 2, 3);
69 | String json = objectMapper.writeValueAsString(sampleObject);
70 |
71 | assertEquals("{\"field2\":2}", json);
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/ser/JsonAppendTest.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.ser;
2 |
3 | import com.fasterxml.jackson.core.JsonGenerator;
4 | import com.fasterxml.jackson.databind.*;
5 | import com.fasterxml.jackson.databind.annotation.JsonAppend;
6 | import com.fasterxml.jackson.databind.cfg.MapperConfig;
7 | import com.fasterxml.jackson.databind.introspect.AnnotatedClass;
8 | import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
9 | import com.fasterxml.jackson.databind.ser.VirtualBeanPropertyWriter;
10 | import com.fasterxml.jackson.databind.util.Annotations;
11 | import com.fasterxml.jackson.module.afterburner.AfterburnerTestBase;
12 |
13 | // most for [module-afterburner#57]
14 | public class JsonAppendTest extends AfterburnerTestBase
15 | {
16 | @JsonAppend(props = @JsonAppend.Prop(name = "virtual", value = MyVirtualPropertyWriter.class))
17 | public static class Pojo {
18 | public final String name;
19 | public Pojo(String name) {
20 | this.name = name;
21 | }
22 | }
23 |
24 | @SuppressWarnings("serial")
25 | public static class MyVirtualPropertyWriter extends VirtualBeanPropertyWriter {
26 | protected MyVirtualPropertyWriter() { }
27 |
28 | protected MyVirtualPropertyWriter(BeanPropertyDefinition propDef, Annotations contextAnnotations,
29 | JavaType declaredType) {
30 | super(propDef, contextAnnotations, declaredType);
31 | }
32 | @Override
33 | protected Object value(Object bean, JsonGenerator g, SerializerProvider prov) throws Exception {
34 | return "bar";
35 | }
36 | @Override
37 | public VirtualBeanPropertyWriter withConfig(MapperConfig> config, AnnotatedClass declaringClass,
38 | BeanPropertyDefinition propDef, JavaType type) {
39 | return new MyVirtualPropertyWriter(propDef, declaringClass.getAnnotations(), type);
40 | }
41 | }
42 |
43 | public void testSimpleAppend() throws Exception
44 | {
45 | ObjectMapper mapper = mapperWithModule();
46 | // ObjectMapper mapper = new ObjectMapper();
47 | String json = mapper.writeValueAsString(new Pojo("foo"));
48 | assertEquals("{\"name\":\"foo\",\"virtual\":\"bar\"}", json);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/ser/SerializeWithViewTest.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.ser;
2 |
3 | import com.fasterxml.jackson.annotation.*;
4 | import com.fasterxml.jackson.databind.ObjectMapper;
5 |
6 | import com.fasterxml.jackson.module.afterburner.AfterburnerTestBase;
7 |
8 | public class SerializeWithViewTest extends AfterburnerTestBase
9 | {
10 | @JsonPropertyOrder({ "a", "b" })
11 | static class Bean {
12 | @JsonView({ String.class })
13 | public int a;
14 |
15 | @JsonView({ Integer.class, Character.class })
16 | public int b;
17 | }
18 |
19 | public void testWriterWithView() throws Exception
20 | {
21 | ObjectMapper mapper = mapperWithModule();
22 |
23 | String json = mapper.writeValueAsString(new Bean());
24 | // by default: both fields serialized
25 | assertEquals("{\"a\":0,\"b\":0}", json);
26 |
27 | // but with view enabled, just one
28 | json = mapper.writerWithView(Integer.class).writeValueAsString(new Bean());
29 | assertEquals("{\"b\":0}", json);
30 |
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/ser/TestAccessorGeneration.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.ser;
2 |
3 | import java.lang.reflect.Method;
4 |
5 | import com.fasterxml.jackson.databind.PropertyName;
6 | import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
7 | import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
8 | import com.fasterxml.jackson.databind.util.SimpleBeanPropertyDefinition;
9 | import com.fasterxml.jackson.module.afterburner.AfterburnerTestBase;
10 |
11 | public class TestAccessorGeneration extends AfterburnerTestBase
12 | {
13 | /*
14 | /**********************************************************************
15 | /* Helper types
16 | /**********************************************************************
17 | */
18 |
19 | public static class Bean1 {
20 | public int getX() { return 13; }
21 | }
22 |
23 | public static class Bean3 {
24 | public int getX() { return 13; }
25 | public int getY() { return 27; }
26 | public int get3() { return 3; }
27 | }
28 |
29 | public static class BeanN {
30 | public int getX() { return 13; }
31 | public int getY() { return 27; }
32 |
33 | public int get3() { return 3; }
34 | public int get4() { return 4; }
35 | public int get5() { return 5; }
36 | public int get6() { return 6; }
37 | public int get7() { return 7; }
38 | }
39 |
40 | /*
41 | /**********************************************************************
42 | /* Test methods
43 | /**********************************************************************
44 | */
45 |
46 | public void testSingleIntAccessorGeneration() throws Exception
47 | {
48 | Method method = Bean1.class.getDeclaredMethod("getX");
49 | AnnotatedMethod annMethod = new AnnotatedMethod(null, method, null, null);
50 | PropertyAccessorCollector coll = new PropertyAccessorCollector(Bean1.class);
51 | BeanPropertyWriter bpw = new BeanPropertyWriter(SimpleBeanPropertyDefinition
52 | .construct(null, annMethod, new PropertyName("x")),
53 | annMethod, null,
54 | null,
55 | null, null, null,
56 | false, null);
57 | coll.addIntGetter(bpw);
58 | BeanPropertyAccessor acc = coll.findAccessor(null);
59 | Bean1 bean = new Bean1();
60 | int value = acc.intGetter(bean, 0);
61 | assertEquals(bean.getX(), value);
62 | }
63 |
64 | public void testDualIntAccessorGeneration() throws Exception
65 | {
66 | PropertyAccessorCollector coll = new PropertyAccessorCollector(Bean3.class);
67 |
68 | String[] methodNames = new String[] {
69 | "getX", "getY", "get3"
70 | };
71 |
72 | /*
73 | public BeanPropertyWriter(BeanPropertyDefinition propDef,
74 | AnnotatedMember member, Annotations contextAnnotations,
75 | JavaType declaredType,
76 | JsonSerializer ser, TypeSerializer typeSer, JavaType serType,
77 | boolean suppressNulls, Object suppressableValue)
78 | */
79 |
80 | for (String methodName : methodNames) {
81 | Method method = Bean3.class.getDeclaredMethod(methodName);
82 | AnnotatedMethod annMethod = new AnnotatedMethod(null, method, null, null);
83 | // should we translate from method name to property name?
84 | coll.addIntGetter(new BeanPropertyWriter(SimpleBeanPropertyDefinition
85 | .construct(null, annMethod, new PropertyName(methodName)),
86 | annMethod, null,
87 | null,
88 | null, null, null,
89 | false, null));
90 | }
91 |
92 | BeanPropertyAccessor acc = coll.findAccessor(null);
93 | Bean3 bean = new Bean3();
94 |
95 | assertEquals(bean.getX(), acc.intGetter(bean, 0));
96 | assertEquals(bean.getY(), acc.intGetter(bean, 1));
97 | assertEquals(bean.get3(), acc.intGetter(bean, 2));
98 | }
99 |
100 | // And then test to ensure Switch-table construction also works...
101 | public void testLotsaIntAccessorGeneration() throws Exception
102 | {
103 | PropertyAccessorCollector coll = new PropertyAccessorCollector(BeanN.class);
104 | String[] methodNames = new String[] {
105 | "getX", "getY", "get3", "get4", "get5", "get6", "get7"
106 | };
107 | for (String methodName : methodNames) {
108 | Method method = BeanN.class.getDeclaredMethod(methodName);
109 | AnnotatedMethod annMethod = new AnnotatedMethod(null, method, null, null);
110 | coll.addIntGetter(new BeanPropertyWriter(SimpleBeanPropertyDefinition.construct(
111 | null, annMethod, new PropertyName(methodName)),
112 | annMethod, null,
113 | null,
114 | null, null, null,
115 | false, null));
116 | }
117 |
118 | BeanPropertyAccessor acc = coll.findAccessor(null);
119 | BeanN bean = new BeanN();
120 |
121 | assertEquals(bean.getX(), acc.intGetter(bean, 0));
122 | assertEquals(bean.getY(), acc.intGetter(bean, 1));
123 |
124 | assertEquals(bean.get3(), acc.intGetter(bean, 2));
125 | assertEquals(bean.get4(), acc.intGetter(bean, 3));
126 | assertEquals(bean.get5(), acc.intGetter(bean, 4));
127 | assertEquals(bean.get6(), acc.intGetter(bean, 5));
128 | assertEquals(bean.get7(), acc.intGetter(bean, 6));
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/ser/TestInclusionAnnotations.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.ser;
2 |
3 | import com.fasterxml.jackson.annotation.JsonInclude;
4 |
5 | import com.fasterxml.jackson.databind.ObjectMapper;
6 |
7 | import com.fasterxml.jackson.module.afterburner.AfterburnerTestBase;
8 |
9 | public class TestInclusionAnnotations extends AfterburnerTestBase
10 | {
11 | static class IntWrapper
12 | {
13 | @JsonInclude(JsonInclude.Include.NON_NULL)
14 | public Integer value;
15 |
16 | public IntWrapper(Integer v) { value = v; }
17 | }
18 |
19 | static class NonEmptyIntWrapper {
20 | private int value;
21 | public NonEmptyIntWrapper(int v) { value = v; }
22 | @JsonInclude(JsonInclude.Include.NON_EMPTY)
23 | public int getValue() { return value; }
24 | }
25 |
26 | @JsonInclude(JsonInclude.Include.NON_EMPTY)
27 | static class NonEmptyIntWrapper2 {
28 | public int value;
29 | public NonEmptyIntWrapper2(int v) { value = v; }
30 | }
31 |
32 | // But whereas 'empty' should NOT include '0', 'default' for property should
33 | static class NonDefaultIntWrapper {
34 | private int value;
35 | public NonDefaultIntWrapper(int v) { value = v; }
36 | @JsonInclude(JsonInclude.Include.NON_DEFAULT)
37 | public int getValue() { return value; }
38 | }
39 |
40 | public class NonEmptyStringWrapper {
41 | @JsonInclude(JsonInclude.Include.NON_EMPTY)
42 | public String value;
43 | public NonEmptyStringWrapper(String v) { value = v; }
44 | }
45 |
46 | @JsonInclude(JsonInclude.Include.NON_EMPTY)
47 | public class NonEmptyStringWrapper2 {
48 | public String value;
49 | public NonEmptyStringWrapper2(String v) { value = v; }
50 | }
51 |
52 | public class AnyWrapper
53 | {
54 | public String name = "Foo";
55 |
56 | @JsonInclude(JsonInclude.Include.NON_NULL)
57 | public Object wrapped;
58 |
59 | public AnyWrapper(Object w) { wrapped = w; }
60 | }
61 |
62 | /*
63 | /**********************************************************************
64 | /* Test methods
65 | /**********************************************************************
66 | */
67 |
68 | public void testIncludeUsingAnnotation() throws Exception
69 | {
70 | ObjectMapper mapper = mapperWithModule();
71 |
72 | String json = mapper.writeValueAsString(new IntWrapper(3));
73 | assertEquals("{\"value\":3}", json);
74 | json = mapper.writeValueAsString(new IntWrapper(null));
75 | assertEquals("{}", json);
76 |
77 | json = mapper.writeValueAsString(new AnyWrapper(new IntWrapper(null)));
78 | assertEquals("{\"name\":\"Foo\",\"wrapped\":{}}", json);
79 | json = mapper.writeValueAsString(new AnyWrapper(null));
80 | assertEquals("{\"name\":\"Foo\"}", json);
81 | }
82 |
83 | // [module-afterburner#39]
84 | public void testEmptyExclusion() throws Exception
85 | {
86 | ObjectMapper mapper = mapperWithModule();
87 | String json;
88 |
89 | json = mapper.writeValueAsString(new NonEmptyIntWrapper(3));
90 | assertEquals("{\"value\":3}", json);
91 | // as per [module-afterburner#63], ints should not have "empty" value
92 | // (temporarily, for 2.6, they did have)
93 | json = mapper.writeValueAsString(new NonEmptyIntWrapper(0));
94 | assertEquals("{\"value\":0}", json);
95 |
96 | json = mapper.writeValueAsString(new NonEmptyStringWrapper("x"));
97 | assertEquals("{\"value\":\"x\"}", json);
98 | json = mapper.writeValueAsString(new NonEmptyStringWrapper(""));
99 | assertEquals("{}", json);
100 | json = mapper.writeValueAsString(new NonEmptyStringWrapper(null));
101 | assertEquals("{}", json);
102 | }
103 |
104 | public void testEmptyExclusionViaClass() throws Exception
105 | {
106 | ObjectMapper mapper = mapperWithModule();
107 |
108 | assertEquals("{\"value\":3}",
109 | mapper.writeValueAsString(new NonEmptyIntWrapper2(3)));
110 | assertEquals("{\"value\":0}",
111 | mapper.writeValueAsString(new NonEmptyIntWrapper2(0)));
112 |
113 | assertEquals("{\"value\":\"x\"}",
114 | mapper.writeValueAsString(new NonEmptyStringWrapper2("x")));
115 | assertEquals("{}",
116 | mapper.writeValueAsString(new NonEmptyStringWrapper2("")));
117 | assertEquals("{}",
118 | mapper.writeValueAsString(new NonEmptyStringWrapper2(null)));
119 | }
120 |
121 | public void testDefaultExclusion() throws Exception
122 | {
123 | ObjectMapper mapper = mapperWithModule();
124 | String json;
125 |
126 | json = mapper.writeValueAsString(new NonDefaultIntWrapper(3));
127 | assertEquals("{\"value\":3}", json);
128 | json = mapper.writeValueAsString(new NonDefaultIntWrapper(0));
129 | assertEquals("{}", json);
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/ser/TestInterfaceSerialize.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.ser;
2 |
3 | import com.fasterxml.jackson.databind.ObjectMapper;
4 | import com.fasterxml.jackson.module.afterburner.AfterburnerTestBase;
5 |
6 | public class TestInterfaceSerialize extends AfterburnerTestBase
7 | {
8 | public interface Wat
9 | {
10 | String getFoo();
11 | }
12 |
13 | public void testInterfaceSerialize() throws Exception
14 | {
15 | ObjectMapper mapper = mapperWithModule();
16 |
17 | Wat wat = new Wat() {
18 | @Override
19 | public String getFoo() {
20 | return "bar";
21 | }
22 | };
23 |
24 | // Causes IncompatibleClassChangeError
25 | assertEquals("{\"foo\":\"bar\"}", mapper.writerFor(Wat.class).writeValueAsString(wat));
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/ser/TestJsonFilter.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.ser;
2 |
3 | import com.fasterxml.jackson.annotation.*;
4 | import com.fasterxml.jackson.databind.*;
5 | import com.fasterxml.jackson.databind.ser.FilterProvider;
6 | import com.fasterxml.jackson.databind.ser.impl.*;
7 | import com.fasterxml.jackson.module.afterburner.AfterburnerTestBase;
8 |
9 | /**
10 | * Tests for verifying that bean property filtering using JsonFilter
11 | * works as expected.
12 | */
13 | public class TestJsonFilter extends AfterburnerTestBase
14 | {
15 | @JsonFilter("RootFilter")
16 | static class Bean {
17 | public String a = "a";
18 | public String b = "b";
19 | }
20 |
21 |
22 | // [Issue#89]
23 | static class Pod
24 | {
25 | protected String username;
26 |
27 | // @JsonProperty(value = "user_password")
28 | protected String userPassword;
29 |
30 | public String getUsername() {
31 | return username;
32 | }
33 |
34 | public void setUsername(String value) {
35 | this.username = value;
36 | }
37 |
38 | @JsonIgnore
39 | @JsonProperty(value = "user_password")
40 | public java.lang.String getUserPassword() {
41 | return userPassword;
42 | }
43 |
44 | @JsonProperty(value = "user_password")
45 | public void setUserPassword(String value) {
46 | this.userPassword = value;
47 | }
48 | }
49 |
50 | // [Issue#306]: JsonFilter for properties, too!
51 |
52 | @JsonPropertyOrder(alphabetic=true)
53 | static class FilteredProps
54 | {
55 | // will default to using "RootFilter", only including 'a'
56 | public Bean first = new Bean();
57 |
58 | // but minimal includes 'b'
59 | @JsonFilter("b")
60 | public Bean second = new Bean();
61 | }
62 |
63 | /*
64 | /**********************************************************
65 | /* Unit tests
66 | /**********************************************************
67 | */
68 |
69 | private final ObjectMapper MAPPER = mapperWithModule();
70 |
71 | public void testSimpleInclusionFilter() throws Exception
72 | {
73 | FilterProvider prov = new SimpleFilterProvider().addFilter("RootFilter",
74 | SimpleBeanPropertyFilter.filterOutAllExcept("a"));
75 | assertEquals("{\"a\":\"a\"}", MAPPER.writer(prov).writeValueAsString(new Bean()));
76 |
77 | // [JACKSON-504]: also verify it works via mapper
78 | ObjectMapper mapper = new ObjectMapper();
79 | mapper.setFilterProvider(prov);
80 | assertEquals("{\"a\":\"a\"}", mapper.writeValueAsString(new Bean()));
81 | }
82 |
83 | public void testSimpleExclusionFilter() throws Exception
84 | {
85 | FilterProvider prov = new SimpleFilterProvider().addFilter("RootFilter",
86 | SimpleBeanPropertyFilter.serializeAllExcept("a"));
87 | assertEquals("{\"b\":\"b\"}", MAPPER.writer(prov).writeValueAsString(new Bean()));
88 | }
89 |
90 | // should handle missing case gracefully
91 | public void testMissingFilter() throws Exception
92 | {
93 | // First: default behavior should be to throw an exception
94 | try {
95 | MAPPER.writeValueAsString(new Bean());
96 | fail("Should have failed without configured filter");
97 | } catch (JsonMappingException e) { // should be resolved to a MappingException (internally may be something else)
98 | verifyException(e, "Can not resolve PropertyFilter with id 'RootFilter'");
99 | }
100 |
101 | // but when changing behavior, should work difference
102 | SimpleFilterProvider fp = new SimpleFilterProvider().setFailOnUnknownId(false);
103 | ObjectMapper mapper = new ObjectMapper();
104 | mapper.setFilterProvider(fp);
105 | String json = mapper.writeValueAsString(new Bean());
106 | assertEquals("{\"a\":\"a\",\"b\":\"b\"}", json);
107 | }
108 |
109 | // defaulting, as per [JACKSON-449]
110 | public void testDefaultFilter() throws Exception
111 | {
112 | FilterProvider prov = new SimpleFilterProvider().setDefaultFilter(SimpleBeanPropertyFilter.filterOutAllExcept("b"));
113 | assertEquals("{\"b\":\"b\"}", MAPPER.writer(prov).writeValueAsString(new Bean()));
114 | }
115 |
116 | // [Issue#89] combining @JsonIgnore, @JsonProperty
117 | public void testIssue89() throws Exception
118 | {
119 | ObjectMapper mapper = new ObjectMapper();
120 | Pod pod = new Pod();
121 | pod.username = "Bob";
122 | pod.userPassword = "s3cr3t!";
123 |
124 | String json = mapper.writeValueAsString(pod);
125 |
126 | assertEquals("{\"username\":\"Bob\"}", json);
127 |
128 | Pod pod2 = mapper.readValue("{\"username\":\"Bill\",\"user_password\":\"foo!\"}", Pod.class);
129 | assertEquals("Bill", pod2.username);
130 | assertEquals("foo!", pod2.userPassword);
131 | }
132 |
133 | // Wrt [Issue#306]
134 | public void testFilterOnProperty() throws Exception
135 | {
136 | FilterProvider prov = new SimpleFilterProvider()
137 | .addFilter("RootFilter", SimpleBeanPropertyFilter.filterOutAllExcept("a"))
138 | .addFilter("b", SimpleBeanPropertyFilter.filterOutAllExcept("b"));
139 |
140 | assertEquals("{\"first\":{\"a\":\"a\"},\"second\":{\"b\":\"b\"}}",
141 | MAPPER.writer(prov).writeValueAsString(new FilteredProps()));
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/ser/TestJsonSerializeAnnotationBug.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.ser;
2 |
3 | import java.math.BigDecimal;
4 |
5 | import com.fasterxml.jackson.annotation.JsonCreator;
6 | import com.fasterxml.jackson.annotation.JsonProperty;
7 |
8 | import com.fasterxml.jackson.databind.ObjectMapper;
9 | import com.fasterxml.jackson.databind.annotation.JsonSerialize;
10 | import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
11 |
12 | public class TestJsonSerializeAnnotationBug
13 | extends com.fasterxml.jackson.module.afterburner.AfterburnerTestBase
14 | {
15 | public static class TestObjectWithJsonSerialize {
16 | @JsonSerialize(using = ToStringSerializer.class)
17 | private final BigDecimal amount;
18 |
19 | @JsonCreator
20 | public TestObjectWithJsonSerialize(@JsonProperty("amount") BigDecimal amount) {
21 | this.amount = amount;
22 | }
23 |
24 | @JsonSerialize(using = ToStringSerializer.class) @JsonProperty("amount")
25 | public BigDecimal getAmount() {
26 | return amount;
27 | }
28 | }
29 |
30 | public void testAfterburnerModule() throws Exception
31 | {
32 | ObjectMapper mapper = mapperWithModule();
33 |
34 | String value = mapper.writeValueAsString(new TestObjectWithJsonSerialize(new BigDecimal("870.04")));
35 | assertNotNull(value);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/ser/TestRawValues.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.ser;
2 |
3 | import com.fasterxml.jackson.annotation.JsonRawValue;
4 | import com.fasterxml.jackson.databind.ObjectMapper;
5 | import com.fasterxml.jackson.module.afterburner.AfterburnerTestBase;
6 |
7 | public class TestRawValues extends AfterburnerTestBase
8 | {
9 | static class SerializableObject
10 | {
11 | public SerializableObject(String v) { value = v; }
12 |
13 | @JsonRawValue
14 | public String value;
15 | }
16 |
17 | /*
18 | /**********************************************************
19 | /* Unit tests
20 | /**********************************************************
21 | */
22 |
23 | private final ObjectMapper MAPPER = mapperWithModule();
24 |
25 | public void testAfterBurner() throws Exception
26 | {
27 | SerializableObject so = new SerializableObject("[123]");
28 |
29 | assertEquals("{\"value\":[123]}", MAPPER.writeValueAsString(so));
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/ser/TestStdSerializerOverrides.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.ser;
2 |
3 | import java.io.IOException;
4 |
5 | import com.fasterxml.jackson.core.JsonGenerator;
6 | import com.fasterxml.jackson.core.Version;
7 |
8 | import com.fasterxml.jackson.databind.ObjectMapper;
9 | import com.fasterxml.jackson.databind.SerializerProvider;
10 | import com.fasterxml.jackson.databind.annotation.JsonSerialize;
11 | import com.fasterxml.jackson.databind.module.SimpleModule;
12 | import com.fasterxml.jackson.databind.ser.std.StdSerializer;
13 |
14 | import com.fasterxml.jackson.module.afterburner.AfterburnerTestBase;
15 |
16 | public class TestStdSerializerOverrides extends AfterburnerTestBase
17 | {
18 | static class ClassWithPropOverrides
19 | {
20 | public String a = "a";
21 |
22 | @JsonSerialize(using=MyStringSerializer.class)
23 | public String b = "b";
24 | }
25 |
26 | @SuppressWarnings("serial")
27 | static class MyStringSerializer extends StdSerializer
28 | {
29 | public MyStringSerializer() { super(String.class); }
30 |
31 | @Override
32 | public void serialize(String value, JsonGenerator gen,
33 | SerializerProvider provider) throws IOException {
34 | gen.writeString("Foo:"+value);
35 | }
36 | }
37 |
38 | // for [module-afterburner#59]
39 | static class FooBean {
40 | public String field = "value";
41 | }
42 |
43 | /*
44 | /**********************************************************************
45 | /* Test methods
46 | /**********************************************************************
47 | */
48 |
49 | public void testFiveMinuteDoc() throws Exception
50 | {
51 | ObjectMapper plainMapper = new ObjectMapper();
52 | ObjectMapper abMapper = mapperWithModule();
53 | ClassWithPropOverrides input = new ClassWithPropOverrides();
54 | String jsonPlain = plainMapper.writeValueAsString(input);
55 | String jsonAb = abMapper.writeValueAsString(input);
56 | assertEquals(jsonPlain, jsonAb);
57 | }
58 |
59 | public void testStringSerOverideNoAfterburner() throws Exception
60 | {
61 | final FooBean input = new FooBean();
62 | final String EXP = "{\"field\":\"Foo:value\"}";
63 | String json = new ObjectMapper()
64 | .registerModule(new SimpleModule("module", Version.unknownVersion())
65 | .addSerializer(String.class, new MyStringSerializer()))
66 | .writeValueAsString(input);
67 | assertEquals(EXP, json);
68 | }
69 |
70 | public void testStringSerOverideWithAfterburner() throws Exception
71 | {
72 | final FooBean input = new FooBean();
73 | final String EXP = "{\"field\":\"Foo:value\"}";
74 | String json = mapperWithModule()
75 | .registerModule(new SimpleModule("module", Version.unknownVersion())
76 | .addSerializer(String.class, new MyStringSerializer()))
77 | .writeValueAsString(input);
78 | assertEquals(EXP, json);
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/test/java/com/fasterxml/jackson/module/afterburner/util/MyClassLoaderTest.java:
--------------------------------------------------------------------------------
1 | package com.fasterxml.jackson.module.afterburner.util;
2 |
3 | import com.fasterxml.jackson.module.afterburner.AfterburnerTestBase;
4 |
5 | public class MyClassLoaderTest extends AfterburnerTestBase
6 | {
7 | public void testNameReplacement() throws Exception
8 | {
9 | byte[] input = "Something with FOO in it (but not just FO!): FOOFOO".getBytes("UTF-8");
10 | int count = MyClassLoader.replaceName(input, "FOO", "BAR");
11 | assertEquals(3, count);
12 | assertEquals("Something with BAR in it (but not just FO!): BARBAR", new String(input, "UTF-8"));
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/test/java/perf/MediaItem.java:
--------------------------------------------------------------------------------
1 | package perf;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | public class MediaItem
7 | {
8 | public Media media;
9 | public List images;
10 |
11 | public MediaItem() { }
12 |
13 | public MediaItem addPhoto(Image i) {
14 | if (images == null) {
15 | images = new ArrayList();
16 | }
17 | images.add(i);
18 | return this;
19 | }
20 |
21 | static MediaItem buildItem()
22 | {
23 | Media content = new Media();
24 | content.player = Player.JAVA;
25 | content.uri = "http://javaone.com/keynote.mpg";
26 | content.title = "Javaone Keynote";
27 | content.width = 640;
28 | content.height = 480;
29 | content.format = "video/mpeg4";
30 | content.duration = 18000000L;
31 | content.size = 58982400L;
32 | content.bitrate = 262144;
33 | content.copyright = "None";
34 | content.addPerson("Bill Gates");
35 | content.addPerson("Steve Jobs");
36 |
37 | MediaItem item = new MediaItem();
38 | item.media = content;
39 |
40 | item.addPhoto(new Image("http://javaone.com/keynote_large.jpg", "Javaone Keynote", 1024, 768, Size.LARGE));
41 | item.addPhoto(new Image("http://javaone.com/keynote_small.jpg", "Javaone Keynote", 320, 240, Size.SMALL));
42 |
43 | return item;
44 | }
45 | }
46 |
47 | enum Size { SMALL, LARGE };
48 |
49 | class Image
50 | {
51 | public Image() { }
52 | public Image(String uri, String title, int w, int h, Size s) {
53 | this.uri = uri;
54 | this.title = title;
55 | width = w;
56 | height = h;
57 | size = s;
58 | }
59 |
60 | public String uri;
61 | public String title;
62 | public int width, height;
63 | public Size size;
64 | }
65 |
66 | enum Player { JAVA, FLASH; }
67 |
68 | class Media {
69 |
70 | public String uri;
71 | public String title; // Can be unset.
72 | public int width;
73 | public int height;
74 | public String format;
75 | public long duration;
76 | public long size;
77 | public int bitrate; // Can be unset.
78 | // public boolean hasBitrate;
79 |
80 | public List persons;
81 |
82 | public Player player;
83 |
84 | public String copyright; // Can be unset.
85 |
86 | public Media addPerson(String p) {
87 | if (persons == null) {
88 | persons = new ArrayList();
89 | }
90 | persons.add(p);
91 | return this;
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/test/java/perf/NopOutputStream.java:
--------------------------------------------------------------------------------
1 | package perf;
2 |
3 | import java.io.IOException;
4 | import java.io.OutputStream;
5 |
6 | class NopOutputStream extends OutputStream
7 | {
8 | public NopOutputStream() { }
9 |
10 | @Override
11 | public void write(int b) throws IOException { }
12 |
13 | @Override
14 | public void write(byte[] b) throws IOException { }
15 |
16 | @Override
17 | public void write(byte[] b, int offset, int len) throws IOException { }
18 | }
--------------------------------------------------------------------------------
/src/test/java/perf/TestPojo.java:
--------------------------------------------------------------------------------
1 | package perf;
2 |
3 | class TestPojo
4 | {
5 | public int a = 1, b;
6 | public String name = "Something";
7 | public Value value1, value2;
8 |
9 | public TestPojo() { }
10 | public TestPojo(int a, int b,
11 | String name, Value v) {
12 | this.a = a;
13 | this.b = b;
14 | this.name = name;
15 | this.value1 = v;
16 | this.value2 = v;
17 | }
18 | }
--------------------------------------------------------------------------------
/src/test/java/perf/Value.java:
--------------------------------------------------------------------------------
1 | package perf;
2 |
3 | class Value {
4 | public int x, y;
5 |
6 | public Value() { }
7 | public Value(int x, int y) {
8 | this.x = x;
9 | this.y = y;
10 | }
11 | }
--------------------------------------------------------------------------------
/src/test/java/perftest/TestDeserializePerf.java:
--------------------------------------------------------------------------------
1 | package perftest;
2 |
3 | import java.io.IOException;
4 |
5 | import com.fasterxml.jackson.core.JsonFactory;
6 | import com.fasterxml.jackson.databind.ObjectMapper;
7 |
8 | import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
9 |
10 | public class TestDeserializePerf
11 | {
12 | public final static class Bean
13 | {
14 | public int a, b, c123, d;
15 | public int e, foobar, g, habitus;
16 |
17 | public Bean setUp() {
18 | a = 1;
19 | b = 999;
20 | c123 = -1000;
21 | d = 13;
22 | e = 6;
23 | foobar = -33;
24 | g = 0;
25 | habitus = 123456789;
26 | return this;
27 | }
28 |
29 | public void setA(int v) { a = v; }
30 | public void setB(int v) { b = v; }
31 | public void setC(int v) { c123 = v; }
32 | public void setD(int v) { d = v; }
33 |
34 | public void setE(int v) { e = v; }
35 | public void setF(int v) { foobar = v; }
36 | public void setG(int v) { g = v; }
37 | public void setH(int v) { habitus = v; }
38 |
39 | @Override
40 | public int hashCode() {
41 | return a + b + c123 + d + e + foobar + g + habitus;
42 | }
43 | }
44 |
45 | public static void main(String[] args) throws Exception
46 | {
47 | // JsonFactory f = new org.codehaus.jackson.smile.SmileFactory();
48 | JsonFactory f = new JsonFactory();
49 | ObjectMapper mapperSlow = new ObjectMapper(f);
50 | ObjectMapper mapperFast = new ObjectMapper(f);
51 |
52 | // !!! TEST -- to get profile info, comment out:
53 | // mapperSlow.registerModule(new AfterburnerModule());
54 |
55 | mapperFast.registerModule(new AfterburnerModule());
56 | new TestDeserializePerf().testWith(mapperSlow, mapperFast);
57 | }
58 |
59 | private void testWith(ObjectMapper slowMapper, ObjectMapper fastMapper)
60 | throws IOException
61 | {
62 | byte[] json = slowMapper.writeValueAsBytes(new Bean().setUp());
63 | boolean fast = true;
64 |
65 | while (true) {
66 | long now = System.currentTimeMillis();
67 |
68 | ObjectMapper m = fast ? fastMapper : slowMapper;
69 | Bean bean = null;
70 |
71 | for (int i = 0; i < 199999; ++i) {
72 | bean = m.readValue(json, Bean.class);
73 | }
74 | long time = System.currentTimeMillis() - now;
75 |
76 | System.out.println("Mapper (fast: "+fast+"; "+bean.hashCode()+"); took "+time+" msecs");
77 |
78 | fast = !fast;
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/test/java/perftest/TestJvmDeserPerf.java:
--------------------------------------------------------------------------------
1 | package perftest;
2 |
3 | import com.fasterxml.jackson.core.JsonFactory;
4 | import com.fasterxml.jackson.core.JsonParser;
5 | import com.fasterxml.jackson.databind.JavaType;
6 | import com.fasterxml.jackson.databind.ObjectMapper;
7 | import com.fasterxml.jackson.databind.type.TypeFactory;
8 |
9 | /**
10 | * Micro-benchmark for comparing performance of bean deserialization
11 | */
12 | public final class TestJvmDeserPerf
13 | {
14 | /*
15 | /**********************************************************
16 | /* Actual test
17 | /**********************************************************
18 | */
19 |
20 | private final int REPS;
21 |
22 | private TestJvmDeserPerf() {
23 | // Let's try to guestimate suitable size
24 | REPS = 35000;
25 | }
26 |
27 | private MediaItem buildItem()
28 | {
29 | MediaItem.Content content = new MediaItem.Content();
30 | content.setPlayer(MediaItem.Content.Player.JAVA);
31 | content.setUri("http://javaone.com/keynote.mpg");
32 | content.setTitle("Javaone Keynote");
33 | content.setWidth(640);
34 | content.setHeight(480);
35 | content.setFormat("video/mpeg4");
36 | content.setDuration(18000000L);
37 | content.setSize(58982400L);
38 | content.setBitrate(262144);
39 | content.setCopyright("None");
40 | content.addPerson("Bill Gates");
41 | content.addPerson("Steve Jobs");
42 |
43 | MediaItem item = new MediaItem(content);
44 |
45 | item.addPhoto(new MediaItem.Photo("http://javaone.com/keynote_large.jpg", "Javaone Keynote", 1024, 768, MediaItem.Photo.Size.LARGE));
46 | item.addPhoto(new MediaItem.Photo("http://javaone.com/keynote_small.jpg", "Javaone Keynote", 320, 240, MediaItem.Photo.Size.SMALL));
47 |
48 | return item;
49 | }
50 |
51 | public void test()
52 | throws Exception
53 | {
54 | int sum = 0;
55 |
56 | final MediaItem item = buildItem();
57 | JsonFactory jsonF =
58 | // new org.codehaus.jackson.smile.SmileFactory();
59 | new JsonFactory()
60 | ;
61 |
62 | final ObjectMapper jsonMapper = new ObjectMapper(jsonF);
63 | jsonMapper.registerModule(new com.fasterxml.jackson.module.afterburner.AfterburnerModule());
64 |
65 | byte[] json = jsonMapper.writeValueAsBytes(item);
66 | System.out.println("Warmed up: data size is "+json.length+" bytes; "+REPS+" reps -> "
67 | +((REPS * json.length) >> 10)+" kB per iteration");
68 | System.out.println();
69 |
70 | int round = 0;
71 | while (true) {
72 | // try { Thread.sleep(100L); } catch (InterruptedException ie) { }
73 |
74 | round = (round + 1) % 2;
75 | long curr = System.currentTimeMillis();
76 | String msg;
77 | boolean lf = (round == 0);
78 |
79 | switch (round) {
80 |
81 | case 0:
82 | msg = "Deserialize/databind, JSON";
83 | sum += testDeser(jsonMapper, json, REPS);
84 | break;
85 |
86 | case 1:
87 | msg = "Deserialize/manual, JSON";
88 | sum += testDeser(jsonMapper.getFactory(), json, REPS);
89 | break;
90 |
91 | default:
92 | throw new Error("Internal error");
93 | }
94 |
95 | curr = System.currentTimeMillis() - curr;
96 | if (lf) {
97 | System.out.println();
98 | }
99 | System.out.println("Test '"+msg+"' -> "+curr+" msecs ("
100 | +(sum & 0xFF)+").");
101 | }
102 | }
103 |
104 | protected int testDeser(ObjectMapper mapper, byte[] input, int reps)
105 | throws Exception
106 | {
107 | JavaType type = TypeFactory.defaultInstance().constructType(MediaItem.class);
108 | MediaItem item = null;
109 | for (int i = 0; i < reps; ++i) {
110 | item = mapper.readValue(input, 0, input.length, type);
111 | }
112 | return item.hashCode(); // just to get some non-optimizable number
113 | }
114 |
115 | protected int testDeser(JsonFactory jf, byte[] input, int reps)
116 | throws Exception
117 | {
118 | MediaItem item = null;
119 | for (int i = 0; i < reps; ++i) {
120 | JsonParser jp = jf.createParser(input);
121 | item = MediaItem.deserialize(jp);
122 | jp.close();
123 | }
124 | return item.hashCode(); // just to get some non-optimizable number
125 | }
126 |
127 | public static void main(String[] args) throws Exception
128 | {
129 | new TestJvmDeserPerf().test();
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/src/test/java/perftest/TestJvmSerPerf.java:
--------------------------------------------------------------------------------
1 | package perftest;
2 |
3 | import java.io.ByteArrayOutputStream;
4 |
5 | import com.fasterxml.jackson.core.*;
6 |
7 | import com.fasterxml.jackson.databind.ObjectMapper;
8 |
9 | import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
10 |
11 | public final class TestJvmSerPerf
12 | {
13 | /*
14 | /**********************************************************
15 | /* Actual test
16 | /**********************************************************
17 | */
18 |
19 | private final int REPS;
20 |
21 | private TestJvmSerPerf() throws Exception
22 | {
23 | // Let's try to guestimate suitable size...
24 | REPS = 20000;
25 | }
26 |
27 | private MediaItem buildItem()
28 | {
29 | MediaItem.Content content = new MediaItem.Content();
30 | content.setPlayer(MediaItem.Content.Player.JAVA);
31 | content.setUri("http://javaone.com/keynote.mpg");
32 | content.setTitle("Javaone Keynote");
33 | content.setWidth(640);
34 | content.setHeight(480);
35 | content.setFormat("video/mpeg4");
36 | content.setDuration(18000000L);
37 | content.setSize(58982400L);
38 | content.setBitrate(262144);
39 | content.setCopyright("None");
40 | content.addPerson("Bill Gates");
41 | content.addPerson("Steve Jobs");
42 |
43 | MediaItem item = new MediaItem(content);
44 |
45 | item.addPhoto(new MediaItem.Photo("http://javaone.com/keynote_large.jpg", "Javaone Keynote", 1024, 768, MediaItem.Photo.Size.LARGE));
46 | item.addPhoto(new MediaItem.Photo("http://javaone.com/keynote_small.jpg", "Javaone Keynote", 320, 240, MediaItem.Photo.Size.SMALL));
47 |
48 | return item;
49 | }
50 |
51 | public void test()
52 | throws Exception
53 | {
54 | int i = 0;
55 | int sum = 0;
56 |
57 | ByteArrayOutputStream result = new ByteArrayOutputStream();
58 |
59 | final MediaItem item = buildItem();
60 | final JsonFactory jsonF =
61 | new JsonFactory()
62 | // new org.codehaus.jackson.smile.SmileFactory();
63 | ;
64 | // ((SmileFactory) jsonF).configure(SmileGenerator.Feature.CHECK_SHARED_NAMES, false);
65 |
66 | final ObjectMapper jsonMapper = new ObjectMapper(jsonF);
67 | jsonMapper.registerModule(new AfterburnerModule());
68 |
69 | // jsonMapper.configure(SerializationConfig.Feature.USE_STATIC_TYPING, true);
70 |
71 | /*
72 | final SmileFactory smileFactory = new SmileFactory();
73 | smileFactory.configure(SmileGenerator.Feature.CHECK_SHARED_NAMES, true);
74 | smileFactory.configure(SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES, false);
75 | final ObjectMapper smileMapper = new ObjectMapper(smileFactory);
76 | */
77 |
78 | while (true) {
79 | // Thread.sleep(150L);
80 | ++i;
81 | int round = (i % 2);
82 |
83 | // override?
84 | // round = 0;
85 |
86 | long curr = System.currentTimeMillis();
87 | String msg;
88 |
89 | switch (round) {
90 |
91 | case 0:
92 | msg = "Serialize, JSON/databind";
93 | sum += testObjectSer(jsonMapper, item, REPS+REPS, result);
94 | break;
95 |
96 | case 1:
97 | msg = "Serialize, JSON/manual";
98 | sum += testObjectSer(jsonMapper.getFactory(), item, REPS+REPS, result);
99 | break;
100 |
101 | /*
102 | case 2:
103 | msg = "Serialize, Smile";
104 | sum += testObjectSer(smileMapper, item, REPS, result);
105 | break;
106 |
107 | case 3:
108 | msg = "Serialize, Smile/manual";
109 | sum += testObjectSer(smileFactory, item, REPS+REPS, result);
110 | break;
111 | */
112 |
113 | default:
114 | throw new Error("Internal error");
115 | }
116 |
117 | curr = System.currentTimeMillis() - curr;
118 | // if (round == 0) { System.out.println(); }
119 | System.out.println("Test '"+msg+"' -> "+curr+" msecs ("+(sum & 0xFF)+").");
120 | if ((i & 0x1F) == 0) { // GC every 64 rounds
121 | System.out.println("[GC]");
122 | Thread.sleep(20L);
123 | System.gc();
124 | Thread.sleep(20L);
125 | }
126 | }
127 | }
128 |
129 | protected int testObjectSer(ObjectMapper mapper, Object value, int reps, ByteArrayOutputStream result)
130 | throws Exception
131 | {
132 | for (int i = 0; i < reps; ++i) {
133 | result.reset();
134 | mapper.writeValue(result, value);
135 | }
136 | return result.size(); // just to get some non-optimizable number
137 | }
138 |
139 | protected int testObjectSer(JsonFactory jf, MediaItem value, int reps, ByteArrayOutputStream result)
140 | throws Exception
141 | {
142 | for (int i = 0; i < reps; ++i) {
143 | result.reset();
144 | JsonGenerator jgen = jf.createGenerator(result, JsonEncoding.UTF8);
145 | value.serialize(jgen);
146 | jgen.close();
147 | }
148 | return result.size(); // just to get some non-optimizable number
149 | }
150 |
151 | public static void main(String[] args) throws Exception
152 | {
153 | new TestJvmSerPerf().test();
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/src/test/java/perftest/TestSerializePerf.java:
--------------------------------------------------------------------------------
1 | package perftest;
2 |
3 | import java.io.*;
4 |
5 | import com.fasterxml.jackson.core.JsonFactory;
6 |
7 | import com.fasterxml.jackson.databind.ObjectMapper;
8 |
9 | import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
10 |
11 | public class TestSerializePerf
12 | {
13 | public final static class IntBean
14 | {
15 | public int getA() { return 37; }
16 | public int getBaobab() { return -123; }
17 | public int getC() { return 0; }
18 | public int getDonkey() { return 999999; }
19 |
20 | public int getE() { return 1; }
21 | public int getFoobar() { return 21; }
22 | public int getG() { return 345; }
23 | public int getHibernate() { return 99; }
24 | }
25 |
26 | public static void main(String[] args) throws Exception
27 | {
28 | // JsonFactory f = new org.codehaus.jackson.smile.SmileFactory();
29 | JsonFactory f = new JsonFactory();
30 | ObjectMapper mapperSlow = new ObjectMapper(f);
31 | ObjectMapper mapperFast = new ObjectMapper(f);
32 |
33 | // !!! TEST -- to get profile info, comment out:
34 | mapperSlow.registerModule(new AfterburnerModule());
35 |
36 | mapperFast.registerModule(new AfterburnerModule());
37 | new TestSerializePerf().testWith(mapperSlow, mapperFast);
38 | }
39 |
40 | private void testWith(ObjectMapper slowMapper, ObjectMapper fastMapper)
41 | throws IOException
42 | {
43 | ByteArrayOutputStream out = new ByteArrayOutputStream();
44 | boolean fast = true;
45 | final IntBean bean = new IntBean();
46 |
47 | while (true) {
48 | long now = System.currentTimeMillis();
49 |
50 | ObjectMapper m = fast ? fastMapper : slowMapper;
51 | int len = 0;
52 |
53 | for (int i = 0; i < 399999; ++i) {
54 | out.reset();
55 | m.writeValue(out, bean);
56 | len = out.size();
57 | }
58 | long time = System.currentTimeMillis() - now;
59 |
60 | System.out.println("Mapper (fast: "+fast+"; "+len+"); took "+time+" msecs");
61 |
62 | fast = !fast;
63 | }
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------