Skip to content

Commit

Permalink
Merge branch 'master' into merge-jdk8
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Sep 24, 2017
2 parents ed0d7b8 + 2122863 commit 3941e8f
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 136 deletions.
2 changes: 2 additions & 0 deletions release-notes/VERSION
Expand Up @@ -8,3 +8,5 @@ Versions: 3.x (for earlier see VERSION-2.x)
3.0.0 (not yet released)

#1762: `StdDateFormat`: serialize time offset using colon
#1772: Remove `MapperFeature. USE_STD_BEAN_NAMING`

16 changes: 0 additions & 16 deletions src/main/java/com/fasterxml/jackson/databind/MapperFeature.java
Expand Up @@ -382,22 +382,6 @@ public enum MapperFeature implements ConfigFeature
*/
USE_WRAPPER_NAME_AS_PROPERTY_NAME(false),

/**
* Feature that may be enabled to enforce strict compatibility with
* Bean name introspection, instead of slightly different mechanism
* Jackson defaults to.
* Specific difference is that Jackson always lower cases leading upper-case
* letters, so "getURL()" becomes "url" property; whereas standard Bean
* naming <b>only</b> lower-cases the first letter if it is NOT followed by
* another upper-case letter (so "getURL()" would result in "URL" property).
*<p>
* Feature is disabled by default for backwards compatibility purposes: earlier
* Jackson versions used Jackson's own mechanism.
*
* @since 2.5
*/
USE_STD_BEAN_NAMING(false),

/**
* Feature that when enabled will allow explicitly named properties (i.e., fields or methods
* annotated with {@link com.fasterxml.jackson.annotation.JsonProperty}("explicitName")) to
Expand Down
Expand Up @@ -37,11 +37,6 @@ public class POJOPropertiesCollector
*/
protected final boolean _forSerialization;

/**
* @since 2.5
*/
protected final boolean _stdBeanNaming;

