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 023/** 024 * This is a support class for some example programs. It is a sample implementation of the ProtocolCommandListener interface which just prints out to a 025 * specified stream all command/reply traffic. 026 * 027 * @since 2.0 028 */ 029 030public class PrintCommandListener implements ProtocolCommandListener { 031 private final PrintWriter writer; 032 private final boolean nologin; 033 private final char eolMarker; 034 private final boolean directionMarker; 035 036 /** 037 * Create the default instance which prints everything. 038 * 039 * @param stream where to write the commands and responses e.g. System.out 040 * @since 3.0 041 */ 042 public PrintCommandListener(final PrintStream stream) { 043 this(new PrintWriter(stream)); 044 } 045 046 /** 047 * Create an instance which optionally suppresses login command text and indicates where the EOL starts with the specified character. 048 * 049 * @param stream where to write the commands and responses 050 * @param suppressLogin if {@code true}, only print command name for login 051 * 052 * @since 3.0 053 */ 054 public PrintCommandListener(final PrintStream stream, final boolean suppressLogin) { 055 this(new PrintWriter(stream), suppressLogin); 056 } 057 058 /** 059 * Create an instance which optionally suppresses login command text and indicates where the EOL starts with the specified character. 060 * 061 * @param stream where to write the commands and responses 062 * @param suppressLogin if {@code true}, only print command name for login 063 * @param eolMarker if non-zero, add a marker just before the EOL. 064 * 065 * @since 3.0 066 */ 067 public PrintCommandListener(final PrintStream stream, final boolean suppressLogin, final char eolMarker) { 068 this(new PrintWriter(stream), suppressLogin, eolMarker); 069 } 070 071 /** 072 * Create an instance which optionally suppresses login command text and indicates where the EOL starts with the specified character. 073 * 074 * @param stream where to write the commands and responses 075 * @param suppressLogin if {@code true}, only print command name for login 076 * @param eolMarker if non-zero, add a marker just before the EOL. 077 * @param showDirection if {@code true}, add {@code "> "} or {@code "< "} as appropriate to the output 078 * 079 * @since 3.0 080 */ 081 public PrintCommandListener(final PrintStream stream, final boolean suppressLogin, final char eolMarker, final boolean showDirection) { 082 this(new PrintWriter(stream), suppressLogin, eolMarker, showDirection); 083 } 084 085 /** 086 * Create the default instance which prints everything. 087 * 088 * @param writer where to write the commands and responses 089 */ 090 public PrintCommandListener(final PrintWriter writer) { 091 this(writer, false); 092 } 093 094 /** 095 * Create an instance which optionally suppresses login command text. 096 * 097 * @param writer where to write the commands and responses 098 * @param suppressLogin if {@code true}, only print command name for login 099 * 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}