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

com.feilong.lib.beanutils.DynaProperty Maven / Gradle / Ivy

Go to download

feilong is a suite of core and expanded libraries that include utility classes, http, excel,cvs, io classes, and much much more.

There is a newer version: 4.0.8
Show 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 com.feilong.lib.beanutils;

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;

/**
 * 

* 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 implementatin may choose to ignore this property. * All keys for maps must be of type String so no meta data is needed for map keys. *

* * @version $Id$ */ public class DynaProperty implements Serializable{ // ----------------------------------------------------------- Constants /** * */ 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; // ----------------------------------------------------------- Constructors /** * Construct a property that accepts any data type. * * @param name * Name of the property being described */ public DynaProperty(final String name){ this(name, Object.class); } /** * Construct 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){ super(); this.name = name; this.type = type; if (type != null && type.isArray()){ this.contentType = type.getComponentType(); } } /** * Construct an indexed or mapped 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){ super(); this.name = name; this.type = type; this.contentType = contentType; } // ------------------------------------------------------------- Properties /** Property name */ protected String name = null; /** * Get the name of this property. * * @return the name of the property */ public String getName(){ return (this.name); } /** Property type */ protected transient Class type = null; /** *

* 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 transient *

* * @return the property type */ public Class getType(){ return (this.type); } /** The (optional) type of content elements for indexed DynaProperty */ protected transient Class contentType; /** * Gets the (optional) type of the indexed content for 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 DynaProperty * and this feature is supported. Otherwise null. */ public Class getContentType(){ return contentType; } // --------------------------------------------------------- Public Methods /** * Does this property represent an indexed value (ie an array or List)? * * @return true if the property is indexed (i.e. is a List or * array), otherwise false */ public boolean isIndexed(){ if (type == null){ return (false); }else if (type.isArray()){ return (true); }else if (List.class.isAssignableFrom(type)){ return (true); }else{ return (false); } } /** * Does this property represent a mapped value (ie a Map)? * * @return true if the property is a Map * otherwise false */ public boolean isMapped(){ if (type == null){ return (false); }else{ return (Map.class.isAssignableFrom(type)); } } /** * Checks this instance against the specified Object for equality. Overrides the * default refererence test for equality provided by {@link java.lang.Object#equals(Object)} * * @param obj * The object to compare to * @return true if object is a dyna property with the same name * type and content type, otherwise false * @since 1.8.0 */ @Override public boolean equals(final Object obj){ boolean result = false; result = (obj == this); if ((!result) && obj instanceof DynaProperty){ final DynaProperty that = (DynaProperty) obj; result = ((this.name == null) ? (that.name == null) : (this.name.equals(that.name))) && ((this.type == null) ? (that.type == null) : (this.type.equals(that.type))) && ((this.contentType == null) ? (that.contentType == null) : (this.contentType.equals(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; } /** * Return 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()); } // --------------------------------------------------------- Serialization helper methods /** * 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. */ 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. * * @throws StreamCorruptedException * when the stream data values are outside expected range */ 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."); } }else{ // it's another class return ((Class) in.readObject()); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy