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

org.diirt.datasource.loc.LocalDataSource 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.loc;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Logger;
import org.diirt.datasource.ChannelHandler;
import org.diirt.datasource.ChannelReadRecipe;
import org.diirt.datasource.ChannelWriteRecipe;
import org.diirt.datasource.DataSource;
import org.diirt.datasource.ReadRecipe;
import org.diirt.datasource.WriteRecipe;
import org.diirt.datasource.vtype.DataTypeSupport;
import org.diirt.datasource.util.FunctionParser;
import org.diirt.util.array.ArrayDouble;

/**
 * Data source for locally written data. Each instance of this
 * data source will have its own separate channels and values.
 *
 * @author carcassi
 */
public class LocalDataSource extends DataSource {

    private final boolean zeroInitialization;

    static {
        // Install type support for the types it generates.
        DataTypeSupport.install();
    }

    /**
     * Creates a new data source.
     */
    public LocalDataSource() {
        this(false);
    }
    
    /**
     * Zero initialization is deprecated. Will be removed in a future release.
     * 
     * @param zeroInitialization whether to initialize variable to 0
     * @deprecated do not use zero initialization of local variable: does not work for non numeric variables
     */
    @Deprecated
    public LocalDataSource(boolean zeroInitialization) {
        super(true);
        this.zeroInitialization = zeroInitialization;
    }

    private final String CHANNEL_SYNTAX_ERROR_MESSAGE = 
            "Syntax for local channel must be either name, name(Double) or name(String) (e.g \"foo\", \"foo(2.0)\" or \"foo(\"bar\")";
    
    @Override
    protected ChannelHandler createChannel(String channelName) {
        // Parse the channel name
        List parsedTokens = parseName(channelName);
        
        LocalChannelHandler channel = new LocalChannelHandler(parsedTokens.get(0).toString());
        return channel;
    }
    
    private List parseName(String channelName) {
        List tokens = FunctionParser.parseFunctionWithScalarOrArrayArguments(".+", channelName, CHANNEL_SYNTAX_ERROR_MESSAGE);
        String nameAndType = tokens.get(0).toString();
        String name = nameAndType;
        String type = null;
        int index = nameAndType.lastIndexOf('<');
        if (nameAndType.endsWith(">") && index != -1) {
            name = nameAndType.substring(0, index);
            type = nameAndType.substring(index + 1, nameAndType.length() - 1);
        }
        List newTokens = new ArrayList<>();
        newTokens.add(name);
        newTokens.add(type);
        if (tokens.size() > 1) {
            newTokens.addAll(tokens.subList(1, tokens.size()));
        }
        return newTokens;
    }

    @Override
    protected String channelHandlerLookupName(String channelName) {
        List parsedTokens = parseName(channelName);
        return parsedTokens.get(0).toString();
    }
    
    private void initialize(String channelName) {
        List parsedTokens = parseName(channelName);

        LocalChannelHandler channel = (LocalChannelHandler) getChannels().get(channelHandlerLookupName(channelName));
        channel.setType((String) parsedTokens.get(1));
        if (parsedTokens.size() > 2) {
            if (channel != null) {
                channel.setInitialValue(parsedTokens.get(2));
            }
        } else if (zeroInitialization) {
            Logger.getLogger(this.getClass().getName()).warning("Using zero initialization for channel " + channelName);
            channel.setInitialValue(0);
        }
    }

    @Override
    public void connectRead(ReadRecipe readRecipe) {
        super.connectRead(readRecipe);
        
        // Initialize all values
        for (ChannelReadRecipe channelReadRecipe : readRecipe.getChannelReadRecipes()) {
            initialize(channelReadRecipe.getChannelName());
        }
    }

    @Override
    public void connectWrite(WriteRecipe writeRecipe) {
        super.connectWrite(writeRecipe);
        
        // Initialize all values
        for (ChannelWriteRecipe channelWriteRecipe : writeRecipe.getChannelWriteRecipes()) {
            initialize(channelWriteRecipe.getChannelName());
        }
    }

}