JoscarTester.java :  » Messenger » joscar » net » kano » joscardemo » Java Open Source

Java Open Source » Messenger » joscar 
joscar » net » kano » joscardemo » JoscarTester.java
/*
 *  Copyright (c) 2002-2003, The Joust Project
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *  - Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  - Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  - Neither the name of the Joust Project nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 *  File created by keith @ Mar 25, 2003
 *
 */

package net.kano.joscardemo;

import net.kano.joscar.ByteBlock;
import net.kano.joscar.OscarTools;
import net.kano.joscar.SeqNum;
import net.kano.joscar.flapcmd.SnacCommand;
import net.kano.joscar.net.ConnDescriptor;
import net.kano.joscar.snac.SnacRequest;
import net.kano.joscar.snac.SnacRequestListener;
import net.kano.joscar.snaccmd.FullRoomInfo;
import net.kano.joscar.snaccmd.FullUserInfo;
import net.kano.joscar.snaccmd.chat.ChatMsg;
import net.kano.joscar.snaccmd.conn.ServiceRequest;
import net.kano.joscar.snaccmd.icbm.OldIconHashInfo;
import net.kano.joscar.snaccmd.icbm.SendImIcbm;
import net.kano.joscar.snaccmd.rooms.JoinRoomCmd;
import net.kano.joscardemo.security.SecureSession;
import net.kano.joscardemo.security.SecureSessionException;
import net.kano.joustsim.Screenname;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.NumberFormat;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.ConsoleHandler;
import java.util.logging.Formatter;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class JoscarTester implements CmdLineListener, ServiceListener {
    public static byte[] hashIcon(String filename) throws IOException {
        FileInputStream in = new FileInputStream(filename);
        try {
            byte[] block = new byte[1024];
            MessageDigest md;
            try {
                md = MessageDigest.getInstance("MD5");
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
                return null;
            }
            for (;;) {
                int count = in.read(block);
                if (count == -1) break;

                md.update(block, 0, count);
            }
            return md.digest();
        } finally {
            in.close();
        }
    }

    private static final int DEFAULT_SERVICE_PORT = 5190;

    private CLHandler clHandler = new CLHandler(this);

    private String sn = null;
    private String pass = null;
    private int uin = -1;
    private SeqNum icqSeqNum = new SeqNum(0, Integer.MAX_VALUE);

    private LoginConn loginConn = null;
    private BosFlapConn bosConn = null;
    private Set<ServiceConn> services = new HashSet<ServiceConn>();
    private Map<String,ChatConn> chats = new HashMap<String, ChatConn>();

    private NumberFormat formatter = NumberFormat.getNumberInstance();
    { // init
        formatter.setGroupingUsed(true);
        formatter.setMaximumFractionDigits(1);
    }

    private SecureSession secureSession = SecureSession.getInstance();
    private String aimExp = "the60s";

    private String mb(long bytes) {
        float divby;
        String suffix;

        if (bytes > 1000000) {
            divby = 1048576.0f;
            suffix = "MB";

        } else {
            divby = 1024.0f;
            suffix = "KB";
        }

        return formatter.format(bytes / divby) + suffix;
    }


    public JoscarTester(String sn, String pass) {
        new CmdLineReader(this);
        this.sn = sn;
        this.pass = pass;
        try {
            this.uin = Integer.parseInt(this.sn);
        }
        catch(NumberFormatException ex) {
            this.uin = -1;
        }
    }

    public String getScreenname() { return sn; }

    public String getPassword() { return pass; }

    public int getUIN() {
        if (uin == -1) {
            throw new IllegalStateException("Not connected to ICQ");
        }
        return uin;
    }

    public long nextIcqId() { return icqSeqNum.next(); }

    public void connect() {
        ConnDescriptor cd = new ConnDescriptor("login.oscar.aol.com",
                DEFAULT_SERVICE_PORT);
        loginConn = new LoginConn(cd, this);
        loginConn.connect();
    }

    void loginFailed(String reason) {
        System.err.println("login failed: " + reason);
    }

    void setScreennameFormat(String screenname) {
        sn = screenname;
    }

    void startBosConn(String server, int port, ByteBlock cookie) {
        bosConn = new BosFlapConn(new ConnDescriptor(server, port), this, cookie);
        bosConn.connect();
    }

    void registerSnacFamilies(BasicConn conn) {
        snacMgr.register(conn);
    }

    public void connectToService(int snacFamily, String host, ByteBlock cookie) {
        ConnDescriptor cd = new ConnDescriptor(host, DEFAULT_SERVICE_PORT);
        ServiceConn conn = new ServiceConn(cd, this, cookie, snacFamily);

        conn.connect();
    }

    public void serviceFailed(ServiceConn conn) {
    }

    public void serviceConnected(ServiceConn conn) {
        services.add(conn);
    }

    public void serviceReady(ServiceConn conn) {
        snacMgr.dequeueSnacs(conn);
    }

    public void serviceDied(ServiceConn conn) {
        services.remove(conn);
        snacMgr.unregister(conn);
    }

    public void joinChat(int exchange, String roomname) {
        FullRoomInfo roomInfo
                = new FullRoomInfo(exchange, roomname, "us-ascii", "en");
        handleRequest(new SnacRequest(new JoinRoomCmd(roomInfo), null));
    }

    void connectToChat(FullRoomInfo roomInfo, String host,
            ByteBlock cookie) {
        ConnDescriptor cd = new ConnDescriptor(host, DEFAULT_SERVICE_PORT);
        ChatConn conn = new ChatConn(cd, this, cookie, roomInfo);

        conn.addChatListener(new MyChatConnListener());

        conn.connect();
    }

    public ChatConn getChatConn(String name) {
        return chats.get(Screenname.normalize(name));
    }

    private SnacManager snacMgr = new SnacManager(new PendingSnacListener() {
        public void dequeueSnacs(List<SnacRequest> pending) {
            System.out.println("dequeuing " + pending.size() + " snacs");
            for (SnacRequest request : pending) {
                handleRequest(request);
            }
        }
    });

    synchronized void handleRequest(SnacRequest request) {
        int family = request.getCommand().getFamily();
        if (snacMgr.isPending(family)) {
            snacMgr.addRequest(request);
            return;
        }

        BasicConn conn = snacMgr.getConn(family);

        if (conn != null) {
            conn.sendRequest(request);
        } else {
            // it's time to request a service
            if (!(request.getCommand() instanceof ServiceRequest)) {
                System.out.println("requesting " + Integer.toHexString(family)
                        + " service.");
                snacMgr.setPending(family, true);
                snacMgr.addRequest(request);
                request(new ServiceRequest(family));
            } else {
                System.err.println("eep! can't find a service redirector " +
                        "server.");
            }
        }
    }

    public SnacRequest request(SnacCommand cmd) {
        return request(cmd, null);
    }

    private SnacRequest request(SnacCommand cmd, SnacRequestListener listener) {
        SnacRequest req = new SnacRequest(cmd, listener);
        handleRequest(req);
        return req;
    }

    private OldIconHashInfo oldIconInfo;
    private File iconFile = null;
    {
        if (false) {
            // this is not executed
            try {
                ClassLoader classLoader = getClass().getClassLoader();
                URL iconResource = classLoader.getResource("images/beck.gif");
                String ext = iconResource.toExternalForm();
                System.out.println("ext: " + ext);
                URI uri = new URI(ext);
                iconFile = new File(uri);
                oldIconInfo = new OldIconHashInfo(iconFile);
            } catch (IOException e) {
                e.printStackTrace();
            } catch (URISyntaxException e) {
                e.printStackTrace();
            }
        }
    }

    public OldIconHashInfo getOldIconInfo() { return oldIconInfo; }

    private static final Pattern cmdRE = Pattern.compile(
            "\\s*(?:\"(.*?[^\\\\]?)\"|(\\S+))(?:\\s|$)");

    public void processCmd(CmdLineReader reader, String line) {
        Matcher m = cmdRE.matcher(line);
        LinkedList<String> arglist = new LinkedList<String>();
        while (m.find()) {
            String arg = m.group(1);
            if (arg == null) arg = m.group(2);
            if (arg == null) {
                System.err.println("Error: line parser failed to read "
                        + "arguments");
                return;
            }
            arglist.add(arg);
        }

        if (arglist.isEmpty()) return;

        String cmd = arglist.removeFirst();

        CLCommand handler = clHandler.getCommand(cmd);

        if (handler == null) {
            System.err.println("!! There is no command called '" + cmd + "'");
            System.err.println("!! Try typing 'help'");
        } else {
            try {
                handler.handle(this, line, cmd, arglist);
            } catch (Throwable t) {
                System.err.println("!! Error executing command '" + cmd + "'!");
                System.err.println("!! Try typing 'help " + cmd + "'");
                System.err.println("!! Stack trace of error:");
                t.printStackTrace();
                System.err.println("!! Try typing 'help " + cmd + "'");
            }
        }
    }

    public void printMemUsage() {
        Runtime runtime = Runtime.getRuntime();
        long total = runtime.totalMemory();
        long free = runtime.freeMemory();
        System.out.println("Using " + mb(total-free) + " memory of "
                + mb(total) + " allocated");
    }

    public void sendIM(String nick, String text) {
        request(new SendImIcbm(nick, text));
    }

    public SecureSession getSecureSession() { return secureSession; }

    public void setAimExp(String aimExp) { this.aimExp = aimExp; }

    public String getAimExp() { return aimExp; }

    public BasicConn getBosConn() { return bosConn; }

    private class MyChatConnListener implements ChatConnListener {
        public void connFailed(ChatConn conn, Object reason) { }

        public void connected(ChatConn conn) { }

        public void joined(ChatConn conn, List<FullUserInfo> members) {
            String name = conn.getRoomInfo().getName();
            chats.put(Screenname.normalize(name), conn);

            System.out.println("*** Joined "
                    + conn.getRoomInfo().getRoomName() + ", members:");
            for (FullUserInfo member : members) {
                System.out.println("  " + member.getScreenname());
            }
        }

        public void left(ChatConn conn, Object reason) {
            String name = conn.getRoomInfo().getName();
            chats.remove(Screenname.normalize(name));

            System.out.println("*** Left "
                    + conn.getRoomInfo().getRoomName());
        }

        public void usersJoined(ChatConn conn, List<FullUserInfo> members) {
            for (FullUserInfo member : members) {
                System.out.println("*** " + member.getScreenname()
                        + " joined " + conn.getRoomInfo().getRoomName());
            }
        }

        public void usersLeft(ChatConn conn, List<FullUserInfo> members) {
            for (FullUserInfo member : members) {
                System.out.println("*** " + member.getScreenname()
                        + " left " + conn.getRoomInfo().getRoomName());
            }
        }

        public void gotMsg(ChatConn conn, FullUserInfo sender,
                ChatMsg msg) {
            String msgStr = msg.getMessage();
            String ct = msg.getContentType();
            if (msgStr == null && ct.equals(ChatMsg.CONTENTTYPE_SECURE)) {
                ByteBlock msgData = msg.getMessageData();

                try {
                    msgStr = secureSession.parseChatMessage(conn.getRoomName(),
                            sender.getScreenname(), msgData);
                } catch (SecureSessionException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("<" + sender.getScreenname()
                    + ":#" + conn.getRoomInfo().getRoomName() + "> "
                    + OscarTools.stripHtml(msgStr));
        }


    }

    public static void main(String[] args) throws IOException {
        String screenname;
        String password;
        if (args.length != 2) {
            BufferedReader reader = new BufferedReader(
                new InputStreamReader(System.in));
            System.out.print("Screenname: ");
            screenname = reader.readLine();
            System.out.print("Password: ");
            password = reader.readLine();
        } else {
            screenname = args[0];
            password = args[1];
        }
        String levelstr = "fine";
        System.out.println("Connecting to AIM as " + screenname + "...");

        ConsoleHandler handler = new ConsoleHandler();
        handler.setFormatter(new Formatter() {
          private String lineSeparator = System.getProperty("line.separator");

          public String format(LogRecord record) {
            StringBuffer sb = new StringBuffer();
            sb.append("[");
            sb.append(record.getLevel().getLocalizedName());
            sb.append("] ");
            sb.append(record.getMessage());
            sb.append(lineSeparator);

            if (record.getThrown() != null) {
              try {
                StringWriter sw = new StringWriter();
                PrintWriter pw = new PrintWriter(sw);
                record.getThrown().printStackTrace(pw);
                pw.close();
                sb.append(sw.toString());
              } catch (Exception ex) {
                // SimpleFormatter in the JDK does this, so I do too
              }
            }
            return sb.toString();
          }
        });
        Level level = Level.parse(levelstr.toUpperCase());
        handler.setLevel(level);
        Logger logger = Logger.getLogger("net.kano.joscar");
        logger.addHandler(handler);
        logger.setLevel(Level.ALL);

        final JoscarTester tester = new JoscarTester(screenname, password);
        tester.connect();

        new Timer(true).scheduleAtFixedRate(new TimerTask() {
          public void run() {
            tester.printMemUsage();
          }
        },
                30 * 1000, 5 * 60 * 1000);
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.