com.vitesify.languidmpd.streams.MPDStreamProcesser.java Source code

Java tutorial

Introduction

Here is the source code for com.vitesify.languidmpd.streams.MPDStreamProcesser.java

Source

package com.vitesify.languidmpd.streams;

/*
 *  MPDStreamProcessor
 *  Copyright (C) 2014  Christopher Nelson <christopher.nelson@cavein.org>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *  
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.nio.charset.Charset;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.io.IOUtils;

/**
 * A Processor of Streams, which should be read off of Sockets.
 * @author Christopher Nelson
 *
 */
public class MPDStreamProcesser {

    /**
     * The type of message you'd like to send to the server.
     * @author Christopher Nelson
     *
     */
    public enum Message {
        CLEAR_ERROR, IDLE, STATUS, STATS;

        /**
         * Returns the NAME of this constant in lower case.
         * We conventionally use the command name, in upper case
         * for the Enum value
         */
        public String toString() {
            return name().toLowerCase();
        }
    }

    private Writer ow;
    private Reader ir;
    private boolean last_command_status;
    private Collection<String> last_return_codes;

    /**
     * Construct a Stream Processor for MPD streams.
     * @param is the InputStream gleaned off a socket
     * @param os the OutputStream gleaned off a socket
     */
    public MPDStreamProcesser(InputStream is, OutputStream os) {
        this.ir = new InputStreamReader(is, Charset.forName("UTF-8"));
        this.ow = new OutputStreamWriter(os, Charset.forName("UTF-8"));
    }

    /**
     * Send a command to the MPD stream.
     * @param messageType the type of message to send
     * @param args a list of string arguments to send to the stream
     * @return true is the MPD tells us the last command succeeded, false otherwise
     * @throws IOException if the streams cannot be read and/or writter
     */
    public boolean send_command(Message messageType, Collection<String> args) throws IOException {
        last_return_codes = parse_return_code(send_message_and_return_response(messageType, args));
        return last_command_succeeded();
    }

    /**
     * The "return code" is a String which may be suitable to display to the user.
     * @return the raw string which MPD gave us 
     */
    public String get_return_code() {
        StringBuilder b = new StringBuilder();
        for (String str : last_return_codes) {
            b.append(str).append("\n");
        }
        return b.toString();
    }

    /**
     * We really mean the last command, in case of a list.
     * @return true if it succeeded, false otherwise
     */
    public boolean last_command_succeeded() {
        return last_command_status;
    }

    private Collection<String> send_message_and_return_response(Message messageType, Collection<String> args)
            throws IOException {
        ow.write(messageType.toString());
        Collection<String> result = IOUtils.readLines(ir);
        return result;
    }

    private Collection<String> parse_return_code(Collection<String> return_code) {
        List<String> ret = new LinkedList<String>();
        boolean failure = false;
        String last_str = null;
        Iterator<String> iter = return_code.iterator();
        while (iter.hasNext()) {
            last_str = iter.next();
            ret.add(last_str);
        }
        ret.remove(ret.size() - 1);
        if (!last_str.startsWith("OK")) {
            failure = true;
        }

        last_command_status = !failure;
        return ret;
    }

}