001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2006-2009 Sun Microsystems, Inc. 015 * Portions Copyright 2014-2015 ForgeRock AS. 016 */ 017package org.opends.server.types; 018 019import org.forgerock.opendj.ldap.ByteString; 020import org.forgerock.opendj.ldap.ByteStringBuilder; 021 022import java.io.InputStream; 023import java.io.IOException; 024 025/** 026 * A wrapper InputStream that will record all reads from an underlying 027 * InputStream. The recorded bytes will append to any previous 028 * recorded bytes until the clear method is called. 029 */ 030public class RecordingInputStream extends InputStream 031{ 032 private boolean enableRecording; 033 private InputStream parentStream; 034 private ByteStringBuilder buffer; 035 036 /** 037 * Constructs a new RecordingInputStream that will record all reads 038 * from the given input stream. 039 * 040 * @param parentStream The input stream to record. 041 */ 042 public RecordingInputStream(InputStream parentStream) 043 { 044 this.enableRecording = false; 045 this.parentStream = parentStream; 046 this.buffer = new ByteStringBuilder(32); 047 } 048 049 /** {@inheritDoc} */ 050 @Override 051 public int read() throws IOException { 052 int readByte = parentStream.read(); 053 if(enableRecording) 054 { 055 buffer.appendByte(readByte); 056 } 057 return readByte; 058 } 059 060 /** {@inheritDoc} */ 061 @Override 062 public int read(byte[] bytes) throws IOException { 063 int bytesRead = parentStream.read(bytes); 064 if(enableRecording) 065 { 066 buffer.appendBytes(bytes, 0, bytesRead); 067 } 068 return bytesRead; 069 } 070 071 /** {@inheritDoc} */ 072 @Override 073 public int read(byte[] bytes, int i, int i1) throws IOException { 074 int bytesRead = parentStream.read(bytes, i, i1); 075 if(enableRecording) 076 { 077 buffer.appendBytes(bytes, i, bytesRead); 078 } 079 return bytesRead; 080 } 081 082 /** {@inheritDoc} */ 083 @Override 084 public long skip(long l) throws IOException { 085 return parentStream.skip(l); 086 } 087 088 /** {@inheritDoc} */ 089 @Override 090 public int available() throws IOException { 091 return parentStream.available(); 092 } 093 094 /** {@inheritDoc} */ 095 @Override 096 public void close() throws IOException { 097 parentStream.close(); 098 } 099 100 /** {@inheritDoc} */ 101 @Override 102 public void mark(int i) { 103 parentStream.mark(i); 104 } 105 106 /** {@inheritDoc} */ 107 @Override 108 public void reset() throws IOException { 109 parentStream.reset(); 110 } 111 112 /** {@inheritDoc} */ 113 @Override 114 public boolean markSupported() { 115 return parentStream.markSupported(); 116 } 117 118 /** 119 * Retrieve the bytes read from this input stream since the last 120 * clear. 121 * 122 * @return the bytes read from this input stream since the last 123 * clear. 124 */ 125 public ByteString getRecordedBytes() { 126 return buffer.toByteString(); 127 } 128 129 /** 130 * Clear the bytes currently recorded by this input stream. 131 */ 132 public void clearRecordedBytes() { 133 buffer.clear(); 134 } 135 136 /** 137 * Retrieves whether recording is enabled. 138 * 139 * @return whether recording is enabled. 140 */ 141 public boolean isRecordingEnabled() 142 { 143 return enableRecording; 144 } 145 146 /** 147 * Set whether if this input stream is recording all reads or not. 148 * 149 * @param enabled <code>true</code> to recording all reads or 150 * <code>false</code> otherwise. 151 */ 152 public void setRecordingEnabled(boolean enabled) 153 { 154 this.enableRecording = enabled; 155 } 156}