org.openhab.io.console.ConsoleInterpreter.java Source code

Java tutorial

Introduction

Here is the source code for org.openhab.io.console.ConsoleInterpreter.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.console;

import java.util.Collection;

import org.apache.commons.lang.ArrayUtils;
import org.openhab.core.events.EventPublisher;
import org.openhab.core.items.Item;
import org.openhab.core.items.ItemNotFoundException;
import org.openhab.core.items.ItemNotUniqueException;
import org.openhab.core.items.ItemRegistry;
import org.openhab.core.scriptengine.Script;
import org.openhab.core.scriptengine.ScriptEngine;
import org.openhab.core.scriptengine.ScriptExecutionException;
import org.openhab.core.scriptengine.ScriptParsingException;
import org.openhab.core.types.Command;
import org.openhab.core.types.State;
import org.openhab.core.types.TypeParser;
import org.openhab.io.console.internal.ConsoleActivator;
import org.openhab.io.multimedia.actions.Audio;

import com.google.common.base.Joiner;

/**
 * This class provides generic methods for handling console input (i.e. pure strings).
 * 
 * @author Kai Kreuzer
 * @since 0.4.0
 *
 */
public class ConsoleInterpreter {

    /**
     * This method simply takes a list of arguments, where the first one is treated
     * as the console command (such as "update", "send" etc.). The following entries
     * are then the arguments for this command.
     * If the command is unknown, the complete usage is printed to the console.
     * 
     * @param args array which contains the console command and all its arguments
     * @param console the console for printing messages for the user
     */
    static public void handleRequest(String[] args, Console console) {
        String arg = args[0];
        args = (String[]) ArrayUtils.remove(args, 0);
        if (arg.equals("items")) {
            ConsoleInterpreter.handleItems(args, console);
        } else if (arg.equals("send")) {
            ConsoleInterpreter.handleSend(args, console);
        } else if (arg.equals("update")) {
            ConsoleInterpreter.handleUpdate(args, console);
        } else if (arg.equals("status")) {
            ConsoleInterpreter.handleStatus(args, console);
        } else if (arg.equals("say")) {
            ConsoleInterpreter.handleSay(args, console);
        } else if (arg.equals(">")) {
            ConsoleInterpreter.handleScript(args, console);
        } else {
            console.printUsage(getUsage());
        }
    }

    /**
     * This method handles an update command. 
     * 
     * @param args array which contains the arguments for the update command
     * @param console the console for printing messages for the user
     */
    static public void handleUpdate(String[] args, Console console) {
        ItemRegistry registry = (ItemRegistry) ConsoleActivator.itemRegistryTracker.getService();
        EventPublisher publisher = (EventPublisher) ConsoleActivator.eventPublisherTracker.getService();
        if (publisher != null) {
            if (registry != null) {
                if (args.length > 0) {
                    String itemName = args[0];
                    try {
                        Item item = registry.getItemByPattern(itemName);
                        if (args.length > 1) {
                            String stateName = args[1];
                            State state = TypeParser.parseState(item.getAcceptedDataTypes(), stateName);
                            if (state != null) {
                                publisher.postUpdate(item.getName(), state);
                                console.println("Update has been sent successfully.");
                            } else {
                                console.println("Error: State '" + stateName + "' is not valid for item '"
                                        + itemName + "'");
                                console.print("Valid data types are: ( ");
                                for (Class<? extends State> acceptedType : item.getAcceptedDataTypes()) {
                                    console.print(acceptedType.getSimpleName() + " ");
                                }
                                console.println(")");
                            }
                        } else {
                            console.printUsage(ConsoleInterpreter.getUpdateUsage());
                        }
                    } catch (ItemNotFoundException e) {
                        console.println("Error: Item '" + itemName + "' does not exist.");
                    } catch (ItemNotUniqueException e) {
                        console.print("Error: Multiple items match this pattern: ");
                        for (Item item : e.getMatchingItems()) {
                            console.print(item.getName() + " ");
                        }
                    }
                } else {
                    console.printUsage(ConsoleInterpreter.getUpdateUsage());
                }
            } else {
                console.println("Sorry, no item registry service available!");
            }
        } else {
            console.println("Sorry, no event publisher service available!");
        }
    }

    /**
     * This method handles a send command. 
     * 
     * @param args array which contains the arguments for the send command
     * @param console the console for printing messages for the user
     */
    static public void handleSend(String[] args, Console console) {
        ItemRegistry registry = (ItemRegistry) ConsoleActivator.itemRegistryTracker.getService();
        EventPublisher publisher = (EventPublisher) ConsoleActivator.eventPublisherTracker.getService();
        if (publisher != null) {
            if (registry != null) {
                if (args.length > 0) {
                    String itemName = args[0];
                    try {
                        Item item = registry.getItemByPattern(itemName);
                        if (args.length > 1) {
                            String commandName = args[1];
                            Command command = TypeParser.parseCommand(item.getAcceptedCommandTypes(), commandName);
                            if (command != null) {
                                publisher.sendCommand(itemName, command);
                                console.println("Command has been sent successfully.");
                            } else {
                                console.println("Error: Command '" + commandName + "' is not valid for item '"
                                        + itemName + "'");
                                console.print("Valid command types are: ( ");
                                for (Class<? extends Command> acceptedType : item.getAcceptedCommandTypes()) {
                                    console.print(acceptedType.getSimpleName() + " ");
                                }
                                console.println(")");
                            }
                        } else {
                            console.printUsage(ConsoleInterpreter.getCommandUsage());
                        }
                    } catch (ItemNotFoundException e) {
                        console.println("Error: Item '" + itemName + "' does not exist.");
                    } catch (ItemNotUniqueException e) {
                        console.print("Error: Multiple items match this pattern: ");
                        for (Item item : e.getMatchingItems()) {
                            console.print(item.getName() + " ");
                        }
                    }
                } else {
                    console.printUsage(ConsoleInterpreter.getCommandUsage());
                }
            } else {
                console.println("Sorry, no item registry service available!");
            }
        } else {
            console.println("Sorry, no event publisher service available!");
        }
    }

