    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *      http://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017
    018package org.apache.commons.net;
    019
    020import java.io.PrintStream;
    021import java.io.PrintWriter;
    022
    023/***
    024 * This is a support class for some of the example programs.  It is
    025 * a sample implementation of the ProtocolCommandListener interface
    026 * which just prints out to a specified stream all command/reply traffic.
    027 * <p>
    028 *
    029 * @since 2.0
    030 ***/
    031
    032public class PrintCommandListener implements ProtocolCommandListener
    033{
    034    private final PrintWriter __writer;
    035    private final boolean __nologin;
    036    private final char __eolMarker;
    037    private final boolean __directionMarker;
    038
    039    /**
    040     * Create the default instance which prints everything.
    041     *
    042     * @param stream where to write the commands and responses
    043     * e.g. System.out
    044     * @since 3.0
    045     */
    046    public PrintCommandListener(PrintStream stream)
    047    {
    048        this(new PrintWriter(stream));
    049    }
    050
    051    /**
    052     * Create an instance which optionally suppresses login command text
    053     * and indicates where the EOL starts with the specified character.
    054     *
    055     * @param stream where to write the commands and responses
    056     * @param suppressLogin if {@code true}, only print command name for login
    057     *
    058     * @since 3.0
    059     */
    060    public PrintCommandListener(PrintStream stream, boolean suppressLogin) {
    061        this(new PrintWriter(stream), suppressLogin);
    062    }
    063
    064    /**
    065     * Create an instance which optionally suppresses login command text
    066     * and indicates where the EOL starts with the specified character.
    067     *
    068     * @param stream where to write the commands and responses
    069     * @param suppressLogin if {@code true}, only print command name for login
    070     * @param eolMarker if non-zero, add a marker just before the EOL.
    071     *
    072     * @since 3.0
    073     */
    074    public PrintCommandListener(PrintStream stream, boolean suppressLogin, char eolMarker) {
    075        this(new PrintWriter(stream), suppressLogin, eolMarker);
    076    }
    077
    078    /**
    079     * Create an instance which optionally suppresses login command text
    080     * and indicates where the EOL starts with the specified character.
    081     *
    082     * @param stream where to write the commands and responses
    083     * @param suppressLogin if {@code true}, only print command name for login
    084     * @param eolMarker if non-zero, add a marker just before the EOL.
    085     * @param showDirection if {@code true}, add "> " or "< " as appropriate to the output
    086     *
    087     * @since 3.0
    088     */
    089    public PrintCommandListener(PrintStream stream, boolean suppressLogin, char eolMarker, boolean showDirection) {
    090        this(new PrintWriter(stream), suppressLogin, eolMarker, showDirection);
    091    }
    092
    093    /**
    094     * Create the default instance which prints everything.
    095     *
    096     * @param writer where to write the commands and responses
    097     */
    098    public PrintCommandListener(PrintWriter writer)
    099    {
    100        this(writer, false);
    101    }
    102
    103    /**
    104     * Create an instance which optionally suppresses login command text.
    105     *
    106     * @param writer where to write the commands and responses
    107     * @param suppressLogin if {@code true}, only print command name for login
    108     *
    109     * @since 3.0
    110     */
    111    public PrintCommandListener(PrintWriter writer, boolean suppressLogin)
    112    {
    113        this(writer, suppressLogin, (char) 0);
    114    }
    115
    116    /**
    117     * Create an instance which optionally suppresses login command text
    118     * and indicates where the EOL starts with the specified character.
    119     *
    120     * @param writer where to write the commands and responses
    121     * @param suppressLogin if {@code true}, only print command name for login
    122     * @param eolMarker if non-zero, add a marker just before the EOL.
    123     *
    124     * @since 3.0
    125     */
    126    public PrintCommandListener(PrintWriter writer, boolean suppressLogin, char eolMarker)
    127    {
    128        this(writer, suppressLogin, eolMarker, false);
    129    }
    130
    131    /**
    132     * Create an instance which optionally suppresses login command text
    133     * and indicates where the EOL starts with the specified character.
    134     *
    135     * @param writer where to write the commands and responses
    136     * @param suppressLogin if {@code true}, only print command name for login
    137     * @param eolMarker if non-zero, add a marker just before the EOL.
    138     * @param showDirection if {@code true}, add "> " or "< " as appropriate to the output
    139     *
    140     * @since 3.0
    141     */
    142    public PrintCommandListener(PrintWriter writer, boolean suppressLogin, char eolMarker, boolean showDirection)
    143    {
    144        __writer = writer;
    145        __nologin = suppressLogin;
    146        __eolMarker = eolMarker;
    147        __directionMarker = showDirection;
    148    }
    149
    150//    @Override
    151    public void protocolCommandSent(ProtocolCommandEvent event)
    152    {
    153        if (__directionMarker) {
    154            __writer.print("> ");
    155        }
    156        if (__nologin) {
    157            String cmd = event.getCommand();
    158            if ("PASS".equalsIgnoreCase(cmd) || "USER".equalsIgnoreCase(cmd)) {
    159                __writer.print(cmd);
    160                __writer.println(" *******"); // Don't bother with EOL marker for this!
    161            } else {
    162                final String IMAP_LOGIN = "LOGIN";
    163                if (IMAP_LOGIN.equalsIgnoreCase(cmd)) { // IMAP
    164                    String msg = event.getMessage();
    165                    msg=msg.substring(0, msg.indexOf(IMAP_LOGIN)+IMAP_LOGIN.length());
    166                    __writer.print(msg);
    167                    __writer.println(" *******"); // Don't bother with EOL marker for this!
    168                } else {
    169                    __writer.print(getPrintableString(event.getMessage()));
    170                }
    171            }
    172        } else {
    173            __writer.print(getPrintableString(event.getMessage()));
    174        }
    175        __writer.flush();
    176    }
    177
    178    private String getPrintableString(String msg){
    179        if (__eolMarker == 0) {
    180            return msg;
    181        }
    182        int pos = msg.indexOf(SocketClient.NETASCII_EOL);
    183        if (pos > 0) {
    184            StringBuilder sb = new StringBuilder();
    185            sb.append(msg.substring(0,pos));
    186            sb.append(__eolMarker);
    187            sb.append(msg.substring(pos));
    188            return sb.toString();
    189        }
    190        return msg;
    191    }
    192//    @Override
    193    public void protocolReplyReceived(ProtocolCommandEvent event)
    194    {
    195        if (__directionMarker) {
    196            __writer.print("< ");
    197        }
    198        __writer.print(event.getMessage());
    199        __writer.flush();
    200    }
    201}
    202