I'm facing the issue of how to reconstruct data across a network in Java. As part of my Component based game engine (read about it here, I have to encode components as XML on the server, send it to the client, and then reconstruct the appropriate component with all the data included in the XML. For example:
package.TextureComponent
id 1 /id
width 100 /width
height 100 /height
/package.TextureComponent
Right now, I use reflection on the client to construct a new TextureComponent (but this will work for any component with primitive data types) using the complete name of the class. I then sequentially read all the String parameters from the XML into the component using reflection in this BasicDecoder:
public class BasicDecoder implements DataDecoder {
@Override
public void decode(DataComponent component, String[] data) {
Class<? extends DataComponent> compClass = component.getClass();
// fills in all public fields with data in order
Field[] fields = compClass.getFields();
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
Class fieldType = field.getType();
String typeName = fieldType.getName().toUpperCase().replace(".", "");
FieldType type;
try {
type = FieldType.valueOf(typeName);
} catch (Exception ex) {
throw new RuntimeException("BasicDecoder cannot handle field: " + typeName);
}
try {
switch (type) {
case INT:
field.setInt(component, Integer.parseInt(data[i]));
break;
case DOUBLE:
field.setDouble(component, Double.parseDouble(data[i]));
break;
case BYTE:
field.setByte(component, Byte.parseByte(data[i]));
break;
case SHORT:
field.setShort(component, Short.parseShort(data[i]));
break;
case LONG:
field.setLong(component, Long.parseLong(data[i]));
break;
case FLOAT:
field.setFloat(component, Float.parseFloat(data[i]));
break;
case BOOLEAN:
field.setBoolean(component, Boolean.parseBoolean(data[i]));
break;
case CHAR:
field.setChar(component, data[i].charAt(0));
break;
case JAVALANGSTRING:
field.set(component, data[i]);
break;
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
private enum FieldType {
INT, DOUBLE, BYTE, SHORT, LONG, FLOAT, BOOLEAN, CHAR, JAVALANGSTRING
}
}
Is there any way I can improve this code? Is reflection the wrong way to go? I shied away from having each Component define its own decoder because I felt that it would result in a lot of classes which look more or less similar.