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 }