org.rifidi.emulator.reader.thingmagic.commandobjects.SelectCommand.java Source code

Java tutorial

Introduction

Here is the source code for org.rifidi.emulator.reader.thingmagic.commandobjects.SelectCommand.java

Source

/*
 *  SelectCommand.java
 *
 *  Created:   August 7, 2008
 *  Project:   RiFidi Emulator - A Software Simulation Tool for RFID Devices
 *              http://www.rifidi.org
 *              http://rifidi.sourceforge.net
 *  Copyright:   Pramari LLC and the Rifidi Project
 *  License:   Lesser GNU Public License (LGPL)
 *              http://www.opensource.org/licenses/lgpl-license.html
 */
package org.rifidi.emulator.reader.thingmagic.commandobjects;

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.NoSuchElementException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.rifidi.emulator.reader.thingmagic.commandobjects.exceptions.CommandCreationException;
import org.rifidi.emulator.reader.thingmagic.conditional.MasterFilter;
import org.rifidi.emulator.reader.thingmagic.database.IDBRow;
import org.rifidi.emulator.reader.thingmagic.database.IDBTable;
import org.rifidi.emulator.reader.thingmagic.database.impl.DBTagID;
import org.rifidi.emulator.reader.thingmagic.module.ThingMagicReaderSharedResources;

/**
 * @author Jerry Maine - jerry@pramari.com
 * 
 */
public class SelectCommand extends Command {
    private static Log logger = LogFactory.getLog(SelectCommand.class);

    private String command;

    private List<String> columns = new ArrayList<String>();
    private String table;

    private ThingMagicReaderSharedResources tmsr;

    private MasterFilter filter;

    public SelectCommand(String command, ThingMagicReaderSharedResources tmsr) throws CommandCreationException {
        this.tmsr = tmsr;
        this.command = command;

        // TODO Auto-generated constructor stub

        logger.debug("Parsing command: " + command);

        List<String> tokens = tokenizer(command);

        ListIterator<String> tokenIterator = tokens.listIterator();

        String token = tokenIterator.next();

        if (!token.equals("select")) {
            throw new CommandCreationException("Error 0100:     syntax error at '" + token + "'");

        }

        logger.debug("Huray! we are in the correct command object!");
        // TODO Refine the error handling to mirror more exactly what the
        // thingmagic would return;
        try {
            token = tokenIterator.next();

            /*
             * Look for white spaces
             */
            if (!token.matches(WHITE_SPACE)) {
                throw new CommandCreationException("Error 0100:     syntax error at '" + token + "'");
            }

            logger.debug("Expected whitespace found.");
            do {
                token = tokenIterator.next();

                /*
                 * look a word
                 */
                if (token.matches(A_WORD)) {
                    columns.add(token);
                } else {
                    throw new CommandCreationException("Error 0100:     syntax error at '" + token + "'");
                }
                token = tokenIterator.next();
                /*
                 * look for a comma with any number of white spaces on either
                 * side.
                 */
            } while (token.matches(COMMA_WITH_WS));

            if (tokenIterator.next().equals("from")) {

                if (!token.matches(WHITE_SPACE))
                    throw new CommandCreationException("Error 0100:     syntax error at 'from'");

            } else {
                throw new CommandCreationException("Error 0100:     syntax error at ','");
            }

            token = tokenIterator.next();
            /*
             * Look for white spaces
             */
            if (!token.matches(WHITE_SPACE)) {
                throw new CommandCreationException("Error 0100:     syntax error at '" + token + "'");
            }

            token = tokenIterator.next();

            /*
             * Look for words
             */
            if (token.matches(A_WORD)) {
                table = token;
            } else {
                throw new CommandCreationException("Error 0100:     syntax error at '" + token + "'");
            }

            if (tokenIterator.hasNext()) {
                token = tokenIterator.next();

                if (token.matches(WHITE_SPACE)) {

                    if (tokenIterator.hasNext()) {
                        token = tokenIterator.next();

                        if (token.equals("where")) {

                            token = tokenIterator.next();

                            if (!token.matches(WHITE_SPACE)) {
                                throw new CommandCreationException(
                                        "Error 0100:     syntax error at '" + token + "'");
                            }

                            filter = new MasterFilter(tokenIterator, table, tmsr);
                        } else {
                            //No where clause found... back up..
                            tokenIterator.previous();
                            tokenIterator.previous();
                        }
                    }

                } else {
                    //No where clause found... back up..
                    tokenIterator.previous();
                }
            }

            //TODO: Add the parsing for the "SET key=value ..." clause here.

            // check if the command correctly ends in a semicolon
            logger.debug("Checking for correct terminating sequence...");
            if (tokenIterator.hasNext()) {
                token = tokenIterator.next();

                if (token.matches(WHITE_SPACE)) {
                    token = tokenIterator.next();
                }

                if (!token.equals(";")) {
                    throw new CommandCreationException("Error 0100:     syntax error at '" + token + "'");
                }
            } else {
                throw new CommandCreationException("Error 0100:     syntax error at '\n'");
            }

        } catch (NoSuchElementException e) {
            /*
             * if we get here... we run out of tokens prematurely... Our job now
             * is to walk backwards to find the last non space tokens and throw
             * an exception saying that there is an syntax error at that point.
             */

            /*
             * look for the last offending command block that is not a series of
             * whitespaces.
             */

            token = tokenIterator.previous();
            while (token.matches("\\s+")) {
                token = tokenIterator.previous();
            }
            logger.debug("Premature end of token list detected.");
            throw new CommandCreationException("Error 0100:     syntax error at '" + token + "'");
        }

        IDBTable tableImpl = tmsr.getDataBase().getTable(table);
        if (tableImpl == null) {
            throw new CommandCreationException("Error 0100:     syntax error at '" + table + "'");
        }

        /*
         * This is an exception to the rule for the thingmagic reader. If we are
         * reading a tag... make best effort to complete the command in an
         * orderly and predictable manner.
         */
        if (tableImpl instanceof DBTagID) {
            return;
        }

        for (int x = 0; x < tableImpl.size(); x++) {
            IDBRow row = tableImpl.get(x);
            for (String column : columns) {
                if (!row.containsColumn(column)) {
                    throw new CommandCreationException("Error 0100:     Unknown " + column);
                }

                if (!row.isReadable(column)) {
                    throw new CommandCreationException(
                            "Error 0100:     Could not read from '" + column + "' in '" + table + "'");
                }
            }
        }
    }

