001    package org.LiveGraph.dataCache;
002    
003    import java.io.Closeable;
004    import java.io.IOException;
005    import java.io.InputStream;
006    import java.util.List;
007    
008    import org.LiveGraph.dataFile.common.DataFormatException;
009    import org.LiveGraph.dataFile.read.DataStreamObserver;
010    import org.LiveGraph.dataFile.read.DataStreamReader;
011    
012    
013    /**
014     * This reader will parse a data stream using {@link DataStreamReader} and store all
015     * information in a data cache for further processing by the application.<br />
016     * <br />
017     * See {@link org.LiveGraph.dataFile.write.DataStreamWriter} for the details of the data file format. 
018     * 
019     * <p style="font-size:smaller;">This product includes software developed by the
020     *    <strong>LiveGraph</strong> project and its contributors.<br />
021     *    (<a href="http://www.live-graph.org" target="_blank">http://www.live-graph.org</a>)<br />
022     *    Copyright (c) 2007 G. Paperin.<br />
023     *    All rights reserved.
024     * </p>
025     * <p style="font-size:smaller;">File: DataStreamToCacheReader.java</p> 
026     * <p style="font-size:smaller;">Redistribution and use in source and binary forms, with or
027     *    without modification, are permitted provided that the following terms and conditions are met:
028     * </p>
029     * <p style="font-size:smaller;">1. Redistributions of source code must retain the above
030     *    acknowledgement of the LiveGraph project and its web-site, the above copyright notice,
031     *    this list of conditions and the following disclaimer.<br />
032     *    2. Redistributions in binary form must reproduce the above acknowledgement of the
033     *    LiveGraph project and its web-site, the above copyright notice, this list of conditions
034     *    and the following disclaimer in the documentation and/or other materials provided with
035     *    the distribution.<br />
036     *    3. All advertising materials mentioning features or use of this software or any derived
037     *    software must display the following acknowledgement:<br />
038     *    <em>This product includes software developed by the LiveGraph project and its
039     *    contributors.<br />(http://www.live-graph.org)</em><br />
040     *    4. All advertising materials distributed in form of HTML pages or any other technology
041     *    permitting active hyper-links that mention features or use of this software or any
042     *    derived software must display the acknowledgment specified in condition 3 of this
043     *    agreement, and in addition, include a visible and working hyper-link to the LiveGraph
044     *    homepage (http://www.live-graph.org).
045     * </p>
046     * <p style="font-size:smaller;">THIS SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY
047     *    OF ANY KIND, EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
048     *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT SHALL
049     *    THE AUTHORS, CONTRIBUTORS OR COPYRIGHT  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
050     *    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING  FROM, OUT OF OR
051     *    IN CONNECTION WITH THE SOFTWARE OR THE USE OR  OTHER DEALINGS IN THE SOFTWARE.
052     * </p>
053     * 
054     * @author Greg Paperin (<a href="http://www.paperin.org" target="_blank">http://www.paperin.org</a>)
055     * @version {@value org.LiveGraph.LiveGraph#version}
056     */
057    public class DataStreamToCacheReader implements Closeable, DataStreamObserver {
058    
059    /**
060     * Data stream reader.
061     */
062    private DataStreamReader in = null;
063    
064    /**
065     * Cache for storage of extracted data.
066     */
067    private DataCache cache = null;
068    
069    /**
070     * Creates a data reader on the specified stream.
071     * 
072     * @param is The stream from which to read.
073     * @param cache The data cache into which to store the data. 
074     */
075    public DataStreamToCacheReader(InputStream is, DataCache cache) {
076            
077            if (null == cache)
078                    throw new NullPointerException("Cannot use a null cache.");
079            
080            this.in = new DataStreamReader(is, this);       
081            this.cache = cache;     
082    }
083    
084    /**
085     * @return The data cache used by this reader.
086     */
087    public DataCache getDataCache() {
088            return cache;
089    }
090    
091    /**
092     * Tells whether this reader's underlying data stream is ready to be read.
093     * 
094     * @return {@code true} if the next {@code readFromStream()} is guaranteed not to block for input,
095     * {@code false} otherwise. Note that returning {@code false} does not guarantee that the next read will block.
096     * @throws IOException If an I/O error occurs.
097     */
098    public boolean ready() throws IOException {
099            return in.ready();
100    }
101    
102    /**
103     * Closes the underlying data stream. Further reading is not possible after calling this method.
104     * @throws IOException If an I/O error occurs.
105     */
106    public void close() throws IOException {
107            in.close();
108    }
109    
110    /**
111     * Reads as many data lines from the underlying stream as there are available, parses the lines and
112     * stores the extracted information (if any) in this reader's data cache.
113     *  
114     * @return number of non-empty file lines read.
115     * @throws IOException If an I/O error occurs.
116     * @throws DataFormatException If the data stream contents do not conform with the expected data
117     * stream format.
118     * @see org.LiveGraph.dataFile.write.DataStreamWriter
119     * @see org.LiveGraph.dataFile.read.DataStreamReader
120     */
121    public int readFromStream() throws IOException, DataFormatException {
122            
123            int lines = in.readFromStream();
124            return lines;   
125    }
126    
127    /**
128     * Used for callback by the {@link DataStreamReader}; does nothing.
129     */
130    public void eventCommentLine(String line, DataStreamReader reader) {
131            ; // No action required.        
132    }
133    
134    /**
135     * Used for callback by the {@link DataStreamReader}; adds a dataset to the cache.
136     */
137    public void eventDataLineRead(List<String> dataTokens, int datasetIndex, DataStreamReader reader) {
138            
139            List<Double> vals = DataStreamReader.convertTokensToDoubles(dataTokens);
140            DataSet ds = new DataSet(vals, datasetIndex);
141            cache.addDataSet(ds);   
142    }
143    
144    /**
145     * Used for callback by the {@link DataStreamReader}; adds a file info line to the cache.
146     */
147    public void eventFileInfoLine(String info, DataStreamReader reader) {
148            cache.addDataFileInfo(info);    
149    }
150    
151    /**
152     * Used for callback by the {@link DataStreamReader}; setts the data column labels in the cache.
153     */
154    public void eventLabelsSet(List<String> labels, DataStreamReader reader) {
155            List<String> uniqueLabels = DataStreamReader.createUniqueLabels(labels, true); 
156            cache.resetLabels(uniqueLabels);        
157    }
158    
159    /**
160     * Used for callback by the {@link DataStreamReader}; does nothing.
161     */
162    public void eventSeparatorSet(String separator, DataStreamReader reader) {
163            ; // No action required.        
164    }
165    
166    }