/**
* Type of POJO for which properties are being collected.
*/
Expand Down Expand Up @@ -127,7 +122,6 @@ protected POJOPropertiesCollector(MapperConfig<?> config, boolean forSerializati
JavaType type, AnnotatedClass classDef, String mutatorPrefix)
{
_config = config;
_stdBeanNaming = config.isEnabled(MapperFeature.USE_STD_BEAN_NAMING);
_forSerialization = forSerialization;
_type = type;
_classDef = classDef;
Expand Down Expand Up @@ -566,10 +560,10 @@ protected void _addGetterMethod(Map<String, POJOPropertyBuilder> props,
if (!nameExplicit) { // no explicit name; must consider implicit
implName = ai.findImplicitPropertyName(m);
if (implName == null) {
implName = BeanUtil.okNameForRegularGetter(m, m.getName(), _stdBeanNaming);
implName = BeanUtil.okNameForRegularGetter(m, m.getName());
}
if (implName == null) { // if not, must skip
implName = BeanUtil.okNameForIsGetter(m, m.getName(), _stdBeanNaming);
implName = BeanUtil.okNameForIsGetter(m, m.getName());
if (implName == null) {
return;
}
Expand All @@ -581,7 +575,7 @@ protected void _addGetterMethod(Map<String, POJOPropertyBuilder> props,
// we still need implicit name to link with other pieces
implName = ai.findImplicitPropertyName(m);
if (implName == null) {
implName = BeanUtil.okNameForGetter(m, _stdBeanNaming);
implName = BeanUtil.okNameForGetter(m);
}
// if not regular getter name, use method name as is
if (implName == null) {
Expand All @@ -608,7 +602,7 @@ protected void _addSetterMethod(Map<String, POJOPropertyBuilder> props,
if (!nameExplicit) { // no explicit name; must follow naming convention
implName = (ai == null) ? null : ai.findImplicitPropertyName(m);
if (implName == null) {
implName = BeanUtil.okNameForMutator(m, _mutatorPrefix, _stdBeanNaming);
implName = BeanUtil.okNameForMutator(m, _mutatorPrefix);
}
if (implName == null) { // if not, must skip
return;
Expand All @@ -618,7 +612,7 @@ protected void _addSetterMethod(Map<String, POJOPropertyBuilder> props,
// we still need implicit name to link with other pieces
implName = (ai == null) ? null : ai.findImplicitPropertyName(m);
if (implName == null) {
implName = BeanUtil.okNameForMutator(m, _mutatorPrefix, _stdBeanNaming);
implName = BeanUtil.okNameForMutator(m, _mutatorPrefix);
}
// if not regular getter name, use method name as is
if (implName == null) {
Expand Down
89 changes: 15 additions & 74 deletions src/main/java/com/fasterxml/jackson/databind/util/BeanUtil.java
Expand Up @@ -6,7 +6,7 @@

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;

/**
* Helper class that contains functionality needed by both serialization
Expand All @@ -20,17 +20,16 @@ public class BeanUtil
/**********************************************************
*/

public static String okNameForGetter(AnnotatedMethod am, boolean stdNaming) {
public static String okNameForGetter(AnnotatedMember am) {
String name = am.getName();
String str = okNameForIsGetter(am, name, stdNaming);
String str = okNameForIsGetter(am, name);
if (str == null) {
str = okNameForRegularGetter(am, name, stdNaming);
str = okNameForRegularGetter(am, name);
}
return str;
}

public static String okNameForRegularGetter(AnnotatedMethod am, String name,
boolean stdNaming)
public static String okNameForRegularGetter(AnnotatedMember am, String name)
{
if (name.startsWith("get")) {
/* 16-Feb-2009, tatu: To handle [JACKSON-53], need to block
Expand All @@ -50,38 +49,27 @@ public static String okNameForRegularGetter(AnnotatedMethod am, String name,
return null;
}
}
return stdNaming
? stdManglePropertyName(name, 3)
: legacyManglePropertyName(name, 3);
return stdManglePropertyName(name, 3);
}
return null;
}

/**
* @since 2.5
*/
public static String okNameForIsGetter(AnnotatedMethod am, String name,
boolean stdNaming)
public static String okNameForIsGetter(AnnotatedMember am, String name)
{
if (name.startsWith("is")) { // plus, must return a boolean
Class<?> rt = am.getRawType();
if (rt == Boolean.class || rt == Boolean.TYPE) {
return stdNaming
? stdManglePropertyName(name, 2)
: legacyManglePropertyName(name, 2);
return stdManglePropertyName(name, 2);
}
}
return null;
}

public static String okNameForMutator(AnnotatedMethod am, String prefix,
boolean stdNaming)
public static String okNameForMutator(AnnotatedMember am, String prefix)
{
String name = am.getName();
if (name.startsWith(prefix)) {
return stdNaming
? stdManglePropertyName(name, prefix.length())
: legacyManglePropertyName(name, prefix.length());
return stdManglePropertyName(name, prefix.length());
}
return null;
}
Expand Down Expand Up @@ -148,7 +136,7 @@ public static Object getDefaultValue(JavaType type)
* indeed injectect by Cglib. We do this by verifying that the
* result type is "net.sf.cglib.proxy.Callback[]"
*/
protected static boolean isCglibGetCallbacks(AnnotatedMethod am)
protected static boolean isCglibGetCallbacks(AnnotatedMember am)
{
Class<?> rt = am.getRawType();
// Ok, first: must return an array type
Expand All @@ -173,21 +161,10 @@ protected static boolean isCglibGetCallbacks(AnnotatedMethod am)
return false;
}

/**
* Similar to {@link #isCglibGetCallbacks}, need to suppress
* a cyclic reference.
*/
protected static boolean isGroovyMetaClassSetter(AnnotatedMethod am)
{
Class<?> argType = am.getRawParameterType(0);
String pkgName = ClassUtil.getPackageName(argType);
return (pkgName != null) && pkgName.startsWith("groovy.lang");
}

/**
* Another helper method to deal with Groovy's problematic metadata accessors
*/
protected static boolean isGroovyMetaClassGetter(AnnotatedMethod am)
protected static boolean isGroovyMetaClassGetter(AnnotatedMember am)
{
String pkgName = ClassUtil.getPackageName(am.getRawType());
return (pkgName != null) && pkgName.startsWith("groovy.lang");
Expand All @@ -199,45 +176,9 @@ protected static boolean isGroovyMetaClassGetter(AnnotatedMethod am)
/**********************************************************
*/

/**
* Method called to figure out name of the property, given
* corresponding suggested name based on a method or field name.
*
* @param basename Name of accessor/mutator method, not including prefix
* ("get"/"is"/"set")
*/
protected static String legacyManglePropertyName(final String basename, final int offset)
{
final int end = basename.length();
if (end == offset) { // empty name, nope
return null;
}
// next check: is the first character upper case? If not, return as is
char c = basename.charAt(offset);
char d = Character.toLowerCase(c);

if (c == d) {
return basename.substring(offset);
}
// otherwise, lower case initial chars. Common case first, just one char
StringBuilder sb = new StringBuilder(end - offset);
sb.append(d);
int i = offset+1;
for (; i < end; ++i) {
c = basename.charAt(i);
d = Character.toLowerCase(c);
if (c == d) {
sb.append(basename, i, end);
break;
}
sb.append(d);
}
return sb.toString();
}

/**
* @since 2.5
*/
// 24-Sep-2017, tatu: note that "std" here refers to earlier (1.x, 2.x) distinction
// between "legacy" (slightly non-conforming) and "std" (fully conforming): with 3.x
// only latter exists.
protected static String stdManglePropertyName(final String basename, final int offset)
{
final int end = basename.length();
Expand Down
Expand Up @@ -16,18 +16,12 @@ public int getA() {
return 3;
}
}

public void testSimple() throws Exception
{
ObjectMapper mapper = new ObjectMapper();
assertFalse(mapper.isEnabled(MapperFeature.USE_STD_BEAN_NAMING));
assertEquals(aposToQuotes("{'url':'http://foo'}"),
mapper.writeValueAsString(new URLBean()));
assertEquals(aposToQuotes("{'a':3}"),
mapper.writeValueAsString(new ABean()));

mapper = new ObjectMapper();
mapper.enable(MapperFeature.USE_STD_BEAN_NAMING);
// 24-Sep-2017, tatu: Used to test for `MapperFeature.USE_STD_BEAN_NAMING`, but with 3.x
// that is always enabled.
public void testMultipleLeadingCapitalLetters() throws Exception
{
ObjectMapper mapper = objectMapper();
assertEquals(aposToQuotes("{'URL':'http://foo'}"),
mapper.writeValueAsString(new URLBean()));
assertEquals(aposToQuotes("{'a':3}"),
Expand Down
Expand Up @@ -37,10 +37,8 @@ public void set() { }

public void testNameMangle()
{
assertEquals("foo", BeanUtil.legacyManglePropertyName("getFoo", 3));
assertEquals("foo", BeanUtil.stdManglePropertyName("getFoo", 3));

assertEquals("url", BeanUtil.legacyManglePropertyName("getURL", 3));
assertEquals("URL", BeanUtil.stdManglePropertyName("getURL", 3));
}

Expand Down Expand Up @@ -98,45 +96,29 @@ public void testOkNameForSetter() throws Exception
*/

private void _testIsGetter(String name, String expName) throws Exception {
_testIsGetter(name, expName, true);
_testIsGetter(name, expName, false);
}

private void _testIsGetter(String name, String expName, boolean useStd) throws Exception
{
AnnotatedMethod m = _method(IsGetters.class, name);
if (expName == null) {
assertNull(BeanUtil.okNameForIsGetter(m, name, useStd));
assertNull(BeanUtil.okNameForIsGetter(m, name));
} else {
assertEquals(expName, BeanUtil.okNameForIsGetter(m, name, useStd));
assertEquals(expName, BeanUtil.okNameForIsGetter(m, name));
}
}

private void _testOkNameForGetter(String name, String expName) throws Exception {
_testOkNameForGetter(name, expName, true);
_testOkNameForGetter(name, expName, false);
}

private void _testOkNameForGetter(String name, String expName, boolean useStd) throws Exception {
AnnotatedMethod m = _method(Getters.class, name);
if (expName == null) {
assertNull(BeanUtil.okNameForGetter(m, useStd));
assertNull(BeanUtil.okNameForGetter(m));
} else {
assertEquals(expName, BeanUtil.okNameForGetter(m, useStd));
assertEquals(expName, BeanUtil.okNameForGetter(m));
}
}

private void _testOkNameForMutator(String name, String expName) throws Exception {
_testOkNameForMutator(name, expName, true);
_testOkNameForMutator(name, expName, false);
}

private void _testOkNameForMutator(String name, String expName, boolean useStd) throws Exception {
AnnotatedMethod m = _method(Setters.class, name);
if (expName == null) {
assertNull(BeanUtil.okNameForMutator(m, "set", useStd));
assertNull(BeanUtil.okNameForMutator(m, "set"));
} else {
assertEquals(expName, BeanUtil.okNameForMutator(m, "set", useStd));
assertEquals(expName, BeanUtil.okNameForMutator(m, "set"));
}
}

Expand Down

0 comments on commit 3941e8f

Please sign in to comment.