net.anidb.udp.UdpResponse.java Source code

Java tutorial

Introduction

Here is the source code for net.anidb.udp.UdpResponse.java

Source

/*
 * Java AniDB API - A Java API for AniDB.net
 * (c) Copyright 2009 grizzlyxp
 * http://anidb.net/perl-bin/animedb.pl?show=userpage&uid=63935
 * 
 * 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.
 */
package net.anidb.udp;

import java.io.UnsupportedEncodingException;
import java.net.DatagramPacket;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Vector;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * A response from the server.
 * @author grizzlyxp
 * (http://anidb.net/perl-bin/animedb.pl?show=userpage&uid=63935)
 * @version <b>1.0</b>, 29.11.2009
 */
public class UdpResponse {
    /** The logging. */
    private final static Log LOG = LogFactory.getLog(UdpResponse.class);

    /** The return code. */
    private int returnCode;
    /** The return string. */
    private String returnString;
    /** The entries. */
    private Vector<UdpResponseEntry> entries = new Vector<UdpResponseEntry>();

    /**
     * Creates a response.
     * @param returnCode The return code.
     * @param returnString The return string.
     * @throws IllegalArgumentException If the return string is
     * <code>null</code>.
     */
    protected UdpResponse(final int returnCode, final String returnString) {
        super();
        this.returnCode = returnCode;
        if (returnString == null) {
            throw new IllegalArgumentException("Argument returnString is null.");
        }
        this.returnString = returnString;
    }

    /**
     * Returns the return code.
     * @return The return code.
     */
    public int getReturnCode() {
        return this.returnCode;
    }

    /**
     * Returns the return string.
     * @return The return string.
     */
    public String getReturnString() {
        return this.returnString;
    }

    /**
     * Returns a instance of the class.
     * @param packet The datagram packet.
     * @param charset The charset.
     * @return The instance.
     * @throws IllegalArgumentException If the datagram packet is
     * <code>null</code>.
     * @throws UdpConnectionException If the structure of datagram packet isn't
     * valid.
     * @throws UnsupportedEncodingException If the given charset isn't
     * supported.
     */
    protected static UdpResponse getInstance(final DatagramPacket packet, final Charset charset)
            throws UdpConnectionException, UnsupportedEncodingException {

        ByteBuffer byteBuffer;
        String data, returnCodeStr, returnString;
        int returnCode;
        UdpResponse response;
        int index;
        String[] entries, dataFields;
        UdpResponseEntry entry;

        if (packet == null) {
            throw new IllegalArgumentException("Argument packet is null.");
        }
        if (packet.getLength() < 5) {
            throw new UdpConnectionException(
                    "The packet length is less than " + "the minimum of 5 bytes: " + packet.getLength());
        }
        byteBuffer = ByteBuffer.allocate(packet.getLength());
        byteBuffer = (ByteBuffer) byteBuffer.put(packet.getData(), 0, packet.getLength()).flip();
        data = charset.decode(byteBuffer).toString();
        LOG.debug("received = [" + data + ']');
        if (data.length() < 5) {
            throw new UdpConnectionException(
                    "The string length is less than " + "the minimum of 5 characters: " + data);
        }
        // First 3 chars = return code
        returnCodeStr = data.substring(0, 3);
        data = data.substring(4);
        try {
            returnCode = Integer.parseInt(returnCodeStr);
        } catch (NumberFormatException nfe) {
            throw new UdpConnectionException("Couldn't parse return code: " + returnCodeStr, nfe);
        }
        // Return string.
        index = data.indexOf('\n');
        if (index < 0) {
            returnString = data;
            data = "";
        } else {
            returnString = data.substring(0, index);
            data = data.substring(index + 1);
        }
        response = new UdpResponse(returnCode, returnString);
        // Entries?
        if (data.length() > 0) {
            entries = data.split("\\n", -1);
            for (int eIndex = 0; eIndex < entries.length; eIndex++) {
                if ((entries[eIndex].length() == 0) && (eIndex == entries.length - 1)) {
                    break;
                }
                entry = new UdpResponseEntry();
                dataFields = entries[eIndex].split("\\|", -1);
                for (int dfIndex = 0; dfIndex < dataFields.length; dfIndex++) {
                    entry.addDataField(new DataField(dataFields[dfIndex], charset));
                }
                response.entries.addElement(entry);
            }
            // MTU size problem.
            // TODO Implement a better solution for the MTU problem.
            if ((response.entries.size() > 0) && (packet.getLength() == 1400)) {
                /*
                 * I assume if the packet length is equal to the MTU size, the
                 * last entry is cut and must be removed.
                 */
                index = response.entries.size() - 1;
                //            entry = response.entries.elementAt(index);
                //            data = entry.getMessageString();
                //            LOG.debug("last line = [" + data + ']');
                response.entries.removeElementAt(index);
            }
        }
        return response;
    }

    /**
     * Returns the count of the entries.
     * @return The count.
     */
    public int getEntryCount() {
        return this.entries.size();
    }

    /**
     * Returns the entry on the given index.
     * @param index The index.
     * @return The entry.
     * @throws IndexOutOfBoundsException If the index is out of bounds.
     */
    public UdpResponseEntry getEntryAt(final int index) {
        if ((index < 0) || (index >= this.entries.size())) {
            throw new IndexOutOfBoundsException("Index is out of bounds. Lower " + "limit: 0; upper limit: "
                    + (this.entries.size() - 1) + "; index: " + index);
        }
        return this.entries.elementAt(index);
    }

    /**
     * Returns the entries as an message string.
     * @return The message string or <code>null</code>, if this response hasn't
     * any entries.
     */
    public String getMessageString() {
        StringBuffer messageString;
        Iterator<UdpResponseEntry> iterator;
        UdpResponseEntry entry = null;

        if (this.entries.size() == 0) {
            return null;
        }
        messageString = new StringBuffer();
        iterator = this.entries.iterator();
        while (iterator.hasNext()) {
            if (entry != null) {
                messageString.append('\n');
            }
            entry = iterator.next();
            messageString.append(entry.getMessageString());
        }
        return messageString.toString();
    }

    /**
     * Returns the entries as an message string as one line wihout line feeds.
     * @return The message string or <code>null</code>, if this response hasn't
     * any entries.
     */
    public String getTrimedMessageString() {
        StringBuffer messageString;
        Iterator<UdpResponseEntry> iterator;
        UdpResponseEntry entry = null;

        if (this.entries.size() == 0) {
            return null;
        }
        messageString = new StringBuffer();
        iterator = this.entries.iterator();
        while (iterator.hasNext()) {
            if (entry != null) {
                messageString.append(' ');
            }
            entry = iterator.next();
            messageString.append(entry.getTrimedMessageString());
        }
        return messageString.toString().trim();
    }

    public String toString() {
        StringBuffer sb;
        String entries;

        sb = new StringBuffer();
        sb.append(this.returnCode);
        sb.append(' ');
        sb.append(this.returnString);
        entries = this.getMessageString();
        if (entries != null) {
            sb.append('\n');
            sb.append(entries);
        }
        return sb.toString();
    }
}