Abstracted record construction

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@754828 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Josh Micich 2009-03-16 07:03:13 +00:00
parent 032d57431f
commit 4f4ad37765

View File

@ -46,6 +46,37 @@ import org.apache.poi.hssf.record.pivottable.*;
public final class RecordFactory { public final class RecordFactory {
private static final int NUM_RECORDS = 512; private static final int NUM_RECORDS = 512;
private interface I_RecordCreator {
Record create(RecordInputStream in);
String getRecordClassName();
}
private static final class ReflectionRecordCreator implements I_RecordCreator {
private final Constructor<? extends Record> _c;
public ReflectionRecordCreator(Constructor<? extends Record> c) {
_c = c;
}
public Record create(RecordInputStream in) {
Object[] args = { in, };
try {
return _c.newInstance(args);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RecordFormatException("Unable to construct record instance" , e.getTargetException());
}
}
public String getRecordClassName() {
return _c.getDeclaringClass().getName();
}
}
private static final Class<?>[] CONSTRUCTOR_ARGS = { RecordInputStream.class, }; private static final Class<?>[] CONSTRUCTOR_ARGS = { RecordInputStream.class, };
/** /**
@ -189,7 +220,7 @@ public final class RecordFactory {
/** /**
* cache of the recordsToMap(); * cache of the recordsToMap();
*/ */
private static Map<Short, Constructor<? extends Record>> recordsMap = recordsToMap(recordClasses); private static Map<Short, I_RecordCreator> recordsMap = recordsToMap(recordClasses);
private static short[] _allKnownRecordSIDs; private static short[] _allKnownRecordSIDs;
@ -213,24 +244,14 @@ public final class RecordFactory {
return new Record[] { record, }; return new Record[] { record, };
} }
private static Record createSingleRecord(RecordInputStream in) { static Record createSingleRecord(RecordInputStream in) {
Constructor<? extends Record> constructor = recordsMap.get(new Short(in.getSid())); I_RecordCreator constructor = recordsMap.get(new Short(in.getSid()));
if (constructor == null) { if (constructor == null) {
return new UnknownRecord(in); return new UnknownRecord(in);
} }
try { return constructor.create(in);
return constructor.newInstance(new Object[] { in });
} catch (InvocationTargetException e) {
throw new RecordFormatException("Unable to construct record instance" , e.getTargetException());
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
} }
/** /**
@ -290,8 +311,8 @@ public final class RecordFactory {
* @return map of SIDs to short,short,byte[] constructors for Record classes * @return map of SIDs to short,short,byte[] constructors for Record classes
* most of org.apache.poi.hssf.record.* * most of org.apache.poi.hssf.record.*
*/ */
private static Map<Short, Constructor<? extends Record>> recordsToMap(Class<? extends Record> [] records) { private static Map<Short, I_RecordCreator> recordsToMap(Class<? extends Record> [] records) {
Map<Short, Constructor<? extends Record>> result = new HashMap<Short, Constructor<? extends Record>>(); Map<Short, I_RecordCreator> result = new HashMap<Short, I_RecordCreator>();
Set<Class<?>> uniqueRecClasses = new HashSet<Class<?>>(records.length * 3 / 2); Set<Class<?>> uniqueRecClasses = new HashSet<Class<?>>(records.length * 3 / 2);
for (int i = 0; i < records.length; i++) { for (int i = 0; i < records.length; i++) {
@ -318,11 +339,11 @@ public final class RecordFactory {
} }
Short key = new Short(sid); Short key = new Short(sid);
if (result.containsKey(key)) { if (result.containsKey(key)) {
Class<? extends Record> prev = result.get(key).getDeclaringClass(); String prevClassName = result.get(key).getRecordClassName();
throw new RuntimeException("duplicate record sid 0x" + Integer.toHexString(sid).toUpperCase() throw new RuntimeException("duplicate record sid 0x" + Integer.toHexString(sid).toUpperCase()
+ " for classes (" + recClass.getName() + ") and (" + prev.getName() + ")"); + " for classes (" + recClass.getName() + ") and (" + prevClassName + ")");
} }
result.put(key, constructor); result.put(key, new ReflectionRecordCreator(constructor));
} }
return result; return result;
} }