001/**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.activemq.console.command;
018
019import java.io.BufferedReader;
020import java.io.IOException;
021import java.io.InputStream;
022import java.io.InputStreamReader;
023import java.util.List;
024
025import org.apache.activemq.ActiveMQConnectionMetaData;
026import org.apache.activemq.console.CommandContext;
027import org.apache.activemq.util.IntrospectionSupport;
028
029public abstract class AbstractCommand implements Command {
030    public static final String COMMAND_OPTION_DELIMETER = ",";
031
032    private boolean isPrintHelp;
033    private boolean isPrintVersion;
034
035    protected CommandContext context;
036
037    public void setCommandContext(CommandContext context) {
038        this.context = context;
039    }
040    
041    /**
042     * Execute a generic command, which includes parsing the options for the
043     * command and running the specific task.
044     * 
045     * @param tokens - command arguments
046     * @throws Exception
047     */
048    public void execute(List<String> tokens) throws Exception {
049        // Parse the options specified by "-"
050        parseOptions(tokens);
051
052        // Print the help file of the task
053        if (isPrintHelp) {
054            printHelp();
055
056            // Print the AMQ version
057        } else if (isPrintVersion) {
058            context.printVersion(ActiveMQConnectionMetaData.PROVIDER_VERSION);
059
060            // Run the specified task
061        } else {
062            runTask(tokens);
063        }
064    }
065
066    /**
067     * Parse any option parameters in the command arguments specified by a '-'
068     * as the first character of the token.
069     * 
070     * @param tokens - command arguments
071     * @throws Exception
072     */
073    protected void parseOptions(List<String> tokens) throws Exception {
074        while (!tokens.isEmpty()) {
075            String token = tokens.remove(0);
076            if (token.startsWith("-")) {
077                // Token is an option
078                handleOption(token, tokens);
079            } else {
080                // Push back to list of tokens
081                tokens.add(0, token);
082                return;
083            }
084        }
085    }
086
087    /**
088     * Handle the general options for each command, which includes -h, -?,
089     * --help, -D, --version.
090     * 
091     * @param token - option token to handle
092     * @param tokens - succeeding command arguments
093     * @throws Exception
094     */
095    protected void handleOption(String token, List<String> tokens) throws Exception {
096        isPrintHelp = false;
097        isPrintVersion = false;
098        // If token is a help option
099        if (token.equals("-h") || token.equals("-?") || token.equals("--help")) {
100            isPrintHelp = true;
101            tokens.clear();
102
103            // If token is a version option
104        } else if (token.equals("--version")) {
105            isPrintVersion = true;
106            tokens.clear();
107        } else if (token.startsWith("-D")) {
108            // If token is a system property define option
109            String key = token.substring(2);
110            String value = "";
111            int pos = key.indexOf("=");
112            if (pos >= 0) {
113                value = key.substring(pos + 1);
114                key = key.substring(0, pos);
115            }
116            System.setProperty(key, value);
117        } else {
118            if (token.startsWith("--")) {
119                String prop = token.substring(2);
120                if (tokens.isEmpty() || tokens.get(0).startsWith("-")) {
121                    context.print("Property '" + prop + "' is not specified!");
122                } else if (IntrospectionSupport.setProperty(this, prop, tokens.remove(0))) {
123                    return;
124                }
125            }
126            // Token is unrecognized
127            context.printInfo("Unrecognized option: " + token);
128            isPrintHelp = true;
129        }
130    }
131
132    /**
133     * Run the specific task.
134     * 
135     * @param tokens - command arguments
136     * @throws Exception
137     */
138    protected abstract void runTask(List<String> tokens) throws Exception;
139
140    /**
141     * Print the help messages for the specific task
142     */
143    protected abstract void printHelp();
144
145    protected void printHelpFromFile() {
146        BufferedReader reader = null;
147        try {
148            InputStream is = getClass().getResourceAsStream(getName() + ".txt");
149            reader = new BufferedReader(new InputStreamReader(is));
150            String line;
151            while ((line = reader.readLine()) != null) {
152                context.print(line);
153            }
154        } catch (Exception e) {} finally {
155            if (reader != null) {
156                try {
157                    reader.close();
158                } catch (IOException e) {}
159            }
160        }
161    }
162}