| /* |
| * 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.geode.pdx.internal; |
| |
| import java.io.Externalizable; |
| import java.io.ObjectOutputStream; |
| import java.io.Serializable; |
| import java.lang.ref.WeakReference; |
| import java.lang.reflect.Field; |
| import java.lang.reflect.Method; |
| import java.lang.reflect.Modifier; |
| import java.util.ArrayList; |
| import java.util.Date; |
| import java.util.Enumeration; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.LinkedHashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Properties; |
| import java.util.Set; |
| import java.util.concurrent.CopyOnWriteArrayList; |
| import java.util.concurrent.CopyOnWriteArraySet; |
| import java.util.regex.Pattern; |
| |
| import org.apache.logging.log4j.Logger; |
| |
| import org.apache.geode.CancelException; |
| import org.apache.geode.annotations.Immutable; |
| import org.apache.geode.cache.RegionService; |
| import org.apache.geode.distributed.internal.DistributionConfig; |
| import org.apache.geode.internal.CopyOnWriteHashSet; |
| import org.apache.geode.internal.PdxSerializerObject; |
| import org.apache.geode.internal.util.concurrent.CopyOnWriteWeakHashMap; |
| import org.apache.geode.logging.internal.log4j.api.LogService; |
| import org.apache.geode.pdx.FieldType; |
| import org.apache.geode.pdx.NonPortableClassException; |
| import org.apache.geode.pdx.PdxReader; |
| import org.apache.geode.pdx.PdxSerializationException; |
| import org.apache.geode.pdx.PdxWriter; |
| import org.apache.geode.pdx.ReflectionBasedAutoSerializer; |
| import org.apache.geode.unsafe.internal.sun.misc.Unsafe; |
| |
| /** |
| * The core of auto serialization which is used in both aspect and reflection-based |
| * auto-serialization. This simple manager class is a singleton which tracks the relevant fields for |
| * each class which is to be auto-serialized. This class used to be a singleton. But now every |
| * instance of ReflectionBasedAutoSerializer will have its own instance of this class. We allow |
| * instances of this class to be found so that tests can access internal apis that are not exposed |
| * on the public ReflectionBasedAutoSerializer. |
| * |
| * @since GemFire 6.6 |
| */ |
| |
| public class AutoSerializableManager { |
| private static final Logger logger = LogService.getLogger(); |
| |
| private static final String INIT_CLASSES_PARAM = "classes"; |
| private static final String INIT_CHECK_PORTABILITY_PARAM = "check-portability"; |
| private static final String OPT_IDENTITY = "identity"; |
| private static final String OPT_EXCLUDE = "exclude"; |
| |
| /* |
| * Map of class and list of fields, we're interested in, for that class. |
| */ |
| private final Map<Class<?>, AutoClassInfo> classMap = |
| new CopyOnWriteWeakHashMap<Class<?>, AutoClassInfo>(); |
| |
| /* |
| * Mapping between class patterns and identity field patterns. |
| */ |
| private final List<String[]> identityPatterns = new CopyOnWriteArrayList<String[]>(); |
| |
| /* |
| * Mapping between class patterns and patterns of fields to exclude |
| */ |
| private final List<String[]> excludePatterns = new CopyOnWriteArrayList<String[]>(); |
| |
| /* |
| * This is an internal parameter which, when set either as a system property or via cache.xml will |
| * not evaluate any hardcoded excludes. This helps with testing as well as possibly debugging |
| * future customer issues. |
| */ |
| public static final String NO_HARDCODED_EXCLUDES_PARAM = |
| DistributionConfig.GEMFIRE_PREFIX + "auto.serialization.no.hardcoded.excludes"; |
| |
| private boolean noHardcodedExcludes = Boolean.getBoolean(NO_HARDCODED_EXCLUDES_PARAM); |
| |
| |
| /* |
| * Holds a set of regex patterns which match the list of classes we're interested in. |
| */ |
| private final Set<Pattern> classPatterns = new LinkedHashSet<Pattern>(); |
| |
| /* |
| * Hardcoded set of patterns which we always exclude. |
| */ |
| private Set<Pattern> hardcodedExclusions = new HashSet<Pattern>() { |
| { |
| add(Pattern.compile("org\\.apache\\.geode\\..*")); |
| add(Pattern.compile("com\\.gemstone\\..*")); |
| add(Pattern.compile("java\\..*")); |
| add(Pattern.compile("javax\\..*")); |
| } |
| }; |
| |
| /* |
| * Cache of class names which have been determined to be excluded from serialization. Built up |
| * within isRelevant(). |
| */ |
| private final Set<String> cachedExcludedClasses = new CopyOnWriteHashSet<String>(); |
| |
| /* |
| * Cache of class names which have been determined to be included for serialization. Built up |
| * within isRelevant(). |
| */ |
| private final Set<String> cachedIncludedClasses = new CopyOnWriteHashSet<String>(); |
| |
| /* |
| * Used to hold the class names which have triggered a warning because they have been determined |
| * that they should be auto serialized based on a pattern much but were not because that either do |
| * not have a public no-arg constructor or have explicit java serialization code. |
| */ |
| private final Set<String> loggedNoAutoSerializeMsg = new CopyOnWriteHashSet<String>(); |
| |
| |
| private final ReflectionBasedAutoSerializer owner; |
| |
| public ReflectionBasedAutoSerializer getOwner() { |
| return this.owner; |
| } |
| |
| public static AutoSerializableManager create(ReflectionBasedAutoSerializer owner, |
| boolean checkPortability, String... patterns) { |
| AutoSerializableManager result = new AutoSerializableManager(owner); |
| result.reconfigure(checkPortability, patterns); |
| return result; |
| } |
| |
| private AutoSerializableManager(ReflectionBasedAutoSerializer owner) { |
| this.owner = owner; |
| } |
| |
| public Map<Class<?>, AutoClassInfo> getClassMap() { |
| return classMap; |
| } |
| |
| private boolean checkPortability; |
| |
| public void setCheckPortability(boolean b) { |
| this.checkPortability = b; |
| } |
| |
| public boolean getCheckPortability() { |
| return this.checkPortability; |
| } |
| |
| public void resetCachedTypes() { |
| classMap.clear(); |
| } |
| |
| public void resetCaches() { |
| identityPatterns.clear(); |
| excludePatterns.clear(); |
| resetCachedTypes(); |
| } |
| |
| public void resetAll() { |
| resetCaches(); |
| this.checkPortability = false; |
| classPatterns.clear(); |
| cachedIncludedClasses.clear(); |
| cachedExcludedClasses.clear(); |
| loggedNoAutoSerializeMsg.clear(); |
| this.noHardcodedExcludes = Boolean.getBoolean(NO_HARDCODED_EXCLUDES_PARAM); |
| } |
| |
| /* |
| * Helper method to determine whether the class of a given object is a class which we are |
| * interested in (de)serializing. |
| * |
| * |
| * @return true if the object should be considered for serialization or false otherwise |
| */ |
| private boolean isRelevant(Class<?> clazz) { |
| String className = clazz.getName(); |
| |
| // Do some short-circuiting if possible |
| if (cachedIncludedClasses.contains(className)) { |
| return true; |
| } else if (cachedExcludedClasses.contains(className)) { |
| return false; |
| } |
| |
| boolean result = getOwner().isClassAutoSerialized(clazz); |
| if (result) { |
| cachedIncludedClasses.add(className); |
| } else { |
| cachedExcludedClasses.add(className); |
| } |
| return result; |
| } |
| |
| /** |
| * Determines whether objects of the named class are excluded from auto-serialization. The classes |
| * that are excluded are Geode-internal classes and Java classes. |
| * |
| * @param className Class name including packages. |
| * @return <code>true</code> if the named class is excluded. |
| */ |
| public boolean isExcluded(String className) { |
| if (!noHardcodedExcludes) { |
| for (Pattern p : hardcodedExclusions) { |
| if (p.matcher(className).matches()) { |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| public boolean defaultIsClassAutoSerialized(Class<?> clazz) { |
| if (clazz.isEnum()) { |
| return false; |
| } |
| String className = clazz.getName(); |
| if (isExcluded(className)) { |
| if (!PdxSerializerObject.class.isAssignableFrom(clazz)) { |
| return false; |
| } |
| } |
| |
| for (Pattern p : classPatterns) { |
| if (p.matcher(className).matches()) { |
| if (hasValidConstructor(clazz, p) && !needsStandardSerialization(clazz, p)) { |
| return true; |
| } else { |
| return false; |
| } |
| } |
| } |
| return false; |
| } |
| |
| /* |
| * Helper method to determine whether a class has a default constructor. That's needed so that it |
| * can be re-instantiated by PDX on de-serialization. |
| * |
| */ |
| private boolean hasValidConstructor(Class<?> clazz, Pattern matchedPattern) { |
| if (unsafe != null && !USE_CONSTRUCTOR) { |
| // unsafe allows us to create instances without a constructor |
| return true; |
| } |
| try { |
| clazz.getConstructor(); |
| return true; |
| } catch (NoSuchMethodException nex) { |
| String className = clazz.getName(); |
| if (!loggedNoAutoSerializeMsg.contains(className)) { |
| loggedNoAutoSerializeMsg.add(className); |
| logger.warn( |
| "Class {} matched with '{}' cannot be auto-serialized due to missing public no-arg constructor. Will attempt using Java serialization.", |
| className, matchedPattern.pattern()); |
| } |
| return false; |
| } |
| } |
| |
| private boolean needsStandardSerialization(Class<?> clazz, Pattern matchedPattern) { |
| if (Serializable.class.isAssignableFrom(clazz)) { |
| if (Externalizable.class.isAssignableFrom(clazz)) { |
| String className = clazz.getName(); |
| if (!loggedNoAutoSerializeMsg.contains(className)) { |
| loggedNoAutoSerializeMsg.add(className); |
| logger.warn( |
| "Class {} matched with '{}' cannot be auto-serialized because it is Externalizable. Java serialization will be used instead of auto-serialization.", |
| className, matchedPattern.pattern()); |
| } |
| return true; |
| } else { |
| if (getPrivateMethod(clazz, "writeObject", new Class[] {ObjectOutputStream.class}, |
| Void.TYPE)) { |
| String className = clazz.getName(); |
| if (!loggedNoAutoSerializeMsg.contains(className)) { |
| loggedNoAutoSerializeMsg.add(className); |
| logger.warn( |
| "Class {} matched with '{}' cannot be auto-serialized because it has a writeObject(ObjectOutputStream) method. Java serialization will be used instead of auto-serialization.", |
| className, matchedPattern.pattern()); |
| } |
| return true; |
| } else if (getInheritableMethod(clazz, "writeReplace", null, Object.class)) { |
| String className = clazz.getName(); |
| if (!loggedNoAutoSerializeMsg.contains(className)) { |
| loggedNoAutoSerializeMsg.add(className); |
| logger.warn( |
| "Class {} matched with '{}' cannot be auto-serialized because it has a writeReplace() method. Java serialization will be used instead of auto-serialization.", |
| className, matchedPattern.pattern()); |
| } |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Returns true if a non-private static method with given signature defined by given class, or |
| * false if none found. |
| */ |
| private static boolean getPrivateMethod(Class cl, String name, Class[] argTypes, |
| Class returnType) { |
| try { |
| Method meth = cl.getDeclaredMethod(name, argTypes); |
| int mods = meth.getModifiers(); |
| return ((meth.getReturnType() == returnType) && ((mods & Modifier.STATIC) == 0) |
| && ((mods & Modifier.PRIVATE) != 0)); |
| } catch (NoSuchMethodException ex) { |
| return false; |
| } |
| } |
| |
| /** |
| * Returns true if a non-static, non-abstract method with given signature provided it is defined |
| * by or accessible (via inheritance) by the given class, or false if no match found. |
| */ |
| private static boolean getInheritableMethod(Class cl, String name, Class[] argTypes, |
| Class returnType) { |
| Method meth = null; |
| Class defCl = cl; |
| while (defCl != null) { |
| try { |
| meth = defCl.getDeclaredMethod(name, argTypes); |
| break; |
| } catch (NoSuchMethodException ex) { |
| defCl = defCl.getSuperclass(); |
| } |
| } |
| |
| if ((meth == null) || (meth.getReturnType() != returnType)) { |
| return false; |
| } |
| int mods = meth.getModifiers(); |
| if ((mods & (Modifier.STATIC | Modifier.ABSTRACT)) != 0) { |
| return false; |
| } else if ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) != 0) { |
| return true; |
| } else if ((mods & Modifier.PRIVATE) != 0) { |
| return (cl == defCl); |
| } else { |
| return packageEquals(cl, defCl); |
| } |
| } |
| |
| /** |
| * Returns true if classes are defined in the same runtime package, false otherwise. |
| */ |
| private static boolean packageEquals(Class cl1, Class cl2) { |
| return (cl1.getClassLoader() == cl2.getClassLoader() |
| && getPackageName(cl1).equals(getPackageName(cl2))); |
| } |
| |
| /** |
| * Returns package name of given class. |
| */ |
| private static String getPackageName(Class cl) { |
| String s = cl.getName(); |
| int i = s.lastIndexOf('['); |
| if (i >= 0) { |
| s = s.substring(i + 2); |
| } |
| i = s.lastIndexOf('.'); |
| return (i >= 0) ? s.substring(0, i) : ""; |
| } |
| |
| /** |
| * Given a class, figure out which fields we're interested in serializing. The class' entire |
| * hierarchy will be traversed and used. Transients and statics will be ignored. |
| * |
| * @param clazz the <code>Class</code> we're interested in |
| * @return a list of fields to be used when this class is (de)serialized |
| */ |
| public List<PdxFieldWrapper> getFields(Class<?> clazz) { |
| return getClassInfo(clazz).getFields(); |
| |
| } |
| |
| public AutoClassInfo getExistingClassInfo(Class<?> clazz) { |
| return classMap.get(clazz); |
| } |
| |
| public AutoClassInfo getClassInfo(Class<?> clazz) { |
| Class<?> tmpClass = clazz; |
| AutoClassInfo classInfo = getExistingClassInfo(tmpClass); |
| if (classInfo == null) { |
| synchronized (classMap) { |
| classInfo = classMap.get(tmpClass); |
| if (classInfo != null) |
| return classInfo; |
| |
| List<PdxFieldWrapper> fieldList = new ArrayList<PdxFieldWrapper>(); |
| List<PdxFieldWrapper> variableLenFields = new ArrayList<PdxFieldWrapper>(); |
| |
| while (tmpClass != Object.class) { |
| Field[] fields = tmpClass.getDeclaredFields(); |
| for (Field f : fields) { |
| if (getOwner().isFieldIncluded(f, clazz)) { |
| // Should this be reset at some point? |
| f.setAccessible(true); |
| FieldType ft = getOwner().getFieldType(f, clazz); |
| PdxFieldWrapper fw = PdxFieldWrapper.create(this, f, ft, |
| getOwner().getFieldName(f, clazz), getOwner().transformFieldValue(f, clazz), |
| getOwner().isIdentityField(f, clazz)); |
| if (ft.isFixedWidth()) { |
| fieldList.add(fw); |
| } else { |
| variableLenFields.add(fw); |
| } |
| } |
| } |
| tmpClass = tmpClass.getSuperclass(); |
| } |
| |
| fieldList.addAll(variableLenFields); |
| classInfo = new AutoClassInfo(clazz, fieldList); |
| logger.info("Auto serializer generating type for {} for fields: {}", clazz, |
| classInfo.toFormattedString()); |
| classMap.put(clazz, classInfo); |
| } // end sync |
| } |
| return classInfo; |
| } |
| |
| public boolean defaultIsIdentityField(Field f, Class<?> clazz) { |
| return fieldMatches(f, clazz.getName(), identityPatterns); |
| } |
| |
| public boolean defaultIsFieldIncluded(Field f, Class<?> clazz) { |
| return !Modifier.isTransient(f.getModifiers()) && !Modifier.isStatic(f.getModifiers()) |
| && !fieldMatches(f, clazz.getName(), excludePatterns); |
| } |
| |
| public FieldType defaultGetFieldType(Field f, Class<?> clazz) { |
| return FieldType.get(f.getType()); |
| } |
| |
| private static class FieldWrapper { |
| private final Field field; |
| |
| public FieldWrapper(Field f) { |
| this.field = f; |
| } |
| |
| public Field getField() { |
| return this.field; |
| } |
| |
| public int getInt(Object o) throws IllegalArgumentException, IllegalAccessException { |
| return this.field.getInt(o); |
| } |
| |
| public void setInt(Object o, int v) throws IllegalArgumentException, IllegalAccessException { |
| this.field.setInt(o, v); |
| } |
| |
| public boolean getBoolean(Object o) throws IllegalArgumentException, IllegalAccessException { |
| return this.field.getBoolean(o); |
| } |
| |
| public void setBoolean(Object o, boolean v) |
| throws IllegalArgumentException, IllegalAccessException { |
| this.field.setBoolean(o, v); |
| } |
| |
| public byte getByte(Object o) throws IllegalArgumentException, IllegalAccessException { |
| return this.field.getByte(o); |
| } |
| |
| public void setByte(Object o, byte v) throws IllegalArgumentException, IllegalAccessException { |
| this.field.setByte(o, v); |
| } |
| |
| public short getShort(Object o) throws IllegalArgumentException, IllegalAccessException { |
| return this.field.getShort(o); |
| } |
| |
| public void setShort(Object o, short v) |
| throws IllegalArgumentException, IllegalAccessException { |
| this.field.setShort(o, v); |
| } |
| |
| public char getChar(Object o) throws IllegalArgumentException, IllegalAccessException { |
| return this.field.getChar(o); |
| } |
| |
| public void setChar(Object o, char v) throws IllegalArgumentException, IllegalAccessException { |
| this.field.setChar(o, v); |
| } |
| |
| public long getLong(Object o) throws IllegalArgumentException, IllegalAccessException { |
| return this.field.getLong(o); |
| } |
| |
| public void setLong(Object o, long v) throws IllegalArgumentException, IllegalAccessException { |
| this.field.setLong(o, v); |
| } |
| |
| public float getFloat(Object o) throws IllegalArgumentException, IllegalAccessException { |
| return this.field.getFloat(o); |
| } |
| |
| public void setFloat(Object o, float v) |
| throws IllegalArgumentException, IllegalAccessException { |
| this.field.setFloat(o, v); |
| } |
| |
| public double getDouble(Object o) throws IllegalArgumentException, IllegalAccessException { |
| return this.field.getDouble(o); |
| } |
| |
| public void setDouble(Object o, double v) |
| throws IllegalArgumentException, IllegalAccessException { |
| this.field.setDouble(o, v); |
| } |
| |
| public Object getObject(Object o) throws IllegalArgumentException, IllegalAccessException { |
| return this.field.get(o); |
| } |
| |
| public void setObject(Object o, Object v) |
| throws IllegalArgumentException, IllegalAccessException { |
| this.field.set(o, v); |
| } |
| |
| @Override |
| public String toString() { |
| return field.toString(); |
| } |
| } |
| |
| private static class UnsafeFieldWrapper extends FieldWrapper { |
| private final long offset; |
| |
| public UnsafeFieldWrapper(Field f) { |
| super(f); |
| this.offset = unsafe.objectFieldOffset(f); |
| } |
| |
| @Override |
| public int getInt(Object o) throws IllegalArgumentException, IllegalAccessException { |
| return unsafe.getInt(o, this.offset); |
| } |
| |
| @Override |
| public void setInt(Object o, int v) throws IllegalArgumentException, IllegalAccessException { |
| unsafe.putInt(o, this.offset, v); |
| } |
| |
| @Override |
| public boolean getBoolean(Object o) throws IllegalArgumentException, IllegalAccessException { |
| return unsafe.getBoolean(o, this.offset); |
| } |
| |
| @Override |
| public void setBoolean(Object o, boolean v) |
| throws IllegalArgumentException, IllegalAccessException { |
| unsafe.putBoolean(o, this.offset, v); |
| } |
| |
| @Override |
| public byte getByte(Object o) throws IllegalArgumentException, IllegalAccessException { |
| return unsafe.getByte(o, this.offset); |
| } |
| |
| @Override |
| public void setByte(Object o, byte v) throws IllegalArgumentException, IllegalAccessException { |
| unsafe.putByte(o, this.offset, v); |
| } |
| |
| @Override |
| public short getShort(Object o) throws IllegalArgumentException, IllegalAccessException { |
| return unsafe.getShort(o, this.offset); |
| } |
| |
| @Override |
| public void setShort(Object o, short v) |
| throws IllegalArgumentException, IllegalAccessException { |
| unsafe.putShort(o, this.offset, v); |
| } |
| |
| @Override |
| public char getChar(Object o) throws IllegalArgumentException, IllegalAccessException { |
| return unsafe.getChar(o, this.offset); |
| } |
| |
| @Override |
| public void setChar(Object o, char v) throws IllegalArgumentException, IllegalAccessException { |
| unsafe.putChar(o, this.offset, v); |
| } |
| |
| @Override |
| public long getLong(Object o) throws IllegalArgumentException, IllegalAccessException { |
| return unsafe.getLong(o, this.offset); |
| } |
| |
| @Override |
| public void setLong(Object o, long v) throws IllegalArgumentException, IllegalAccessException { |
| unsafe.putLong(o, this.offset, v); |
| } |
| |
| @Override |
| public float getFloat(Object o) throws IllegalArgumentException, IllegalAccessException { |
| return unsafe.getFloat(o, this.offset); |
| } |
| |
| @Override |
| public void setFloat(Object o, float v) |
| throws IllegalArgumentException, IllegalAccessException { |
| unsafe.putFloat(o, this.offset, v); |
| } |
| |
| @Override |
| public double getDouble(Object o) throws IllegalArgumentException, IllegalAccessException { |
| return unsafe.getDouble(o, this.offset); |
| } |
| |
| @Override |
| public void setDouble(Object o, double v) |
| throws IllegalArgumentException, IllegalAccessException { |
| unsafe.putDouble(o, this.offset, v); |
| } |
| |
| @Override |
| public Object getObject(Object o) throws IllegalArgumentException, IllegalAccessException { |
| return unsafe.getObject(o, this.offset); |
| } |
| |
| @Override |
| public void setObject(Object o, Object v) |
| throws IllegalArgumentException, IllegalAccessException { |
| unsafe.putObject(o, this.offset, v); |
| } |
| } |
| |
| // unsafe will be null if the Unsafe class is not available or SAFE was requested. |
| // We attempt to use Unsafe by default for best performance. |
| @Immutable |
| private static final Unsafe unsafe; |
| static { |
| Unsafe tmp = null; |
| // only use Unsafe if SAFE was not explicitly requested |
| if (!Boolean.getBoolean(DistributionConfig.GEMFIRE_PREFIX + "AutoSerializer.SAFE")) { |
| try { |
| tmp = new Unsafe(); |
| // only throw an exception if UNSAFE was explicitly requested |
| } catch (RuntimeException ex) { |
| if (Boolean.getBoolean(DistributionConfig.GEMFIRE_PREFIX + "AutoSerializer.UNSAFE")) { |
| throw ex; |
| } |
| } catch (Error ex) { |
| if (Boolean.getBoolean(DistributionConfig.GEMFIRE_PREFIX + "AutoSerializer.UNSAFE")) { |
| throw ex; |
| } |
| } |
| } |
| unsafe = tmp; |
| } |
| |
| public abstract static class PdxFieldWrapper { |
| private final FieldWrapper field; |
| private final String fieldName; |
| private final boolean transformValue; |
| private final AutoSerializableManager owner; |
| private final boolean isIdentityField; |
| |
| protected PdxFieldWrapper(AutoSerializableManager owner, Field f, String name, |
| boolean transformValue, boolean isIdentityField) { |
| FieldWrapper tmp; |
| if (unsafe != null) { |
| tmp = new UnsafeFieldWrapper(f); |
| } else { |
| tmp = new FieldWrapper(f); |
| } |
| this.field = tmp; |
| this.fieldName = name; |
| this.transformValue = transformValue; |
| this.owner = owner; |
| this.isIdentityField = isIdentityField; |
| } |
| |
| public static PdxFieldWrapper create(AutoSerializableManager owner, Field f, FieldType ft, |
| String name, boolean transformValue, boolean isIdentityField) { |
| switch (ft) { |
| case INT: |
| return new IntField(owner, f, name, transformValue, isIdentityField); |
| case BYTE: |
| return new ByteField(owner, f, name, transformValue, isIdentityField); |
| case LONG: |
| return new LongField(owner, f, name, transformValue, isIdentityField); |
| case BOOLEAN: |
| return new BooleanField(owner, f, name, transformValue, isIdentityField); |
| case CHAR: |
| return new CharField(owner, f, name, transformValue, isIdentityField); |
| case SHORT: |
| return new ShortField(owner, f, name, transformValue, isIdentityField); |
| case DOUBLE: |
| return new DoubleField(owner, f, name, transformValue, isIdentityField); |
| case FLOAT: |
| return new FloatField(owner, f, name, transformValue, isIdentityField); |
| case STRING: |
| return new StringField(owner, f, name, transformValue, isIdentityField); |
| case DATE: |
| return new DateField(owner, f, name, transformValue, isIdentityField); |
| case BYTE_ARRAY: |
| return new ByteArrayField(owner, f, name, transformValue, isIdentityField); |
| case STRING_ARRAY: |
| return new StringArrayField(owner, f, name, transformValue, isIdentityField); |
| case ARRAY_OF_BYTE_ARRAYS: |
| return new ByteArrayArrayField(owner, f, name, transformValue, isIdentityField); |
| case BOOLEAN_ARRAY: |
| return new BooleanArrayField(owner, f, name, transformValue, isIdentityField); |
| case CHAR_ARRAY: |
| return new CharArrayField(owner, f, name, transformValue, isIdentityField); |
| case SHORT_ARRAY: |
| return new ShortArrayField(owner, f, name, transformValue, isIdentityField); |
| case INT_ARRAY: |
| return new IntArrayField(owner, f, name, transformValue, isIdentityField); |
| case LONG_ARRAY: |
| return new LongArrayField(owner, f, name, transformValue, isIdentityField); |
| case FLOAT_ARRAY: |
| return new FloatArrayField(owner, f, name, transformValue, isIdentityField); |
| case DOUBLE_ARRAY: |
| return new DoubleArrayField(owner, f, name, transformValue, isIdentityField); |
| case OBJECT_ARRAY: |
| return new ObjectArrayField(owner, f, name, transformValue, isIdentityField); |
| case OBJECT: |
| return new ObjectField(owner, f, name, transformValue, isIdentityField); |
| default: |
| throw new IllegalStateException("unhandled field type " + ft); |
| } |
| } |
| |
| public boolean getCheckPortability() { |
| return this.owner.getCheckPortability(); |
| } |
| |
| public Field getField() { |
| return this.field.getField(); |
| } |
| |
| public String getName() { |
| return this.fieldName; |
| } |
| |
| public boolean transform() { |
| return this.transformValue; |
| } |
| |
| public abstract void serialize(PdxWriterImpl writer, Object obj, boolean optimizeWrite); |
| |
| public abstract void serializeValue(PdxWriterImpl writer, Object newValue, |
| boolean optimizeWrite); |
| |
| public abstract void deserialize(InternalPdxReader reader, Object obj); |
| |
| public abstract void orderedDeserialize(InternalPdxReader reader, Object obj); |
| |
| protected Object readTransformIf(Object o, Object serializedValue) |
| throws IllegalArgumentException, IllegalAccessException { |
| if (!transform()) |
| return serializedValue; |
| return readTransform(o, serializedValue); |
| } |
| |
| protected Object readTransform(Object o, Object serializedValue) |
| throws IllegalArgumentException, IllegalAccessException { |
| return this.owner.getOwner().readTransform(getField(), o.getClass(), serializedValue); |
| } |
| |
| protected void handleException(boolean serialization, Object obj, Exception ex) { |
| AutoSerializableManager.handleException(ex, serialization, getName(), obj); |
| } |
| |
| protected int getInt(Object o) throws IllegalArgumentException, IllegalAccessException { |
| return this.field.getInt(o); |
| } |
| |
| protected void setInt(Object o, int v) throws IllegalArgumentException, IllegalAccessException { |
| this.field.setInt(o, v); |
| } |
| |
| protected boolean getBoolean(Object o) throws IllegalArgumentException, IllegalAccessException { |
| return this.field.getBoolean(o); |
| } |
| |
| protected void setBoolean(Object o, boolean v) |
| throws IllegalArgumentException, IllegalAccessException { |
| this.field.setBoolean(o, v); |
| } |
| |
| protected byte getByte(Object o) throws IllegalArgumentException, IllegalAccessException { |
| return this.field.getByte(o); |
| } |
| |
| protected void setByte(Object o, byte v) |
| throws IllegalArgumentException, IllegalAccessException { |
| this.field.setByte(o, v); |
| } |
| |
| protected short getShort(Object o) throws IllegalArgumentException, IllegalAccessException { |
| return this.field.getShort(o); |
| } |
| |
| protected void setShort(Object o, short v) |
| throws IllegalArgumentException, IllegalAccessException { |
| this.field.setShort(o, v); |
| } |
| |
| protected char getChar(Object o) throws IllegalArgumentException, IllegalAccessException { |
| return this.field.getChar(o); |
| } |
| |
| protected void setChar(Object o, char v) |
| throws IllegalArgumentException, IllegalAccessException { |
| this.field.setChar(o, v); |
| } |
| |
| protected long getLong(Object o) throws IllegalArgumentException, IllegalAccessException { |
| return this.field.getLong(o); |
| } |
| |
| protected void setLong(Object o, long v) |
| throws IllegalArgumentException, IllegalAccessException { |
| this.field.setLong(o, v); |
| } |
| |
| protected float getFloat(Object o) throws IllegalArgumentException, IllegalAccessException { |
| return this.field.getFloat(o); |
| } |
| |
| protected void setFloat(Object o, float v) |
| throws IllegalArgumentException, IllegalAccessException { |
| this.field.setFloat(o, v); |
| } |
| |
| protected double getDouble(Object o) throws IllegalArgumentException, IllegalAccessException { |
| return this.field.getDouble(o); |
| } |
| |
| protected void setDouble(Object o, double v) |
| throws IllegalArgumentException, IllegalAccessException { |
| this.field.setDouble(o, v); |
| } |
| |
| protected Object getObject(Object o) throws IllegalArgumentException, IllegalAccessException { |
| return this.field.getObject(o); |
| } |
| |
| protected void setObject(Object o, Object v) |
| throws IllegalArgumentException, IllegalAccessException { |
| this.field.setObject(o, v); |
| } |
| |
| public boolean isIdentityField() { |
| return this.isIdentityField; |
| } |
| |
| @Override |
| public String toString() { |
| return this.fieldName + ": " + field.toString(); |
| } |
| } |
| |
| public static class IntField extends PdxFieldWrapper { |
| public IntField(AutoSerializableManager owner, Field f, String name, boolean transformValue, |
| boolean isIdentityField) { |
| super(owner, f, name, transformValue, isIdentityField); |
| } |
| |
| @Override |
| public void serialize(PdxWriterImpl writer, Object obj, boolean optimizeWrite) { |
| try { |
| if (optimizeWrite) { |
| writer.writeInt(getInt(obj)); |
| } else { |
| writer.writeInt(getName(), getInt(obj)); |
| } |
| } catch (Exception ex) { |
| handleException(true, obj, ex); |
| } |
| } |
| |
| @Override |
| public void serializeValue(PdxWriterImpl writer, Object newValue, boolean optimizeWrite) { |
| if (optimizeWrite) { |
| writer.writeInt((Integer) newValue); |
| } else { |
| writer.writeInt(getName(), (Integer) newValue); |
| } |
| } |
| |
| @Override |
| public void deserialize(InternalPdxReader reader, Object obj) { |
| PdxField pf = reader.getPdxField(getName()); |
| if (pf != null) { |
| try { |
| if (transform()) { |
| setObject(obj, readTransform(obj, reader.readInt(pf))); |
| } else { |
| setInt(obj, reader.readInt(pf)); |
| } |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| |
| @Override |
| public void orderedDeserialize(InternalPdxReader reader, Object obj) { |
| try { |
| if (transform()) { |
| setObject(obj, readTransform(obj, reader.readInt())); |
| } else { |
| setInt(obj, reader.readInt()); |
| } |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| public static class ByteField extends PdxFieldWrapper { |
| public ByteField(AutoSerializableManager owner, Field f, String name, boolean transformValue, |
| boolean isIdentityField) { |
| super(owner, f, name, transformValue, isIdentityField); |
| } |
| |
| @Override |
| public void serialize(PdxWriterImpl writer, Object obj, boolean optimizeWrite) { |
| try { |
| if (optimizeWrite) { |
| writer.writeByte(getByte(obj)); |
| } else { |
| writer.writeByte(getName(), getByte(obj)); |
| } |
| } catch (Exception ex) { |
| handleException(true, obj, ex); |
| } |
| } |
| |
| @Override |
| public void serializeValue(PdxWriterImpl writer, Object newValue, boolean optimizeWrite) { |
| if (optimizeWrite) { |
| writer.writeByte((Byte) newValue); |
| } else { |
| writer.writeByte(getName(), (Byte) newValue); |
| } |
| } |
| |
| @Override |
| public void deserialize(InternalPdxReader reader, Object obj) { |
| PdxField pf = reader.getPdxField(getName()); |
| if (pf != null) { |
| try { |
| if (transform()) { |
| setObject(obj, readTransform(obj, reader.readByte(pf))); |
| } else { |
| setByte(obj, reader.readByte(pf)); |
| } |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| |
| @Override |
| public void orderedDeserialize(InternalPdxReader reader, Object obj) { |
| try { |
| if (transform()) { |
| setObject(obj, readTransform(obj, reader.readByte())); |
| } else { |
| setByte(obj, reader.readByte()); |
| } |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| public static class LongField extends PdxFieldWrapper { |
| public LongField(AutoSerializableManager owner, Field f, String name, boolean transformValue, |
| boolean isIdentityField) { |
| super(owner, f, name, transformValue, isIdentityField); |
| } |
| |
| @Override |
| public void serialize(PdxWriterImpl writer, Object obj, boolean optimizeWrite) { |
| try { |
| if (optimizeWrite) { |
| writer.writeLong(getLong(obj)); |
| } else { |
| writer.writeLong(getName(), getLong(obj)); |
| } |
| } catch (Exception ex) { |
| handleException(true, obj, ex); |
| } |
| } |
| |
| @Override |
| public void serializeValue(PdxWriterImpl writer, Object newValue, boolean optimizeWrite) { |
| if (optimizeWrite) { |
| writer.writeLong((Long) newValue); |
| } else { |
| writer.writeLong(getName(), (Long) newValue); |
| } |
| } |
| |
| @Override |
| public void deserialize(InternalPdxReader reader, Object obj) { |
| PdxField pf = reader.getPdxField(getName()); |
| if (pf != null) { |
| try { |
| if (transform()) { |
| setObject(obj, readTransform(obj, reader.readLong(pf))); |
| } else { |
| setLong(obj, reader.readLong(pf)); |
| } |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| |
| @Override |
| public void orderedDeserialize(InternalPdxReader reader, Object obj) { |
| try { |
| if (transform()) { |
| setObject(obj, readTransform(obj, reader.readLong())); |
| } else { |
| setLong(obj, reader.readLong()); |
| } |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| public static class BooleanField extends PdxFieldWrapper { |
| public BooleanField(AutoSerializableManager owner, Field f, String name, boolean transformValue, |
| boolean isIdentityField) { |
| super(owner, f, name, transformValue, isIdentityField); |
| } |
| |
| @Override |
| public void serialize(PdxWriterImpl writer, Object obj, boolean optimizeWrite) { |
| try { |
| if (optimizeWrite) { |
| writer.writeBoolean(getBoolean(obj)); |
| } else { |
| writer.writeBoolean(getName(), getBoolean(obj)); |
| } |
| } catch (Exception ex) { |
| handleException(true, obj, ex); |
| } |
| } |
| |
| @Override |
| public void serializeValue(PdxWriterImpl writer, Object newValue, boolean optimizeWrite) { |
| if (optimizeWrite) { |
| writer.writeBoolean((Boolean) newValue); |
| } else { |
| writer.writeBoolean(getName(), (Boolean) newValue); |
| } |
| } |
| |
| @Override |
| public void deserialize(InternalPdxReader reader, Object obj) { |
| PdxField pf = reader.getPdxField(getName()); |
| if (pf != null) { |
| try { |
| if (transform()) { |
| setObject(obj, readTransform(obj, reader.readBoolean(pf))); |
| } else { |
| setBoolean(obj, reader.readBoolean(pf)); |
| } |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| |
| @Override |
| public void orderedDeserialize(InternalPdxReader reader, Object obj) { |
| try { |
| if (transform()) { |
| setObject(obj, readTransform(obj, reader.readBoolean())); |
| } else { |
| setBoolean(obj, reader.readBoolean()); |
| } |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| public static class CharField extends PdxFieldWrapper { |
| public CharField(AutoSerializableManager owner, Field f, String name, boolean transformValue, |
| boolean isIdentityField) { |
| super(owner, f, name, transformValue, isIdentityField); |
| } |
| |
| @Override |
| public void serialize(PdxWriterImpl writer, Object obj, boolean optimizeWrite) { |
| try { |
| if (optimizeWrite) { |
| writer.writeChar(getChar(obj)); |
| } else { |
| writer.writeChar(getName(), getChar(obj)); |
| } |
| } catch (Exception ex) { |
| handleException(true, obj, ex); |
| } |
| } |
| |
| @Override |
| public void serializeValue(PdxWriterImpl writer, Object newValue, boolean optimizeWrite) { |
| if (optimizeWrite) { |
| writer.writeChar((Character) newValue); |
| } else { |
| writer.writeChar(getName(), (Character) newValue); |
| } |
| } |
| |
| @Override |
| public void deserialize(InternalPdxReader reader, Object obj) { |
| PdxField pf = reader.getPdxField(getName()); |
| if (pf != null) { |
| try { |
| if (transform()) { |
| setObject(obj, readTransform(obj, reader.readChar(pf))); |
| } else { |
| setChar(obj, reader.readChar(pf)); |
| } |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| |
| @Override |
| public void orderedDeserialize(InternalPdxReader reader, Object obj) { |
| try { |
| if (transform()) { |
| setObject(obj, readTransform(obj, reader.readChar())); |
| } else { |
| setChar(obj, reader.readChar()); |
| } |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| public static class ShortField extends PdxFieldWrapper { |
| public ShortField(AutoSerializableManager owner, Field f, String name, boolean transformValue, |
| boolean isIdentityField) { |
| super(owner, f, name, transformValue, isIdentityField); |
| } |
| |
| @Override |
| public void serialize(PdxWriterImpl writer, Object obj, boolean optimizeWrite) { |
| try { |
| if (optimizeWrite) { |
| writer.writeShort(getShort(obj)); |
| } else { |
| writer.writeShort(getName(), getShort(obj)); |
| } |
| } catch (Exception ex) { |
| handleException(true, obj, ex); |
| } |
| } |
| |
| @Override |
| public void serializeValue(PdxWriterImpl writer, Object newValue, boolean optimizeWrite) { |
| if (optimizeWrite) { |
| writer.writeShort((Short) newValue); |
| } else { |
| writer.writeShort(getName(), (Short) newValue); |
| } |
| } |
| |
| @Override |
| public void deserialize(InternalPdxReader reader, Object obj) { |
| PdxField pf = reader.getPdxField(getName()); |
| if (pf != null) { |
| try { |
| if (transform()) { |
| setObject(obj, readTransform(obj, reader.readShort(pf))); |
| } else { |
| setShort(obj, reader.readShort(pf)); |
| } |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| |
| @Override |
| public void orderedDeserialize(InternalPdxReader reader, Object obj) { |
| try { |
| if (transform()) { |
| setObject(obj, readTransform(obj, reader.readShort())); |
| } else { |
| setShort(obj, reader.readShort()); |
| } |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| public static class FloatField extends PdxFieldWrapper { |
| public FloatField(AutoSerializableManager owner, Field f, String name, boolean transformValue, |
| boolean isIdentityField) { |
| super(owner, f, name, transformValue, isIdentityField); |
| } |
| |
| @Override |
| public void serialize(PdxWriterImpl writer, Object obj, boolean optimizeWrite) { |
| try { |
| if (optimizeWrite) { |
| writer.writeFloat(getFloat(obj)); |
| } else { |
| writer.writeFloat(getName(), getFloat(obj)); |
| } |
| } catch (Exception ex) { |
| handleException(true, obj, ex); |
| } |
| } |
| |
| @Override |
| public void serializeValue(PdxWriterImpl writer, Object newValue, boolean optimizeWrite) { |
| if (optimizeWrite) { |
| writer.writeFloat((Float) newValue); |
| } else { |
| writer.writeFloat(getName(), (Float) newValue); |
| } |
| } |
| |
| @Override |
| public void deserialize(InternalPdxReader reader, Object obj) { |
| PdxField pf = reader.getPdxField(getName()); |
| if (pf != null) { |
| try { |
| if (transform()) { |
| setObject(obj, readTransform(obj, reader.readFloat(pf))); |
| } else { |
| setFloat(obj, reader.readFloat(pf)); |
| } |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| |
| @Override |
| public void orderedDeserialize(InternalPdxReader reader, Object obj) { |
| try { |
| if (transform()) { |
| setObject(obj, readTransform(obj, reader.readFloat())); |
| } else { |
| setFloat(obj, reader.readFloat()); |
| } |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| public static class DoubleField extends PdxFieldWrapper { |
| public DoubleField(AutoSerializableManager owner, Field f, String name, boolean transformValue, |
| boolean isIdentityField) { |
| super(owner, f, name, transformValue, isIdentityField); |
| } |
| |
| @Override |
| public void serialize(PdxWriterImpl writer, Object obj, boolean optimizeWrite) { |
| try { |
| if (optimizeWrite) { |
| writer.writeDouble(getDouble(obj)); |
| } else { |
| writer.writeDouble(getName(), getDouble(obj)); |
| } |
| } catch (Exception ex) { |
| handleException(true, obj, ex); |
| } |
| } |
| |
| @Override |
| public void serializeValue(PdxWriterImpl writer, Object newValue, boolean optimizeWrite) { |
| if (optimizeWrite) { |
| writer.writeDouble((Double) newValue); |
| } else { |
| writer.writeDouble(getName(), (Double) newValue); |
| } |
| } |
| |
| @Override |
| public void deserialize(InternalPdxReader reader, Object obj) { |
| PdxField pf = reader.getPdxField(getName()); |
| if (pf != null) { |
| try { |
| if (transform()) { |
| setObject(obj, readTransform(obj, reader.readDouble(pf))); |
| } else { |
| setDouble(obj, reader.readDouble(pf)); |
| } |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| |
| @Override |
| public void orderedDeserialize(InternalPdxReader reader, Object obj) { |
| try { |
| if (transform()) { |
| setObject(obj, readTransform(obj, reader.readDouble())); |
| } else { |
| setDouble(obj, reader.readDouble()); |
| } |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| public static class ObjectField extends PdxFieldWrapper { |
| public ObjectField(AutoSerializableManager owner, Field f, String name, boolean transformValue, |
| boolean isIdentityField) { |
| super(owner, f, name, transformValue, isIdentityField); |
| } |
| |
| @Override |
| public void serialize(PdxWriterImpl writer, Object obj, boolean optimizeWrite) { |
| try { |
| serializeValue(writer, getObject(obj), optimizeWrite); |
| } catch (Exception ex) { |
| handleException(true, obj, ex); |
| } |
| } |
| |
| @Override |
| public void serializeValue(PdxWriterImpl writer, Object newValue, boolean optimizeWrite) { |
| if (optimizeWrite) { |
| writer.writeObject(newValue, getCheckPortability()); |
| } else { |
| writer.writeObject(getName(), newValue, getCheckPortability()); |
| } |
| } |
| |
| @Override |
| public void deserialize(InternalPdxReader reader, Object obj) { |
| PdxField pf = reader.getPdxField(getName()); |
| if (pf != null) { |
| try { |
| setObject(obj, readTransformIf(obj, reader.readObject(pf))); |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| |
| @Override |
| public void orderedDeserialize(InternalPdxReader reader, Object obj) { |
| try { |
| setObject(obj, readTransformIf(obj, reader.readObject())); |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| public static class StringField extends PdxFieldWrapper { |
| public StringField(AutoSerializableManager owner, Field f, String name, boolean transformValue, |
| boolean isIdentityField) { |
| super(owner, f, name, transformValue, isIdentityField); |
| } |
| |
| @Override |
| public void serialize(PdxWriterImpl writer, Object obj, boolean optimizeWrite) { |
| try { |
| serializeValue(writer, getObject(obj), optimizeWrite); |
| } catch (Exception ex) { |
| handleException(true, obj, ex); |
| } |
| } |
| |
| @Override |
| public void serializeValue(PdxWriterImpl writer, Object newValue, boolean optimizeWrite) { |
| if (optimizeWrite) { |
| writer.writeString((String) newValue); |
| } else { |
| writer.writeString(getName(), (String) newValue); |
| } |
| } |
| |
| @Override |
| public void deserialize(InternalPdxReader reader, Object obj) { |
| PdxField pf = reader.getPdxField(getName()); |
| if (pf != null) { |
| try { |
| setObject(obj, readTransformIf(obj, reader.readString(pf))); |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| |
| @Override |
| public void orderedDeserialize(InternalPdxReader reader, Object obj) { |
| try { |
| setObject(obj, readTransformIf(obj, reader.readString())); |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| public static class DateField extends PdxFieldWrapper { |
| public DateField(AutoSerializableManager owner, Field f, String name, boolean transformValue, |
| boolean isIdentityField) { |
| super(owner, f, name, transformValue, isIdentityField); |
| } |
| |
| @Override |
| public void serialize(PdxWriterImpl writer, Object obj, boolean optimizeWrite) { |
| try { |
| serializeValue(writer, getObject(obj), optimizeWrite); |
| } catch (Exception ex) { |
| handleException(true, obj, ex); |
| } |
| } |
| |
| @Override |
| public void serializeValue(PdxWriterImpl writer, Object newValue, boolean optimizeWrite) { |
| if (optimizeWrite) { |
| writer.writeDate((Date) newValue); |
| } else { |
| writer.writeDate(getName(), (Date) newValue); |
| } |
| } |
| |
| @Override |
| public void deserialize(InternalPdxReader reader, Object obj) { |
| PdxField pf = reader.getPdxField(getName()); |
| if (pf != null) { |
| try { |
| setObject(obj, readTransformIf(obj, reader.readDate(pf))); |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| |
| @Override |
| public void orderedDeserialize(InternalPdxReader reader, Object obj) { |
| try { |
| setObject(obj, readTransformIf(obj, reader.readDate())); |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| public static class ByteArrayField extends PdxFieldWrapper { |
| public ByteArrayField(AutoSerializableManager owner, Field f, String name, |
| boolean transformValue, boolean isIdentityField) { |
| super(owner, f, name, transformValue, isIdentityField); |
| } |
| |
| @Override |
| public void serialize(PdxWriterImpl writer, Object obj, boolean optimizeWrite) { |
| try { |
| serializeValue(writer, getObject(obj), optimizeWrite); |
| } catch (Exception ex) { |
| handleException(true, obj, ex); |
| } |
| } |
| |
| @Override |
| public void serializeValue(PdxWriterImpl writer, Object newValue, boolean optimizeWrite) { |
| if (optimizeWrite) { |
| writer.writeByteArray((byte[]) newValue); |
| } else { |
| writer.writeByteArray(getName(), (byte[]) newValue); |
| } |
| } |
| |
| @Override |
| public void deserialize(InternalPdxReader reader, Object obj) { |
| PdxField pf = reader.getPdxField(getName()); |
| if (pf != null) { |
| try { |
| setObject(obj, readTransformIf(obj, reader.readByteArray(pf))); |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| |
| @Override |
| public void orderedDeserialize(InternalPdxReader reader, Object obj) { |
| try { |
| setObject(obj, readTransformIf(obj, reader.readByteArray())); |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| public static class BooleanArrayField extends PdxFieldWrapper { |
| public BooleanArrayField(AutoSerializableManager owner, Field f, String name, |
| boolean transformValue, boolean isIdentityField) { |
| super(owner, f, name, transformValue, isIdentityField); |
| } |
| |
| @Override |
| public void serialize(PdxWriterImpl writer, Object obj, boolean optimizeWrite) { |
| try { |
| serializeValue(writer, getObject(obj), optimizeWrite); |
| } catch (Exception ex) { |
| handleException(true, obj, ex); |
| } |
| } |
| |
| @Override |
| public void serializeValue(PdxWriterImpl writer, Object newValue, boolean optimizeWrite) { |
| if (optimizeWrite) { |
| writer.writeBooleanArray((boolean[]) newValue); |
| } else { |
| writer.writeBooleanArray(getName(), (boolean[]) newValue); |
| } |
| } |
| |
| @Override |
| public void deserialize(InternalPdxReader reader, Object obj) { |
| PdxField pf = reader.getPdxField(getName()); |
| if (pf != null) { |
| try { |
| setObject(obj, readTransformIf(obj, reader.readBooleanArray(pf))); |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| |
| @Override |
| public void orderedDeserialize(InternalPdxReader reader, Object obj) { |
| try { |
| setObject(obj, readTransformIf(obj, reader.readBooleanArray())); |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| public static class ShortArrayField extends PdxFieldWrapper { |
| public ShortArrayField(AutoSerializableManager owner, Field f, String name, |
| boolean transformValue, boolean isIdentityField) { |
| super(owner, f, name, transformValue, isIdentityField); |
| } |
| |
| @Override |
| public void serialize(PdxWriterImpl writer, Object obj, boolean optimizeWrite) { |
| try { |
| serializeValue(writer, getObject(obj), optimizeWrite); |
| } catch (Exception ex) { |
| handleException(true, obj, ex); |
| } |
| } |
| |
| @Override |
| public void serializeValue(PdxWriterImpl writer, Object newValue, boolean optimizeWrite) { |
| if (optimizeWrite) { |
| writer.writeShortArray((short[]) newValue); |
| } else { |
| writer.writeShortArray(getName(), (short[]) newValue); |
| } |
| } |
| |
| @Override |
| public void deserialize(InternalPdxReader reader, Object obj) { |
| PdxField pf = reader.getPdxField(getName()); |
| if (pf != null) { |
| try { |
| setObject(obj, readTransformIf(obj, reader.readShortArray(pf))); |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| |
| @Override |
| public void orderedDeserialize(InternalPdxReader reader, Object obj) { |
| try { |
| setObject(obj, readTransformIf(obj, reader.readShortArray())); |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| public static class CharArrayField extends PdxFieldWrapper { |
| public CharArrayField(AutoSerializableManager owner, Field f, String name, |
| boolean transformValue, boolean isIdentityField) { |
| super(owner, f, name, transformValue, isIdentityField); |
| } |
| |
| @Override |
| public void serialize(PdxWriterImpl writer, Object obj, boolean optimizeWrite) { |
| try { |
| serializeValue(writer, getObject(obj), optimizeWrite); |
| } catch (Exception ex) { |
| handleException(true, obj, ex); |
| } |
| } |
| |
| @Override |
| public void serializeValue(PdxWriterImpl writer, Object newValue, boolean optimizeWrite) { |
| if (optimizeWrite) { |
| writer.writeCharArray((char[]) newValue); |
| } else { |
| writer.writeCharArray(getName(), (char[]) newValue); |
| } |
| } |
| |
| @Override |
| public void deserialize(InternalPdxReader reader, Object obj) { |
| PdxField pf = reader.getPdxField(getName()); |
| if (pf != null) { |
| try { |
| setObject(obj, readTransformIf(obj, reader.readCharArray(pf))); |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| |
| @Override |
| public void orderedDeserialize(InternalPdxReader reader, Object obj) { |
| try { |
| setObject(obj, readTransformIf(obj, reader.readCharArray())); |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| public static class IntArrayField extends PdxFieldWrapper { |
| public IntArrayField(AutoSerializableManager owner, Field f, String name, |
| boolean transformValue, boolean isIdentityField) { |
| super(owner, f, name, transformValue, isIdentityField); |
| } |
| |
| @Override |
| public void serialize(PdxWriterImpl writer, Object obj, boolean optimizeWrite) { |
| try { |
| serializeValue(writer, getObject(obj), optimizeWrite); |
| } catch (Exception ex) { |
| handleException(true, obj, ex); |
| } |
| } |
| |
| @Override |
| public void serializeValue(PdxWriterImpl writer, Object newValue, boolean optimizeWrite) { |
| if (optimizeWrite) { |
| writer.writeIntArray((int[]) newValue); |
| } else { |
| writer.writeIntArray(getName(), (int[]) newValue); |
| } |
| } |
| |
| @Override |
| public void deserialize(InternalPdxReader reader, Object obj) { |
| PdxField pf = reader.getPdxField(getName()); |
| if (pf != null) { |
| try { |
| setObject(obj, readTransformIf(obj, reader.readIntArray(pf))); |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| |
| @Override |
| public void orderedDeserialize(InternalPdxReader reader, Object obj) { |
| try { |
| setObject(obj, readTransformIf(obj, reader.readIntArray())); |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| public static class LongArrayField extends PdxFieldWrapper { |
| public LongArrayField(AutoSerializableManager owner, Field f, String name, |
| boolean transformValue, boolean isIdentityField) { |
| super(owner, f, name, transformValue, isIdentityField); |
| } |
| |
| @Override |
| public void serialize(PdxWriterImpl writer, Object obj, boolean optimizeWrite) { |
| try { |
| serializeValue(writer, getObject(obj), optimizeWrite); |
| } catch (Exception ex) { |
| handleException(true, obj, ex); |
| } |
| } |
| |
| @Override |
| public void serializeValue(PdxWriterImpl writer, Object newValue, boolean optimizeWrite) { |
| if (optimizeWrite) { |
| writer.writeLongArray((long[]) newValue); |
| } else { |
| writer.writeLongArray(getName(), (long[]) newValue); |
| } |
| } |
| |
| @Override |
| public void deserialize(InternalPdxReader reader, Object obj) { |
| PdxField pf = reader.getPdxField(getName()); |
| if (pf != null) { |
| try { |
| setObject(obj, readTransformIf(obj, reader.readLongArray(pf))); |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| |
| @Override |
| public void orderedDeserialize(InternalPdxReader reader, Object obj) { |
| try { |
| setObject(obj, readTransformIf(obj, reader.readLongArray())); |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| public static class FloatArrayField extends PdxFieldWrapper { |
| public FloatArrayField(AutoSerializableManager owner, Field f, String name, |
| boolean transformValue, boolean isIdentityField) { |
| super(owner, f, name, transformValue, isIdentityField); |
| } |
| |
| @Override |
| public void serialize(PdxWriterImpl writer, Object obj, boolean optimizeWrite) { |
| try { |
| serializeValue(writer, getObject(obj), optimizeWrite); |
| } catch (Exception ex) { |
| handleException(true, obj, ex); |
| } |
| } |
| |
| @Override |
| public void serializeValue(PdxWriterImpl writer, Object newValue, boolean optimizeWrite) { |
| if (optimizeWrite) { |
| writer.writeFloatArray((float[]) newValue); |
| } else { |
| writer.writeFloatArray(getName(), (float[]) newValue); |
| } |
| } |
| |
| @Override |
| public void deserialize(InternalPdxReader reader, Object obj) { |
| PdxField pf = reader.getPdxField(getName()); |
| if (pf != null) { |
| try { |
| setObject(obj, readTransformIf(obj, reader.readFloatArray(pf))); |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| |
| @Override |
| public void orderedDeserialize(InternalPdxReader reader, Object obj) { |
| try { |
| setObject(obj, readTransformIf(obj, reader.readFloatArray())); |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| public static class DoubleArrayField extends PdxFieldWrapper { |
| public DoubleArrayField(AutoSerializableManager owner, Field f, String name, |
| boolean transformValue, boolean isIdentityField) { |
| super(owner, f, name, transformValue, isIdentityField); |
| } |
| |
| @Override |
| public void serialize(PdxWriterImpl writer, Object obj, boolean optimizeWrite) { |
| try { |
| serializeValue(writer, getObject(obj), optimizeWrite); |
| } catch (Exception ex) { |
| handleException(true, obj, ex); |
| } |
| } |
| |
| @Override |
| public void serializeValue(PdxWriterImpl writer, Object newValue, boolean optimizeWrite) { |
| if (optimizeWrite) { |
| writer.writeDoubleArray((double[]) newValue); |
| } else { |
| writer.writeDoubleArray(getName(), (double[]) newValue); |
| } |
| } |
| |
| @Override |
| public void deserialize(InternalPdxReader reader, Object obj) { |
| PdxField pf = reader.getPdxField(getName()); |
| if (pf != null) { |
| try { |
| setObject(obj, readTransformIf(obj, reader.readDoubleArray(pf))); |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| |
| @Override |
| public void orderedDeserialize(InternalPdxReader reader, Object obj) { |
| try { |
| setObject(obj, readTransformIf(obj, reader.readDoubleArray())); |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| public static class StringArrayField extends PdxFieldWrapper { |
| public StringArrayField(AutoSerializableManager owner, Field f, String name, |
| boolean transformValue, boolean isIdentityField) { |
| super(owner, f, name, transformValue, isIdentityField); |
| } |
| |
| @Override |
| public void serialize(PdxWriterImpl writer, Object obj, boolean optimizeWrite) { |
| try { |
| serializeValue(writer, getObject(obj), optimizeWrite); |
| } catch (Exception ex) { |
| handleException(true, obj, ex); |
| } |
| } |
| |
| @Override |
| public void serializeValue(PdxWriterImpl writer, Object newValue, boolean optimizeWrite) { |
| if (optimizeWrite) { |
| writer.writeStringArray((String[]) newValue); |
| } else { |
| writer.writeStringArray(getName(), (String[]) newValue); |
| } |
| } |
| |
| @Override |
| public void deserialize(InternalPdxReader reader, Object obj) { |
| PdxField pf = reader.getPdxField(getName()); |
| if (pf != null) { |
| try { |
| setObject(obj, readTransformIf(obj, reader.readStringArray(pf))); |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| |
| @Override |
| public void orderedDeserialize(InternalPdxReader reader, Object obj) { |
| try { |
| setObject(obj, readTransformIf(obj, reader.readStringArray())); |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| public static class ByteArrayArrayField extends PdxFieldWrapper { |
| public ByteArrayArrayField(AutoSerializableManager owner, Field f, String name, |
| boolean transformValue, boolean isIdentityField) { |
| super(owner, f, name, transformValue, isIdentityField); |
| } |
| |
| @Override |
| public void serialize(PdxWriterImpl writer, Object obj, boolean optimizeWrite) { |
| try { |
| serializeValue(writer, getObject(obj), optimizeWrite); |
| } catch (Exception ex) { |
| handleException(true, obj, ex); |
| } |
| } |
| |
| @Override |
| public void serializeValue(PdxWriterImpl writer, Object newValue, boolean optimizeWrite) { |
| if (optimizeWrite) { |
| writer.writeArrayOfByteArrays((byte[][]) newValue); |
| } else { |
| writer.writeArrayOfByteArrays(getName(), (byte[][]) newValue); |
| } |
| } |
| |
| @Override |
| public void deserialize(InternalPdxReader reader, Object obj) { |
| PdxField pf = reader.getPdxField(getName()); |
| if (pf != null) { |
| try { |
| setObject(obj, readTransformIf(obj, reader.readArrayOfByteArrays(pf))); |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| |
| @Override |
| public void orderedDeserialize(InternalPdxReader reader, Object obj) { |
| try { |
| setObject(obj, readTransformIf(obj, reader.readArrayOfByteArrays())); |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| public static class ObjectArrayField extends PdxFieldWrapper { |
| public ObjectArrayField(AutoSerializableManager owner, Field f, String name, |
| boolean transformValue, boolean isIdentityField) { |
| super(owner, f, name, transformValue, isIdentityField); |
| } |
| |
| @Override |
| public void serialize(PdxWriterImpl writer, Object obj, boolean optimizeWrite) { |
| try { |
| serializeValue(writer, getObject(obj), optimizeWrite); |
| } catch (Exception ex) { |
| handleException(true, obj, ex); |
| } |
| } |
| |
| @Override |
| public void serializeValue(PdxWriterImpl writer, Object newValue, boolean optimizeWrite) { |
| if (optimizeWrite) { |
| writer.writeObjectArray((Object[]) newValue, getCheckPortability()); |
| } else { |
| writer.writeObjectArray(getName(), (Object[]) newValue, getCheckPortability()); |
| } |
| } |
| |
| @Override |
| public void deserialize(InternalPdxReader reader, Object obj) { |
| PdxField pf = reader.getPdxField(getName()); |
| if (pf != null) { |
| try { |
| setObject(obj, readTransformIf(obj, reader.readObjectArray(pf))); |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| |
| @Override |
| public void orderedDeserialize(InternalPdxReader reader, Object obj) { |
| try { |
| setObject(obj, readTransformIf(obj, reader.readObjectArray())); |
| } catch (Exception ex) { |
| handleException(false, obj, ex); |
| } |
| } |
| } |
| |
| /** |
| * Given an object, use its class to determine which fields are to be used when (de)serializing. |
| * |
| * @param obj the object whose class we're interested in |
| * @return a list of fields to be used when this object's class is (de)serialized |
| */ |
| public List<PdxFieldWrapper> getFields(Object obj) { |
| return getFields(obj.getClass()); |
| } |
| |
| /** |
| * Using the given PdxWriter, write out the relevant fields for the object instance passed in. |
| * |
| * @param writer the <code>PdxWriter</code> to use when writing the object |
| * @param obj the object to serialize |
| * @return <code>true</code> if the object was serialized, <code>false</code> otherwise |
| */ |
| public boolean writeData(PdxWriter writer, Object obj) { |
| if (isRelevant(obj.getClass())) { |
| writeData(writer, obj, getClassInfo(obj.getClass())); |
| return true; |
| } |
| return false; |
| } |
| |
| private static void handleException(Exception ex, boolean serialization, String fieldName, |
| Object obj) { |
| if (ex instanceof CancelException) { |
| // fix for bug 43936 |
| throw (CancelException) ex; |
| } else if (ex instanceof NonPortableClassException) { |
| throw (NonPortableClassException) ex; |
| } else { |
| throw new PdxSerializationException((serialization ? "Serialization" : "Deserialization") |
| + " error on field " + fieldName + " for class " + obj.getClass().getName(), ex); |
| } |
| } |
| |
| /** |
| * Using the given PdxWriter, write out the fields which have been passed in. |
| * |
| * @param writer the <code>PdxWriter</code> to use when writing the object |
| * @param obj the object to serialize |
| * @param autoClassInfo a <code>List</code> of <code>Field</code>s which are to be written out |
| */ |
| public void writeData(PdxWriter writer, Object obj, AutoClassInfo autoClassInfo) { |
| PdxWriterImpl w = (PdxWriterImpl) writer; |
| boolean optimizeFieldWrites = false; |
| if (autoClassInfo.getSerializedType() != null) { |
| // check to see if we have unread data for this instance |
| if (w.initUnreadData() == null) { |
| // we don't so we can optimize the field writes since |
| // we will write them in the correct order |
| optimizeFieldWrites = true; |
| } |
| } |
| for (PdxFieldWrapper f : autoClassInfo.getFields()) { |
| // System.out.println("DEBUG writing field=" + f.getField().getName() + " offset=" + |
| // ((PdxWriterImpl)writer).position()); |
| if (f.transform()) { |
| try { |
| Object newValue = |
| getOwner().writeTransform(f.getField(), obj.getClass(), f.getObject(obj)); |
| f.serializeValue(w, newValue, optimizeFieldWrites); |
| } catch (Exception ex) { |
| f.handleException(true, obj, ex); |
| } |
| } else { |
| f.serialize(w, obj, optimizeFieldWrites); |
| } |
| if (f.isIdentityField() && w.definingNewPdxType()) { |
| try { |
| w.markIdentityField(f.getName()); |
| } catch (Exception ex) { |
| handleException(ex, true, f.getName(), obj); |
| } |
| } |
| } |
| if (autoClassInfo.getSerializedType() == null) { |
| autoClassInfo.setSerializedType(w.getAutoPdxType()); |
| } |
| } |
| |
| private static final boolean USE_CONSTRUCTOR = |
| !Boolean.getBoolean(DistributionConfig.GEMFIRE_PREFIX + "autopdx.ignoreConstructor"); |
| |
| /** |
| * Using the given PdxReader, recreate the given object. |
| * |
| * @param reader the <code>PdxReader</code> to use when reading the object |
| * @param clazz the class of the object to re-create |
| */ |
| public Object readData(PdxReader reader, Class<?> clazz) { |
| Object result = null; |
| if (isRelevant(clazz)) { |
| AutoClassInfo ci = getClassInfo(clazz); |
| result = ci.newInstance(clazz); |
| InternalPdxReader ri = (InternalPdxReader) reader; |
| PdxType pt = ri.getPdxType(); |
| if (ci.matchesPdxType(pt)) { |
| pt.setAutoInfo(ci); |
| ri.orderedDeserialize(result, ci); |
| } else { |
| for (PdxFieldWrapper f : ci.getFields()) { |
| f.deserialize(ri, result); |
| } |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * Add a new class pattern / identity-field pattern tuple |
| * |
| * @param classPattern the class pattern |
| * @param fieldPattern the pattern to identify a field as an identity field within the given class |
| * pattern |
| */ |
| public void addIdentityPattern(String classPattern, String fieldPattern) { |
| identityPatterns.add(new String[] {classPattern, fieldPattern}); |
| } |
| |
| /** |
| * Return the identity patterns. The patterns are returned as a <code>List</code> of |
| * <code>String</code> arrays of size 2 - essentially a tuple of the form |
| * |
| * <pre> |
| * (classPattern, identityPattern) |
| * </pre> |
| * |
| * @return the identity patterns |
| */ |
| public List<String[]> getIdentityPatterns() { |
| return identityPatterns; |
| } |
| |
| /** |
| * Add a new class pattern / exclude-field pattern tuple |
| * |
| * @param classPattern the class pattern |
| * @param fieldPattern the pattern to exclude a field from serialization within the given class |
| * pattern |
| */ |
| public void addExcludePattern(String classPattern, String fieldPattern) { |
| excludePatterns.add(new String[] {classPattern, fieldPattern}); |
| } |
| |
| /** |
| * Return the exclude patterns. The patterns are returned as a <code>List</code> of |
| * <code>String</code> arrays of size 2 - essentially a tuple of the form |
| * |
| * <pre> |
| * (classPattern, excludePattern) |
| * </pre> |
| * |
| * @return the exclude patterns |
| */ |
| public List<String[]> getExcludePatterns() { |
| return excludePatterns; |
| } |
| |
| /* |
| * Helper method which determines whether a given field matches a set of class/field patterns. |
| * |
| * @param field the <code>Field</code> to consider |
| * |
| * @param field the className which references this field |
| * |
| * @param matches a map containing the |
| * |
| */ |
| private boolean fieldMatches(Field field, String className, List<String[]> matches) { |
| String fieldName = field.getName(); |
| |
| for (String[] e : matches) { |
| if (className.matches(e[0]) && fieldName.matches(e[1])) { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| /** |
| * Holds meta information about a class that we have auto serialized. |
| * |
| */ |
| public static class AutoClassInfo { |
| private final WeakReference<Class<?>> clazzRef; |
| /** |
| * The fields that describe the class |
| */ |
| private final List<PdxFieldWrapper> fields; |
| /** |
| * The pdxType ids that we are known to exactly match. |
| */ |
| private final Set<Integer> matchingPdxIds = new CopyOnWriteArraySet<Integer>(); |
| /** |
| * The pdxType ids that do not exactly match our class. Either their field order differs it they |
| * have extra or missing fields. |
| */ |
| private final Set<Integer> mismatchingPdxIds = new CopyOnWriteArraySet<Integer>(); |
| |
| /** |
| * The PdxType created by the first serialization by the auto serializer. |
| */ |
| private PdxType serializedType = null; |
| |
| public AutoClassInfo(Class<?> clazz, List<PdxFieldWrapper> fields) { |
| this.clazzRef = new WeakReference<Class<?>>(clazz); |
| this.fields = fields; |
| } |
| |
| public String toFormattedString() { |
| StringBuffer sb = new StringBuffer(); |
| boolean first = true; |
| for (Object o : this.fields) { |
| if (first) { |
| first = false; |
| sb.append('\n'); |
| } |
| sb.append(" ").append(o).append('\n'); |
| } |
| return sb.toString(); |
| } |
| |
| public Object newInstance(Class<?> clazz) { |
| Object result; |
| try { |
| if (unsafe != null && !USE_CONSTRUCTOR) { |
| result = unsafe.allocateInstance(clazz); |
| } else { |
| result = clazz.newInstance(); |
| } |
| } catch (Exception ex) { |
| throw new PdxSerializationException( |
| String.format("Could not create an instance of a class %s", |
| clazz.getName()), |
| ex); |
| } |
| return result; |
| } |
| |
| public void setSerializedType(PdxType v) { |
| this.serializedType = v; |
| } |
| |
| public PdxType getSerializedType() { |
| return this.serializedType; |
| } |
| |
| public Class<?> getInfoClass() { |
| return this.clazzRef.get(); |
| } |
| |
| public List<PdxFieldWrapper> getFields() { |
| return this.fields; |
| } |
| |
| public boolean matchesPdxType(PdxType t) { |
| Integer pdxTypeId = Integer.valueOf(t.getTypeId()); |
| if (this.matchingPdxIds.contains(pdxTypeId)) { |
| return true; |
| } else if (this.mismatchingPdxIds.contains(pdxTypeId)) { |
| return false; |
| } else if (checkForMatch(t)) { |
| this.matchingPdxIds.add(pdxTypeId); |
| return true; |
| } else { |
| this.mismatchingPdxIds.add(pdxTypeId); |
| return false; |
| } |
| } |
| |
| private boolean checkForMatch(PdxType t) { |
| if (this.fields.size() != t.getUndeletedFieldCount()) { |
| return false; |
| } |
| Iterator<PdxField> pdxIt = t.getFields().iterator(); |
| for (PdxFieldWrapper f : this.fields) { |
| PdxField pdxF = pdxIt.next(); |
| if (pdxF.isDeleted()) { |
| return false; // If the type has a deleted field then we can't do ordered deserialization |
| // because we need to skip over the deleted field's bytes. |
| } |
| if (!f.getName().equals(pdxF.getFieldName())) { |
| return false; |
| } |
| if (!FieldType.get(f.getField().getType()).equals(pdxF.getFieldType())) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| @Override |
| public String toString() { |
| return "AutoClassInfo [fields=" + fields + "]"; |
| } |
| } |
| |
| public void init(Properties props) { |
| resetAll(); |
| if (props != null) { |
| Enumeration<?> it = props.propertyNames(); |
| while (it.hasMoreElements()) { |
| Object o = it.nextElement(); |
| if (o instanceof String) { |
| String key = (String) o; |
| if (INIT_CLASSES_PARAM.equals(key)) { |
| String propValue = props.getProperty(INIT_CLASSES_PARAM); |
| if (propValue != null) { |
| processInitParams(propValue); |
| } |
| } else if (INIT_CHECK_PORTABILITY_PARAM.equals(key)) { |
| String propValue = props.getProperty(INIT_CHECK_PORTABILITY_PARAM); |
| if (propValue != null) { |
| setCheckPortability(Boolean.parseBoolean(propValue)); |
| } |
| } else if (NO_HARDCODED_EXCLUDES_PARAM.equals(key)) { |
| if (props.getProperty(NO_HARDCODED_EXCLUDES_PARAM) != null) { |
| noHardcodedExcludes = true; |
| } |
| } else { |
| throw new IllegalArgumentException( |
| "ReflectionBasedAutoSerializer: unknown init property \"" + key + "\""); |
| } |
| } else { |
| throw new IllegalArgumentException( |
| "ReflectionBasedAutoSerializer: unknown non-String init property \"" + o + "\""); |
| } |
| } |
| } |
| } |
| |
| public Properties getConfig() { |
| Properties props = new Properties(); |
| if (classPatterns.isEmpty()) { |
| return props; |
| } |
| |
| StringBuilder sb = new StringBuilder(); |
| // This is so that we can exclude duplicates |
| // LinkedHashSet is used to preserve the order of classPatterns. See bug 52286. |
| Set<String> tmp = new LinkedHashSet<String>(); |
| for (Pattern p : classPatterns) { |
| tmp.add(p.pattern()); |
| } |
| for (Iterator<String> i = tmp.iterator(); i.hasNext();) { |
| String s = i.next(); |
| sb.append(s); |
| if (i.hasNext()) { |
| sb.append(", "); |
| } |
| } |
| |
| if (getIdentityPatterns().size() > 0) { |
| sb.append(", "); |
| for (Iterator<String[]> i = getIdentityPatterns().iterator(); i.hasNext();) { |
| String[] s = i.next(); |
| sb.append(s[0]).append("#" + OPT_IDENTITY + "=").append(s[1]); |
| if (i.hasNext()) { |
| sb.append(", "); |
| } |
| } |
| } |
| |
| if (getExcludePatterns().size() > 0) { |
| sb.append(", "); |
| for (Iterator<String[]> i = getExcludePatterns().iterator(); i.hasNext();) { |
| String[] s = i.next(); |
| sb.append(s[0]).append("#" + OPT_EXCLUDE + "=").append(s[1]); |
| if (i.hasNext()) { |
| sb.append(", "); |
| } |
| } |
| } |
| |
| props.put(INIT_CLASSES_PARAM, sb.toString()); |
| |
| if (getCheckPortability()) { |
| props.put(INIT_CHECK_PORTABILITY_PARAM, "true"); |
| } |
| |
| return props; |
| } |
| |
| public void reconfigure(boolean b, String... patterns) { |
| resetAll(); |
| setCheckPortability(b); |
| for (String c : patterns) { |
| processInitParams(c); |
| } |
| } |
| |
| private void processInitParams(String value) { |
| String identityPattern; |
| String excludePattern; |
| |
| for (String s : value.split("[, ]+")) { |
| if (s.length() > 0) { |
| // Let's check for any additional embedded params... |
| String[] split = s.split("#"); |
| for (int i = 1; i < split.length; i++) { |
| identityPattern = null; |
| excludePattern = null; |
| |
| String[] paramVals = split[i].split("="); |
| if (paramVals.length != 2) { |
| throw new IllegalArgumentException( |
| "Unable to correctly process auto serialization init value: " + value); |
| } |
| if (OPT_IDENTITY.equalsIgnoreCase(paramVals[0])) { |
| identityPattern = paramVals[1]; |
| } else if (OPT_EXCLUDE.equalsIgnoreCase(paramVals[0])) { |
| excludePattern = paramVals[1]; |
| } else { |
| throw new IllegalArgumentException( |
| "Unable to correctly process auto serialization init value: " + value); |
| } |
| if (identityPattern != null) { |
| addIdentityPattern(split[0], identityPattern); |
| } |
| if (excludePattern != null) { |
| addExcludePattern(split[0], excludePattern); |
| } |
| } |
| classPatterns.add(Pattern.compile(split[0])); |
| } |
| } |
| } |
| |
| private RegionService cache; |
| |
| public RegionService getRegionService() { |
| return this.cache; |
| } |
| |
| public void setRegionService(RegionService rs) { |
| this.cache = rs; |
| } |
| |
| @Override |
| public int hashCode() { |
| final int prime = 31; |
| int result = 1; |
| result = prime * result + (checkPortability ? 1231 : 1237); |
| result = prime * result + ((classPatterns == null) ? 0 : classPatterns.hashCode()); |
| result = prime * result + ((excludePatterns == null) ? 0 : excludePatterns.hashCode()); |
| result = prime * result + ((identityPatterns == null) ? 0 : identityPatterns.hashCode()); |
| return result; |
| } |
| |
| @Override |
| public boolean equals(Object obj) { |
| if (this == obj) |
| return true; |
| if (obj == null) |
| return false; |
| if (getClass() != obj.getClass()) |
| return false; |
| AutoSerializableManager other = (AutoSerializableManager) obj; |
| if (checkPortability != other.checkPortability) |
| return false; |
| if (classPatterns == null) { |
| if (other.classPatterns != null) |
| return false; |
| } else if (!classPatterns.equals(other.classPatterns)) |
| return false; |
| if (excludePatterns == null) { |
| if (other.excludePatterns != null) |
| return false; |
| } else if (!excludePatterns.equals(other.excludePatterns)) |
| return false; |
| if (identityPatterns == null) { |
| if (other.identityPatterns != null) |
| return false; |
| } else if (!identityPatterns.equals(other.identityPatterns)) |
| return false; |
| return true; |
| } |
| } |