Package de.kopis.jusenet.nntp

Source Code of de.kopis.jusenet.nntp.NNTPUtils

package de.kopis.jusenet.nntp;

import gnu.inet.nntp.ArticleNumberIterator;
import gnu.inet.nntp.ArticleResponse;
import gnu.inet.nntp.GroupIterator;
import gnu.inet.nntp.LineIterator;
import gnu.inet.nntp.NNTPConnection;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.EventListener;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.Stack;

import javax.swing.SwingUtilities;
import javax.swing.event.EventListenerList;

import de.kopis.jusenet.Application;
import de.kopis.jusenet.nntp.exceptions.NntpNotConnectedException;
import de.kopis.jusenet.nntp.listeners.ArticleListener;
import de.kopis.jusenet.nntp.listeners.GroupListener;
import de.kopis.jusenet.nntp.listeners.GroupManager;
import de.kopis.jusenet.nntp.listeners.ServerListener;
import de.kopis.jusenet.utils.HibernateUtils;
import de.kopis.utils.FileUtils;

/**
* NNTPUtils is a utility class for handling a NNTP connection.<br>
* <br>
* This class should implement all actions in Events/Listeners. This is
* neccessary to use multi-threading and multiple connections.<br>
*
* @author cringe
* @version 0.1
* @created 08.03.2007 11:26:38
*/
public class NNTPUtils implements EventListener, GroupManager {
   
    /**
     * Current instance of NNTPUtils to be used through all parts of
     * application.
     */
    private static NNTPUtils instance;
    /**
     * Pool of available NNTPConnections
     */
    private Stack<NNTPConnection> availableConnections;
    /**
     * Pool of used NNTPConnections
     */
    private Stack<NNTPConnection> usedConnections;
    /**
     * EventListeners for Group, Server, Article
     */
    private EventListenerList listeners;
   
    public NNTPUtils() {
        listeners = new EventListenerList();
        availableConnections = new Stack<NNTPConnection>();
        usedConnections = new Stack<NNTPConnection>();
    }
   
    /**
     * Returns the available instance of NNTPUtils.
     *
     * @return Instance of NNTPUtils to be used
     */
    public static NNTPUtils getInstance() {
        if(instance == null) {
            instance = new NNTPUtils();
        }
       
        return instance;
    }
   
    /**
     * Adds a <code>gnu.inet.nntp.NNTPConnection</code> to the pool.
     *
     * @param connection
     */
    public void addNntpConnection(NNTPConnection connection) {
        availableConnections.push(connection);
    }
   
    public void addGroupListener(GroupListener listener) {
        listeners.add(GroupListener.class, listener);
    }
   
    public void removeGroupListener(GroupListener listener) {
        listeners.remove(GroupListener.class, listener);
    }
   
    public void addArticleListener(ArticleListener listener) {
        listeners.add(ArticleListener.class, listener);
    }
   
    public void removeArticleListener(ArticleListener listener) {
        listeners.remove(ArticleListener.class, listener);
    }
   
    public void addServerListener(ServerListener listener) {
        listeners.add(ServerListener.class, listener);
    }
   
    public void removeServerListener(ServerListener listener) {
        listeners.remove(ServerListener.class, listener);
    }
   
    /**
     * Fires an event when article HEAD is loaded from server.
     *
     * @param a     Newly loaded article
     */
    private void fireArticleHeaderLoaded(Article a) {}
   
    /**
     * Fires an event when article BODY is loaded from server.
     *
     * @param a     Newly loaded article with BODY
     */
    private void fireArticleBodyLoaded(Article a) {}
   
    /**
     * Fires an event when a complete article (HEAD + BODY) is loaded from server.
     *
     * @param a     Newly loaded article with full data
     */
    private void fireArticleLoaded(Article a) {
        ArticleListener[] l = listeners.getListeners(ArticleListener.class);
        for (int i = 0; i < l.length; i++) {
            l[i].articleLoaded(a);
        }
    }
   
    /**
     * Fires an event when an article is sent to the server.
     *
     */
    private void fireArticleSent() {}
   
   
    /**
     * Fires an event when connected to server.
     *
     */
    private void fireConnected() {
        ServerListener[] l = listeners.getListeners(ServerListener.class);
        for (int i = 0; i < l.length; i++) {
            l[i].connected();
        }
    }
   
