org.openhab.io.caldav.internal.util.ExecuteCommandJob.java Source code

Java tutorial

Introduction

Here is the source code for org.openhab.io.caldav.internal.util.ExecuteCommandJob.java

Source

/**
 * Copyright (c) 2010-2015, openHAB.org and others.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 */
package org.openhab.io.caldav.internal.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StreamTokenizer;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.openhab.io.console.Console;
import org.openhab.io.console.ConsoleInterpreter;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Implementation of Quartz {@link Job}-Interface. It parses the Calendar-Event
 * content into single commands and let {@link ConsoleInterpreter} handle those
 * commands.
 * 
 * @author Thomas.Eichstaedt-Engelen
 * @since 0.7.0
 */
public class ExecuteCommandJob implements Job {

    private static final Logger logger = LoggerFactory.getLogger(ExecuteCommandJob.class);

    public static final String JOB_DATA_CONTENT_KEY = "content";

    public void execute(JobExecutionContext context) throws JobExecutionException {
        String content = (String) context.getJobDetail().getJobDataMap().get(JOB_DATA_CONTENT_KEY);

        if (StringUtils.isNotBlank(content)) {
            String[] commands = parseCommands(content);
            for (String command : commands) {
                String[] args = parseCommand(command);
                logger.debug("About to execute CommandJob with arguments {}", Arrays.asList(args));
                try {
                    ConsoleInterpreter.handleRequest(args, new LogConsole());
                } catch (Exception e) {
                    throw new JobExecutionException("Executing command '" + command
                            + "' throws an Exception. Job will be refired immediately.", e, true);
                }
            }
        }

    }

    /**
     * Reads the Calendar-Event content String line by line. It is assumed, that
     * each line contains a single command. Blank lines are omitted.
     * 
     * @param content the Calendar-Event content
     * @return an array of single commands which can be executed afterwards
     */
    protected String[] parseCommands(String content) {
        Collection<String> parsedCommands = new ArrayList<String>();
        BufferedReader in = new BufferedReader(new StringReader(content));

        try {
            String command;
            while ((command = in.readLine()) != null) {
                if (StringUtils.isNotBlank(command)) {
                    parsedCommands.add(command.trim());
                }
            }
        } catch (IOException ioe) {
            logger.error("reading event content throws exception", ioe);
        } finally {
            try {
                in.close();
            } catch (IOException ioe) {
            }
        }

        return parsedCommands.toArray(new String[0]);
    }

    /**
     * Parses a <code>command</code>. Utilizes the {@link StreamTokenizer} which
     * takes care of quoted Strings as well.
     * 
     * @param command the command to parse 
     * @return the tokenized command which can be processed by the 
     * <code>ConsoleInterpreter</code>
     * 
     * @see org.openhab.io.console.ConsoleInterpreter
     */
    protected String[] parseCommand(String command) {
        logger.trace("going to parse command '{}'", command);

        // if the command starts with '>' it contains a script which needs no
        // further handling here ...
        if (command.startsWith(">")) {
            return new String[] { ">", command.substring(1).trim() };
        }

        StreamTokenizer tokenizer = new StreamTokenizer(new StringReader(command));
        tokenizer.wordChars('_', '_');
        tokenizer.wordChars('-', '-');
        tokenizer.wordChars('.', '.');

        List<String> tokens = new ArrayList<String>();
        try {
            int tokenType = 0;
            while (tokenType != StreamTokenizer.TT_EOF && tokenType != StreamTokenizer.TT_EOL) {
                tokenType = tokenizer.nextToken();
                String token = "";
                switch (tokenType) {
                case StreamTokenizer.TT_WORD:
                case 34 /* quoted String */:
                    token = tokenizer.sval;
                    break;
                case StreamTokenizer.TT_NUMBER:
                    token = String.valueOf(tokenizer.nval);
                    break;
                }
                tokens.add(token);
                logger.trace("read value {} from the given command", token);
            }
        } catch (IOException ioe) {
        }

        return tokens.toArray(new String[0]);
    }

    /**
     * Simple implementation of the {@link Console} interface. It's output is
     * send to the logger (INFO-Level).
     * 
     * @author Thomas.Eichstaedt-Engelen
     * @since 0.7.0
     */
    private static class LogConsole implements Console {

        public void print(String s) {
            logger.info(s);
        }

        public void println(String s) {
            logger.info(s);
        }

        public void printUsage(String s) {
            logger.info(s);
        }

    }

}