View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.net;
19  
20  import java.io.PrintStream;
21  import java.io.PrintWriter;
22  
23  /**
24   * This is a support class for some example programs. It is a sample implementation of the ProtocolCommandListener interface which just prints out to a
25   * specified stream all command/reply traffic.
26   *
27   * @since 2.0
28   */
29  
30  public class PrintCommandListener implements ProtocolCommandListener {
31      private final PrintWriter writer;
32      private final boolean nologin;
33      private final char eolMarker;
34      private final boolean directionMarker;
35  
36      /**
37       * Create the default instance which prints everything.
38       *
39       * @param stream where to write the commands and responses e.g. System.out
40       * @since 3.0
41       */
42      public PrintCommandListener(final PrintStream stream) {
43          this(new PrintWriter(stream));
44      }
45  
46      /**
47       * Create an instance which optionally suppresses login command text and indicates where the EOL starts with the specified character.
48       *
49       * @param stream        where to write the commands and responses
50       * @param suppressLogin if {@code true}, only print command name for login
51       *
52       * @since 3.0
53       */
54      public PrintCommandListener(final PrintStream stream, final boolean suppressLogin) {
55          this(new PrintWriter(stream), suppressLogin);
56      }
57  
58      /**
59       * Create an instance which optionally suppresses login command text and indicates where the EOL starts with the specified character.
60       *
61       * @param stream        where to write the commands and responses
62       * @param suppressLogin if {@code true}, only print command name for login
63       * @param eolMarker     if non-zero, add a marker just before the EOL.
64       *
65       * @since 3.0
66       */
67      public PrintCommandListener(final PrintStream stream, final boolean suppressLogin, final char eolMarker) {
68          this(new PrintWriter(stream), suppressLogin, eolMarker);
69      }
70  
71      /**
72       * Create an instance which optionally suppresses login command text and indicates where the EOL starts with the specified character.
73       *
74       * @param stream        where to write the commands and responses
75       * @param suppressLogin if {@code true}, only print command name for login
76       * @param eolMarker     if non-zero, add a marker just before the EOL.
77       * @param showDirection if {@code true}, add {@code "> "} or {@code "< "} as appropriate to the output
78       *
79       * @since 3.0
80       */
81      public PrintCommandListener(final PrintStream stream, final boolean suppressLogin, final char eolMarker, final boolean showDirection) {
82          this(new PrintWriter(stream), suppressLogin, eolMarker, showDirection);
83      }
84  
85      /**
86       * Create the default instance which prints everything.
87       *
88       * @param writer where to write the commands and responses
89       */
90      public PrintCommandListener(final PrintWriter writer) {
91          this(writer, false);
92      }
93  
94      /**
95       * Create an instance which optionally suppresses login command text.
96       *
97       * @param writer        where to write the commands and responses
98       * @param suppressLogin if {@code true}, only print command name for login
99       *
100      * @since 3.0
101      */
102     public PrintCommandListener(final PrintWriter writer, final boolean suppressLogin) {
103         this(writer, suppressLogin, (char) 0);
104     }
105 
106     /**
107      * Create an instance which optionally suppresses login command text and indicates where the EOL starts with the specified character.
108      *
109      * @param writer        where to write the commands and responses
110      * @param suppressLogin if {@code true}, only print command name for login
111      * @param eolMarker     if non-zero, add a marker just before the EOL.
112      *
113      * @since 3.0
114      */
115     public PrintCommandListener(final PrintWriter writer, final boolean suppressLogin, final char eolMarker) {
116         this(writer, suppressLogin, eolMarker, false);
117     }
118 
119     /**
120      * Create an instance which optionally suppresses login command text 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      * @param showDirection if {@code true}, add {@code ">} " or {@code "< "} as appropriate to the output
126      *
127      * @since 3.0
128      */
129     public PrintCommandListener(final PrintWriter writer, final boolean suppressLogin, final char eolMarker, final boolean showDirection) {
130         this.writer = writer;
131         this.nologin = suppressLogin;
132         this.eolMarker = eolMarker;
133         this.directionMarker = showDirection;
134     }
135 
136     private String getPrintableString(final String msg) {
137         if (eolMarker == 0) {
138             return msg;
139         }
140         final int pos = msg.indexOf(SocketClient.NETASCII_EOL);
141         if (pos > 0) {
142             final StringBuilder sb = new StringBuilder();
143             sb.append(msg.substring(0, pos));
144             sb.append(eolMarker);
145             sb.append(msg.substring(pos));
146             return sb.toString();
147         }
148         return msg;
149     }
150 
151     @Override
152     public void protocolCommandSent(final ProtocolCommandEvent event) {
153         if (directionMarker) {
154             writer.print("> ");
155         }
156         if (nologin) {
157             final 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     @Override
179     public void protocolReplyReceived(final ProtocolCommandEvent event) {
180         if (directionMarker) {
181             writer.print("< ");
182         }
183         writer.print(event.getMessage());
184         writer.flush();
185     }
186 }