    @Override
    public ArrayList<Object> execute() {
        // TODO Auto-generated method stub
        ArrayList<Object> retVal = new ArrayList<Object>();
        // TODO add filtering
        logger.debug("Getting table: " + table);
        logger.debug("Getting column data: " + columns);

        /*
         * here is the method we need to send the "Set key=value ..." clause
         * to in the form of a map.
         */
        //TODO: Implement this.
        tmsr.getDataBase().getTable(table).preTableAccess(null);

        // TODO implement this better.
        List<IDBRow> rows = new ArrayList<IDBRow>();
        for (int x = 0; x < tmsr.getDataBase().getTable(table).size(); x++) {
            rows.add(tmsr.getDataBase().getTable(table).get(x));
        }

        //TODO: ThingMagic reader ignores the filter when it is not the tag_id or tag_data tables
        if (filter != null) {
            rows = filter.filter(rows);
        }
        /*
         * Do the select database work.
         */
        for (int x = 0; x < rows.size(); x++) {
            IDBRow row = rows.get(x);

            StringBuffer buff = new StringBuffer();
            for (int y = 0; y < columns.size(); y++) {
                buff.append(row.get(columns.get(y)));
                if (y < columns.size() - 1)
                    buff.append("|");
            }
            retVal.add(buff.toString());
        }

        /*
         * there must be a blank line at the end.. even if we didn't send
         * something useful back.
         * 
         * When the messages are formated for return (in
         * ThingMagicRQLCommandFormatter) a new line is appended to each string
         * even if it is an empty string.
         */
        // place holder for newline.
        retVal.add("");

        return retVal;
    }

    @Override
    public String toCommandString() {
        // TODO Auto-generated method stub
        return command;
    }

}