package mil.nga.giat.geowave.mapreduce; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.collections.IteratorUtils; import org.apache.commons.collections.Transformer; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.mapreduce.JobContext; import mil.nga.giat.geowave.core.index.ByteArrayId; import mil.nga.giat.geowave.core.store.CloseableIterator; import mil.nga.giat.geowave.core.store.CloseableIteratorWrapper; import mil.nga.giat.geowave.core.store.adapter.AdapterStore; import mil.nga.giat.geowave.core.store.adapter.DataAdapter; /** * This class implements an adapter store by first checking the job context for * an adapter and keeping a local cache of adapters that have been discovered. * It will check the metadata store if it cannot find an adapter in the job * context. */ public class JobContextAdapterStore implements AdapterStore { private static final Class<?> CLASS = JobContextAdapterStore.class; private final JobContext context; private final AdapterStore persistentAdapterStore; private final Map<ByteArrayId, DataAdapter<?>> adapterCache = new HashMap<ByteArrayId, DataAdapter<?>>(); public JobContextAdapterStore( final JobContext context, final AdapterStore persistentAdapterStore ) { this.context = context; this.persistentAdapterStore = persistentAdapterStore; } @Override public void addAdapter( final DataAdapter<?> adapter ) { adapterCache.put( adapter.getAdapterId(), adapter); } @Override public DataAdapter<?> getAdapter( final ByteArrayId adapterId ) { DataAdapter<?> adapter = adapterCache.get(adapterId); if (adapter == null) { adapter = getAdapterInternal(adapterId); } return adapter; } @Override public boolean adapterExists( final ByteArrayId adapterId ) { if (adapterCache.containsKey(adapterId)) { return true; } final DataAdapter<?> adapter = getAdapterInternal(adapterId); return adapter != null; } private DataAdapter<?> getAdapterInternal( final ByteArrayId adapterId ) { // first try to get it from the job context DataAdapter<?> adapter = getDataAdapter( context, adapterId); if (adapter == null) { // then try to get it from the persistent store adapter = persistentAdapterStore.getAdapter(adapterId); } if (adapter != null) { adapterCache.put( adapterId, adapter); } return adapter; } @Override public void removeAll() { adapterCache.clear(); } @Override public CloseableIterator<DataAdapter<?>> getAdapters() { final CloseableIterator<DataAdapter<?>> it = persistentAdapterStore.getAdapters(); // cache any results return new CloseableIteratorWrapper<DataAdapter<?>>( it, IteratorUtils.transformedIterator( it, new Transformer() { @Override public Object transform( final Object obj ) { if (obj instanceof DataAdapter) { adapterCache.put( ((DataAdapter) obj).getAdapterId(), (DataAdapter) obj); } return obj; } })); } public List<ByteArrayId> getAdapterIds() { final DataAdapter<?>[] userAdapters = GeoWaveConfiguratorBase.getDataAdapters( CLASS, context); if ((userAdapters == null) || (userAdapters.length <= 0)) { return IteratorUtils.toList(IteratorUtils.transformedIterator( getAdapters(), new Transformer() { @Override public Object transform( final Object input ) { if (input instanceof DataAdapter) { return ((DataAdapter) input).getAdapterId(); } return input; } })); } else { final List<ByteArrayId> retVal = new ArrayList<ByteArrayId>( userAdapters.length); for (final DataAdapter<?> adapter : userAdapters) { retVal.add(adapter.getAdapterId()); } return retVal; } } protected static DataAdapter<?> getDataAdapter( final JobContext context, final ByteArrayId adapterId ) { return GeoWaveConfiguratorBase.getDataAdapter( CLASS, context, adapterId); } public static DataAdapter<?>[] getDataAdapters( final JobContext context ) { return GeoWaveConfiguratorBase.getDataAdapters( CLASS, context); } public static void addDataAdapter( final Configuration configuration, final DataAdapter<?> adapter ) { GeoWaveConfiguratorBase.addDataAdapter( CLASS, configuration, adapter); } }