/* * @(#) CompositeRowProcessor.java * Created May 25, 2012 by oleg * (C) ONE, SIA */ package org.apache.cassandra.db.proc; import java.util.ArrayList; import java.util.List; import java.util.Properties; import org.apache.cassandra.db.ColumnFamily; import org.apache.cassandra.db.ColumnFamilyStore; import org.apache.cassandra.db.DecoratedKey; import org.apache.cassandra.utils.Pair; /** * If several row processors are configured for a column family store, this class ensures all processors will be called * one by one. * * @author Oleg Anastasyev<oa@hq.one.lv> * */ public class RowProcessorChain implements IRowProcessor { private final ArrayList<IRowProcessor> processors = new ArrayList<IRowProcessor>(); boolean procUnchanged, procIncomplete, procEmpty; public RowProcessorChain add(IRowProcessor p) { processors.add(p); procUnchanged|=p.shouldProcessUnchanged(); procIncomplete|=p.shouldProcessIncomplete(); procEmpty|=p.shouldProcessEmpty(); return this; } public RowProcessorChain add(Pair<Class<? extends IRowProcessor>, Properties> processorDef) { try { IRowProcessor rp = processorDef.left.newInstance(); rp.setConfiguration(processorDef.right); add(rp); } catch (Exception e) { throw new RuntimeException("Cannot init row processor "+processorDef.left.getName(),e); } return this; } public RowProcessorChain addAll(List<Pair<Class<? extends IRowProcessor>,Properties>> defs) { if (defs==null) return this; for (Pair<Class<? extends IRowProcessor>, Properties> pair : defs) { add(pair); } return this; } public IRowProcessor build() { if (processors.size()==1) return processors.get(0); return this; } /* (non-Javadoc) * @see org.apache.cassandra.db.proc.IRowProcessor#shouldProcessIncomplete() */ @Override public boolean shouldProcessIncomplete() { return procIncomplete; } /* (non-Javadoc) * @see org.apache.cassandra.db.proc.IRowProcessor#shouldProcessUnchanged() */ @Override public boolean shouldProcessUnchanged() { return procUnchanged; } /* (non-Javadoc) * @see org.apache.cassandra.db.proc.IRowProcessor.shouldProcessEmpty() */ @Override public boolean shouldProcessEmpty() { return procEmpty; } /* (non-Javadoc) * @see org.apache.cassandra.db.proc.IRowProcessor#setColumnFamilyStore(org.apache.cassandra.db.ColumnFamilyStore) */ @Override public void setColumnFamilyStore(ColumnFamilyStore cfs) { for (int i=0;i<processors.size();i++) { processors.get(i).setColumnFamilyStore(cfs); } } /* (non-Javadoc) * @see org.apache.cassandra.db.proc.IRowProcessor#process(org.apache.cassandra.db.DecoratedKey, org.apache.cassandra.db.ColumnFamily, boolean) */ @Override public ColumnFamily process(DecoratedKey key, ColumnFamily columns, boolean incomplete) { for (int i=0;i<processors.size();i++) { boolean empty = (columns == null || columns.getColumnsMap().isEmpty()); // Do not continue to process the chain if column family became empty if (empty && !this.procEmpty) break; IRowProcessor p = processors.get(i); boolean procIncomplete = p.shouldProcessIncomplete(); boolean procEmpty = p.shouldProcessEmpty(); if ((!incomplete || procIncomplete) && (!empty || procEmpty)) columns=p.process(key,columns,incomplete); } return columns; } /* (non-Javadoc) * @see org.apache.cassandra.db.proc.IRowProcessor#setConfiguration(java.util.Properties) */ @Override public void setConfiguration(Properties config) { } }