    /**
     * Fires an event when disconnected from server.
     *
     */
    private void fireDisconnected() {
        ServerListener[] l = listeners.getListeners(ServerListener.class);
        for (int i = 0; i < l.length; i++) {
            l[i].disconnected();
        }
    }
   
    /**
     * Fires an event when a group is loaded.<br>
     * <br>
     * Loads only the group, not the articles or other detailed data.
     *
     * @param g
     */
    private void fireGroupLoaded(Group g) {
        GroupListener[] l = listeners.getListeners(GroupListener.class);
        for (int i = 0; i < l.length; i++) {
            l[i].groupLoaded(g);
        }
    }
   
   
    /**
     * Establishes one connection to the server.
     * @throws NntpNotConnectedException
     *
     */
    public void connect() throws NntpNotConnectedException {
        connect(1);
    }
   
    /**
     * Connects to the server.
     *
     * @param connections   Number of simultaneous connections
     * @throws NntpNotConnectedException
     */
    private void connect(int numberOfConnections) throws NntpNotConnectedException {
        //TODO check available connections
        if(availableConnections.size() < 1) {
            try {
                NNTPConnection con = new NNTPConnection(Application.getInstance().getProperty("nntp.hostname", "localhost"),
                        Integer.parseInt(Application.getInstance().getProperty("nntp.port", "119")));
                String username = Application.getInstance().getProperty("nntp.username");
                if(!"".equals(username)) {
                    if(con.authinfo(username, Application.getInstance().getProperty("nntp.password"))) {
                        System.out.println(new Date() + ": connected");
                        availableConnections.push(con);
                    } else {
                        System.err.println(new Date() + ": not connected. check username/password");
                        throw new NntpNotConnectedException();
                    }
                }
            } catch (NumberFormatException e) {
//                e.printStackTrace();
                throw new NntpNotConnectedException();
            } catch(UnknownHostException e) {
//                e.printStackTrace();
                throw new NntpNotConnectedException();
            } catch (IOException e) {
//                e.printStackTrace();
                throw new NntpNotConnectedException();
            }
        }
       
        //TODO open multiple connections
        for (int i = 0; i < numberOfConnections; i++) {
            if(i >= availableConnections.size()) break;
            NNTPConnection con = availableConnections.pop();
            //TODO connect
//          con.connect();
            fireConnected();
            usedConnections.push(con);
        }
    }
   
    /**
     * Disconnects all opened connections from the server.
     * @throws IOException
     *
     */
    public void disconnect() throws IOException {
        Iterator it = usedConnections.iterator();
        while(it.hasNext()) {
            NNTPConnection con = (NNTPConnection) it.next();
            //TODO disconnect connection
            con.quit();
            availableConnections.push(con);
        }
        fireDisconnected();
    }
   
    /**
     * Returns the number of available connections.
     *
     * @return
     */
    public int getAvailableConnectionCount() {
        return availableConnections.size();
    }
    /**
     * Returns the number of used connections.
     *
     * @return
     */
    public int getOpenedConnectionCount() {
        return usedConnections.size();
    }
   
    /**
     * Returns number of all available and used connections.
     *
     * @return
     */
    public int getConnectionCount() {
        return availableConnections.size() + usedConnections.size();
    }
   
