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