// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.core.store; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * Provides functionality common to all object reader implementations. * * @author Brett Henderson */ public abstract class BaseObjectReader implements ObjectReader { private StoreReader storeReader; private StoreClassRegister storeClassRegister; private StoreableConstructorCache constructorCache; /** * Creates a new instance. * * @param storeReader * The store writer to read all serialised data from. * @param storeClassRegister * The register for class to identifier mappings. */ public BaseObjectReader(StoreReader storeReader, StoreClassRegister storeClassRegister) { this.storeReader = storeReader; this.storeClassRegister = storeClassRegister; constructorCache = new StoreableConstructorCache(); } /** * Identifies the class using data from the underlying stream. * * @param sr * The store reader to read all serialised data from. * @param scr * The register for class to identifier mappings. * @return The next class type in the data stream. */ protected abstract Class<?> readClassFromIdentifier(StoreReader sr, StoreClassRegister scr); /** * Reads an object from storage using identifiers embedded in the stream to * determine the correct class type to instantiate. * * @return The re-instantiated object. */ public Storeable readObject() { Class<?> clazz; Constructor<?> constructor; clazz = readClassFromIdentifier(storeReader, storeClassRegister); constructor = constructorCache.getStoreableConstructor(clazz); try { return (Storeable) constructor.newInstance(new Object[] {storeReader, storeClassRegister}); } catch (IllegalAccessException e) { throw new OsmosisRuntimeException( "The class " + constructor.getDeclaringClass().getName() + " could not be instantiated.", e); } catch (InvocationTargetException e) { Throwable cause = e.getCause(); if (cause instanceof EndOfStoreException) { throw (EndOfStoreException) cause; } throw new OsmosisRuntimeException( "The class " + constructor.getDeclaringClass().getName() + " could not be instantiated.", e); } catch (InstantiationException e) { throw new OsmosisRuntimeException( "The class " + constructor.getDeclaringClass().getName() + " could not be instantiated.", e); } } }