All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.fasterxml.jackson.databind.PropertyName Maven / Gradle / Ivy

The newest version!
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;

import java.util.Objects;

/**
 * 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.
     */
    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.
     */
    public final static PropertyName NO_NAME = new PropertyName(new String(_NO_NAME), null);

    /**
     * Basic name of the property.
     */
    protected final String _simpleName;

    /**
     * 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 {@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 */ public static PropertyName construct(String simpleName) { if (simpleName == null || simpleName.isEmpty()) { 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.isEmpty()) { return USE_DEFAULT; } return new PropertyName(InternCache.instance.intern(simpleName), ns); } /** * Method that will combine information from two {@link PropertyName} * instances * * @param name1 Name with higher precedence; may be {@code null} * @param name2 Name with lower precedence; may be {@code null} * * @return Merged information; only {@code null} if both arguments * are {@code null}s. * * @since 2.17 */ public static PropertyName merge(PropertyName name1, PropertyName name2) { if (name1 == null) { return name2; } if (name2 == null) { return name1; } String ns = _nonEmpty(name1._namespace, name2._namespace); String simple = _nonEmpty(name1._simpleName, name2._simpleName); // But see if we can just return one of arguments as-is: if (ns == name1._namespace && simple == name1._simpleName) { return name1; } if (ns == name2._namespace && simple == name2._simpleName) { return name2; } return construct(simple, ns); } private static String _nonEmpty(String str1, String str2) { if (str1 == null) { return str2; } if (str2 == null) { return str1; } if (str1.isEmpty()) { return str2; } return str1; } public PropertyName internSimpleName() { if (_simpleName.isEmpty()) { // 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. */ 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. */ 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 */ 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.isEmpty(); } /** * @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 */ 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() { return Objects.hashCode(_simpleName) * 31 + Objects.hashCode(_namespace); } @Override public String toString() { if (_namespace == null) { return _simpleName; } return "{"+_namespace + "}" + _simpleName; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy