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    
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    
032    public 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        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        public void protocolReplyReceived(ProtocolCommandEvent event)
192        {
193            if (__directionMarker) {
194                __writer.print("< ");
195            }
196            __writer.print(event.getMessage());
197            __writer.flush();
198        }
199    }
200