@Override protected void onInitialize( ClientServiceManager serviceManager ) { // Make sure our message type is registered if it isn't already if( Serializer.getExactSerializerRegistration(SerializerRegistrationsMessage.class) == null ) { // This is the minimum we'd need just to be able to register // the rest... otherwise we can't even receive this message. Serializer.registerClass(SerializerRegistrationsMessage.class); Serializer.registerClass(SerializerRegistrationsMessage.Registration.class); } else { log.log(Level.INFO, "Skipping registration of SerializerRegistrationsMessage."); } // Add our listener for that message type serviceManager.getClient().addMessageListener(this, SerializerRegistrationsMessage.class); }
Serializer.writeClass(buffer, elementClass); Serializer serializer = Serializer.getSerializer(elementClass); serializer.writeObject(buffer, elem); Serializer.writeClassAndObject(buffer, elem);
@SuppressWarnings("unchecked") public <T> T readObject(ByteBuffer data, Class<T> c) throws IOException { int length = data.getInt(); Collection collection; try { collection = (Collection)c.newInstance(); } catch (Exception e) { log.log(Level.FINE, "[Serializer][???] Could not determine collection type. Using ArrayList."); collection = new ArrayList(length); } if (length == 0) return (T)collection; if (data.get() == (byte)1) { SerializerRegistration reg = Serializer.readClass(data); Class clazz = reg.getType(); Serializer serializer = reg.getSerializer(); for (int i = 0; i != length; ++i) { collection.add(serializer.readObject(data, clazz)); } } else { for (int i = 0; i != length; ++i) { collection.add(Serializer.readClassAndObject(data)); } } return (T)collection; }
public static SerializerRegistration registerClass(Class cls, Serializer serializer) { SerializerRegistration existingReg = getExactSerializerRegistration(cls); short id; if (existingReg != null) { id = existingReg.getId(); } else { id = nextId(); } return registerClassForId( id, cls, serializer ); }
private void writeArray(Serializer elementSerializer, ByteBuffer buffer, Object array, int dimension, int dimensionCount) throws IOException { int length = Array.getLength(array); if (dimension > 0) { buffer.putInt(length); } // Write array data. boolean elementsAreArrays = dimension < dimensionCount - 1; for (int i = 0; i < length; i++) { Object element = Array.get(array, i); if (elementsAreArrays) { if (element != null) writeArray(elementSerializer, buffer, element, dimension + 1, dimensionCount); } else if (elementSerializer != null) { elementSerializer.writeObject(buffer, element); } else { // Each element could be a different type. Store the class with the object. Serializer.writeClassAndObject(buffer, element); } } }
private void readArray (Serializer elementSerializer, Class elementClass, ByteBuffer buffer, Object array, int dimension, int[] dimensions) throws IOException { boolean elementsAreArrays = dimension < dimensions.length - 1; int length; if (dimension == 0) { length = dimensions[0]; } else { length = buffer.getInt(); } for (int i = 0; i < length; i++) { if (elementsAreArrays) { // Nested array. Object element = Array.get(array, i); if (element != null) readArray(elementSerializer, elementClass, buffer, element, dimension + 1, dimensions); } else if (elementSerializer != null) { // Use same converter (and class) for all elements. Array.set(array, i, elementSerializer.readObject(buffer, elementClass)); } else { // Each element could be a different type. Look up the class with the object. Array.set(array, i, Serializer.readClassAndObject(buffer)); } } } }
public static void registerClasses(Class... classes) { for( Class c : classes ) { registerClass(c); } }
/** * @deprecated This cannot be implemented in a reasonable way that works in * all deployment methods. */ @Deprecated public static SerializerRegistration[] registerPackage(String pkgName) { try { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); String path = pkgName.replace('.', '/'); Enumeration<URL> resources = classLoader.getResources(path); List<File> dirs = new ArrayList<File>(); while (resources.hasMoreElements()) { URL resource = resources.nextElement(); dirs.add(new File(resource.getFile())); } ArrayList<Class> classes = new ArrayList<Class>(); for (File directory : dirs) { classes.addAll(findClasses(directory, pkgName)); } SerializerRegistration[] registeredClasses = new SerializerRegistration[classes.size()]; for (int i = 0; i != classes.size(); ++i) { Class clz = classes.get(i); registeredClasses[i] = registerClass(clz, false); } return registeredClasses; } catch (Exception e) { e.printStackTrace(); } return new SerializerRegistration[0]; }
/** * Registers the specified class. The failOnMiss flag controls whether or * not this method returns null for failed registration or throws an exception. */ @SuppressWarnings("unchecked") public static SerializerRegistration registerClass(Class cls, boolean failOnMiss) { if (cls.isAnnotationPresent(Serializable.class)) { Serializable serializable = (Serializable)cls.getAnnotation(Serializable.class); Class serializerClass = serializable.serializer(); short classId = serializable.id(); if (classId == 0) classId = nextId(); Serializer serializer = getSerializer(serializerClass, false); if (serializer == null) serializer = fieldSerializer; SerializerRegistration existingReg = getExactSerializerRegistration(cls); if (existingReg != null) classId = existingReg.getId(); SerializerRegistration reg = new SerializerRegistration(serializer, cls, classId); return registerClassForId( classId, cls, serializer ); } if (failOnMiss) { throw new IllegalArgumentException( "Class is not marked @Serializable:" + cls ); } return null; }
public static Serializer getSerializer(Class cls) { return getSerializer(cls, true); }
/** * Read the class and the object. * * @param buffer Buffer to read from. * @return The Object that was read. * @throws IOException If serialization failed. */ @SuppressWarnings("unchecked") public static Object readClassAndObject(ByteBuffer buffer) throws IOException { SerializerRegistration reg = readClass(buffer); if (reg == NULL_CLASS) return null; if (reg == null) throw new SerializerException( "Class not found for buffer data." ); return reg.getSerializer().readObject(buffer, reg.getType()); }
/** * Write the class and object. * * @param buffer The buffer to write to. * @param object The object to write. * @throws IOException If serializing fails. */ public static void writeClassAndObject(ByteBuffer buffer, Object object) throws IOException { if (object == null) { buffer.putShort((short)-1); return; } SerializerRegistration reg = writeClass(buffer, object.getClass()); // If the caller (or us) has registered a generic base class (like Enum) // that is meant to steer automatic resolution for things like FieldSerializer // that have final classes in fields... then there are cases where the exact // type isn't known by the outer class. (Think of a message object // that has an Object field but tries to send an Enum subclass in it.) // In that case, the SerializerRegistration object we get back isn't // really going to be capable of recreating the object on the other // end because it won't know what class to use. This only comes up // in writeclassAndObejct() because we just wrote an ID to a more generic // class than will be readable on the other end. The check is simple, though. if( reg.getType() != object.getClass() ) { throw new IllegalArgumentException("Class has not been registered:" + object.getClass() + " but resolved to generic serializer for:" + reg.getType()); } reg.getSerializer().writeObject(buffer, object); }
private void writeMethodReturn(ByteBuffer buffer, RemoteMethodReturnMessage ret) throws IOException{ buffer.putShort(ret.invocationID); if (ret.retVal != null){ buffer.put((byte)0x01); Serializer.writeClassAndObject(buffer, ret.retVal); }else{ buffer.put((byte)0x00); } }
/** * Creates a message from the properly sized byte buffer * and adds it to the messages queue. */ protected void createMessage( ByteBuffer buffer ) { try { Object obj = Serializer.readClassAndObject( buffer ); Message m = (Message)obj; messages.add(m); } catch( IOException e ) { throw new RuntimeException( "Error deserializing object, class ID:" + buffer.getShort(0), e ); } } }
registerClassForId( DisconnectMessage.SERIALIZER_ID, DisconnectMessage.class, new DisconnectMessage.DisconnectSerializer() ); registerClassForId( ClientRegistrationMessage.SERIALIZER_ID, ClientRegistrationMessage.class, new ClientRegistrationMessage.ClientRegistrationSerializer() ); registerClass(boolean.class, new BooleanSerializer()); registerClass(byte.class, new ByteSerializer()); registerClass(char.class, new CharSerializer()); registerClass(short.class, new ShortSerializer()); registerClass(int.class, new IntSerializer()); registerClass(long.class, new LongSerializer()); registerClass(float.class, new FloatSerializer()); registerClass(double.class, new DoubleSerializer()); registerClass(Boolean.class, new BooleanSerializer()); registerClass(Byte.class, new ByteSerializer()); registerClass(Character.class, new CharSerializer()); registerClass(Short.class, new ShortSerializer()); registerClass(Integer.class, new IntSerializer()); registerClass(Long.class, new LongSerializer()); registerClass(Float.class, new FloatSerializer()); registerClass(Double.class, new DoubleSerializer()); registerClass(String.class, new StringSerializer()); registerClass(Vector3f.class, new Vector3Serializer()); registerClass(Date.class, new DateSerializer()); registerClass(AbstractCollection.class, new CollectionSerializer());
public static SerializerRegistration getSerializerRegistration(Class cls) { return getSerializerRegistration(cls, strictRegistration); }
/** * Registers the specified class. The failOnMiss flag controls whether or * not this method returns null for failed registration or throws an exception. */ @SuppressWarnings("unchecked") public static SerializerRegistration registerClass(Class cls, boolean failOnMiss) { if (cls.isAnnotationPresent(Serializable.class)) { Serializable serializable = (Serializable)cls.getAnnotation(Serializable.class); Class serializerClass = serializable.serializer(); short classId = serializable.id(); if (classId == 0) classId = --nextId; Serializer serializer = getSerializer(serializerClass, false); if (serializer == null) serializer = fieldSerializer; SerializerRegistration existingReg = getExactSerializerRegistration(cls); if (existingReg != null) classId = existingReg.getId(); SerializerRegistration reg = new SerializerRegistration(serializer, cls, classId); idRegistrations.put(classId, reg); classRegistrations.put(cls, reg); serializer.initialize(cls); log.log( Level.INFO, "Registered class[" + classId + "]:{0}.", cls ); return reg; } if (failOnMiss) { throw new IllegalArgumentException( "Class is not marked @Serializable:" + cls ); } return null; }
public static SerializerRegistration registerClass(Class cls, Serializer serializer) { SerializerRegistration existingReg = getExactSerializerRegistration(cls); short id; if (existingReg != null) { id = existingReg.getId(); } else { id = --nextId; } SerializerRegistration reg = new SerializerRegistration(serializer, cls, id); idRegistrations.put(id, reg); classRegistrations.put(cls, reg); log.log( Level.INFO, "Registered class[" + id + "]:{0} to:" + serializer, cls ); serializer.initialize(cls); return reg; }
private static List<Class> findClasses(File dir, String pkgName) throws ClassNotFoundException { List<Class> classes = new ArrayList<Class>(); if (!dir.exists()) { return classes; } File[] files = dir.listFiles(); for (File file : files) { if (file.isDirectory()) { assert !file.getName().contains("."); classes.addAll(findClasses(file, pkgName + "." + file.getName())); } else if (file.getName().endsWith(".class")) { classes.add(Class.forName(pkgName + '.' + file.getName().substring(0, file.getName().length() - 6))); } } return classes; }
public static boolean isSerializable( Throwable error ) { if( error == null ) { return false; } for( Throwable t = error; t != null; t = t.getCause() ) { if( Serializer.getExactSerializerRegistration(t.getClass()) == null ) { return false; } } return true; }