Package org.jboss.marshalling

Examples of org.jboss.marshalling.ClassExternalizerFactory


        classCache = new IdentityIntMap<Class<?>>((int) ((double)configuration.getClassCount() / (double)loadFactor), loadFactor);
        externalizers = new IdentityHashMap<Class<?>, Externalizer>(configuration.getClassCount());
    }

    protected void doWriteObject(final Object original, final boolean unshared) throws IOException {
        final ClassExternalizerFactory classExternalizerFactory = this.classExternalizerFactory;
        final ObjectResolver objectResolver = this.objectResolver;
        final ObjectResolver objectPreResolver = this.objectPreResolver;
        Object obj = original;
        Class<?> objClass;
        int id;
        boolean isArray, isEnum;
        SerializableClass info;
        boolean unreplaced = true;
        final int configuredVersion = this.configuredVersion;
        try {
            for (;;) {
                if (obj == null) {
                    write(ID_NULL);
                    return;
                }
                final int rid;
                if (! unshared && (rid = instanceCache.get(obj, -1)) != -1) {
                    final int diff = rid - instanceSeq;
                    if (diff >= -256) {
                        write(ID_REPEAT_OBJECT_NEAR);
                        write(diff);
                    } else if (diff >= -65536) {
                        write(ID_REPEAT_OBJECT_NEARISH);
                        writeShort(diff);
                    } else {
                        write(ID_REPEAT_OBJECT_FAR);
                        writeInt(rid);
                    }
                    return;
                }
                // Check for a global pre replacement, before any user replacement is called
                obj = objectPreResolver.writeReplace(obj);
                final ObjectTable.Writer objectTableWriter;
                if (! unshared && (objectTableWriter = objectTable.getObjectWriter(obj)) != null) {
                    write(ID_PREDEFINED_OBJECT);
                    if (configuredVersion == 1) {
                        objectTableWriter.writeObject(getBlockMarshaller(), obj);
                        writeEndBlock();
                    } else {
                        objectTableWriter.writeObject(this, obj);
                    }
                    return;
                }
                objClass = obj.getClass();
                id = getBasicClasses(configuredVersion).get(objClass, -1);
                // First, non-replaceable classes
                if (id == ID_CLASS_CLASS) {
                    final Class<?> classObj = (Class<?>) obj;
                    // If a class is one we have an entry for, we just write that byte directly.
                    // These guys can't be written directly though, otherwise they'll get confused with the objects
                    // of the corresponding type.
                    final int cid = BASIC_CLASSES_V2.get(classObj, -1);
                    switch (cid) {
                        case -1:
                        case ID_SINGLETON_MAP_OBJECT:
                        case ID_SINGLETON_SET_OBJECT:
                        case ID_SINGLETON_LIST_OBJECT:
                        case ID_EMPTY_MAP_OBJECT:
                        case ID_EMPTY_SET_OBJECT:
                        case ID_EMPTY_LIST_OBJECT: {
                            // If the class is one of the above special object types, then we write a
                            // full NEW_OBJECT+CLASS_CLASS header followed by the class byte, or if there is none, write
                            // the full class descriptor.
                            write(ID_NEW_OBJECT);
                            writeClassClass(classObj);
                            return;
                        }

                        default: {
                            write(cid);
                            return;
                        }
                    }
                    // not reached
                }
                isEnum = obj instanceof Enum;
                isArray = objClass.isArray();
                // objects with id != -1 will never make use of the "info" param in *any* way
                info = isArray || isEnum || id != -1 ? null : registry.lookup(objClass);
                // replace once - objects with id != -1 will not have replacement methods but might be globally replaced
                if (unreplaced) {
                    if (info != null) {
                        // check for a user replacement
                        if (info.hasWriteReplace()) {
                            obj = info.callWriteReplace(obj);
                        }
                    }
                    // Check for a global replacement
                    obj = objectResolver.writeReplace(obj);
                    if (obj != original) {
                        unreplaced = false;
                        continue;
                    } else {
                        break;
                    }
                } else {
                    break;
                }
            }

            if (isEnum) {
                // objClass cannot equal Enum.class because it is abstract
                final Enum<?> theEnum = (Enum<?>) obj;
                // enums are always shared
                write(ID_NEW_OBJECT);
                writeEnumClass(theEnum.getDeclaringClass());
                writeString(theEnum.name());
                instanceCache.put(obj, instanceSeq++);
                return;
            }
            // Now replaceable classes
            switch (id) {
                case ID_BYTE_CLASS: {
                    write(ID_BYTE_OBJECT);
                    writeByte(((Byte) obj).byteValue());
                    return;
                }
                case ID_BOOLEAN_CLASS: {
                    write(((Boolean) obj).booleanValue() ? ID_BOOLEAN_OBJECT_TRUE : ID_BOOLEAN_OBJECT_FALSE);
                    return;
                }
                case ID_CHARACTER_CLASS: {
                    write(ID_CHARACTER_OBJECT);
                    writeChar(((Character) obj).charValue());
                    return;
                }
                case ID_DOUBLE_CLASS: {
                    write(ID_DOUBLE_OBJECT);
                    writeDouble(((Double) obj).doubleValue());
                    return;
                }
                case ID_FLOAT_CLASS: {
                    write(ID_FLOAT_OBJECT);
                    writeFloat(((Float) obj).floatValue());
                    return;
                }
                case ID_INTEGER_CLASS: {
                    write(ID_INTEGER_OBJECT);
                    writeInt(((Integer) obj).intValue());
                    return;
                }
                case ID_LONG_CLASS: {
                    write(ID_LONG_OBJECT);
                    writeLong(((Long) obj).longValue());
                    return;
                }
                case ID_SHORT_CLASS: {
                    write(ID_SHORT_OBJECT);
                    writeShort(((Short) obj).shortValue());
                    return;
                }
                case ID_STRING_CLASS: {
                    final String string = (String) obj;
                    final int len = string.length();
                    if (len == 0) {
                        write(ID_STRING_EMPTY);
                        // don't cache empty strings
                        return;
                    } else if (len <= 0x100) {
                        write(ID_STRING_SMALL);
                        write(len);
                    } else if (len <= 0x10000) {
                        write(ID_STRING_MEDIUM);
                        writeShort(len);
                    } else {
                        write(ID_STRING_LARGE);
                        writeInt(len);
                    }
                    shallowFlush();
                    UTFUtils.writeUTFBytes(byteOutput, string);
                    if (unshared) {
                        instanceCache.put(obj, -1);
                        instanceSeq++;
                    } else {
                        instanceCache.put(obj, instanceSeq++);
                    }
                    return;
                }
                case ID_BYTE_ARRAY_CLASS: {
                    if (! unshared) {
                        instanceCache.put(obj, instanceSeq++);
                    }
                    final byte[] bytes = (byte[]) obj;
                    final int len = bytes.length;
                    if (len == 0) {
                        write(unshared ? ID_ARRAY_EMPTY_UNSHARED : ID_ARRAY_EMPTY);
                        write(ID_PRIM_BYTE);
                    } else if (len <= 256) {
                        write(unshared ? ID_ARRAY_SMALL_UNSHARED : ID_ARRAY_SMALL);
                        write(len);
                        write(ID_PRIM_BYTE);
                        write(bytes, 0, len);
                    } else if (len <= 65536) {
                        write(unshared ? ID_ARRAY_MEDIUM_UNSHARED : ID_ARRAY_MEDIUM);
                        writeShort(len);
                        write(ID_PRIM_BYTE);
                        write(bytes, 0, len);
                    } else {
                        write(unshared ? ID_ARRAY_LARGE_UNSHARED : ID_ARRAY_LARGE);
                        writeInt(len);
                        write(ID_PRIM_BYTE);
                        write(bytes, 0, len);
                    }
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case ID_BOOLEAN_ARRAY_CLASS: {
                    if (! unshared) {
                        instanceCache.put(obj, instanceSeq++);
                    }
                    final boolean[] booleans = (boolean[]) obj;
                    final int len = booleans.length;
                    if (len == 0) {
                        write(unshared ? ID_ARRAY_EMPTY_UNSHARED : ID_ARRAY_EMPTY);
                        write(ID_PRIM_BOOLEAN);
                    } else if (len <= 256) {
                        write(unshared ? ID_ARRAY_SMALL_UNSHARED : ID_ARRAY_SMALL);
                        write(len);
                        write(ID_PRIM_BOOLEAN);
                        writeBooleanArray(booleans);
                    } else if (len <= 65536) {
                        write(unshared ? ID_ARRAY_MEDIUM_UNSHARED : ID_ARRAY_MEDIUM);
                        writeShort(len);
                        write(ID_PRIM_BOOLEAN);
                        writeBooleanArray(booleans);
                    } else {
                        write(unshared ? ID_ARRAY_LARGE_UNSHARED : ID_ARRAY_LARGE);
                        writeInt(len);
                        write(ID_PRIM_BOOLEAN);
                        writeBooleanArray(booleans);
                    }
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case ID_CHAR_ARRAY_CLASS: {
                    if (! unshared) {
                        instanceCache.put(obj, instanceSeq++);
                    }
                    final char[] chars = (char[]) obj;
                    final int len = chars.length;
                    if (len == 0) {
                        write(unshared ? ID_ARRAY_EMPTY_UNSHARED : ID_ARRAY_EMPTY);
                        write(ID_PRIM_CHAR);
                    } else if (len <= 256) {
                        write(unshared ? ID_ARRAY_SMALL_UNSHARED : ID_ARRAY_SMALL);
                        write(len);
                        write(ID_PRIM_CHAR);
                        for (int i = 0; i < len; i ++) {
                            writeChar(chars[i]);
                        }
                    } else if (len <= 65536) {
                        write(unshared ? ID_ARRAY_MEDIUM_UNSHARED : ID_ARRAY_MEDIUM);
                        writeShort(len);
                        write(ID_PRIM_CHAR);
                        for (int i = 0; i < len; i ++) {
                            writeChar(chars[i]);
                        }
                    } else {
                        write(unshared ? ID_ARRAY_LARGE_UNSHARED : ID_ARRAY_LARGE);
                        writeInt(len);
                        write(ID_PRIM_CHAR);
                        for (int i = 0; i < len; i ++) {
                            writeChar(chars[i]);
                        }
                    }
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case ID_SHORT_ARRAY_CLASS: {
                    if (! unshared) {
                        instanceCache.put(obj, instanceSeq++);
                    }
                    final short[] shorts = (short[]) obj;
                    final int len = shorts.length;
                    if (len == 0) {
                        write(unshared ? ID_ARRAY_EMPTY_UNSHARED : ID_ARRAY_EMPTY);
                        write(ID_PRIM_SHORT);
                    } else if (len <= 256) {
                        write(unshared ? ID_ARRAY_SMALL_UNSHARED : ID_ARRAY_SMALL);
                        write(len);
                        write(ID_PRIM_SHORT);
                        for (int i = 0; i < len; i ++) {
                            writeShort(shorts[i]);
                        }
                    } else if (len <= 65536) {
                        write(unshared ? ID_ARRAY_MEDIUM_UNSHARED : ID_ARRAY_MEDIUM);
                        writeShort(len);
                        write(ID_PRIM_SHORT);
                        for (int i = 0; i < len; i ++) {
                            writeShort(shorts[i]);
                        }
                    } else {
                        write(unshared ? ID_ARRAY_LARGE_UNSHARED : ID_ARRAY_LARGE);
                        writeInt(len);
                        write(ID_PRIM_SHORT);
                        for (int i = 0; i < len; i ++) {
                            writeShort(shorts[i]);
                        }
                    }
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case ID_INT_ARRAY_CLASS: {
                    if (! unshared) {
                        instanceCache.put(obj, instanceSeq++);
                    }
                    final int[] ints = (int[]) obj;
                    final int len = ints.length;
                    if (len == 0) {
                        write(unshared ? ID_ARRAY_EMPTY_UNSHARED : ID_ARRAY_EMPTY);
                        write(ID_PRIM_INT);
                    } else if (len <= 256) {
                        write(unshared ? ID_ARRAY_SMALL_UNSHARED : ID_ARRAY_SMALL);
                        write(len);
                        write(ID_PRIM_INT);
                        for (int i = 0; i < len; i ++) {
                            writeInt(ints[i]);
                        }
                    } else if (len <= 65536) {
                        write(unshared ? ID_ARRAY_MEDIUM_UNSHARED : ID_ARRAY_MEDIUM);
                        writeShort(len);
                        write(ID_PRIM_INT);
                        for (int i = 0; i < len; i ++) {
                            writeInt(ints[i]);
                        }
                    } else {
                        write(unshared ? ID_ARRAY_LARGE_UNSHARED : ID_ARRAY_LARGE);
                        writeInt(len);
                        write(ID_PRIM_INT);
                        for (int i = 0; i < len; i ++) {
                            writeInt(ints[i]);
                        }
                    }
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case ID_LONG_ARRAY_CLASS: {
                    if (! unshared) {
                        instanceCache.put(obj, instanceSeq++);
                    }
                    final long[] longs = (long[]) obj;
                    final int len = longs.length;
                    if (len == 0) {
                        write(unshared ? ID_ARRAY_EMPTY_UNSHARED : ID_ARRAY_EMPTY);
                        write(ID_PRIM_LONG);
                    } else if (len <= 256) {
                        write(unshared ? ID_ARRAY_SMALL_UNSHARED : ID_ARRAY_SMALL);
                        write(len);
                        write(ID_PRIM_LONG);
                        for (int i = 0; i < len; i ++) {
                            writeLong(longs[i]);
                        }
                    } else if (len <= 65536) {
                        write(unshared ? ID_ARRAY_MEDIUM_UNSHARED : ID_ARRAY_MEDIUM);
                        writeShort(len);
                        write(ID_PRIM_LONG);
                        for (int i = 0; i < len; i ++) {
                            writeLong(longs[i]);
                        }
                    } else {
                        write(unshared ? ID_ARRAY_LARGE_UNSHARED : ID_ARRAY_LARGE);
                        writeInt(len);
                        write(ID_PRIM_LONG);
                        for (int i = 0; i < len; i ++) {
                            writeLong(longs[i]);
                        }
                    }
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case ID_FLOAT_ARRAY_CLASS: {
                    if (! unshared) {
                        instanceCache.put(obj, instanceSeq++);
                    }
                    final float[] floats = (float[]) obj;
                    final int len = floats.length;
                    if (len == 0) {
                        write(unshared ? ID_ARRAY_EMPTY_UNSHARED : ID_ARRAY_EMPTY);
                        write(ID_PRIM_FLOAT);
                    } else if (len <= 256) {
                        write(unshared ? ID_ARRAY_SMALL_UNSHARED : ID_ARRAY_SMALL);
                        write(len);
                        write(ID_PRIM_FLOAT);
                        for (int i = 0; i < len; i ++) {
                            writeFloat(floats[i]);
                        }
                    } else if (len <= 65536) {
                        write(unshared ? ID_ARRAY_MEDIUM_UNSHARED : ID_ARRAY_MEDIUM);
                        writeShort(len);
                        write(ID_PRIM_FLOAT);
                        for (int i = 0; i < len; i ++) {
                            writeFloat(floats[i]);
                        }
                    } else {
                        write(unshared ? ID_ARRAY_LARGE_UNSHARED : ID_ARRAY_LARGE);
                        writeInt(len);
                        write(ID_PRIM_FLOAT);
                        for (int i = 0; i < len; i ++) {
                            writeFloat(floats[i]);
                        }
                    }
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case ID_DOUBLE_ARRAY_CLASS: {
                    if (! unshared) {
                        instanceCache.put(obj, instanceSeq++);
                    }
                    final double[] doubles = (double[]) obj;
                    final int len = doubles.length;
                    if (len == 0) {
                        write(unshared ? ID_ARRAY_EMPTY_UNSHARED : ID_ARRAY_EMPTY);
                        write(ID_PRIM_DOUBLE);
                    } else if (len <= 256) {
                        write(unshared ? ID_ARRAY_SMALL_UNSHARED : ID_ARRAY_SMALL);
                        write(len);
                        write(ID_PRIM_DOUBLE);
                        for (int i = 0; i < len; i ++) {
                            writeDouble(doubles[i]);
                        }
                    } else if (len <= 65536) {
                        write(unshared ? ID_ARRAY_MEDIUM_UNSHARED : ID_ARRAY_MEDIUM);
                        writeShort(len);
                        write(ID_PRIM_DOUBLE);
                        for (int i = 0; i < len; i ++) {
                            writeDouble(doubles[i]);
                        }
                    } else {
                        write(unshared ? ID_ARRAY_LARGE_UNSHARED : ID_ARRAY_LARGE);
                        writeInt(len);
                        write(ID_PRIM_DOUBLE);
                        for (int i = 0; i < len; i ++) {
                            writeDouble(doubles[i]);
                        }
                    }
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case ID_CC_HASH_SET:
                case ID_CC_LINKED_HASH_SET:
                case ID_CC_TREE_SET:
                case ID_CC_ARRAY_LIST:
                case ID_CC_LINKED_LIST:
                case ID_CC_VECTOR:
                case ID_CC_STACK:
                case ID_CC_ARRAY_DEQUE: {
                    instanceCache.put(obj, instanceSeq++);
                    final Collection<?> collection = (Collection<?>) obj;
                    final int len = collection.size();
                    if (len == 0) {
                        write(unshared ? ID_COLLECTION_EMPTY_UNSHARED : ID_COLLECTION_EMPTY);
                        write(id);
                        if (id == ID_CC_TREE_SET) {
                            doWriteObject(((TreeSet)collection).comparator(), false);
                        }
                    } else if (len <= 256) {
                        write(unshared ? ID_COLLECTION_SMALL_UNSHARED : ID_COLLECTION_SMALL);
                        write(len);
                        write(id);
                        if (id == ID_CC_TREE_SET) {
                            doWriteObject(((TreeSet)collection).comparator(), false);
                        }
                        for (Object o : collection) {
                            doWriteObject(o, false);
                        }
                    } else if (len <= 65536) {
                        write(unshared ? ID_COLLECTION_MEDIUM_UNSHARED : ID_COLLECTION_MEDIUM);
                        writeShort(len);
                        write(id);
                        if (id == ID_CC_TREE_SET) {
                            doWriteObject(((TreeSet)collection).comparator(), false);
                        }
                        for (Object o : collection) {
                            doWriteObject(o, false);
                        }
                    } else {
                        write(unshared ? ID_COLLECTION_LARGE_UNSHARED : ID_COLLECTION_LARGE);
                        writeInt(len);
                        write(id);
                        if (id == ID_CC_TREE_SET) {
                            doWriteObject(((TreeSet)collection).comparator(), false);
                        }
                        for (Object o : collection) {
                            doWriteObject(o, false);
                        }
                    }
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case ID_CC_ENUM_SET_PROXY: {
                    final Enum[] elements = getEnumSetElements(obj);
                    final int len = elements.length;
                    if (len == 0) {
                        write(unshared ? ID_COLLECTION_EMPTY_UNSHARED : ID_COLLECTION_EMPTY);
                        write(id);
                        writeClass(getEnumSetElementType(obj));
                        instanceCache.put(obj, instanceSeq++);
                    } else if (len <= 256) {
                        write(unshared ? ID_COLLECTION_SMALL_UNSHARED : ID_COLLECTION_SMALL);
                        write(len);
                        write(id);
                        writeClass(getEnumSetElementType(obj));
                        instanceCache.put(obj, instanceSeq++);
                        for (Object o : elements) {
                            doWriteObject(o, false);
                        }
                    } else if (len <= 65536) {
                        write(unshared ? ID_COLLECTION_MEDIUM_UNSHARED : ID_COLLECTION_MEDIUM);
                        writeShort(len);
                        write(id);
                        writeClass(getEnumSetElementType(obj));
                        instanceCache.put(obj, instanceSeq++);
                        for (Object o : elements) {
                            doWriteObject(o, false);
                        }
                    } else {
                        write(unshared ? ID_COLLECTION_LARGE_UNSHARED : ID_COLLECTION_LARGE);
                        writeInt(len);
                        write(id);
                        writeClass(getEnumSetElementType(obj));
                        instanceCache.put(obj, instanceSeq++);
                        for (Object o : elements) {
                            doWriteObject(o, false);
                        }
                    }
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case ID_CC_HASH_MAP:
                case ID_CC_HASHTABLE:
                case ID_CC_IDENTITY_HASH_MAP:
                case ID_CC_LINKED_HASH_MAP:
                case ID_CC_TREE_MAP:
                case ID_CC_ENUM_MAP: {
                    instanceCache.put(obj, instanceSeq++);
                    final Map<?, ?> map = (Map<?, ?>) obj;
                    final int len = map.size();
                    if (len == 0) {
                        write(unshared ? ID_COLLECTION_EMPTY_UNSHARED : ID_COLLECTION_EMPTY);
                        write(id);
                        switch (id) {
                            case ID_CC_TREE_MAP: doWriteObject(((TreeMap)map).comparator(), false); break;
                            case ID_CC_ENUM_MAP: writeClass(getEnumMapKeyType(obj)); break;
                        }
                    } else if (len <= 256) {
                        write(unshared ? ID_COLLECTION_SMALL_UNSHARED : ID_COLLECTION_SMALL);
                        write(len);
                        write(id);
                        switch (id) {
                            case ID_CC_TREE_MAP: doWriteObject(((TreeMap)map).comparator(), false); break;
                            case ID_CC_ENUM_MAP: writeClass(getEnumMapKeyType(obj)); break;
                        }
                        for (Map.Entry<?, ?> entry : map.entrySet()) {
                            doWriteObject(entry.getKey(), false);
                            doWriteObject(entry.getValue(), false);
                        }
                    } else if (len <= 65536) {
                        write(unshared ? ID_COLLECTION_MEDIUM_UNSHARED : ID_COLLECTION_MEDIUM);
                        writeShort(len);
                        write(id);
                        switch (id) {
                            case ID_CC_TREE_MAP: doWriteObject(((TreeMap)map).comparator(), false); break;
                            case ID_CC_ENUM_MAP: writeClass(getEnumMapKeyType(obj)); break;
                        }
                        for (Map.Entry<?, ?> entry : map.entrySet()) {
                            doWriteObject(entry.getKey(), false);
                            doWriteObject(entry.getValue(), false);
                        }
                    } else {
                        write(unshared ? ID_COLLECTION_LARGE_UNSHARED : ID_COLLECTION_LARGE);
                        writeInt(len);
                        write(id);
                        switch (id) {
                            case ID_CC_TREE_MAP: doWriteObject(((TreeMap)map).comparator(), false); break;
                            case ID_CC_ENUM_MAP: writeClass(getEnumMapKeyType(obj)); break;
                        }
                        for (Map.Entry<?, ?> entry : map.entrySet()) {
                            doWriteObject(entry.getKey(), false);
                            doWriteObject(entry.getValue(), false);
                        }
                    }
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }

                case ID_EMPTY_MAP_OBJECT:
                case ID_EMPTY_SET_OBJECT:
                case ID_EMPTY_LIST_OBJECT:
                case ID_REVERSE_ORDER_OBJECT: {
                    write(id);
                    return;
                }
                case ID_SINGLETON_MAP_OBJECT: {
                    instanceCache.put(obj, instanceSeq++);
                    write(id);
                    final Map.Entry entry = (Map.Entry) ((Map) obj).entrySet().iterator().next();
                    doWriteObject(entry.getKey(), false);
                    doWriteObject(entry.getValue(), false);
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case ID_SINGLETON_LIST_OBJECT:
                case ID_SINGLETON_SET_OBJECT: {
                    instanceCache.put(obj, instanceSeq++);
                    write(id);
                    doWriteObject(((Collection)obj).iterator().next(), false);
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case ID_REVERSE_ORDER2_OBJECT: {
                    instanceCache.put(obj, instanceSeq++);
                    write(id);
                    try {
                        doWriteObject(Protocol.reverseOrder2Field.get(obj), false);
                    } catch (IllegalAccessException e) {
                        throw new InvalidObjectException("Cannot access standard field for reverse-order comparator");
                    }
                    return;
                }
                case ID_CC_CONCURRENT_HASH_MAP:
                case ID_CC_COPY_ON_WRITE_ARRAY_LIST:
                case ID_CC_COPY_ON_WRITE_ARRAY_SET: {
                    info = registry.lookup(objClass);
                    break;
                }
                case ID_PAIR: {
                    instanceCache.put(obj, instanceSeq++);
                    write(id);
                    Pair<?, ?> pair = (Pair<?, ?>) obj;
                    doWriteObject(pair.getA(), unshared);
                    doWriteObject(pair.getB(), unshared);
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case ID_CC_NCOPIES: {
                    List<?> list = (List<?>) obj;
                    int size = list.size();
                    if (size == 0) {
                        write(ID_EMPTY_LIST_OBJECT);
                        return;
                    }
                    instanceCache.put(obj, instanceSeq++);
                    if (size <= 256) {
                        write(unshared ? ID_COLLECTION_SMALL_UNSHARED : ID_COLLECTION_SMALL);
                        write(size);
                    } else if (size <= 65536) {
                        write(unshared ? ID_COLLECTION_MEDIUM_UNSHARED : ID_COLLECTION_MEDIUM);
                        writeShort(size);
                    } else {
                        write(unshared ? ID_COLLECTION_LARGE_UNSHARED : ID_COLLECTION_LARGE);
                        writeInt(size);
                    }
                    write(id);
                    doWriteObject(list.iterator().next(), false);
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case -1: break;
                default: throw new NotSerializableException(objClass.getName());
            }
            if (isArray) {
                final Object[] objects = (Object[]) obj;
                final int len = objects.length;
                if (len == 0) {
                    write(unshared ? ID_ARRAY_EMPTY_UNSHARED : ID_ARRAY_EMPTY);
                    writeClass(objClass.getComponentType());
                    instanceCache.put(obj, instanceSeq++);
                } else if (len <= 256) {
                    write(unshared ? ID_ARRAY_SMALL_UNSHARED : ID_ARRAY_SMALL);
                    write(len);
                    writeClass(objClass.getComponentType());
                    instanceCache.put(obj, instanceSeq++);
                    for (int i = 0; i < len; i++) {
                        doWriteObject(objects[i], unshared);
                    }
                } else if (len <= 65536) {
                    write(unshared ? ID_ARRAY_MEDIUM_UNSHARED : ID_ARRAY_MEDIUM);
                    writeShort(len);
                    writeClass(objClass.getComponentType());
                    instanceCache.put(obj, instanceSeq++);
                    for (int i = 0; i < len; i++) {
                        doWriteObject(objects[i], unshared);
                    }
                } else {
                    write(unshared ? ID_ARRAY_LARGE_UNSHARED : ID_ARRAY_LARGE);
                    writeInt(len);
                    writeClass(objClass.getComponentType());
                    instanceCache.put(obj, instanceSeq++);
                    for (int i = 0; i < len; i++) {
                        doWriteObject(objects[i], unshared);
                    }
                }
                if (unshared) {
                    instanceCache.put(obj, -1);
                }
                return;
            }
            // serialize proxies efficiently
            if (obj instanceof Proxy) {
                write(unshared ? ID_NEW_OBJECT_UNSHARED : ID_NEW_OBJECT);
                writeProxyClass(objClass);
                instanceCache.put(obj, instanceSeq++);
                doWriteObject(Proxy.getInvocationHandler(obj), false);
                if (unshared) {
                    instanceCache.put(obj, -1);
                }
                return;
            }
            // it's a user type
            // user type #1: externalizer
            Externalizer externalizer;
            if (externalizers.containsKey(objClass)) {
                externalizer = externalizers.get(objClass);
            } else {
                externalizer = classExternalizerFactory.getExternalizer(objClass);
                externalizers.put(objClass, externalizer);
            }
            if (externalizer != null) {
                write(unshared ? ID_NEW_OBJECT_UNSHARED : ID_NEW_OBJECT);
                writeExternalizerClass(objClass, externalizer);
View Full Code Here


        map.put("34890fdu90uq09rdewq", "wqeioqwdias90ifd0adfw");
        map.put("dsajkljwqej21309ejjfdasfda", "dsajkdqwoid");
        map.put("nczxm,ncoijd0q93wjdwdwq", " dsajkldwqj9edwqu");
        runReadWriteTest(new ReadWriteTest() {
            public void configure(final MarshallingConfiguration configuration) throws Throwable {
                configuration.setClassExternalizerFactory(new ClassExternalizerFactory() {
                    public Externalizer getExternalizer(final Class<?> type) {
                        if (type == HashMap.class) {
                            return new HashMapExternalizer();
                        } else {
                            return null;
View Full Code Here

        map.put("34890fdu90uq09rdewq", ext2);
        map.put("nczxm,ncoijd0q93wjdwdwq", ext3);
        final AtomicInteger version = new AtomicInteger();
        runReadWriteTest(new ReadWriteTest() {
            public void configure(final MarshallingConfiguration configuration) throws Throwable {
                configuration.setClassExternalizerFactory(new ClassExternalizerFactory() {
                    public Externalizer getExternalizer(final Class<?> type) {
                        if (type == HashMap.class) {
                            return new HashMapExternalizer();
                        } else {
                            return null;
View Full Code Here

        classCache = new IdentityIntMap<Class<?>>((int) ((double)configuration.getClassCount() / (double)loadFactor), loadFactor);
        externalizers = new IdentityHashMap<Class<?>, Externalizer>(configuration.getClassCount());
    }

    protected void doWriteObject(final Object original, final boolean unshared) throws IOException {
        final ClassExternalizerFactory classExternalizerFactory = this.classExternalizerFactory;
        final ObjectResolver objectResolver = this.objectResolver;
        final ObjectResolver objectPreResolver = this.objectPreResolver;
        Object obj = original;
        Class<?> objClass;
        int id;
        boolean isArray, isEnum;
        SerializableClass info;
        boolean unreplaced = true;
        final int configuredVersion = this.configuredVersion;
        try {
            for (;;) {
                if (obj == null) {
                    write(ID_NULL);
                    return;
                }
                final int rid;
                if (! unshared && (rid = instanceCache.get(obj, -1)) != -1) {
                    final int diff = rid - instanceSeq;
                    if (diff >= -256) {
                        write(ID_REPEAT_OBJECT_NEAR);
                        write(diff);
                    } else if (diff >= -65536) {
                        write(ID_REPEAT_OBJECT_NEARISH);
                        writeShort(diff);
                    } else {
                        write(ID_REPEAT_OBJECT_FAR);
                        writeInt(rid);
                    }
                    return;
                }
                // Check for a global pre replacement, before any user replacement is called
                obj = objectPreResolver.writeReplace(obj);
                final ObjectTable.Writer objectTableWriter;
                if (! unshared && (objectTableWriter = objectTable.getObjectWriter(obj)) != null) {
                    write(ID_PREDEFINED_OBJECT);
                    if (configuredVersion == 1) {
                        objectTableWriter.writeObject(getBlockMarshaller(), obj);
                        writeEndBlock();
                    } else {
                        objectTableWriter.writeObject(this, obj);
                    }
                    return;
                }
                objClass = obj.getClass();
                id = getBasicClasses(configuredVersion).get(objClass, -1);
                // First, non-replaceable classes
                if (id == ID_CLASS_CLASS) {
                    final Class<?> classObj = (Class<?>) obj;
                    // If a class is one we have an entry for, we just write that byte directly.
                    // These guys can't be written directly though, otherwise they'll get confused with the objects
                    // of the corresponding type.
                    final int cid = BASIC_CLASSES_V2.get(classObj, -1);
                    switch (cid) {
                        case -1:
                        case ID_SINGLETON_MAP_OBJECT:
                        case ID_SINGLETON_SET_OBJECT:
                        case ID_SINGLETON_LIST_OBJECT:
                        case ID_EMPTY_MAP_OBJECT:
                        case ID_EMPTY_SET_OBJECT:
                        case ID_EMPTY_LIST_OBJECT: {
                            // If the class is one of the above special object types, then we write a
                            // full NEW_OBJECT+CLASS_CLASS header followed by the class byte, or if there is none, write
                            // the full class descriptor.
                            write(ID_NEW_OBJECT);
                            writeClassClass(classObj);
                            return;
                        }

                        default: {
                            write(cid);
                            return;
                        }
                    }
                    // not reached
                }
                isEnum = obj instanceof Enum;
                isArray = objClass.isArray();
                // objects with id != -1 will never make use of the "info" param in *any* way
                info = isArray || isEnum || id != -1 ? null : registry.lookup(objClass);
                // replace once - objects with id != -1 will not have replacement methods but might be globally replaced
                if (unreplaced) {
                    if (info != null) {
                        // check for a user replacement
                        if (info.hasWriteReplace()) {
                            obj = info.callWriteReplace(obj);
                        }
                    }
                    // Check for a global replacement
                    obj = objectResolver.writeReplace(obj);
                    if (obj != original) {
                        unreplaced = false;
                        continue;
                    } else {
                        break;
                    }
                } else {
                    break;
                }
            }

            if (isEnum) {
                // objClass cannot equal Enum.class because it is abstract
                final Enum<?> theEnum = (Enum<?>) obj;
                // enums are always shared
                write(ID_NEW_OBJECT);
                writeEnumClass(theEnum.getDeclaringClass());
                writeString(theEnum.name());
                instanceCache.put(obj, instanceSeq++);
                return;
            }
            // Now replaceable classes
            switch (id) {
                case ID_BYTE_CLASS: {
                    write(ID_BYTE_OBJECT);
                    writeByte(((Byte) obj).byteValue());
                    return;
                }
                case ID_BOOLEAN_CLASS: {
                    write(((Boolean) obj).booleanValue() ? ID_BOOLEAN_OBJECT_TRUE : ID_BOOLEAN_OBJECT_FALSE);
                    return;
                }
                case ID_CHARACTER_CLASS: {
                    write(ID_CHARACTER_OBJECT);
                    writeChar(((Character) obj).charValue());
                    return;
                }
                case ID_DOUBLE_CLASS: {
                    write(ID_DOUBLE_OBJECT);
                    writeDouble(((Double) obj).doubleValue());
                    return;
                }
                case ID_FLOAT_CLASS: {
                    write(ID_FLOAT_OBJECT);
                    writeFloat(((Float) obj).floatValue());
                    return;
                }
                case ID_INTEGER_CLASS: {
                    write(ID_INTEGER_OBJECT);
                    writeInt(((Integer) obj).intValue());
                    return;
                }
                case ID_LONG_CLASS: {
                    write(ID_LONG_OBJECT);
                    writeLong(((Long) obj).longValue());
                    return;
                }
                case ID_SHORT_CLASS: {
                    write(ID_SHORT_OBJECT);
                    writeShort(((Short) obj).shortValue());
                    return;
                }
                case ID_STRING_CLASS: {
                    final String string = (String) obj;
                    final int len = string.length();
                    if (len == 0) {
                        write(ID_STRING_EMPTY);
                        // don't cache empty strings
                        return;
                    } else if (len <= 0x100) {
                        write(ID_STRING_SMALL);
                        write(len);
                    } else if (len <= 0x10000) {
                        write(ID_STRING_MEDIUM);
                        writeShort(len);
                    } else {
                        write(ID_STRING_LARGE);
                        writeInt(len);
                    }
                    shallowFlush();
                    UTFUtils.writeUTFBytes(byteOutput, string);
                    if (unshared) {
                        instanceCache.put(obj, -1);
                        instanceSeq++;
                    } else {
                        instanceCache.put(obj, instanceSeq++);
                    }
                    return;
                }
                case ID_BYTE_ARRAY_CLASS: {
                    if (! unshared) {
                        instanceCache.put(obj, instanceSeq++);
                    }
                    final byte[] bytes = (byte[]) obj;
                    final int len = bytes.length;
                    if (len == 0) {
                        write(unshared ? ID_ARRAY_EMPTY_UNSHARED : ID_ARRAY_EMPTY);
                        write(ID_PRIM_BYTE);
                    } else if (len <= 256) {
                        write(unshared ? ID_ARRAY_SMALL_UNSHARED : ID_ARRAY_SMALL);
                        write(len);
                        write(ID_PRIM_BYTE);
                        write(bytes, 0, len);
                    } else if (len <= 65536) {
                        write(unshared ? ID_ARRAY_MEDIUM_UNSHARED : ID_ARRAY_MEDIUM);
                        writeShort(len);
                        write(ID_PRIM_BYTE);
                        write(bytes, 0, len);
                    } else {
                        write(unshared ? ID_ARRAY_LARGE_UNSHARED : ID_ARRAY_LARGE);
                        writeInt(len);
                        write(ID_PRIM_BYTE);
                        write(bytes, 0, len);
                    }
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case ID_BOOLEAN_ARRAY_CLASS: {
                    if (! unshared) {
                        instanceCache.put(obj, instanceSeq++);
                    }
                    final boolean[] booleans = (boolean[]) obj;
                    final int len = booleans.length;
                    if (len == 0) {
                        write(unshared ? ID_ARRAY_EMPTY_UNSHARED : ID_ARRAY_EMPTY);
                        write(ID_PRIM_BOOLEAN);
                    } else if (len <= 256) {
                        write(unshared ? ID_ARRAY_SMALL_UNSHARED : ID_ARRAY_SMALL);
                        write(len);
                        write(ID_PRIM_BOOLEAN);
                        writeBooleanArray(booleans);
                    } else if (len <= 65536) {
                        write(unshared ? ID_ARRAY_MEDIUM_UNSHARED : ID_ARRAY_MEDIUM);
                        writeShort(len);
                        write(ID_PRIM_BOOLEAN);
                        writeBooleanArray(booleans);
                    } else {
                        write(unshared ? ID_ARRAY_LARGE_UNSHARED : ID_ARRAY_LARGE);
                        writeInt(len);
                        write(ID_PRIM_BOOLEAN);
                        writeBooleanArray(booleans);
                    }
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case ID_CHAR_ARRAY_CLASS: {
                    if (! unshared) {
                        instanceCache.put(obj, instanceSeq++);
                    }
                    final char[] chars = (char[]) obj;
                    final int len = chars.length;
                    if (len == 0) {
                        write(unshared ? ID_ARRAY_EMPTY_UNSHARED : ID_ARRAY_EMPTY);
                        write(ID_PRIM_CHAR);
                    } else if (len <= 256) {
                        write(unshared ? ID_ARRAY_SMALL_UNSHARED : ID_ARRAY_SMALL);
                        write(len);
                        write(ID_PRIM_CHAR);
                        for (int i = 0; i < len; i ++) {
                            writeChar(chars[i]);
                        }
                    } else if (len <= 65536) {
                        write(unshared ? ID_ARRAY_MEDIUM_UNSHARED : ID_ARRAY_MEDIUM);
                        writeShort(len);
                        write(ID_PRIM_CHAR);
                        for (int i = 0; i < len; i ++) {
                            writeChar(chars[i]);
                        }
                    } else {
                        write(unshared ? ID_ARRAY_LARGE_UNSHARED : ID_ARRAY_LARGE);
                        writeInt(len);
                        write(ID_PRIM_CHAR);
                        for (int i = 0; i < len; i ++) {
                            writeChar(chars[i]);
                        }
                    }
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case ID_SHORT_ARRAY_CLASS: {
                    if (! unshared) {
                        instanceCache.put(obj, instanceSeq++);
                    }
                    final short[] shorts = (short[]) obj;
                    final int len = shorts.length;
                    if (len == 0) {
                        write(unshared ? ID_ARRAY_EMPTY_UNSHARED : ID_ARRAY_EMPTY);
                        write(ID_PRIM_SHORT);
                    } else if (len <= 256) {
                        write(unshared ? ID_ARRAY_SMALL_UNSHARED : ID_ARRAY_SMALL);
                        write(len);
                        write(ID_PRIM_SHORT);
                        for (int i = 0; i < len; i ++) {
                            writeShort(shorts[i]);
                        }
                    } else if (len <= 65536) {
                        write(unshared ? ID_ARRAY_MEDIUM_UNSHARED : ID_ARRAY_MEDIUM);
                        writeShort(len);
                        write(ID_PRIM_SHORT);
                        for (int i = 0; i < len; i ++) {
                            writeShort(shorts[i]);
                        }
                    } else {
                        write(unshared ? ID_ARRAY_LARGE_UNSHARED : ID_ARRAY_LARGE);
                        writeInt(len);
                        write(ID_PRIM_SHORT);
                        for (int i = 0; i < len; i ++) {
                            writeShort(shorts[i]);
                        }
                    }
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case ID_INT_ARRAY_CLASS: {
                    if (! unshared) {
                        instanceCache.put(obj, instanceSeq++);
                    }
                    final int[] ints = (int[]) obj;
                    final int len = ints.length;
                    if (len == 0) {
                        write(unshared ? ID_ARRAY_EMPTY_UNSHARED : ID_ARRAY_EMPTY);
                        write(ID_PRIM_INT);
                    } else if (len <= 256) {
                        write(unshared ? ID_ARRAY_SMALL_UNSHARED : ID_ARRAY_SMALL);
                        write(len);
                        write(ID_PRIM_INT);
                        for (int i = 0; i < len; i ++) {
                            writeInt(ints[i]);
                        }
                    } else if (len <= 65536) {
                        write(unshared ? ID_ARRAY_MEDIUM_UNSHARED : ID_ARRAY_MEDIUM);
                        writeShort(len);
                        write(ID_PRIM_INT);
                        for (int i = 0; i < len; i ++) {
                            writeInt(ints[i]);
                        }
                    } else {
                        write(unshared ? ID_ARRAY_LARGE_UNSHARED : ID_ARRAY_LARGE);
                        writeInt(len);
                        write(ID_PRIM_INT);
                        for (int i = 0; i < len; i ++) {
                            writeInt(ints[i]);
                        }
                    }
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case ID_LONG_ARRAY_CLASS: {
                    if (! unshared) {
                        instanceCache.put(obj, instanceSeq++);
                    }
                    final long[] longs = (long[]) obj;
                    final int len = longs.length;
                    if (len == 0) {
                        write(unshared ? ID_ARRAY_EMPTY_UNSHARED : ID_ARRAY_EMPTY);
                        write(ID_PRIM_LONG);
                    } else if (len <= 256) {
                        write(unshared ? ID_ARRAY_SMALL_UNSHARED : ID_ARRAY_SMALL);
                        write(len);
                        write(ID_PRIM_LONG);
                        for (int i = 0; i < len; i ++) {
                            writeLong(longs[i]);
                        }
                    } else if (len <= 65536) {
                        write(unshared ? ID_ARRAY_MEDIUM_UNSHARED : ID_ARRAY_MEDIUM);
                        writeShort(len);
                        write(ID_PRIM_LONG);
                        for (int i = 0; i < len; i ++) {
                            writeLong(longs[i]);
                        }
                    } else {
                        write(unshared ? ID_ARRAY_LARGE_UNSHARED : ID_ARRAY_LARGE);
                        writeInt(len);
                        write(ID_PRIM_LONG);
                        for (int i = 0; i < len; i ++) {
                            writeLong(longs[i]);
                        }
                    }
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case ID_FLOAT_ARRAY_CLASS: {
                    if (! unshared) {
                        instanceCache.put(obj, instanceSeq++);
                    }
                    final float[] floats = (float[]) obj;
                    final int len = floats.length;
                    if (len == 0) {
                        write(unshared ? ID_ARRAY_EMPTY_UNSHARED : ID_ARRAY_EMPTY);
                        write(ID_PRIM_FLOAT);
                    } else if (len <= 256) {
                        write(unshared ? ID_ARRAY_SMALL_UNSHARED : ID_ARRAY_SMALL);
                        write(len);
                        write(ID_PRIM_FLOAT);
                        for (int i = 0; i < len; i ++) {
                            writeFloat(floats[i]);
                        }
                    } else if (len <= 65536) {
                        write(unshared ? ID_ARRAY_MEDIUM_UNSHARED : ID_ARRAY_MEDIUM);
                        writeShort(len);
                        write(ID_PRIM_FLOAT);
                        for (int i = 0; i < len; i ++) {
                            writeFloat(floats[i]);
                        }
                    } else {
                        write(unshared ? ID_ARRAY_LARGE_UNSHARED : ID_ARRAY_LARGE);
                        writeInt(len);
                        write(ID_PRIM_FLOAT);
                        for (int i = 0; i < len; i ++) {
                            writeFloat(floats[i]);
                        }
                    }
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case ID_DOUBLE_ARRAY_CLASS: {
                    if (! unshared) {
                        instanceCache.put(obj, instanceSeq++);
                    }
                    final double[] doubles = (double[]) obj;
                    final int len = doubles.length;
                    if (len == 0) {
                        write(unshared ? ID_ARRAY_EMPTY_UNSHARED : ID_ARRAY_EMPTY);
                        write(ID_PRIM_DOUBLE);
                    } else if (len <= 256) {
                        write(unshared ? ID_ARRAY_SMALL_UNSHARED : ID_ARRAY_SMALL);
                        write(len);
                        write(ID_PRIM_DOUBLE);
                        for (int i = 0; i < len; i ++) {
                            writeDouble(doubles[i]);
                        }
                    } else if (len <= 65536) {
                        write(unshared ? ID_ARRAY_MEDIUM_UNSHARED : ID_ARRAY_MEDIUM);
                        writeShort(len);
                        write(ID_PRIM_DOUBLE);
                        for (int i = 0; i < len; i ++) {
                            writeDouble(doubles[i]);
                        }
                    } else {
                        write(unshared ? ID_ARRAY_LARGE_UNSHARED : ID_ARRAY_LARGE);
                        writeInt(len);
                        write(ID_PRIM_DOUBLE);
                        for (int i = 0; i < len; i ++) {
                            writeDouble(doubles[i]);
                        }
                    }
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case ID_CC_ARRAY_LIST:
                case ID_CC_LINKED_LIST:
                case ID_CC_VECTOR:
                case ID_CC_STACK:
                case ID_CC_ARRAY_DEQUE: {
                    instanceCache.put(obj, instanceSeq++);
                    final Collection<?> collection = (Collection<?>) obj;
                    final int len = collection.size();
                    if (len == 0) {
                        write(unshared ? ID_COLLECTION_EMPTY_UNSHARED : ID_COLLECTION_EMPTY);
                        write(id);
                    } else if (len <= 256) {
                        write(unshared ? ID_COLLECTION_SMALL_UNSHARED : ID_COLLECTION_SMALL);
                        write(len);
                        write(id);
                        for (Object o : collection) {
                            doWriteObject(o, false);
                        }
                    } else if (len <= 65536) {
                        write(unshared ? ID_COLLECTION_MEDIUM_UNSHARED : ID_COLLECTION_MEDIUM);
                        writeShort(len);
                        write(id);
                        for (Object o : collection) {
                            doWriteObject(o, false);
                        }
                    } else {
                        write(unshared ? ID_COLLECTION_LARGE_UNSHARED : ID_COLLECTION_LARGE);
                        writeInt(len);
                        write(id);
                        for (Object o : collection) {
                            doWriteObject(o, false);
                        }
                    }
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case ID_CC_ENUM_SET_PROXY: {
                    final Enum[] elements = getEnumSetElements(obj);
                    final int len = elements.length;
                    if (len == 0) {
                        write(unshared ? ID_COLLECTION_EMPTY_UNSHARED : ID_COLLECTION_EMPTY);
                        write(id);
                        writeClass(getEnumSetElementType(obj));
                        instanceCache.put(obj, instanceSeq++);
                    } else if (len <= 256) {
                        write(unshared ? ID_COLLECTION_SMALL_UNSHARED : ID_COLLECTION_SMALL);
                        write(len);
                        write(id);
                        writeClass(getEnumSetElementType(obj));
                        instanceCache.put(obj, instanceSeq++);
                        for (Object o : elements) {
                            doWriteObject(o, false);
                        }
                    } else if (len <= 65536) {
                        write(unshared ? ID_COLLECTION_MEDIUM_UNSHARED : ID_COLLECTION_MEDIUM);
                        writeShort(len);
                        write(id);
                        writeClass(getEnumSetElementType(obj));
                        instanceCache.put(obj, instanceSeq++);
                        for (Object o : elements) {
                            doWriteObject(o, false);
                        }
                    } else {
                        write(unshared ? ID_COLLECTION_LARGE_UNSHARED : ID_COLLECTION_LARGE);
                        writeInt(len);
                        write(id);
                        writeClass(getEnumSetElementType(obj));
                        instanceCache.put(obj, instanceSeq++);
                        for (Object o : elements) {
                            doWriteObject(o, false);
                        }
                    }
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case ID_CC_IDENTITY_HASH_MAP:
                case ID_CC_ENUM_MAP: {
                    instanceCache.put(obj, instanceSeq++);
                    final Map<?, ?> map = (Map<?, ?>) obj;
                    final int len = map.size();
                    if (len == 0) {
                        write(unshared ? ID_COLLECTION_EMPTY_UNSHARED : ID_COLLECTION_EMPTY);
                        write(id);
                        switch (id) {
                            case ID_CC_ENUM_MAP: writeClass(getEnumMapKeyType(obj)); break;
                        }
                    } else if (len <= 256) {
                        write(unshared ? ID_COLLECTION_SMALL_UNSHARED : ID_COLLECTION_SMALL);
                        write(len);
                        write(id);
                        switch (id) {
                            case ID_CC_ENUM_MAP: writeClass(getEnumMapKeyType(obj)); break;
                        }
                        for (Map.Entry<?, ?> entry : map.entrySet()) {
                            doWriteObject(entry.getKey(), false);
                            doWriteObject(entry.getValue(), false);
                        }
                    } else if (len <= 65536) {
                        write(unshared ? ID_COLLECTION_MEDIUM_UNSHARED : ID_COLLECTION_MEDIUM);
                        writeShort(len);
                        write(id);
                        switch (id) {
                            case ID_CC_ENUM_MAP: writeClass(getEnumMapKeyType(obj)); break;
                        }
                        for (Map.Entry<?, ?> entry : map.entrySet()) {
                            doWriteObject(entry.getKey(), false);
                            doWriteObject(entry.getValue(), false);
                        }
                    } else {
                        write(unshared ? ID_COLLECTION_LARGE_UNSHARED : ID_COLLECTION_LARGE);
                        writeInt(len);
                        write(id);
                        switch (id) {
                            case ID_CC_ENUM_MAP: writeClass(getEnumMapKeyType(obj)); break;
                        }
                        for (Map.Entry<?, ?> entry : map.entrySet()) {
                            doWriteObject(entry.getKey(), false);
                            doWriteObject(entry.getValue(), false);
                        }
                    }
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }

                case ID_EMPTY_MAP_OBJECT:
                case ID_EMPTY_SET_OBJECT:
                case ID_EMPTY_LIST_OBJECT:
                case ID_REVERSE_ORDER_OBJECT: {
                    write(id);
                    return;
                }
                case ID_SINGLETON_MAP_OBJECT: {
                    instanceCache.put(obj, instanceSeq++);
                    write(id);
                    final Map.Entry entry = (Map.Entry) ((Map) obj).entrySet().iterator().next();
                    doWriteObject(entry.getKey(), false);
                    doWriteObject(entry.getValue(), false);
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case ID_SINGLETON_LIST_OBJECT:
                case ID_SINGLETON_SET_OBJECT: {
                    instanceCache.put(obj, instanceSeq++);
                    write(id);
                    doWriteObject(((Collection)obj).iterator().next(), false);
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case ID_REVERSE_ORDER2_OBJECT: {
                    instanceCache.put(obj, instanceSeq++);
                    write(id);
                    try {
                        doWriteObject(Protocol.reverseOrder2Field.get(obj), false);
                    } catch (IllegalAccessException e) {
                        throw new InvalidObjectException("Cannot access standard field for reverse-order comparator");
                    }
                    return;
                }
                case ID_CC_COPY_ON_WRITE_ARRAY_LIST:
                case ID_CC_COPY_ON_WRITE_ARRAY_SET: {
                    info = registry.lookup(objClass);
                    break;
                }
                case ID_PAIR: {
                    instanceCache.put(obj, instanceSeq++);
                    write(id);
                    Pair<?, ?> pair = (Pair<?, ?>) obj;
                    doWriteObject(pair.getA(), unshared);
                    doWriteObject(pair.getB(), unshared);
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case ID_CC_NCOPIES: {
                    List<?> list = (List<?>) obj;
                    int size = list.size();
                    if (size == 0) {
                        write(ID_EMPTY_LIST_OBJECT);
                        return;
                    }
                    instanceCache.put(obj, instanceSeq++);
                    if (size <= 256) {
                        write(unshared ? ID_COLLECTION_SMALL_UNSHARED : ID_COLLECTION_SMALL);
                        write(size);
                    } else if (size <= 65536) {
                        write(unshared ? ID_COLLECTION_MEDIUM_UNSHARED : ID_COLLECTION_MEDIUM);
                        writeShort(size);
                    } else {
                        write(unshared ? ID_COLLECTION_LARGE_UNSHARED : ID_COLLECTION_LARGE);
                        writeInt(size);
                    }
                    write(id);
                    doWriteObject(list.iterator().next(), false);
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case ID_UNMODIFIABLE_COLLECTION:
                {
                    instanceCache.put(obj, instanceSeq++);
                    write(id);
                    try {
                        doWriteObject(unmodifiableCollectionField.get(obj), false);
                    } catch (IllegalAccessException e) {
                        throw new InvalidObjectException("Cannot access standard field for unmodifiable collections class");
                    }
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case ID_UNMODIFIABLE_SET:
                {
                    instanceCache.put(obj, instanceSeq++);
                    write(id);
                    try {
                        doWriteObject(unmodifiableSetField.get(obj), false);
                    } catch (IllegalAccessException e) {
                        throw new InvalidObjectException("Cannot access standard field for unmodifiable collections class");
                    }
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case ID_UNMODIFIABLE_LIST:
                {
                    instanceCache.put(obj, instanceSeq++);
                    write(id);
                    try {
                        doWriteObject((objClass == unmodifiableRandomAccessListClass ? unmodifiableRandomAccessListField : unmodifiableListField).get(obj), false);
                    } catch (IllegalAccessException e) {
                        throw new InvalidObjectException("Cannot access standard field for unmodifiable collections class");
                    }
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case ID_UNMODIFIABLE_MAP:
                {
                    instanceCache.put(obj, instanceSeq++);
                    write(id);
                    try {
                        doWriteObject(unmodifiableMapField.get(obj), false);
                    } catch (IllegalAccessException e) {
                        throw new InvalidObjectException("Cannot access standard field for unmodifiable collections class");
                    }
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case ID_UNMODIFIABLE_SORTED_MAP:
                {
                    instanceCache.put(obj, instanceSeq++);
                    write(id);
                    try {
                        doWriteObject(unmodifiableSortedMapField.get(obj), false);
                    } catch (IllegalAccessException e) {
                        throw new InvalidObjectException("Cannot access standard field for unmodifiable collections class");
                    }
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }

                case ID_UNMODIFIABLE_SORTED_SET:
                {
                    instanceCache.put(obj, instanceSeq++);
                    write(id);
                    try {
                        doWriteObject(unmodifiableSortedSetField.get(obj), false);
                    } catch (IllegalAccessException e) {
                        throw new InvalidObjectException("Cannot access standard field for unmodifiable collections class");
                    }
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case ID_UNMODIFIABLE_MAP_ENTRY_SET:
                {
                    instanceCache.put(obj, instanceSeq++);
                    write(id);
                    try {
                        doWriteObject(unmodifiableMapEntrySetField.get(obj), false);
                    } catch (IllegalAccessException e) {
                        throw new InvalidObjectException("Cannot access standard field for unmodifiable collections class");
                    }
                    if (unshared) {
                        instanceCache.put(obj, -1);
                    }
                    return;
                }
                case -1: break;
                default: throw new NotSerializableException(objClass.getName());
            }
            if (isArray) {
                final Object[] objects = (Object[]) obj;
                final int len = objects.length;
                if (len == 0) {
                    write(unshared ? ID_ARRAY_EMPTY_UNSHARED : ID_ARRAY_EMPTY);
                    writeClass(objClass.getComponentType());
                    instanceCache.put(obj, instanceSeq++);
                } else if (len <= 256) {
                    write(unshared ? ID_ARRAY_SMALL_UNSHARED : ID_ARRAY_SMALL);
                    write(len);
                    writeClass(objClass.getComponentType());
                    instanceCache.put(obj, instanceSeq++);
                    for (int i = 0; i < len; i++) {
                        doWriteObject(objects[i], unshared);
                    }
                } else if (len <= 65536) {
                    write(unshared ? ID_ARRAY_MEDIUM_UNSHARED : ID_ARRAY_MEDIUM);
                    writeShort(len);
                    writeClass(objClass.getComponentType());
                    instanceCache.put(obj, instanceSeq++);
                    for (int i = 0; i < len; i++) {
                        doWriteObject(objects[i], unshared);
                    }
                } else {
                    write(unshared ? ID_ARRAY_LARGE_UNSHARED : ID_ARRAY_LARGE);
                    writeInt(len);
                    writeClass(objClass.getComponentType());
                    instanceCache.put(obj, instanceSeq++);
                    for (int i = 0; i < len; i++) {
                        doWriteObject(objects[i], unshared);
                    }
                }
                if (unshared) {
                    instanceCache.put(obj, -1);
                }
                return;
            }
            // serialize proxies efficiently
            if (obj instanceof Proxy) {
                write(unshared ? ID_NEW_OBJECT_UNSHARED : ID_NEW_OBJECT);
                writeProxyClass(objClass);
                instanceCache.put(obj, instanceSeq++);
                doWriteObject(Proxy.getInvocationHandler(obj), false);
                if (unshared) {
                    instanceCache.put(obj, -1);
                }
                return;
            }
            // it's a user type
            // user type #1: externalizer
            Externalizer externalizer;
            if (externalizers.containsKey(objClass)) {
                externalizer = externalizers.get(objClass);
            } else {
                externalizer = classExternalizerFactory.getExternalizer(objClass);
                externalizers.put(objClass, externalizer);
            }
            if (externalizer != null) {
                write(unshared ? ID_NEW_OBJECT_UNSHARED : ID_NEW_OBJECT);
                writeExternalizerClass(objClass, externalizer);
View Full Code Here

        addExternalizer(new RemoveAllValuesOperation.Externalizer());
        addExternalizer(new RemoveAtIndexOperation.Externalizer());
        addExternalizer(new RetainAllValuesOperation.Externalizer());
        addExternalizer(new SetValueOperation.Externalizer());
        addExternalizer(new Paths.Externalizer());
        ClassExternalizerFactory externalizerFactory = new MappingClassExternalizerFactory(externalizersByClass);
        configuration.setClassExternalizerFactory(externalizerFactory);
    }
View Full Code Here

TOP

Related Classes of org.jboss.marshalling.ClassExternalizerFactory

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.