    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 *
    028 * @since 2.0
    029 ***/
    030
    031public class PrintCommandListener implements ProtocolCommandListener
    032{
    033    private final PrintWriter __writer;
    034    private final boolean __nologin;
    035    private final char __eolMarker;
    036    private final boolean __directionMarker;
    037
    038    /**
    039     * Create the default instance which prints everything.
    040     *
    041     * @param stream where to write the commands and responses
    042     * e.g. System.out
    043     * @since 3.0
    044     */
    045    public PrintCommandListener(PrintStream stream)
    046    {
    047        this(new PrintWriter(stream));
    048    }
    049
    050    /**
    051     * Create an instance which optionally suppresses login command text
    052     * and indicates where the EOL starts with the specified character.
    053     *
    054     * @param stream where to write the commands and responses
    055     * @param suppressLogin if {@code true}, only print command name for login
    056     *
    057     * @since 3.0
    058     */
    059    public PrintCommandListener(PrintStream stream, boolean suppressLogin) {
    060        this(new PrintWriter(stream), suppressLogin);
    061    }
    062
    063    /**
    064     * Create an instance which optionally suppresses login command text
    065     * and indicates where the EOL starts with the specified character.
    066     *
    067     * @param stream where to write the commands and responses
    068     * @param suppressLogin if {@code true}, only print command name for login
    069     * @param eolMarker if non-zero, add a marker just before the EOL.
    070     *
    071     * @since 3.0
    072     */
    073    public PrintCommandListener(PrintStream stream, boolean suppressLogin, char eolMarker) {
    074        this(new PrintWriter(stream), suppressLogin, eolMarker);
    075    }
    076
    077    /**
    078     * Create an instance which optionally suppresses login command text
    079     * and indicates where the EOL starts with the specified character.
    080     *
    081     * @param stream where to write the commands and responses
    082     * @param suppressLogin if {@code true}, only print command name for login
    083     * @param eolMarker if non-zero, add a marker just before the EOL.
    084     * @param showDirection if {@code true}, add {@code "> "} or {@code "< "} as appropriate to the output
    085     *
    086     * @since 3.0
    087     */
    088    public PrintCommandListener(PrintStream stream, boolean suppressLogin, char eolMarker, boolean showDirection) {
    089        this(new PrintWriter(stream), suppressLogin, eolMarker, showDirection);
    090    }
    091
    092    /**
    093     * Create the default instance which prints everything.
    094     *
    095     * @param writer where to write the commands and responses
    096     */
    097    public PrintCommandListener(PrintWriter writer)
    098    {
    099        this(writer, false);
    100    }
    101
    102    /**
    103     * Create an instance which optionally suppresses login command text.
    104     *
    105     * @param writer where to write the commands and responses
    106     * @param suppressLogin if {@code true}, only print command name for login
    107     *
    108     * @since 3.0
    109     */
    110    public PrintCommandListener(PrintWriter writer, boolean suppressLogin)
    111    {
    112        this(writer, suppressLogin, (char) 0);
    113    }
    114
    115    /**
    116     * Create an instance which optionally suppresses login command text
    117     * and indicates where the EOL starts with the specified character.
    118     *
    119     * @param writer where to write the commands and responses
    120     * @param suppressLogin if {@code true}, only print command name for login
    121     * @param eolMarker if non-zero, add a marker just before the EOL.
    122     *
    123     * @since 3.0
    124     */
    125    public PrintCommandListener(PrintWriter writer, boolean suppressLogin, char eolMarker)
    126    {
    127        this(writer, suppressLogin, eolMarker, false);
    128    }
    129
    130    /**
    131     * Create an instance which optionally suppresses login command text
    132     * and indicates where the EOL starts with the specified character.
    133     *
    134     * @param writer where to write the commands and responses
    135     * @param suppressLogin if {@code true}, only print command name for login
    136     * @param eolMarker if non-zero, add a marker just before the EOL.
    137     * @param showDirection if {@code true}, add {@code ">} " or {@code "< "} as appropriate to the output
    138     *
    139     * @since 3.0
    140     */
    141    public PrintCommandListener(PrintWriter writer, boolean suppressLogin, char eolMarker, boolean showDirection)
    142    {
    143        __writer = writer;
    144        __nologin = suppressLogin;
    145        __eolMarker = eolMarker;
    146        __directionMarker = showDirection;
    147    }
    148
    149    @Override
    150    public void protocolCommandSent(ProtocolCommandEvent event)
    151    {
    152        if (__directionMarker) {
    153            __writer.print("> ");
    154        }
    155        if (__nologin) {
    156            String cmd = event.getCommand();
    157            if ("PASS".equalsIgnoreCase(cmd) || "USER".equalsIgnoreCase(cmd)) {
    158                __writer.print(cmd);
    159                __writer.println(" *******"); // Don't bother with EOL marker for this!
    160            } else {
    161                final String IMAP_LOGIN = "LOGIN";
    162                if (IMAP_LOGIN.equalsIgnoreCase(cmd)) { // IMAP
    163                    String msg = event.getMessage();
    164                    msg=msg.substring(0, msg.indexOf(IMAP_LOGIN)+IMAP_LOGIN.length());
    165                    __writer.print(msg);
    166                    __writer.println(" *******"); // Don't bother with EOL marker for this!
    167                } else {
    168                    __writer.print(getPrintableString(event.getMessage()));
    169                }
    170            }
    171        } else {
    172            __writer.print(getPrintableString(event.getMessage()));
    173        }
    174        __writer.flush();
    175    }
    176
    177    private String getPrintableString(String msg){
    178        if (__eolMarker == 0) {
    179            return msg;
    180        }
    181        int pos = msg.indexOf(SocketClient.NETASCII_EOL);
    182        if (pos > 0) {
    183            StringBuilder sb = new StringBuilder();
    184            sb.append(msg.substring(0,pos));
    185            sb.append(__eolMarker);
    186            sb.append(msg.substring(pos));
    187            return sb.toString();
    188        }
    189        return msg;
    190    }
    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