package com.fasterxml.jackson.databind;
import com.fasterxml.jackson.core.SerializableString;
import com.fasterxml.jackson.core.io.SerializedString;
import com.fasterxml.jackson.core.util.InternCache;
import com.fasterxml.jackson.databind.cfg.MapperConfig;
import com.fasterxml.jackson.databind.util.ClassUtil;
Simple value class used for containing names of properties as defined
by annotations (and possibly other configuration sources).
Since: 2.1
/**
* Simple value class used for containing names of properties as defined
* by annotations (and possibly other configuration sources).
*
* @since 2.1
*/
public class PropertyName
implements java.io.Serializable
{
private static final long serialVersionUID = 1L; // 2.5
private final static String _USE_DEFAULT = "";
private final static String _NO_NAME = "";
Special placeholder value that indicates that name to use should be
based on the standard heuristics. This can be different from returning
null, as null means "no information available, whereas this value
indicates explicit defaulting.
/**
* Special placeholder value that indicates that name to use should be
* based on the standard heuristics. This can be different from returning
* null, as null means "no information available, whereas this value
* indicates explicit defaulting.
*/
public final static PropertyName USE_DEFAULT = new PropertyName(_USE_DEFAULT, null);
Special placeholder value that indicates that there is no name associated.
Exact semantics to use (if any) depend on actual annotation in use, but
commonly this value disables behavior for which name would be needed.
/**
* Special placeholder value that indicates that there is no name associated.
* Exact semantics to use (if any) depend on actual annotation in use, but
* commonly this value disables behavior for which name would be needed.
*/
public final static PropertyName NO_NAME = new PropertyName(new String(_NO_NAME), null);
Basic name of the property.
/**
* Basic name of the property.
*/
protected final String _simpleName;
Additional namespace, for formats that have such concept (JSON
does not, XML does, for example).
/**
* Additional namespace, for formats that have such concept (JSON
* does not, XML does, for example).
*/
protected final String _namespace;
Lazily-constructed efficient representation of the simple name.
NOTE: not defined as volatile to avoid performance problem with concurrent access in multi-core environments; due to statelessness of SerializedString
at most leads to multiple instantiations.
Since: 2.4
/**
* Lazily-constructed efficient representation of the simple name.
*<p>
* NOTE: not defined as volatile to avoid performance problem with
* concurrent access in multi-core environments; due to statelessness
* of {@link SerializedString} at most leads to multiple instantiations.
*
* @since 2.4
*/
protected SerializableString _encodedSimple;
public PropertyName(String simpleName) {
this(simpleName, null);
}
public PropertyName(String simpleName, String namespace)
{
_simpleName = ClassUtil.nonNullString(simpleName);
_namespace = namespace;
}
// To support JDK serialization, recovery of Singleton instance
protected Object readResolve() {
if (_namespace == null) {
if (_simpleName == null || _USE_DEFAULT.equals(_simpleName)) {
return USE_DEFAULT;
}
// 30-Oct-2016, tatu: I don't see how this could ever occur...
// or how to distinguish USE_DEFAULT/NO_NAME from serialized
/*
if (_simpleName.equals(_NO_NAME)) {
return NO_NAME;
}
*/
}
return this;
}
Since: 2.6
/**
* @since 2.6
*/
public static PropertyName construct(String simpleName)
{
if (simpleName == null || simpleName.length() == 0) {
return USE_DEFAULT;
}
return new PropertyName(InternCache.instance.intern(simpleName), null);
}
public static PropertyName construct(String simpleName, String ns)
{
if (simpleName == null) {
simpleName = "";
}
if (ns == null && simpleName.length() == 0) {
return USE_DEFAULT;
}
return new PropertyName(InternCache.instance.intern(simpleName), ns);
}
public PropertyName internSimpleName()
{
if (_simpleName.length() == 0) { // empty String is canonical already
return this;
}
String interned = InternCache.instance.intern(_simpleName);
if (interned == _simpleName) { // was already interned
return this;
}
return new PropertyName(interned, _namespace);
}
Fluent factory method for constructing an instance with different
simple name.
/**
* Fluent factory method for constructing an instance with different
* simple name.
*/
public PropertyName withSimpleName(String simpleName)
{
if (simpleName == null) {
simpleName = "";
}
if (simpleName.equals(_simpleName)) {
return this;
}
return new PropertyName(simpleName, _namespace);
}
Fluent factory method for constructing an instance with different
namespace.
/**
* Fluent factory method for constructing an instance with different
* namespace.
*/
public PropertyName withNamespace(String ns) {
if (ns == null) {
if (_namespace == null) {
return this;
}
} else if (ns.equals(_namespace)) {
return this;
}
return new PropertyName(_simpleName, ns);
}
/*
/**********************************************************
/* Accessors
/**********************************************************
*/
public String getSimpleName() {
return _simpleName;
}
Accessor that may be used to get lazily-constructed efficient
representation of the simple name.
Since: 2.4
/**
* Accessor that may be used to get lazily-constructed efficient
* representation of the simple name.
*
* @since 2.4
*/
public SerializableString simpleAsEncoded(MapperConfig<?> config) {
SerializableString sstr = _encodedSimple;
if (sstr == null) {
if (config == null) {
sstr = new SerializedString(_simpleName);
} else {
sstr = config.compileString(_simpleName);
}
_encodedSimple = sstr;
}
return sstr;
}
public String getNamespace() {
return _namespace;
}
public boolean hasSimpleName() {
return _simpleName.length() > 0;
}
Since: 2.3
/**
* @since 2.3
*/
public boolean hasSimpleName(String str) {
// _simpleName never null so...
return _simpleName.equals(str);
}
public boolean hasNamespace() {
return _namespace != null;
}
Method that is basically equivalent of:
!hasSimpleName() << !hasNamespace();
Since: 2.4
/**
* Method that is basically equivalent of:
*<pre>
* !hasSimpleName() << !hasNamespace();
*</pre>
*
* @since 2.4
*/
public boolean isEmpty() {
return (_namespace == null) && (_simpleName.isEmpty());
}
/*
/**********************************************************
/* Std method overrides
/**********************************************************
*/
@Override
public boolean equals(Object o)
{
if (o == this) return true;
if (o == null) return false;
/* 13-Nov-2012, tatu: by default, require strict type equality.
* Re-evaluate if this becomes an issue.
*/
if (o.getClass() != getClass()) return false;
// 13-Nov-2012, tatu: Should we have specific rules on matching USE_DEFAULT?
// (like, it only ever matching exact instance)
// If we did, would need to check symmetrically; that is, if either 'this'
// or 'o' was USE_DEFAULT, both would have to be.
PropertyName other = (PropertyName) o;
if (_simpleName == null) {
if (other._simpleName != null) return false;
} else if (!_simpleName.equals(other._simpleName)) {
return false;
}
if (_namespace == null) {
return (null == other._namespace);
}
return _namespace.equals(other._namespace);
}
@Override
public int hashCode() {
if (_namespace == null) {
return _simpleName.hashCode();
}
return _namespace.hashCode() ^ _simpleName.hashCode();
}
@Override
public String toString() {
if (_namespace == null) {
return _simpleName;
}
return "{"+_namespace + "}" + _simpleName;
}
}