com.almarsoft.GroundhogReader.lib.NNTPExtended.java Source code

Java tutorial

Introduction

Here is the source code for com.almarsoft.GroundhogReader.lib.NNTPExtended.java

Source

/*
Groundhog Usenet Reader
Copyright (C) 2008-2010  Juan Jose Alvarez Martinez
    
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 com.almarsoft.GroundhogReader.lib;

import java.io.IOException;
import java.util.Vector;

import org.apache.commons.net.nntp.ArticlePointer;
import org.apache.commons.net.nntp.NNTPClient;
import org.apache.commons.net.nntp.NNTPCommand;
import org.apache.commons.net.nntp.NNTPReply;
import org.apache.commons.net.nntp.NewsgroupInfo;

// Extends the apache commons NNTPClient to add support for the 
public class NNTPExtended extends NNTPClient {

    /*
    private long[] __parseListGroup() throws NumberFormatException, IOException {
           
       String line;
       Vector<Long> list;
       BufferedReader reader;
           
       reader = new BufferedReader(new DotTerminatedMessageReader(_reader_));
       list = new Vector<Long>(2048);
           
       while ((line = reader.readLine()) != null) {
     list.add(Long.parseLong(line.trim()));
       }
           
       int listSize = list.size();
       long[] retval = new long[listSize];
           
       for (int i=0; i<listSize; i++) {
     retval[i] = list.get(i);
       }
           
       return retval;
    }
    */

    // ============================================================================================
    // Get the article numbers for the group. This uses the LISTGROUP command with a range if the
    // server supports it. If not, or if it's the first time we get messages from a group, it uses
    // the GROUP, NEXT, and STAT commands (slower but more compatible.)
    // ============================================================================================

    public long[] listGroup(String group, long fromArticle, int limit) throws IOException {

        //String params;

        return getGroupArticles(group, fromArticle, limit);

        /* Disabled, too getGroupArticles give less headaches 
        if (fromArticle == -1) { 
           //params = group;
           // The first time we use the slower getGroupArticles which is faster than asking for the 
           // full group listing in this case
           return getGroupArticles(group, -1, limit);
        }
        else 
           params = group + " " + Long.toString(fromArticle) + "-";
            
        if (!NNTPReply.isPositiveCompletion(sendCommand("LISTGROUP", params))) {
           // If using LISTGROUP fails, we use the slower getGroupArticles
           Log.d("Groundhog", "Server doesnt seem to support ranged LISTGROUP, using the STAT method");
           return getGroupArticles(group, fromArticle, limit);
        }
            
        return __parseListGroup();
        */
    }

    // ================================================================================================
    // Select a group and an article and use "next" to get all the numbers. This is slower than using 
    // listgroup with a range but not all servers support that (mainly giganews)
    // ================================================================================================

    public long[] getGroupArticles(String group, long fromArticle, int limit) throws IOException {

        Vector<Long> list;
        long firstToGet, firstArticle, lastArticle;
        NewsgroupInfo groupInfo = new NewsgroupInfo();

        if (!selectNewsgroup(group, groupInfo))
            return null;

        firstArticle = groupInfo.getFirstArticle();
        lastArticle = groupInfo.getLastArticle();

        if (firstArticle == 0 && lastArticle == 0)
            return new long[0];

        // First sync with this group; see the comment below 
        if (fromArticle == -1)
            firstToGet = firstArticle;

        else {
            if (fromArticle > lastArticle) { // No new articles
                return new long[0];
            } else {
                firstToGet = fromArticle;
            }
        }

        // Now select the first article and start looping until limit or last article reached
        ArticlePointer art = new ArticlePointer();

        list = new Vector<Long>(limit);

        // FIRST CONNECTION TO THE GROUP
        // If this is the first connection we only want the last "limit" articles from the group, 
        // so we ask for the last message and go backwards until we have "limit" articles or 
        // the first one.
        if (fromArticle == -1) {
            if (!selectArticle(lastArticle, art))
                return new long[0];

            for (int i = 0; i < limit; i++) {
                list.insertElementAt((long) art.articleNumber, 0);

                if (art.articleNumber == firstToGet)
                    break;

                if (!selectPreviousArticle(art))
                    break;
            }
        }

        // NON-FIRST CONNECTION TO THE GROUP
        // For normal non-first connection we start with the last article we got on the previous session and advance from that
        // until limit or last article reached
        else {
            if (!selectArticle(firstToGet, art))
                return new long[0];

            for (int i = 0; i <= limit; i++) {
                list.add((long) art.articleNumber);

                if (art.articleNumber == lastArticle)
                    break;

                if (!selectNextArticle(art))
                    break;
            }
        }
        int listSize = list.size();
        long[] articleNumbers = new long[listSize];

        for (int i = 0; i < listSize; i++) {
            articleNumbers[i] = list.get(i);
        }

        return articleNumbers;
    }

    // ===================================================================
    // Overloaded versions of the parent methods accepting long arguments
    // ===================================================================

    public int stat(long articleNumber) throws IOException {
        return sendCommand(NNTPCommand.STAT, Long.toString(articleNumber));
    }

    public boolean selectArticle(long articleNumber, ArticlePointer pointer) throws IOException {
        if (!NNTPReply.isPositiveCompletion(stat(articleNumber)))
            return false;

        if (pointer != null)
            __parseArticlePointer(getReplyString(), pointer);

        return true;
    }

}