All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.diirt.datasource.extra.DynamicGroup Maven / Gradle / Ivy

/**
 * Copyright (C) 2010-14 diirt developers. See COPYRIGHT.TXT
 * All rights reserved. Use is subject to license terms. See LICENSE.TXT
 */
package org.diirt.datasource.extra;

import java.util.ArrayList;
import java.util.List;
import org.diirt.datasource.ReadRecipe;
import org.diirt.datasource.DataSource;
import org.diirt.datasource.expression.DesiredRateExpression;
import org.diirt.datasource.expression.DesiredRateExpressionImpl;
import org.diirt.datasource.ExceptionHandler;
import org.diirt.datasource.PVManager;
import org.diirt.datasource.expression.DesiredRateExpressionListImpl;

/**
 * A expression that returns the result of a dynamically managed group.
 * Once the group is created, any {@link DesiredRateExpression} can be
 * added dynamically. The exceptions eventually generated by those
 * expressions can be obtained through {@link #lastExceptions() }.
 *
 * @author carcassi
 */
public class DynamicGroup extends DesiredRateExpressionImpl> {

    private final DataSource dataSource = PVManager.getDefaultDataSource();
    private final List recipes = new ArrayList();

    /**
     * Creates a new group.
     */
    public DynamicGroup() {
        super(new DesiredRateExpressionListImpl(), new DynamicGroupFunction(), "dynamic group");
    }

    DynamicGroupFunction getGroup() {
        return (DynamicGroupFunction) getFunction();
    }

    /**
     * Returns the last exception for each expression in the group (if present).
     * 
     * @return a list of exceptions (never null)
     */
    public List lastExceptions() {
        synchronized (getGroup()) {
            return new ArrayList(getGroup().getExceptions());
        }
    }

    /**
     * Removes all the expressions currently in the group.
     * 
     * @return this
     */
    public synchronized DynamicGroup clear() {
        for (int index = recipes.size() - 1; index >= 0; index--) {
            ReadRecipe recipe = recipes.remove(index);
            dataSource.disconnectRead(recipe);
            synchronized (getGroup()) {
                getGroup().getArguments().remove(index);
                getGroup().getExceptions().remove(index);
                getGroup().getPreviousValues().remove(index);
            }
        }
        return this;
    }

    /**
     * Returns the number of expressions in the group.
     * 
     * @return number of expressions in the group
     */
    public synchronized int size() {
        return recipes.size();
    }

    /**
     * Adds the expression at the end.
     * 
     * @param expression the expression to be added
     * @return this
     */
    public synchronized DynamicGroup add(DesiredRateExpression expression) {
//        DataRecipe recipe = expression.getDataRecipe();
//        recipe = recipe.withExceptionHandler(handlerFor(recipes.size()));
        synchronized (getGroup()) {
            getGroup().getArguments().add(expression.getFunction());
            getGroup().getExceptions().add(null);
            getGroup().getPreviousValues().add(null);
        }
//        dataSource.connect(recipe);
//        recipes.add(recipe);
        return this;
    }

    /**
     * Removes the expression at the given location.
     * 
     * @param index the position to remove
     * @return this
     */
    public synchronized DynamicGroup remove(int index) {
        ReadRecipe recipe = recipes.remove(index);
        dataSource.disconnectRead(recipe);
        synchronized (getGroup()) {
            getGroup().getArguments().remove(index);
            getGroup().getExceptions().remove(index);
            getGroup().getPreviousValues().remove(index);
        }
        return this;
    }

    /**
     * Changes the expression to the given location.
     * 
     * @param index the position to remove
     * @param expression the new expression
     * @return this
     */
    public synchronized DynamicGroup set(int index, DesiredRateExpression expression) {
//        DataRecipe recipe = expression.getDataRecipe();
//        recipe = recipe.withExceptionHandler(handlerFor(index));
        ReadRecipe oldRecipe = recipes.get(index);
        dataSource.disconnectRead(oldRecipe);

        synchronized (getGroup()) {
            getGroup().getArguments().set(index, expression.getFunction());
            getGroup().getExceptions().set(index, null);
            getGroup().getPreviousValues().set(index, null);
        }
//        dataSource.connect(recipe);
//        recipes.set(index, recipe);
        return this;
    }

    private ExceptionHandler handlerFor(final int index) {
        return new ExceptionHandler() {

            @Override
            public void handleException(Exception ex) {
                synchronized (getGroup()) {
                    getGroup().getExceptions().set(index, ex);
                }
            }
        };
    }
}