001    package org.LiveGraph.settings;
002    
003    import static org.LiveGraph.settings.SettingsEvent.*;
004    
005    import java.io.FileInputStream;
006    import java.io.FileOutputStream;
007    import java.io.IOException;
008    import java.util.Properties;
009    
010    import org.LiveGraph.LiveGraph;
011    import org.LiveGraph.events.Event;
012    
013    /**
014     * Encapsulates the settings concerned with reading the data file, the update frequency
015     * and the caching method. 
016     * 
017     * <p style="font-size:smaller;">This product includes software developed by the
018     *    <strong>LiveGraph</strong> project and its contributors.<br />
019     *    (<a href="http://www.live-graph.org" target="_blank">http://www.live-graph.org</a>)<br />
020     *    Copyright (c) 2007-2008 G. Paperin.<br />
021     *    All rights reserved.
022     * </p>
023     * <p style="font-size:smaller;">File: DataFileSettings.java</p> 
024     * <p style="font-size:smaller;">Redistribution and use in source and binary forms, with or
025     *    without modification, are permitted provided that the following terms and conditions are met:
026     * </p>
027     * <p style="font-size:smaller;">1. Redistributions of source code must retain the above
028     *    acknowledgement of the LiveGraph project and its web-site, the above copyright notice,
029     *    this list of conditions and the following disclaimer.<br />
030     *    2. Redistributions in binary form must reproduce the above acknowledgement of the
031     *    LiveGraph project and its web-site, the above copyright notice, this list of conditions
032     *    and the following disclaimer in the documentation and/or other materials provided with
033     *    the distribution.<br />
034     *    3. All advertising materials mentioning features or use of this software or any derived
035     *    software must display the following acknowledgement:<br />
036     *    <em>This product includes software developed by the LiveGraph project and its
037     *    contributors.<br />(http://www.live-graph.org)</em><br />
038     *    4. All advertising materials distributed in form of HTML pages or any other technology
039     *    permitting active hyper-links that mention features or use of this software or any
040     *    derived software must display the acknowledgment specified in condition 3 of this
041     *    agreement, and in addition, include a visible and working hyper-link to the LiveGraph
042     *    homepage (http://www.live-graph.org).
043     * </p>
044     * <p style="font-size:smaller;">THIS SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY
045     *    OF ANY KIND, EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
046     *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT SHALL
047     *    THE AUTHORS, CONTRIBUTORS OR COPYRIGHT  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
048     *    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING  FROM, OUT OF OR
049     *    IN CONNECTION WITH THE SOFTWARE OR THE USE OR  OTHER DEALINGS IN THE SOFTWARE.
050     * </p>
051     * 
052     * @author Greg Paperin (<a href="http://www.paperin.org" target="_blank">http://www.paperin.org</a>)
053     * @version {@value org.LiveGraph.LiveGraph#version}
054     */
055    public class DataFileSettings extends ObservableSettings {
056    
057    /**
058     * Standard file extension.
059     */
060    public static final String preferredFileExtension = ".lgdfs";
061    
062    /**
063     * Data file name.
064     * Default value: {@code ""}.
065     */
066    private String dataFile = "";
067    
068    /**
069     * Show only tail data (or all data).
070     * Default value: {@code false}.
071     */
072    private boolean showOnlyTailData = false;
073    
074    /**
075     * Do not cache data (i.e. read every time from stream) or cache.
076     * Default value: {@code false}.
077     */
078    private boolean doNotCacheData = false;
079    
080    /**
081     * Data update frequency in milliseconds.
082     * Default value: {@code -1}.
083     */
084    private long updateFrequency = -1L;
085    
086    
087    /**
088     * Creates a new data file settings object with the default settings values.
089     */
090    public DataFileSettings() {
091            super();
092    }
093    
094    /**
095     * Creates a new data file settings object and loads the settings values from
096     * the specified file.
097     *  
098     * @param fileName File to load the settings from.
099     */
100    public DataFileSettings(String fileName) {
101            this();
102            load(fileName, false);
103    }
104    
105    /**
106     * Loads the settings from a specified file.
107     * 
108     * @param fileName The file to load the settings from.
109     * @param ignoreFileName Whether to ignore the DataFile values from the loaded file.
110     * @return {@code true} if the settings were loaded, {@code false} if an exception occured. 
111     */
112    public boolean load(String fileName, boolean ignoreFileName) {
113            
114            Event<? extends SettingsEvent> actionEvent = checkObservers(DFS_Load, fileName);
115            if (null == actionEvent)
116                    return false;
117            
118            Properties values = new Properties();
119            try {
120                    FileInputStream in = new FileInputStream(fileName);
121                    try {
122                            values.loadFromXML(in);
123                    } finally {
124                            in.close();
125                    }               
126            } catch(IOException e) {
127                    e.printStackTrace();
128                    return false;
129            }
130                            
131            String s = values.getProperty("ShowOnlyTailData");
132            showOnlyTailData = "1".equalsIgnoreCase(null != s ? s : "0");
133            
134            s = values.getProperty("DoNotCacheData");
135            doNotCacheData = "1".equalsIgnoreCase(null != s ? s : "0");
136            
137            s = values.getProperty("UpdateFrequency");
138            updateFrequency = Long.parseLong(null != s ? s : "-1");
139            
140            if (!ignoreFileName) {
141                    s = values.getProperty("DataFile");
142                    dataFile = (null != s ? s : "");
143            }
144                                            
145            notifyObservers(actionEvent);
146            return true;
147    }
148    
149    /**
150     * Saves the settings to a specified file.
151     * 
152     * @param fileName The file to save the settings to.
153     * @return {@code true} if the settings were saved, {@code false} if an exception occured. 
154     */
155    public boolean save(String fileName) {
156            
157            Event<? extends SettingsEvent> actionEvent = checkObservers(DFS_Save, fileName);
158            if (null == actionEvent)
159                    return false;
160                    
161            Properties values = new Properties();
162            values.setProperty("DataFile", dataFile);
163            values.setProperty("ShowOnlyTailData", showOnlyTailData ? "1" : "0");
164            values.setProperty("DoNotCacheData", doNotCacheData ? "1" : "0");
165            values.setProperty("UpdateFrequency", Long.toString(updateFrequency));
166            
167            try {
168                    FileOutputStream out = new FileOutputStream(fileName);
169                    try {
170                            values.storeToXML(out, "LiveGraph version " + LiveGraph.version + ". DataFileSettings.");
171                    }
172                    finally {
173                            out.close();
174                    }
175                    
176                    notifyObservers(actionEvent);
177                    return true;
178            } catch(IOException e) {
179                    e.printStackTrace();
180                    return false;
181            }
182    }
183    
184    /**
185     * Gets the data file.
186     * 
187     * @return Name of the data stream to plot.
188     */
189    public String getDataFile() {
190            return dataFile;
191    }
192    
193    /**
194     * Sets the data file.
195     * 
196     * @param fn Name of the data stream to plot.
197     */
198    public void setDataFile(String fn) {
199            
200            // Apply this setting even if same data file is already in use as its contants may have changed.
201            
202            Event<? extends SettingsEvent> actionEvent = checkObservers(DFS_DataFile, fn);
203            if (null == actionEvent)
204                    return;
205            
206            dataFile = fn;
207            notifyObservers(actionEvent);
208    }
209    
210    
211    /**
212     * Gets whether to plot only tail data.
213     *  
214     * @return {@code true} if only the datasets at the end of the data setream should be plotted,
215     * {@code false} if data sets should be sampled from the complete data stream.
216     */
217    public boolean getShowOnlyTailData() {
218            return showOnlyTailData;
219    }
220    
221    /**
222     * Setts whether to plot only tail data.
223     *  
224     * @param v {@code true} if only the datasets at the end of the data setream should be plotted,
225     * {@code false} if data sets should be sampled from the complete data stream.
226     */
227    public void setShowOnlyTailData(boolean v) {
228            
229            if (v == getShowOnlyTailData())
230                    return;
231            
232            Event<? extends SettingsEvent> actionEvent = checkObservers(DFS_ShowOnlyTailData, v);
233            if (null == actionEvent)
234                    return;
235            
236            showOnlyTailData = v;
237            notifyObservers(actionEvent);
238    }
239    
240    /**
241     * Gets whether the data stream should not be cached in memory.
242     *  
243     * @return {@code true} if the data stream should be read from the start each time the graph is updated,
244     * {@code false} if data should be cached in memory and only the new data sets should be read on each update. 
245     */
246    public boolean getDoNotCacheData() {
247            return doNotCacheData;
248    }
249    
250    /**
251     * Sets whether the data stream should not be cached in memory.
252     *  
253     * @param v {@code true} if the data stream should be read from the start each time the graph is updated,
254     * {@code false} if data should be cached in memory and only the new data sets should be read on each update. 
255     */
256    public void setDoNotCacheData(boolean v) {
257            
258            if (v == getDoNotCacheData())
259                    return;
260            
261            Event<? extends SettingsEvent> actionEvent = checkObservers(DFS_DoNotCacheData, v);
262            if (null == actionEvent)
263                    return;
264            
265            doNotCacheData = v;
266            notifyObservers(actionEvent);
267    }
268    
269    /**
270     * Gets the interval between automatic graph updates.
271     * 
272     * @return The number of milliseconds to wait between trying to read from the data stream next time.
273     * If this values is {@code < 1} no automatic update should be initiated.
274     */
275    public long getUpdateFrequency() {
276            return updateFrequency;
277    }
278    
279    /**
280     * Sets the interval between automatic graph updates.
281     * 
282     * @param f The number of milliseconds to wait between trying to read from the data stream next time.
283     * Pass a value {@code f < 1} to indicate that no automatic update should be initiated.
284     */
285    public void setUpdateFrequency(long f) {
286            
287            if (f == getUpdateFrequency())
288                    return;
289            
290            Event<? extends SettingsEvent> actionEvent = checkObservers(DFS_UpdateFrequency, f);
291            if (null == actionEvent)
292                    return;
293            
294            updateFrequency = f;
295            notifyObservers(actionEvent);
296    }
297    
298    } // public class DataFileSettings