package com.onaro.sanscreen.client.view.common.functions; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.eclipse.core.runtime.IAdaptable; import com.onaro.client.leekui.runtime.OnaroAdapterUtils; import com.onaro.commons.lang.OnaroThreadUtils; import com.onaro.sanscreen.server.interfaces.ServerInterfacesUtils; import com.onaro.sanscreen.server.interfaces.data.Context; /** * BulkFunction implementation that handles input objects with different {@link Context}s. The implementation will classify * the input objects based on their Context, and pass the sets with the same Context on to its subclass for evaluation. * To work properly, the input objects must be a subclass of {@link IAdaptable), and support being adapted to Context. * * @param IAdaptable row type this Function is able to operate on. Should allow adapting to Context. * @param data type returned by this Function * * @see IAdaptable * @see Context */ public abstract class AbstractContextAwareBulkFunction extends AbstractRefreshableBulkFunction { static final Logger logger = LogManager.getLogger(AbstractContextAwareBulkFunction.class); public AbstractContextAwareBulkFunction() { super(); } public AbstractContextAwareBulkFunction(boolean isMainView) { super(isMainView); } public void evaluate(Collection inputs, Map outputMap) throws InterruptedException, InvocationTargetException { if (inputs == null || inputs.isEmpty()) { return; } if (isMainView) { // If the function is being evaluated in a main view, assume all items have the same load context I first = inputs.iterator().next(); Context context = OnaroAdapterUtils.getAdapter(first, Context.class); process(context, inputs, outputMap); } else { Map> contextsToAdaptablesMap = new HashMap>(); List nullList = new ArrayList(); OnaroAdapterUtils.indexByAdapter(inputs, Context.class, contextsToAdaptablesMap, nullList); for (Map.Entry> mapEntry : contextsToAdaptablesMap.entrySet()) { Context context = mapEntry.getKey(); List inputsWithSameContext = mapEntry.getValue(); process(context, inputsWithSameContext, outputMap); } if (!nullList.isEmpty()) { process(null, nullList, outputMap); } } } private void process(Context context, Collection inputsWithSameContext, Map outputMap) throws InterruptedException, InvocationTargetException { OnaroThreadUtils.checkInterrupted(); context = ServerInterfacesUtils.getLoadContext(context); evaluate(inputsWithSameContext, context, outputMap); } /** * Evaluate the bulk function on all of the given rows. The results of the call should be placed in the * output map, with each input row having a corresponding data entry in the output. * * @param inputs The IAdaptable inputs all with the same context. * @param context the Context which all the inputs share. * @param outputMap The output of the function, a correspondence between the input row, and the result * of the evaluation of that row. * @throws InterruptedException Calls to this function should be interruptible, and throw this when interrupted. */ protected abstract void evaluate(Collection inputs, Context context, Map outputMap) throws InterruptedException, InvocationTargetException; }