View Javadoc

1   /* Open Log Viewer
2    *
3    * Copyright 2011
4    *
5    * This file is part of the OpenLogViewer project.
6    *
7    * OpenLogViewer software is free software: you can redistribute it and/or modify
8    * it under the terms of the GNU General Public License as published by
9    * the Free Software Foundation, either version 3 of the License, or
10   * (at your option) any later version.
11   *
12   * OpenLogViewer software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   * GNU General Public License for more details.
16   *
17   * You should have received a copy of the GNU General Public License
18   * along with any OpenLogViewer software.  If not, see http://www.gnu.org/licenses/
19   *
20   * I ask that if you make any changes to this file you fork the code on github.com!
21   *
22   */
23  package org.diyefi.openlogviewer.decoder;
24  
25  import java.io.BufferedReader;
26  import java.io.File;
27  import java.io.FileReader;
28  import java.io.IOException;
29  import java.util.Scanner;
30  
31  import org.diyefi.openlogviewer.OpenLogViewer;
32  import org.diyefi.openlogviewer.genericlog.GenericLog;
33  
34  public class CSVTypeLog extends AbstractDecoder {
35  	private static final int initialLength = 75000;
36  	private static final int loadFactor = 2;
37  	private int fieldCount = -1;
38  
39  	/**
40  	 * This constructor is called when a string path is provided
41  	 * @param f
42  	 */
43  	public CSVTypeLog(final File f) {
44  		this.setLogFile(f);
45  		this.setT(new Thread(this, "CSV Type Log Loading"));
46  		this.getT().setPriority(Thread.MAX_PRIORITY);
47  		this.getT().start();
48  	}
49  
50  	@Override
51  	public final void run() {
52  		try {
53  			final long startTime = System.currentTimeMillis();
54  			decodeLog();
55  			OpenLogViewer.getInstance().getEntireGraphingPanel().setGraphSize(this.getDecodedLog().getRecordCount());
56  			this.getDecodedLog().setLogStatus(GenericLog.LogState.LOG_LOADED);
57  			System.out.println("Loaded " + (this.getDecodedLog().getRecordCount() + 1) + " records in " + (System.currentTimeMillis() - startTime) + " millis!");
58  		} catch (Exception e) {
59  			e.printStackTrace();
60  			if (this.getDecodedLog() != null) {
61  				this.getDecodedLog().setLogStatusMessage(e.getMessage());
62  			} else { // TODO create a new log object and set the status...
63  				System.out.println("FIXME!!! CSVTypeLog");
64  			}
65  		}
66  	}
67  
68  	/**
69  	 * Decodes a CSV type of text file,
70  	 * the first ten lines are parsed individually to detect the delimiter type
71  	 *
72  	 * accepted types of delimiters are TAB, comma, ; , : and \
73  	 * this decoder does not yet support markers, it will skip them
74  	 *
75  	 * @throws IOException
76  	 */
77  	protected final void decodeLog() throws IOException {
78  		final Scanner scan = new Scanner(new BufferedReader(new FileReader(getLogFile())));
79  		final String delimiter = scanForDelimiter();
80  
81  		String[] splitLine = new String[1];
82  		String[] headers = new String[1];
83  
84  		String line = "";
85  		boolean headerSet = false;
86  		while (scan.hasNextLine() && !headerSet) {
87  			line = scan.nextLine();
88  			splitLine = line.split(delimiter);
89  
90  			if (splitLine.length == fieldCount) {
91  				headers = splitLine;
92  				this.setDecodedLog(new GenericLog(splitLine, initialLength, loadFactor));
93  				headerSet = true;
94  			}
95  		}
96  
97  		while (scan.hasNextLine()) {
98  			line = scan.nextLine();
99  			splitLine = line.split(delimiter);
100 			this.getDecodedLog().incrementPosition();
101 			if (splitLine.length == fieldCount) {
102 				for (int x = 0; x < splitLine.length; x++) {
103 					this.getDecodedLog().addValue(headers[x], Double.parseDouble(splitLine[x]));
104 				}
105 			}
106 		}
107 	}
108 
109 	/**
110 	 * detects the delimiter and if it finds a suitable delimiter it will return it.
111 	 * @return delimiter in string format
112 	 * @throws IOException
113 	 */
114 	private String scanForDelimiter() throws IOException {
115 		final String[] delim = {"\t", ",", ":", "/", "\\\\"};
116 		final FileReader reader = new FileReader(getLogFile());
117 		final Scanner scan = new Scanner(reader);
118 
119 		final int magicNumber = 10; // Remove the MAGIC!
120 		String delimiterFind = "";
121 		String[] split = new String[1];
122 		int delimNum = -1;
123 
124 		for (int i = 0; i < magicNumber && scan.hasNext(); i++) {
125 			delimiterFind = scan.nextLine();
126 			for (int j = 0; j < delim.length; j++) {
127 				split = delimiterFind.split(delim[j]);
128 				if (split.length > fieldCount) {
129 					fieldCount = split.length;
130 					delimNum = j;
131 				}
132 			}
133 		}
134 
135 		scan.close();
136 		reader.close();
137 		return delim[delimNum];
138 	}
139 }