1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/rt/emul/compact/src/main/java/java/io/ObjectStreamField.java Tue Jan 17 07:04:06 2017 +0100
1.3 @@ -0,0 +1,314 @@
1.4 +/*
1.5 + * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1.7 + *
1.8 + * This code is free software; you can redistribute it and/or modify it
1.9 + * under the terms of the GNU General Public License version 2 only, as
1.10 + * published by the Free Software Foundation. Oracle designates this
1.11 + * particular file as subject to the "Classpath" exception as provided
1.12 + * by Oracle in the LICENSE file that accompanied this code.
1.13 + *
1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1.17 + * version 2 for more details (a copy is included in the LICENSE file that
1.18 + * accompanied this code).
1.19 + *
1.20 + * You should have received a copy of the GNU General Public License version
1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1.23 + *
1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1.25 + * or visit www.oracle.com if you need additional information or have any
1.26 + * questions.
1.27 + */
1.28 +
1.29 +package java.io;
1.30 +
1.31 +import java.lang.reflect.Field;
1.32 +
1.33 +/**
1.34 + * A description of a Serializable field from a Serializable class. An array
1.35 + * of ObjectStreamFields is used to declare the Serializable fields of a class.
1.36 + *
1.37 + * @author Mike Warres
1.38 + * @author Roger Riggs
1.39 + * @see ObjectStreamClass
1.40 + * @since 1.2
1.41 + */
1.42 +public class ObjectStreamField
1.43 + implements Comparable<Object>
1.44 +{
1.45 +
1.46 + /** field name */
1.47 + private final String name;
1.48 + /** canonical JVM signature of field type */
1.49 + private final String signature;
1.50 + /** field type (Object.class if unknown non-primitive type) */
1.51 + private final Class<?> type;
1.52 + /** whether or not to (de)serialize field values as unshared */
1.53 + private final boolean unshared;
1.54 + /** corresponding reflective field object, if any */
1.55 + private final Field field;
1.56 + /** offset of field value in enclosing field group */
1.57 + private int offset = 0;
1.58 +
1.59 + /**
1.60 + * Create a Serializable field with the specified type. This field should
1.61 + * be documented with a <code>serialField</code> tag.
1.62 + *
1.63 + * @param name the name of the serializable field
1.64 + * @param type the <code>Class</code> object of the serializable field
1.65 + */
1.66 + public ObjectStreamField(String name, Class<?> type) {
1.67 + this(name, type, false);
1.68 + }
1.69 +
1.70 + /**
1.71 + * Creates an ObjectStreamField representing a serializable field with the
1.72 + * given name and type. If unshared is false, values of the represented
1.73 + * field are serialized and deserialized in the default manner--if the
1.74 + * field is non-primitive, object values are serialized and deserialized as
1.75 + * if they had been written and read by calls to writeObject and
1.76 + * readObject. If unshared is true, values of the represented field are
1.77 + * serialized and deserialized as if they had been written and read by
1.78 + * calls to writeUnshared and readUnshared.
1.79 + *
1.80 + * @param name field name
1.81 + * @param type field type
1.82 + * @param unshared if false, write/read field values in the same manner
1.83 + * as writeObject/readObject; if true, write/read in the same
1.84 + * manner as writeUnshared/readUnshared
1.85 + * @since 1.4
1.86 + */
1.87 + public ObjectStreamField(String name, Class<?> type, boolean unshared) {
1.88 + if (name == null) {
1.89 + throw new NullPointerException();
1.90 + }
1.91 + this.name = name;
1.92 + this.type = type;
1.93 + this.unshared = unshared;
1.94 + signature = getClassSignature(type).intern();
1.95 + field = null;
1.96 + }
1.97 +
1.98 + /**
1.99 + * Creates an ObjectStreamField representing a field with the given name,
1.100 + * signature and unshared setting.
1.101 + */
1.102 + ObjectStreamField(String name, String signature, boolean unshared) {
1.103 + if (name == null) {
1.104 + throw new NullPointerException();
1.105 + }
1.106 + this.name = name;
1.107 + this.signature = signature.intern();
1.108 + this.unshared = unshared;
1.109 + field = null;
1.110 +
1.111 + switch (signature.charAt(0)) {
1.112 + case 'Z': type = Boolean.TYPE; break;
1.113 + case 'B': type = Byte.TYPE; break;
1.114 + case 'C': type = Character.TYPE; break;
1.115 + case 'S': type = Short.TYPE; break;
1.116 + case 'I': type = Integer.TYPE; break;
1.117 + case 'J': type = Long.TYPE; break;
1.118 + case 'F': type = Float.TYPE; break;
1.119 + case 'D': type = Double.TYPE; break;
1.120 + case 'L':
1.121 + case '[': type = Object.class; break;
1.122 + default: throw new IllegalArgumentException("illegal signature");
1.123 + }
1.124 + }
1.125 +
1.126 + /**
1.127 + * Creates an ObjectStreamField representing the given field with the
1.128 + * specified unshared setting. For compatibility with the behavior of
1.129 + * earlier serialization implementations, a "showType" parameter is
1.130 + * necessary to govern whether or not a getType() call on this
1.131 + * ObjectStreamField (if non-primitive) will return Object.class (as
1.132 + * opposed to a more specific reference type).
1.133 + */
1.134 + ObjectStreamField(Field field, boolean unshared, boolean showType) {
1.135 + this.field = field;
1.136 + this.unshared = unshared;
1.137 + name = field.getName();
1.138 + Class<?> ftype = field.getType();
1.139 + type = (showType || ftype.isPrimitive()) ? ftype : Object.class;
1.140 + signature = getClassSignature(ftype).intern();
1.141 + }
1.142 +
1.143 + /**
1.144 + * Get the name of this field.
1.145 + *
1.146 + * @return a <code>String</code> representing the name of the serializable
1.147 + * field
1.148 + */
1.149 + public String getName() {
1.150 + return name;
1.151 + }
1.152 +
1.153 + /**
1.154 + * Get the type of the field. If the type is non-primitive and this
1.155 + * <code>ObjectStreamField</code> was obtained from a deserialized {@link
1.156 + * ObjectStreamClass} instance, then <code>Object.class</code> is returned.
1.157 + * Otherwise, the <code>Class</code> object for the type of the field is
1.158 + * returned.
1.159 + *
1.160 + * @return a <code>Class</code> object representing the type of the
1.161 + * serializable field
1.162 + */
1.163 + public Class<?> getType() {
1.164 + return type;
1.165 + }
1.166 +
1.167 + /**
1.168 + * Returns character encoding of field type. The encoding is as follows:
1.169 + * <blockquote><pre>
1.170 + * B byte
1.171 + * C char
1.172 + * D double
1.173 + * F float
1.174 + * I int
1.175 + * J long
1.176 + * L class or interface
1.177 + * S short
1.178 + * Z boolean
1.179 + * [ array
1.180 + * </pre></blockquote>
1.181 + *
1.182 + * @return the typecode of the serializable field
1.183 + */
1.184 + // REMIND: deprecate?
1.185 + public char getTypeCode() {
1.186 + return signature.charAt(0);
1.187 + }
1.188 +
1.189 + /**
1.190 + * Return the JVM type signature.
1.191 + *
1.192 + * @return null if this field has a primitive type.
1.193 + */
1.194 + // REMIND: deprecate?
1.195 + public String getTypeString() {
1.196 + return isPrimitive() ? null : signature;
1.197 + }
1.198 +
1.199 + /**
1.200 + * Offset of field within instance data.
1.201 + *
1.202 + * @return the offset of this field
1.203 + * @see #setOffset
1.204 + */
1.205 + // REMIND: deprecate?
1.206 + public int getOffset() {
1.207 + return offset;
1.208 + }
1.209 +
1.210 + /**
1.211 + * Offset within instance data.
1.212 + *
1.213 + * @param offset the offset of the field
1.214 + * @see #getOffset
1.215 + */
1.216 + // REMIND: deprecate?
1.217 + protected void setOffset(int offset) {
1.218 + this.offset = offset;
1.219 + }
1.220 +
1.221 + /**
1.222 + * Return true if this field has a primitive type.
1.223 + *
1.224 + * @return true if and only if this field corresponds to a primitive type
1.225 + */
1.226 + // REMIND: deprecate?
1.227 + public boolean isPrimitive() {
1.228 + char tcode = signature.charAt(0);
1.229 + return ((tcode != 'L') && (tcode != '['));
1.230 + }
1.231 +
1.232 + /**
1.233 + * Returns boolean value indicating whether or not the serializable field
1.234 + * represented by this ObjectStreamField instance is unshared.
1.235 + *
1.236 + * @since 1.4
1.237 + */
1.238 + public boolean isUnshared() {
1.239 + return unshared;
1.240 + }
1.241 +
1.242 + /**
1.243 + * Compare this field with another <code>ObjectStreamField</code>. Return
1.244 + * -1 if this is smaller, 0 if equal, 1 if greater. Types that are
1.245 + * primitives are "smaller" than object types. If equal, the field names
1.246 + * are compared.
1.247 + */
1.248 + // REMIND: deprecate?
1.249 + public int compareTo(Object obj) {
1.250 + ObjectStreamField other = (ObjectStreamField) obj;
1.251 + boolean isPrim = isPrimitive();
1.252 + if (isPrim != other.isPrimitive()) {
1.253 + return isPrim ? -1 : 1;
1.254 + }
1.255 + return name.compareTo(other.name);
1.256 + }
1.257 +
1.258 + /**
1.259 + * Return a string that describes this field.
1.260 + */
1.261 + public String toString() {
1.262 + return signature + ' ' + name;
1.263 + }
1.264 +
1.265 + /**
1.266 + * Returns field represented by this ObjectStreamField, or null if
1.267 + * ObjectStreamField is not associated with an actual field.
1.268 + */
1.269 + Field getField() {
1.270 + return field;
1.271 + }
1.272 +
1.273 + /**
1.274 + * Returns JVM type signature of field (similar to getTypeString, except
1.275 + * that signature strings are returned for primitive fields as well).
1.276 + */
1.277 + String getSignature() {
1.278 + return signature;
1.279 + }
1.280 +
1.281 + /**
1.282 + * Returns JVM type signature for given class.
1.283 + */
1.284 + private static String getClassSignature(Class<?> cl) {
1.285 + StringBuilder sbuf = new StringBuilder();
1.286 + while (cl.isArray()) {
1.287 + sbuf.append('[');
1.288 + cl = cl.getComponentType();
1.289 + }
1.290 + if (cl.isPrimitive()) {
1.291 + if (cl == Integer.TYPE) {
1.292 + sbuf.append('I');
1.293 + } else if (cl == Byte.TYPE) {
1.294 + sbuf.append('B');
1.295 + } else if (cl == Long.TYPE) {
1.296 + sbuf.append('J');
1.297 + } else if (cl == Float.TYPE) {
1.298 + sbuf.append('F');
1.299 + } else if (cl == Double.TYPE) {
1.300 + sbuf.append('D');
1.301 + } else if (cl == Short.TYPE) {
1.302 + sbuf.append('S');
1.303 + } else if (cl == Character.TYPE) {
1.304 + sbuf.append('C');
1.305 + } else if (cl == Boolean.TYPE) {
1.306 + sbuf.append('Z');
1.307 + } else if (cl == Void.TYPE) {
1.308 + sbuf.append('V');
1.309 + } else {
1.310 + throw new InternalError();
1.311 + }
1.312 + } else {
1.313 + sbuf.append('L' + cl.getName().replace('.', '/') + ';');
1.314 + }
1.315 + return sbuf.toString();
1.316 + }
1.317 +}