    /**
     * Fetches a complete list of groups from server.
     *
     * @throws NntpNotConnectedException
     *
     */
    public void getGroups() throws NntpNotConnectedException {
        if(usedConnections.size() == 0) {
            throw new NntpNotConnectedException();
        }
       
        // TODO start a thread to get list of groups
        Thread t = new Thread() {
            // get first connection
            NNTPConnection con = usedConnections.get(0);
           
            public void run() {
                GroupIterator git;
                try {
                    git = con.list();
                    while(git.hasNext()) {
                        gnu.inet.nntp.Group g = (gnu.inet.nntp.Group) git.next();
                        Group group = new Group();
                        group.setName(g.getName());
                        group.setFirst(g.getFirst());
                        group.setLast(g.getLast());
                        group.setLastUpdate(new Date());
                        group.setSubscribed(false);
                        HibernateUtils.addGroup(group);
                        // TODO copy attributes
                        fireGroupLoaded(group);
                        Thread.sleep(5);
                    }
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        };
        t.start();
    }
   
    /**
     * Gets all articles from a group.
     *
     * @param g     Group to update
     * @throws NntpNotConnectedException
     */
    public void getArticles(final Group g) throws NntpNotConnectedException {
        //TODO get all articles from group
        if(usedConnections.size() == 0) {
            throw new NntpNotConnectedException();
        }
       
        // TODO start a thread to get list of articles
        Thread t = new Thread() {
            // get first connection
            private NNTPConnection con = usedConnections.get(0);
            private Stack<Integer> articlesIds = new Stack<Integer>();
           
            public void run() {
                ArticleNumberIterator ait;
                try {
                    ait = con.listGroup(g.getName());
                    while(ait.hasNext()) {
                        Integer id = (Integer) ait.next();
                        System.out.println("Got article ID '" + id + "'");
                        //TODO check if ArticleResponse, int articleID or Article is returned
                        articlesIds.push(id);
                        Thread.sleep(2);
                    }
                   
                    for (Integer id : articlesIds) {
//                        System.out.println("Reading article '" + id + "'");
                        ArticleResponse a = (ArticleResponse) con.article(id);
                        StringWriter sw = new StringWriter();
                        PrintWriter pw = new PrintWriter(sw);
                        BufferedReader br = new BufferedReader(new InputStreamReader(a.in));
                        String line = null;
                        while((line = br.readLine()) != null) {
//                            System.out.println("line: " + line);
                            pw.println(line);
                        }
                        Article article = extract(sw.toString());
                        HibernateUtils.addArticle(g, article);
                        fireArticleLoaded(article);
                        Thread.sleep(5);
                    }

                    // TODO change group update date
                    g.setLastUpdate(getCurrentDate());
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        };
        t.start();
    }
   
    /**
     * Returns a <code>Date</code> with the current time.
     *
     * @return
     */
    private Date getCurrentDate() {
        return GregorianCalendar.getInstance().getTime();
    }

    /**
     * Gets all articles from a group.
     *
     * @param g     Group to update
     * @throws NntpNotConnectedException
     */
    public void getArticleHeaders(final Group g) throws NntpNotConnectedException {
        //TODO get all articles from group
        if(usedConnections.size() == 0) {
            throw new NntpNotConnectedException();
        }
       
        // TODO start a thread to get list of articles
        Thread t = new Thread() {
            // get first connection
            NNTPConnection con = usedConnections.get(0);
           
            public void run() {
                ArticleNumberIterator ait;
                try {
                    ait = con.listGroup(g.getName());
                    while(ait.hasNext()) {
                        //TODO check if ArticleResponse, int articleID or Article is returned
                        int aid = (Integer) ait.next();
                        ArticleResponse a = con.head(aid);
                        StringWriter sw = new StringWriter();
                        PrintWriter pw = new PrintWriter(sw);
                        BufferedReader br = new BufferedReader(new InputStreamReader(a.in));
                        String line = null;
                        while((line = br.readLine()) != null) {
//                            System.out.println("line: " + line);
                            pw.println(line);
                        }
                        Article article = extract(sw.toString());
                        //TODO update article attributes
                        HibernateUtils.addArticle(g, article);
                        fireArticleLoaded(article);
                        Thread.sleep(5);
                    }
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        };
        t.start();
        // TODO change group update date
//      g.setLastUpdate(new Date());
    }
   
    /**
     * Gets all articles from a group.
     *
     * @param g     Group to update
     * @throws NntpNotConnectedException
     */
    public void getArticleBodies(final Group g) throws NntpNotConnectedException {
        //TODO get all article bodies from group
        if(usedConnections.size() == 0) {
            throw new NntpNotConnectedException();
        }
       
        // TODO start a thread to get list of articles
        Thread t = new Thread() {
            // get first connection
            private NNTPConnection con = usedConnections.get(0);
           
            public void run() {
                ArticleNumberIterator ait;
                try {
                    ait = con.listGroup(g.getName());
                    while(ait.hasNext()) {
                        //TODO check if ArticleResponse, int articleID or Article is returned
                        int aid = (Integer) ait.next();
                        ArticleResponse a = con.body(aid);
                        StringWriter sw = new StringWriter();
                        PrintWriter pw = new PrintWriter(sw);
                        BufferedReader br = new BufferedReader(new InputStreamReader(a.in));
                        String line = null;
                        while((line = br.readLine()) != null) {
//                            System.out.println("line: " + line);
                            pw.println(line);
                        }
                        Article article = extract(sw.toString());
                        // TODO copy attributes
                        fireArticleLoaded(article);
                        Thread.sleep(5);
                    }
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        };
        t.start();
        // TODO change group update date
//      g.setLastUpdate(new Date());
    }
   
    /**
     * Gets an article via message ID.
     *
     * @param messageId     Unique message ID to get
     * @throws NntpNotConnectedException
     */
    public void getArticle(final String messageId) throws NntpNotConnectedException {
        //TODO get article
        if(usedConnections.size() == 0) {
            throw new NntpNotConnectedException();
        }
       
        // TODO start a thread to get list of articles
        Thread t = new Thread() {
            // get first connection
            private NNTPConnection con = usedConnections.get(0);
            public void run() {
                try {
                    ArticleResponse ait = con.article(messageId);
                    Article article = new Article();
                    // TODO update article
                    // TODO get group from article
                    //HibernateUtils.addArticle(group, article);
                    fireArticleLoaded(article);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        };
        t.start();
        // TODO change group update date
//      g.setLastUpdate(new Date());
    }
   
    /**
     * Gets an article.
     *
     * @param articleId     Unique Article ID to get
     * @throws NntpNotConnectedException
     */
    private void getArticle(final int articleId) throws NntpNotConnectedException {
        //TODO get article
        if(usedConnections.size() == 0) {
            throw new NntpNotConnectedException();
        }
       
        // TODO start a thread to get list of articles
        Thread t = new Thread() {
            // get first connection
            private NNTPConnection con = usedConnections.get(0);
            public void run() {
                try {
                    ArticleResponse ait = con.article(articleId);
                    Article article = new Article();
                    // TODO update article
                    // TODO get group from article
                    //HibernateUtils.addArticle(group, article);
                    fireArticleLoaded(article);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        };
        t.start();
        // TODO change group update date
//      g.setLastUpdate(new Date());
    }
   
    public void send(final String content) throws NntpNotConnectedException {
        // TODO send article
        if(usedConnections.size() == 0) {
            throw new NntpNotConnectedException();
        }
       
        Thread t = new Thread() {
            // get first connection
            private NNTPConnection con = usedConnections.get(0);
            public void run() {
                //TODO get article in RFC format
                try {
                    PrintWriter pw = new PrintWriter(con.post());
                    pw.write(content);
                    fireArticleSent();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        };
        t.start();
    }
   
    public void read(Group group) {
        HibernateUtils.markRead(group, true);
    }
   
    public void unread(Group group) {
        HibernateUtils.markRead(group, false);
    }
   
    public void subscribe(Group group) {
        HibernateUtils.subscribe(group, true);
    }
   
    public void unsubscribe(Group group) {
        HibernateUtils.subscribe(group, false);
       
    }
   
    public void update(final Group group) throws NntpNotConnectedException {
        // TODO get new articles for group
        if(usedConnections.size() == 0) {
            throw new NntpNotConnectedException();
        }
       
        // TODO start a thread to get list of articles
        Thread t = new Thread() {
            // get first connection
            private NNTPConnection con = usedConnections.get(0);
            public void run() {
                LineIterator ait;
                try {
                    ait = con.newNews(group.getName(), group.getLastUpdate(), null);
                    System.out.println("NEW NEWS: ");
                    while(ait.hasNext()) {
                        //TODO get new articles for this group
                        System.out.println(ait.nextLine());
                    }
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        };
        t.start();
        // TODO change group update date
        group.setLastUpdate(new Date());
    }

    public void newGroups(final Date date) throws NntpNotConnectedException {
        // TODO get new groups
        if(usedConnections.size() == 0) {
            throw new NntpNotConnectedException();
        }
       
        // TODO start a thread to get list of articles
        Thread t = new Thread() {
            // get first connection
            private NNTPConnection con = usedConnections.get(0);
            public void run() {
                LineIterator lit;
                try {
                    lit = con.newGroups(date, null);
                    System.out.println("NEW NEWS: ");
                    while(lit.hasNext()) {
                        //TODO get new groups
                        System.out.println(lit.nextLine());
                        //TODO fire NewGroupEvent
                    }
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        };
        t.start();
    }

    public void getArticles(String groupname) {
        // TODO convert groupname to Group
        Group group;
        //TODO lookup group
        group = HibernateUtils.getGroup(groupname);
        try {
            getArticles(group);
        } catch (NntpNotConnectedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
   
    /**
     * Extract informations from plain text article.<br/>
     * <br/>
     * Splits on \n\n for Header/Body separation and uses the start words
     * for header recognition. This is hardcoded from RFC and must not be
     * changed.<br/>
     * <br/>
     * TODO make sure extract() works even for HEAD/BODY only
     *
     * @param content
     * @return
     */
    private static Article extract(String content) {
        Article a = new Article();
        content = content.replaceAll("\\r", "");
        int pos = content.indexOf("\n\n");
        // get body
        String body;
        pos = content.indexOf("\n\n");
        // get headers and body
        if(pos != -1) {
            String[] headers = content.substring(0, pos).split("\\n");
            a.setHeaders(headers);
            body = content.substring(pos);
        } else {
            body = content;
        }
       
        // cut signature from body
        pos = body.indexOf("-- ");
        if(pos != -1) {
            String tmp = body.substring(pos + 3).trim();
            a.setSignature(tmp);
            tmp = body.substring(0, pos);
            body = tmp;
        }
       
        a.setText(body.trim());
       
        return a;
    }

    public void getArticles(final Group g, final Date lastUpdate) throws NntpNotConnectedException {
        //TODO get all articles from group since lastUpdate
        if(usedConnections.size() == 0) {
            throw new NntpNotConnectedException();
        }
       
        // TODO start a thread to get list of articles
//        Thread t = new Thread() {
            // get first connection
            NNTPConnection con = usedConnections.get(0);
            Stack<Integer> articlesIds = new Stack<Integer>();
           
//            public void run() {
                try {
                    ArticleNumberIterator ait = con.listGroup(g.getName());
                    while(ait.hasNext()) {
                        Integer id = (Integer) ait.next();
                        System.out.println("Got article ID '" + id + "'");
                        //TODO check if ArticleResponse, int articleID or Article is returned
                        articlesIds.push(id);
//                        Thread.sleep(2);
                    }
                   
                    for (Integer id : articlesIds) {
//                        System.out.println("Reading article '" + id + "'");
                        ArticleResponse a = (ArticleResponse) con.article(id);
                        StringWriter sw = new StringWriter();
                        PrintWriter pw = new PrintWriter(sw);
                        BufferedReader br = new BufferedReader(new InputStreamReader(a.in));
                        String line = null;
                        while((line = br.readLine()) != null) {
//                            System.out.println("line: " + line);
                            pw.println(line);
                        }
                        final Article article = extract(sw.toString());
//                        Article article = new Article();
//                        article.setMessageId(a.messageId);
//                        //TODO use real subject
//                        article.setSubject(a.messageId);
//                        article.setText(sw.toString());
//                        System.out.println("Article: " + article);
                        //TODO update article attributes
                        HibernateUtils.addArticle(g, article);
                        SwingUtilities.invokeLater(new Runnable() {
                            public void run() {
                                fireArticleLoaded(article);
                            }
                        });
                        Thread.sleep(5);
                    }
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
//        };
//        t.start();
//    }
   
    public static void main(String[] args) {
        try {
            Article a = extract(FileUtils.getFileContents(args[0]));
            System.out.println("This is what I got:");
            System.out.println("Subject:\n'" + a.getSubject() + "'");
            System.out.println("Author:\n'" + a.getAuthor() + "'");
            System.out.println("Sent:\n'" + a.getSent() + "'");
            System.out.println("Message-ID:\n'" + a.getMessageId() + "'");
            System.out.println("TEXT:\n" + a.getText());
            System.out.println("SIGNATURE:\n" + a.getSignature());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
TOP

Related Classes of de.kopis.jusenet.nntp.NNTPUtils

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.