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

org.apache.commons.beanutils2.DynaProperty Maven / Gradle / Ivy

Go to download

Apache Commons BeanUtils provides an easy-to-use but flexible wrapper around reflection and introspection.

The newest version!
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.commons.beanutils2;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.io.StreamCorruptedException;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 

The metadata describing an individual property of a DynaBean.

* *

The meta contains an optional content type property ({@link #getContentType}) * for use by mapped and iterated properties. * A mapped or iterated property may choose to indicate the type it expects. * The DynaBean implementation may choose to enforce this type on its entries. * Alternatively, an implementation may choose to ignore this property. * All keys for maps must be of type String so no meta data is needed for map keys.

* */ public class DynaProperty implements Serializable { private static final long serialVersionUID = -3084907613499830175L; /* * There are issues with serializing primitive class types on certain JVM versions * (including java 1.3). * This class uses a custom serialization implementation that writes an integer * for these primitive class. * This list of constants are the ones used in serialization. * If these values are changed, then older versions will no longer be read correctly */ private static final int BOOLEAN_TYPE = 1; private static final int BYTE_TYPE = 2; private static final int CHAR_TYPE = 3; private static final int DOUBLE_TYPE = 4; private static final int FLOAT_TYPE = 5; private static final int INT_TYPE = 6; private static final int LONG_TYPE = 7; private static final int SHORT_TYPE = 8; /** * Constructs a property that accepts any data type. * * @param name Name of the property being described */ public DynaProperty(final String name) { this(name, Object.class); } /** * Constructs a property of the specified data type. * * @param name Name of the property being described * @param type Java class representing the property data type */ public DynaProperty(final String name, final Class type) { this.name = name; this.type = type; if (type != null && type.isArray()) { this.contentType = type.getComponentType(); } } /** * Constructs an indexed or mapped {@code DynaProperty} that supports (pseudo)-introspection * of the content type. * * @param name Name of the property being described * @param type Java class representing the property data type * @param contentType Class that all indexed or mapped elements are instances of */ public DynaProperty(final String name, final Class type, final Class contentType) { this.name = name; this.type = type; this.contentType = contentType; } /** Property name */ protected String name; /** * Get the name of this property. * @return the name of the property */ public String getName() { return this.name; } /** Property type */ protected transient Class type; /** *

Gets the Java class representing the data type of the underlying property * values.

* *

There are issues with serializing primitive class types on certain JVM versions * (including java 1.3). * Therefore, this field must not be serialized using the standard methods.

* *

Please leave this field as {@code transient}

* * @return the property type */ public Class getType() { return this.type; } /** The (optional) type of content elements for indexed {@code DynaProperty} */ protected transient Class contentType; /** * Empty array. */ static final DynaProperty[] EMPTY_DYNA_PROPERTY_ARRAY = new DynaProperty[0]; /** * Gets the (optional) type of the indexed content for {@code DynaProperty}'s * that support this feature. * *

There are issues with serializing primitive class types on certain JVM versions * (including java 1.3). * Therefore, this field must not be serialized using the standard methods.

* * @return the Class for the content type if this is an indexed {@code DynaProperty} * and this feature is supported. Otherwise null. */ public Class getContentType() { return contentType; } /** * Does this property represent an indexed value (ie an array or List)? * * @return {@code true} if the property is indexed (i.e. is a List or * array), otherwise {@code false} */ public boolean isIndexed() { if (type == null) { return false; } else if (type.isArray() || List.class.isAssignableFrom(type)) { return true; } else { return false; } } /** * Does this property represent a mapped value (ie a Map)? * * @return {@code true} if the property is a Map * otherwise {@code false} */ public boolean isMapped() { if (type == null) { return false; } return Map.class.isAssignableFrom(type); } /** * Checks this instance against the specified Object for equality. Overrides the * default reference test for equality provided by {@link java.lang.Object#equals(Object)} * @param obj The object to compare to * @return {@code true} if object is a dyna property with the same name * type and content type, otherwise {@code false} * @since 1.8.0 */ @Override public boolean equals(final Object obj) { boolean result; result = obj == this; if (!result && obj instanceof DynaProperty) { final DynaProperty that = (DynaProperty) obj; result = (Objects.equals(this.name, that.name)) && (Objects.equals(this.type, that.type)) && (Objects.equals(this.contentType, that.contentType)); } return result; } /** * @return the hashcode for this dyna property * @see java.lang.Object#hashCode * @since 1.8.0 */ @Override public int hashCode() { int result = 1; result = result * 31 + (name == null ? 0 : name.hashCode()); result = result * 31 + (type == null ? 0 : type.hashCode()); result = result * 31 + (contentType == null ? 0 : contentType.hashCode()); return result; } /** * Gets a String representation of this Object. * @return a String representation of the dyna property */ @Override public String toString() { final StringBuilder sb = new StringBuilder("DynaProperty[name="); sb.append(this.name); sb.append(",type="); sb.append(this.type); if (isMapped() || isIndexed()) { sb.append(" <").append(this.contentType).append(">"); } sb.append("]"); return sb.toString(); } /** * Writes this object safely. * There are issues with serializing primitive class types on certain JVM versions * (including java 1.3). * This method provides a workaround. * * @param out {@link ObjectOutputStream} to write object to * @throws IOException if the object can't be written */ private void writeObject(final ObjectOutputStream out) throws IOException { writeAnyClass(this.type,out); if (isMapped() || isIndexed()) { writeAnyClass(this.contentType,out); } // write out other values out.defaultWriteObject(); } /** * Write a class using safe encoding to workaround java 1.3 serialization bug. */ private void writeAnyClass(final Class clazz, final ObjectOutputStream out) throws IOException { // safely write out any class int primitiveType = 0; if (Boolean.TYPE.equals(clazz)) { primitiveType = BOOLEAN_TYPE; } else if (Byte.TYPE.equals(clazz)) { primitiveType = BYTE_TYPE; } else if (Character.TYPE.equals(clazz)) { primitiveType = CHAR_TYPE; } else if (Double.TYPE.equals(clazz)) { primitiveType = DOUBLE_TYPE; } else if (Float.TYPE.equals(clazz)) { primitiveType = FLOAT_TYPE; } else if (Integer.TYPE.equals(clazz)) { primitiveType = INT_TYPE; } else if (Long.TYPE.equals(clazz)) { primitiveType = LONG_TYPE; } else if (Short.TYPE.equals(clazz)) { primitiveType = SHORT_TYPE; } if (primitiveType == 0) { // then it's not a primitive type out.writeBoolean(false); out.writeObject(clazz); } else { // we'll write out a constant instead out.writeBoolean(true); out.writeInt(primitiveType); } } /** * Reads field values for this object safely. * There are issues with serializing primitive class types on certain JVM versions * (including java 1.3). * This method provides a workaround. * * @param in {@link ObjectInputStream} to read object from * @throws StreamCorruptedException when the stream data values are outside expected range * @throws IOException if the input stream can't be read * @throws ClassNotFoundException When trying to read an object of class that is not on the classpath */ private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException { this.type = readAnyClass(in); if (isMapped() || isIndexed()) { this.contentType = readAnyClass(in); } // read other values in.defaultReadObject(); } /** * Reads a class using safe encoding to workaround java 1.3 serialization bug. */ private Class readAnyClass(final ObjectInputStream in) throws IOException, ClassNotFoundException { // read back type class safely if (in.readBoolean()) { // it's a type constant switch (in.readInt()) { case BOOLEAN_TYPE: return Boolean.TYPE; case BYTE_TYPE: return Byte.TYPE; case CHAR_TYPE: return Character.TYPE; case DOUBLE_TYPE: return Double.TYPE; case FLOAT_TYPE: return Float.TYPE; case INT_TYPE: return Integer.TYPE; case LONG_TYPE: return Long.TYPE; case SHORT_TYPE: return Short.TYPE; default: // something's gone wrong throw new StreamCorruptedException( "Invalid primitive type. " + "Check version of beanutils used to serialize is compatible."); } } // it's another class return (Class) in.readObject(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy