org.globus.ftp.vanilla.Reply.java Source code

Java tutorial

Introduction

Here is the source code for org.globus.ftp.vanilla.Reply.java

Source

/*
 * Copyright 1999-2006 University of Chicago
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.globus.ftp.vanilla;

import org.globus.ftp.exception.FTPReplyParseException;

import java.io.Serializable;
import java.io.EOFException;
import java.io.IOException;
import java.io.BufferedReader;

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

// FTPReplyParseException - move line to exception
// internationalize exceptions

/**
 * <p>
 * Represents the FTP reply.
 * </p>
 */
public class Reply implements Serializable {

    private static Log logger = LogFactory.getLog(Reply.class.getName());

    public static final int POSITIVE_PRELIMINARY = 1;
    public static final int POSITIVE_COMPLETION = 2;
    public static final int POSITIVE_INTERMEDIATE = 3;
    public static final int TRANSIENT_NEGATIVE_COMPLETION = 4;
    public static final int PERMANENT_NEGATIVE_COMPLETION = 5;

    //minimum length of 1st line:
    //message is defined as 3 chars + <sp> + <text> + <CRLF>
    //so if text is empty, minimum 1st line length = 4
    private static final int MIN_FIRST_LEN = 4;

    // instance members
    protected String message;
    protected int code;
    protected int category;
    protected boolean isMultiline;

    // for subclassing
    protected Reply() {
    };

    /**
     * @throws EOFException on end of stream
     * @throws IOException on I/O problem
     * @throws FTPReplyParseException if cannot parse
     **/
    public Reply(BufferedReader input) throws FTPReplyParseException, EOFException, IOException {
        logger.debug("read 1st line");
        String line = input.readLine();
        if (logger.isDebugEnabled()) {
            logger.debug("1st line: " + line);
        }

        //end of stream
        if (line == null) {
            throw new EOFException();
        }

        //for compatibility with GT2.0 wuftp server which is incorrectly inserting \0 between lines
        line = ignoreLeading0(line);

        if (line.length() < MIN_FIRST_LEN) {
            throw new FTPReplyParseException(FTPReplyParseException.STRING_TOO_SHORT, "Minimum 1st line length = "
                    + MIN_FIRST_LEN + ". Here's the incorrect 1st line ->" + line + "<-");
        }

        // code
        String codeString = line.substring(0, 3);

        try {
            code = Integer.parseInt(codeString);
        } catch (NumberFormatException e) {
            throw new FTPReplyParseException(FTPReplyParseException.FIRST_3_CHARS,
                    "Here's the incorrect line ->" + line + "<-" + "and the first 3 chars ->" + codeString + "<-");
        }

        // category
        category = line.charAt(0) - '0';

        // message
        char char4 = line.charAt(3);

        //do not include 4th char in message
        message = line.substring(4, line.length());

        if (char4 == ' ') {

            //single line reply
            isMultiline = false;

        } else if (char4 == '-') {

            //multi - line reply

            isMultiline = true;

            String lastLineStarts = codeString + ' ';
            //platform dependent line separator
            String lineSeparator = System.getProperty("line.separator");
            if (logger.isDebugEnabled()) {
                logger.debug("multiline reply; last line should start with ->" + lastLineStarts + "<-");
                logger.debug("lenght of line.separator on this OS: " + lineSeparator.length());
            }
            StringBuffer buf = new StringBuffer(message);
            for (;;) {
                logger.debug("read line");
                line = input.readLine();

                //end of stream
                if (line == null) {
                    throw new EOFException();
                }

                //for compatibility with GT2.0 wuftp server
                //which is incorrectly inserting \0 between lines
                line = ignoreLeading0(line);
                if (logger.isDebugEnabled()) {
                    logger.debug("line : ->" + line + "<-");
                }
                buf.append(lineSeparator).append(line);

                if (line.startsWith(lastLineStarts)) {
                    logger.debug("end reached");
                    break;
                }
            }
            message = buf.toString();

        } else {
            throw new FTPReplyParseException(FTPReplyParseException.UNEXPECTED_4TH_CHAR,
                    "Here's the incorrect line ->" + line + "<-");
        }
    }

    /**
     *
     * @return the first digit of the reply code.
     *
     */
    public int getCategory() {
        return category;
    }

    /**
     *  @return the reply code
     */
    public int getCode() {
        return code;
    }

    public boolean isMultiline() {
        return isMultiline;
    }

    /**
     * <p>
     * Returns the text that came with the reply, between the leading space and
     * terminating CRLF, excluding the mentioned space and CRLF.
     * </p>
     * <p>
     * If the reply is multi-line, this returns the text between the leading
     * dash &quot;-&quot; and the CRLF following the last line, excluding the mentioned
     * dash and CRLF. Note that lines are separated by the local line separator
     * [as returned by System.getProperty("line.separator")] rather than CRLF.
     *
     * </p>
     * <p>
     *
     * </p>
     */
    public String getMessage() {
        return message;
    }

    public static boolean isPositivePreliminary(Reply reply) {
        return (reply.getCategory() == POSITIVE_PRELIMINARY);
    }

    public static boolean isPositiveCompletion(Reply reply) {
        return (reply.getCategory() == POSITIVE_COMPLETION);
    }

    public static boolean isPositiveIntermediate(Reply reply) {
        return (reply.getCategory() == POSITIVE_INTERMEDIATE);
    }

    public static boolean isTransientNegativeCompletion(Reply reply) {
        return (reply.getCategory() == TRANSIENT_NEGATIVE_COMPLETION);
    }

    public static boolean isPermanentNegativeCompletion(Reply reply) {
        return (reply.getCategory() == PERMANENT_NEGATIVE_COMPLETION);
    }

    public String toString() {
        String mult = isMultiline ? "-" : " ";
        return code + mult + message;
    }

    /**
       GT2.0 wuftp server incorrectly inserts \0 between lines. We have to deal with that.
     **/
    protected static String ignoreLeading0(String line) {
        if (line.length() > 0 && line.charAt(0) == 0) {
            logger.debug("WARNING: The first character of the reply is 0. Ignoring the character.");
            /*
            logger.debug( "\n\nWARNING:\n In the reply received from the server, the first character's code is 0! I will ignore it but this means the server is not following the protocol. Here's the details: \n first line of the reply ->" + line + "<-");
            logger.debug( "First 3 chars of reply->" +line.substring(0,3)+"<-");
            logger.debug( "char 0 ->" + line.charAt(0) + "<- code = " + (int)line.charAt(0));
            logger.debug( "char 1 ->" + line.charAt(1) + "<- code = " + (int)line.charAt(1));
            logger.debug( "char 2 ->" + line.charAt(2) + "<- code = " + (int)line.charAt(2));
            logger.debug( "char 3 ->" + line.charAt(3) + "<- code = " + (int)line.charAt(3));
            */
            return line.substring(1, line.length());
        }
        return line;
    }

} // end Reply