001    /*
002     * The MIT License
003     * Copyright (c) 2012 Microsoft Corporation
004     *
005     * Permission is hereby granted, free of charge, to any person obtaining a copy
006     * of this software and associated documentation files (the "Software"), to deal
007     * in the Software without restriction, including without limitation the rights
008     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
009     * copies of the Software, and to permit persons to whom the Software is
010     * furnished to do so, subject to the following conditions:
011     *
012     * The above copyright notice and this permission notice shall be included in
013     * all copies or substantial portions of the Software.
014     *
015     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
016     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
017     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
018     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
019     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
020     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
021     * THE SOFTWARE.
022     */
023    
024    package microsoft.exchange.webservices.data.misc;
025    
026    import microsoft.exchange.webservices.data.core.ExchangeService;
027    import microsoft.exchange.webservices.data.core.request.HangingServiceRequestBase;
028    import microsoft.exchange.webservices.data.core.enumeration.misc.TraceFlags;
029    import org.apache.commons.logging.Log;
030    import org.apache.commons.logging.LogFactory;
031    
032    import javax.xml.stream.XMLStreamException;
033    
034    import java.io.ByteArrayOutputStream;
035    import java.io.IOException;
036    import java.io.InputStream;
037    
038    /**
039     * A stream that traces everything it returns from its Read() call.
040     * That trace may be retrieved at the end of the stream.
041     */
042    public class HangingTraceStream extends InputStream {
043    
044      private static final Log LOG = LogFactory.getLog(HangingTraceStream.class);
045    
046      private final InputStream underlyingStream;
047      private final ExchangeService service;
048      private ByteArrayOutputStream responseCopy;
049    
050      /**
051       * Initializes a new instance of the HangingTraceStream class.
052       *
053       * @param stream  The stream.
054       * @param service the service.
055       */
056      public HangingTraceStream(final InputStream stream, final ExchangeService service) {
057        this.underlyingStream = stream;
058        this.service = service;
059      }
060    
061      /**
062       * Gets a value indicating whether the current stream supports reading.
063       *
064       * @return true
065       */
066      public boolean getCanRead() {
067        return true;
068      }
069    
070      /**
071       * Gets a value indicating whether the current stream supports seeking.
072       *
073       * @return false
074       */
075      public boolean getCanSeek() {
076        return false;
077      }
078    
079      /**
080       * Gets a value indicating whether the current stream supports writing.
081       *
082       * @return false
083       */
084      public boolean getCanWrite() {
085        return false;
086      }
087    
088      /**
089       * When overridden in a derived class, clears all buffers
090       * for this stream and causes any buffered data to be
091       *  written to the underlying device.
092       *@exception An I/O error occurs.
093       */
094            /*
095             * @Override public void close() { // no-op }
096             */
097    
098      /**
099       * When overridden in a derived class, reads a sequence of
100       * bytes from the current stream and advances the
101       * position within the stream by the number of bytes read.
102       *
103       * @param buffer An array of bytes. When this method returns, the buffer
104       *               contains the specified byte array with the values between
105       * @param offset The zero-based byte offset in at which to
106       *               begin storing the data read from the current stream.
107       * @param count  The maximum number of bytes to be read from the current stream.
108       * @return The total number of bytes read into the buffer.
109       * This can be less than the number of bytes requested if that
110       * many bytes are not currently available, or zero (0)
111       * if the end of the stream has been reached.
112       * @throws IOException The sum of offset and count is larger than the buffer length.
113       */
114      @Override
115      public int read(byte[] buffer, int offset, int count) throws IOException {
116        count = HangingServiceRequestBase.BUFFER_SIZE;
117        final int retVal = underlyingStream.read(buffer, offset, count);
118    
119        if (HangingServiceRequestBase.isLogAllWireBytes()) {
120          final String readString = new String(buffer, offset, count, "UTF-8");
121          final String logMessage = String.format(
122              "HangingTraceStream ID [%d] returned %d bytes. Bytes returned: [%s]",
123              hashCode(), retVal, readString);
124    
125          try {
126            service.traceMessage(TraceFlags.DebugMessage, logMessage);
127          } catch (final XMLStreamException e) {
128            LOG.error(e);
129          }
130        }
131    
132        if (responseCopy != null) {
133          responseCopy.write(buffer, offset, retVal);
134        }
135    
136        return retVal;
137      }
138    
139      /**
140       * Sets the response copy.
141       *
142       * @param responseCopy a copy of response
143       */
144      public void setResponseCopy(final ByteArrayOutputStream responseCopy) {
145        this.responseCopy = responseCopy;
146      }
147    
148      @Override
149      public int read() throws IOException {
150        return 0;
151      }
152    
153    }
154