001    /**
002     * Copyright 2007 Mike Kroutikov.
003     *
004     * This program is free software; you can redistribute it and/or modify
005     *   it under the terms of the Lesser GNU General Public License as 
006     *   published by the Free Software Foundation; either version 3 of
007     *   the License, or (at your option) any later version.
008     *
009     *   This program is distributed in the hope that it will be useful,
010     *   but WITHOUT ANY WARRANTY; without even the implied warranty of
011     *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012     *   Lesser GNU General Public License for more details.
013     *
014     *   You should have received a copy of the Lesser GNU General Public License
015     *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
016     */
017    
018    package org.otfeed.support.mock;
019    
020    import java.io.IOException;
021    import java.io.PrintStream;
022    import java.nio.ByteBuffer;
023    
024    import org.otfeed.protocol.connector.IStreamer;
025    import org.otfeed.protocol.connector.IStreamerFactory;
026    import org.otfeed.support.BufferFormat;
027    import org.otfeed.support.IFormat;
028    
029    /**
030     * Wrapper around {@link IStreamerFactory} to log content of
031     * frames to the print stream. Useful for testing, tracing,
032     * and debugging.
033     */
034    public class SpyStreamerFactory implements IStreamerFactory {
035            
036            private final IStreamerFactory engine;
037    
038            /**
039             * Creates new spy with the given id string, wrapping an instance of {@link IStreamerFactory}.
040             *
041             * @param id id string.
042             * @param engine wrapped instance.
043             */
044            public SpyStreamerFactory(String id, IStreamerFactory engine) {
045                    this.id = id;
046                    this.engine = engine;
047            }
048            
049            /**
050             * Creates new spy with the empty id string, wrapping an instance of {@link IStreamerFactory}.
051             * 
052             * @param engine wrapped instance.
053             */
054            public SpyStreamerFactory(IStreamerFactory engine) {
055                    this("", engine);
056            }
057            
058            private PrintStream readLogStream = new PrintStream(System.out, true);
059    
060            /**
061             * Destination for logging the incoming frames.
062             * Defaults to System.out.
063             * 
064             * @return print stream.
065             */
066            public PrintStream getReadLogStream() {
067                    return readLogStream;
068            }
069    
070            /**
071             * Sets read log stream.
072             * 
073             * @param val print stream.
074             */
075            public void setReadLogStream(PrintStream val) {
076                    readLogStream = val;
077            }
078    
079            private PrintStream writeLogStream = new PrintStream(System.out, true);
080            
081            /**
082             * Destination for logging the outgoing frames.
083             * Defaults to System.out.
084             * 
085             * @return print stream.
086             */
087            public PrintStream getWriteLogStream() {
088                    return writeLogStream;
089            }
090    
091            /**
092             * Sets write log stream.
093             * 
094             * @param val print stream.
095             */
096            public void setWriteLogStream(PrintStream val) {
097                    writeLogStream = val;
098            }
099    
100            private String id = "";
101            
102            /**
103             * Identification string (optional).
104             * 
105             * This string is written to the comment area of
106             * generated hexdumps. You may want to set it if
107             * mustiple simultaneous connections are being spyied
108             * upon to distinguish between them.
109             * 
110             * Default value is empty string.
111             * 
112             * @return id string.
113             */
114            public String getId() {
115                    return id;
116            }
117            
118            /**
119             * Sets identification sting.
120             * 
121             * @param val id string.
122             */
123            public void setId(String val) {
124                    id = val;
125            }
126            
127            private IFormat<ByteBuffer> format = new BufferFormat();
128            
129            /**
130             * Format to use when converting ByteBuffer s to human-readable
131             * form. Defaults to {@link BufferFormat}.
132             *
133             * @return format.
134             */
135            public IFormat<ByteBuffer> getFormat() {
136                    return format;
137            }
138            
139            /**
140             * Sets format.
141             * 
142             * @param val format.
143             */
144            public void setFormat(IFormat<ByteBuffer> val) {
145                    format = val;
146            }
147    
148            public IStreamer connect(String host, int port) throws IOException {
149                    
150                    final IStreamer streamer = engine.connect(host, port);
151                    
152                    return new IStreamer() {
153    
154                            public void close() {
155                                    streamer.close();
156                            }
157    
158                            public ByteBuffer read() throws IOException {
159                                    ByteBuffer out = streamer.read();
160                                    
161                                    readLogStream.println("% " + id);
162                                    readLogStream.println("% read timestamp: " + System.currentTimeMillis());
163                                    readLogStream.println(format.format(out));
164                                    
165                                    return out;
166                            }
167    
168                            public void write(ByteBuffer out) throws IOException {
169                                    
170                                    writeLogStream.println("% " + id);
171                                    writeLogStream.println("% write timestamp: " + System.currentTimeMillis());
172                                    writeLogStream.println(format.format(out));
173    
174                                    streamer.write(out);
175                            }
176                    };
177            }
178    }