    /**
     * This method handles an items command. 
     * 
     * @param args array which contains the arguments for the items command
     * @param console the console for printing messages for the user
     */
    static public void handleItems(String[] args, Console console) {
        ItemRegistry registry = (ItemRegistry) ConsoleActivator.itemRegistryTracker.getService();
        if (registry != null) {
            String pattern = (args.length == 0) ? "*" : args[0];
            Collection<Item> items = registry.getItems(pattern);
            if (items.size() > 0) {
                for (Item item : items) {
                    console.println(item.toString());
                }
            } else {
                console.println("No items found for this pattern.");
            }
        } else {
            console.println("Sorry, no item registry service available!");
        }
    }

    /**
     * This method handles a status command. 
     * 
     * @param args array which contains the arguments for the status command
     * @param console the console for printing messages for the user
     */
    static public void handleStatus(String[] args, Console console) {
        ItemRegistry registry = (ItemRegistry) ConsoleActivator.itemRegistryTracker.getService();
        if (registry != null) {
            if (args.length > 0) {
                String itemName = args[0];
                try {
                    Item item = registry.getItemByPattern(itemName);
                    console.println(item.getState().toString());
                } catch (ItemNotFoundException e) {
                    console.println("Error: Item '" + itemName + "' does not exist.");
                } catch (ItemNotUniqueException e) {
                    console.print("Error: Multiple items match this pattern: ");
                    for (Item item : e.getMatchingItems()) {
                        console.print(item.getName() + " ");
                    }
                }
            } else {
                console.printUsage(ConsoleInterpreter.getStatusUsage());
            }
        } else {
            console.println("Sorry, no item registry service available!");
        }
    }

    /**
     * This method handles a say command. 
     * 
     * @param args array which contains the arguments for the status command
     * @param console the console for printing messages for the user
     */
    static public void handleSay(String[] args, Console console) {
        StringBuilder msg = new StringBuilder();
        for (String word : args) {
            if (word.startsWith("%") && word.endsWith("%") && word.length() > 2) {
                String itemName = word.substring(1, word.length() - 1);
                ItemRegistry registry = (ItemRegistry) ConsoleActivator.itemRegistryTracker.getService();
                if (registry != null) {
                    try {
                        Item item = registry.getItemByPattern(itemName);
                        msg.append(item.getState().toString());
                    } catch (ItemNotFoundException e) {
                        console.println("Error: Item '" + itemName + "' does not exist.");
                    } catch (ItemNotUniqueException e) {
                        console.print("Error: Multiple items match this pattern: ");
                        for (Item item : e.getMatchingItems()) {
                            console.print(item.getName() + " ");
                        }
                    }
                } else {
                    console.println("Sorry, no item registry service available!");
                }
            } else {
                msg.append(word);
            }
            msg.append(" ");
        }
        try {
            Audio.say(msg.toString());
            console.println("Said: " + msg);
        } catch (NoClassDefFoundError e) {
            // The dependency to the Audio class is optional, so we have to handle the case that it is not there
            console.println("Could not perform command as no TTS service is available.");
        }
    }

    public static void handleScript(String[] args, Console console) {
        ScriptEngine scriptEngine = ConsoleActivator.scriptEngineTracker.getService();
        if (scriptEngine != null) {
            String scriptString = Joiner.on(" ").join(args);
            Script script;
            try {
                script = scriptEngine.newScriptFromString(scriptString);
                Object result = script.execute();

                if (result != null) {
                    console.println(result.toString());
                } else {
                    console.println("OK");
                }
            } catch (ScriptParsingException e) {
                console.println(e.getMessage());
            } catch (ScriptExecutionException e) {
                console.println(e.getMessage());
            }
        } else {
            console.println("Script engine is not available.");
        }
    }

    /** returns a CR-separated list of usage texts for all available commands */
    private static String getUsage() {
        StringBuilder sb = new StringBuilder();
        for (String usage : ConsoleInterpreter.getUsages()) {
            sb.append(usage + "\n");
        }
        return sb.toString();
    }

    /** returns an array of the usage texts for all available commands */
    static public String[] getUsages() {
        return new String[] { getUpdateUsage(), getCommandUsage(), getStatusUsage(), getItemsUsage(), getSayUsage(),
                getScriptUsage() };
    }

    static public String getUpdateUsage() {
        return "update <item> <state> - sends a status update for an item";
    }

    static public String getCommandUsage() {
        return "send <item> <command> - sends a command for an item";
    }

    static public String getStatusUsage() {
        return "status <item> - shows the current status of an item";
    }

    static public String getItemsUsage() {
        return "items [<pattern>] - lists names and types of all items matching the pattern";
    }

    public static String getSayUsage() {
        return "say <sentence to say> - Says a message through TTS on the host machine";
    }

    public static String getScriptUsage() {
        return "> <script to execute> - Executes a script";
    }

}