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