Let's actually use them fancy little methods.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4695 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -22,9 +22,13 @@
|
|||||||
package com.threerings.io;
|
package com.threerings.io;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import static com.threerings.NaryaLog.log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to read and write a single field of a {@link Streamable} instance.
|
* Used to read and write a single field of a {@link Streamable} instance.
|
||||||
*/
|
*/
|
||||||
@@ -53,6 +57,25 @@ public abstract class FieldMarshaller
|
|||||||
createMarshallers();
|
createMarshallers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// first look to see if this field has custom reader/writer methods
|
||||||
|
Method reader = null, writer = null;
|
||||||
|
try {
|
||||||
|
reader = field.getDeclaringClass().getMethod(
|
||||||
|
getReaderMethodName(field.getName()), READER_ARGS);
|
||||||
|
writer = field.getDeclaringClass().getMethod(
|
||||||
|
getWriterMethodName(field.getName()), WRITER_ARGS);
|
||||||
|
return new MethodFieldMarshaller(reader, writer);
|
||||||
|
} catch (NoSuchMethodException nsme) {
|
||||||
|
// no problem
|
||||||
|
}
|
||||||
|
if ((reader != null || writer != null) && (reader == null || writer == null)) {
|
||||||
|
log.warning("Class contains one but not both custom field reader and writer " +
|
||||||
|
"[class=" + field.getDeclaringClass().getName() +
|
||||||
|
", field=" + field.getName() + ", reader=" + reader +
|
||||||
|
", writer=" + writer + "].");
|
||||||
|
// fall through to using reflection on the fields...
|
||||||
|
}
|
||||||
|
|
||||||
Class ftype = field.getType();
|
Class ftype = field.getType();
|
||||||
if (ftype.isInterface()) {
|
if (ftype.isInterface()) {
|
||||||
// if the class is a pure interface, use Object.
|
// if the class is a pure interface, use Object.
|
||||||
@@ -70,6 +93,24 @@ public abstract class FieldMarshaller
|
|||||||
return fm;
|
return fm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the custom reader method which will be used if it exists to stream a
|
||||||
|
* field with the supplied name.
|
||||||
|
*/
|
||||||
|
public static final String getReaderMethodName (String field)
|
||||||
|
{
|
||||||
|
return "readField_" + field;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the custom writer method which will be used if it exists to stream a
|
||||||
|
* field with the supplied name.
|
||||||
|
*/
|
||||||
|
public static final String getWriterMethodName (String field)
|
||||||
|
{
|
||||||
|
return "writeField_" + field;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to marshall and unmarshall classes for which we have a basic {@link Streamer}.
|
* Used to marshall and unmarshall classes for which we have a basic {@link Streamer}.
|
||||||
*/
|
*/
|
||||||
@@ -110,6 +151,34 @@ public abstract class FieldMarshaller
|
|||||||
protected Streamer _streamer;
|
protected Streamer _streamer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses custom reader and writer methods to read and write a field.
|
||||||
|
*/
|
||||||
|
protected static class MethodFieldMarshaller extends FieldMarshaller
|
||||||
|
{
|
||||||
|
public MethodFieldMarshaller (Method reader, Method writer)
|
||||||
|
{
|
||||||
|
_reader = reader;
|
||||||
|
_writer = writer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// documentation inherited
|
||||||
|
public void readField (Field field, Object target, ObjectInputStream in)
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
_reader.invoke(target, in);
|
||||||
|
}
|
||||||
|
|
||||||
|
// documentation inherited
|
||||||
|
public void writeField (Field field, Object source, ObjectOutputStream out)
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
_writer.invoke(source, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Method _reader, _writer;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates instances of all known field marshaller types and populates the {@link
|
* Creates instances of all known field marshaller types and populates the {@link
|
||||||
* #_marshallers} table with them. This is called the first time a marshaller is requested.
|
* #_marshallers} table with them. This is called the first time a marshaller is requested.
|
||||||
@@ -240,4 +309,10 @@ public abstract class FieldMarshaller
|
|||||||
|
|
||||||
/** Contains a mapping from field type to field marshaller instance for that type. */
|
/** Contains a mapping from field type to field marshaller instance for that type. */
|
||||||
protected static HashMap<Class,FieldMarshaller> _marshallers;
|
protected static HashMap<Class,FieldMarshaller> _marshallers;
|
||||||
|
|
||||||
|
/** Defines the signature to a custom field reader method. */
|
||||||
|
protected static final Class[] READER_ARGS = { ObjectInputStream.class };
|
||||||
|
|
||||||
|
/** Defines the signature to a custom field writer method. */
|
||||||
|
protected static final Class[] WRITER_ARGS = { ObjectOutputStream.class };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ import org.apache.tools.ant.types.FileSet;
|
|||||||
import org.apache.tools.ant.types.Path;
|
import org.apache.tools.ant.types.Path;
|
||||||
|
|
||||||
import com.samskivert.io.StreamUtil;
|
import com.samskivert.io.StreamUtil;
|
||||||
|
import com.threerings.io.FieldMarshaller;
|
||||||
import com.threerings.io.Streamable;
|
import com.threerings.io.Streamable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -154,8 +155,6 @@ public class InstrumentStreamableTask extends Task
|
|||||||
protected void processStreamable (File source, CtClass clazz)
|
protected void processStreamable (File source, CtClass clazz)
|
||||||
throws NotFoundException
|
throws NotFoundException
|
||||||
{
|
{
|
||||||
// System.err.println("Processing " + clazz.getName() + "...");
|
|
||||||
|
|
||||||
ArrayList<CtField> fields = new ArrayList<CtField>();
|
ArrayList<CtField> fields = new ArrayList<CtField>();
|
||||||
for (CtField field : clazz.getDeclaredFields()) {
|
for (CtField field : clazz.getDeclaredFields()) {
|
||||||
int modifiers = field.getModifiers();
|
int modifiers = field.getModifiers();
|
||||||
@@ -173,13 +172,13 @@ public class InstrumentStreamableTask extends Task
|
|||||||
|
|
||||||
int added = 0;
|
int added = 0;
|
||||||
for (CtField field : fields) {
|
for (CtField field : fields) {
|
||||||
String rname = "readField_" + field.getName();
|
String rname = FieldMarshaller.getReaderMethodName(field.getName());
|
||||||
if (!methods.contains(rname)) {
|
if (!methods.contains(rname)) {
|
||||||
String reader =
|
String reader =
|
||||||
"public void " + rname + " (com.threerings.io.ObjectInputStream ins) {\n" +
|
"public void " + rname + " (com.threerings.io.ObjectInputStream ins) {\n" +
|
||||||
" " + field.getName() + " = " + getFieldReader(field) + ";\n" +
|
" " + field.getName() + " = " + getFieldReader(field) + ";\n" +
|
||||||
"}";
|
"}";
|
||||||
// System.err.println("Adding reader " + clazz.getName() + "." + rname);
|
// System.out.println("Adding reader " + clazz.getName() + "." + rname);
|
||||||
try {
|
try {
|
||||||
clazz.addMethod(CtNewMethod.make(reader, clazz));
|
clazz.addMethod(CtNewMethod.make(reader, clazz));
|
||||||
added++;
|
added++;
|
||||||
@@ -189,9 +188,10 @@ public class InstrumentStreamableTask extends Task
|
|||||||
System.err.println(reader);
|
System.err.println(reader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String wname = "writeField_" + field.getName();
|
|
||||||
|
String wname = FieldMarshaller.getWriterMethodName(field.getName());
|
||||||
if (!methods.contains(wname)) {
|
if (!methods.contains(wname)) {
|
||||||
// System.err.println("Adding writer " + clazz.getName() + "." + wname);
|
// System.out.println("Adding writer " + clazz.getName() + "." + wname);
|
||||||
String writer =
|
String writer =
|
||||||
"public void " + wname + " (com.threerings.io.ObjectOutputStream out) {\n" +
|
"public void " + wname + " (com.threerings.io.ObjectOutputStream out) {\n" +
|
||||||
" out." + getFieldWriter(field) + ";\n" +
|
" out." + getFieldWriter(field) + ";\n" +
|
||||||
@@ -209,6 +209,7 @@ public class InstrumentStreamableTask extends Task
|
|||||||
|
|
||||||
if (added > 0) {
|
if (added > 0) {
|
||||||
try {
|
try {
|
||||||
|
System.out.println("Instrumented '" + clazz.getName() + "'.");
|
||||||
clazz.writeFile(_outdir.getPath());
|
clazz.writeFile(_outdir.getPath());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.err.println("Failed to write instrumented class [class=" + clazz +
|
System.err.println("Failed to write instrumented class [class=" + clazz +
|
||||||
|
|||||||
Reference in New Issue
Block a user