001/* 002 * Copyright (c) 2007-2015 Concurrent, Inc. All Rights Reserved. 003 * 004 * Project and contact information: http://www.cascading.org/ 005 * 006 * This file is part of the Cascading project. 007 * 008 * Licensed under the Apache License, Version 2.0 (the "License"); 009 * you may not use this file except in compliance with the License. 010 * You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, software 015 * distributed under the License is distributed on an "AS IS" BASIS, 016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 017 * See the License for the specific language governing permissions and 018 * limitations under the License. 019 */ 020 021package cascading.operation; 022 023import java.beans.ConstructorProperties; 024import java.io.PrintStream; 025 026import cascading.flow.FlowProcess; 027 028/** 029 * Class Debug is a {@link Filter} that will never remove an item from a stream, but will print the Tuple to either 030 * stdout or stderr. 031 * <p/> 032 * Currently, if printFields is true, they will print every 10 Tuples. 033 * <p/> 034 * The frequency that fields and tuples are printed can be set via {@link #setPrintFieldsEvery(int)} and 035 * {@link #setPrintTupleEvery(int)} methods, respectively. 036 */ 037@SuppressWarnings({"UseOfSystemOutOrSystemErr"}) 038public class Debug extends BaseOperation<Long> implements Filter<Long>, PlannedOperation<Long> 039 { 040 static public enum Output 041 { 042 STDOUT, STDERR 043 } 044 045 /** Field output */ 046 private Output output = Output.STDERR; 047 /** Field prefix */ 048 private String prefix = null; 049 /** Field printFields */ 050 private boolean printFields = false; 051 052 /** Field printFieldsEvery */ 053 private int printFieldsEvery = 10; 054 /** Field printTupleEvery */ 055 private int printTupleEvery = 1; 056 057 /** 058 * Constructor Debug creates a new Debug instance that prints to stderr by default, and does not print 059 * the Tuple instance field names. 060 */ 061 public Debug() 062 { 063 } 064 065 /** 066 * Constructor Debug creates a new Debug instance that prints to stderr by default, and does not print 067 * the Tuple instance field names. 068 * 069 * @param prefix of type String 070 */ 071 @ConstructorProperties({"prefix"}) 072 public Debug( String prefix ) 073 { 074 this.prefix = prefix; 075 } 076 077 /** 078 * Constructor Debug creates a new Debug instance that prints to stderr and will print the current 079 * Tuple instance field names if printFields is true. 080 * 081 * @param prefix of type String 082 * @param printFields of type boolean 083 */ 084 @ConstructorProperties({"prefix", "printFields"}) 085 public Debug( String prefix, boolean printFields ) 086 { 087 this.prefix = prefix; 088 this.printFields = printFields; 089 } 090 091 /** 092 * Constructor Debug creates a new Debug instance that prints to stderr and will print the current 093 * Tuple instance field names if printFields is true. 094 * 095 * @param printFields of type boolean 096 */ 097 @ConstructorProperties({"printFields"}) 098 public Debug( boolean printFields ) 099 { 100 this.printFields = printFields; 101 } 102 103 /** 104 * Constructor Debug creates a new Debug instance that prints to the declared stream and does not print the Tuple 105 * field names. 106 * 107 * @param output of type Output 108 */ 109 @ConstructorProperties({"output"}) 110 public Debug( Output output ) 111 { 112 this.output = output; 113 } 114 115 /** 116 * Constructor Debug creates a new Debug instance that prints to the declared stream and does not print the Tuple 117 * field names. 118 * 119 * @param output of type Output 120 * @param prefix of type String 121 */ 122 @ConstructorProperties({"output", "prefix"}) 123 public Debug( Output output, String prefix ) 124 { 125 this.output = output; 126 this.prefix = prefix; 127 } 128 129 /** 130 * Constructor Debug creates a new Debug instance that prints to the declared stream and will print the Tuple instances 131 * field names if printFields is true. 132 * 133 * @param output of type Output 134 * @param prefix of type String 135 * @param printFields of type boolean 136 */ 137 @ConstructorProperties({"output", "prefix", "printFields"}) 138 public Debug( Output output, String prefix, boolean printFields ) 139 { 140 this.output = output; 141 this.prefix = prefix; 142 this.printFields = printFields; 143 } 144 145 /** 146 * Constructor Debug creates a new Debug instance that prints to the declared stream and will print the Tuple instances 147 * field names if printFields is true. 148 * 149 * @param output of type Output 150 * @param printFields of type boolean 151 */ 152 @ConstructorProperties({"output", "printFields"}) 153 public Debug( Output output, boolean printFields ) 154 { 155 this.output = output; 156 this.printFields = printFields; 157 } 158 159 public Output getOutput() 160 { 161 return output; 162 } 163 164 public String getPrefix() 165 { 166 return prefix; 167 } 168 169 public boolean isPrintFields() 170 { 171 return printFields; 172 } 173 174 /** 175 * Method getPrintFieldsEvery returns the printFieldsEvery interval value of this Debug object. 176 * 177 * @return the printFieldsEvery (type int) of this Debug object. 178 */ 179 public int getPrintFieldsEvery() 180 { 181 return printFieldsEvery; 182 } 183 184 /** 185 * Method setPrintFieldsEvery sets the printFieldsEvery interval value of this Debug object. 186 * 187 * @param printFieldsEvery the printFieldsEvery of this Debug object. 188 */ 189 public void setPrintFieldsEvery( int printFieldsEvery ) 190 { 191 this.printFieldsEvery = printFieldsEvery; 192 } 193 194 /** 195 * Method getPrintTupleEvery returns the printTupleEvery interval value of this Debug object. 196 * 197 * @return the printTupleEvery (type int) of this Debug object. 198 */ 199 public int getPrintTupleEvery() 200 { 201 return printTupleEvery; 202 } 203 204 /** 205 * Method setPrintTupleEvery sets the printTupleEvery interval value of this Debug object. 206 * 207 * @param printTupleEvery the printTupleEvery of this Debug object. 208 */ 209 public void setPrintTupleEvery( int printTupleEvery ) 210 { 211 this.printTupleEvery = printTupleEvery; 212 } 213 214 @Override 215 public boolean supportsPlannerLevel( PlannerLevel plannerLevel ) 216 { 217 return plannerLevel instanceof DebugLevel; 218 } 219 220 @Override 221 public void prepare( FlowProcess flowProcess, OperationCall<Long> operationCall ) 222 { 223 super.prepare( flowProcess, operationCall ); 224 225 operationCall.setContext( 0L ); 226 } 227 228 /** @see Filter#isRemove(cascading.flow.FlowProcess, FilterCall) */ 229 public boolean isRemove( FlowProcess flowProcess, FilterCall<Long> filterCall ) 230 { 231 PrintStream stream = output == Output.STDOUT ? System.out : System.err; 232 233 if( printFields && filterCall.getContext() % printFieldsEvery == 0 ) 234 print( stream, filterCall.getArguments().getFields().print() ); 235 236 if( filterCall.getContext() % printTupleEvery == 0 ) 237 print( stream, filterCall.getArguments().getTuple().print() ); 238 239 filterCall.setContext( filterCall.getContext() + 1 ); 240 241 return false; 242 } 243 244 @Override 245 public void cleanup( FlowProcess flowProcess, OperationCall<Long> longOperationCall ) 246 { 247 if( longOperationCall.getContext() == null ) 248 return; 249 250 PrintStream stream = output == Output.STDOUT ? System.out : System.err; 251 252 print( stream, "tuples count: " + longOperationCall.getContext().toString() ); 253 } 254 255 private void print( PrintStream stream, String message ) 256 { 257 if( prefix != null ) 258 { 259 stream.print( prefix ); 260 stream.print( ": " ); 261 } 262 263 stream.println( message ); 264 } 265 266 @Override 267 public boolean equals( Object object ) 268 { 269 if( this == object ) 270 return true; 271 if( !( object instanceof Debug ) ) 272 return false; 273 if( !super.equals( object ) ) 274 return false; 275 276 Debug debug = (Debug) object; 277 278 if( printFields != debug.printFields ) 279 return false; 280 if( printFieldsEvery != debug.printFieldsEvery ) 281 return false; 282 if( printTupleEvery != debug.printTupleEvery ) 283 return false; 284 if( output != debug.output ) 285 return false; 286 if( prefix != null ? !prefix.equals( debug.prefix ) : debug.prefix != null ) 287 return false; 288 289 return true; 290 } 291 292 @Override 293 public int hashCode() 294 { 295 int result = super.hashCode(); 296 result = 31 * result + ( output != null ? output.hashCode() : 0 ); 297 result = 31 * result + ( prefix != null ? prefix.hashCode() : 0 ); 298 result = 31 * result + ( printFields ? 1 : 0 ); 299 result = 31 * result + printFieldsEvery; 300 result = 31 * result + printTupleEvery; 301 return result; 302 } 303 }