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.ResourceBundle;
30  import java.util.Scanner;
31  
32  import org.diyefi.openlogviewer.OpenLogViewer;
33  import org.diyefi.openlogviewer.genericlog.GenericLog;
34  import org.diyefi.openlogviewer.utils.Utilities;
35  import org.diyefi.openlogviewer.Text;
36  
37  public class CSVTypeLog extends AbstractDecoder {
38  	private static final int LOAD_FACTOR = 2;
39  	private static final String[] DELIMITERS = {"\t", ",", ":", "/", "\\\\"};
40  	private final ResourceBundle labels;
41  	private int fieldCount = -1;
42  
43  	/**
44  	 * @param f The CSV file to examine and attempt to load.
45  	 */
46  	public CSVTypeLog(final File f, final ResourceBundle labels) {
47  		this.labels = labels;
48  		this.setLogFile(f);
49  		this.setT(new Thread(this, CSVTypeLog.class.getSimpleName()));
50  		this.getT().setPriority(Thread.MAX_PRIORITY);
51  		this.getT().start();
52  	}
53  
54  	@Override
55  	public final void run() {
56  		try {
57  			final long startTime = System.currentTimeMillis();
58  			decodeLog();
59  			OpenLogViewer.getInstance().getEntireGraphingPanel().setGraphSize(this.getDecodedLog().getRecordCount());
60  			this.getDecodedLog().setLogStatus(GenericLog.LogState.LOG_LOADED);
61  			System.out.println(labels.getString(Text.CSV_LOADED_MSG_PART1)
62  					+ (this.getDecodedLog().getRecordCount() + 1) + labels.getString(Text.CSV_LOADED_MSG_PART2)
63  					+ (System.currentTimeMillis() - startTime) + labels.getString(Text.CSV_LOADED_MSG_PART3));
64  		} catch (IOException e) {
65  			e.printStackTrace();
66  			if (this.getDecodedLog() != null) {
67  				this.getDecodedLog().setLogStatusMessage(e.getMessage());
68  			} else { // TODO create a new log object and set the status...
69  				System.out.println("FIXME!!! CSVTypeLog");
70  			}
71  		}
72  	}
73  
74  	/**
75  	 * Decodes a CSV type of text file,
76  	 * the first ten lines are parsed individually to detect the delimiter type
77  	 *
78  	 * accepted types of delimiters are TAB, comma, ; , : and \
79  	 * this decoder does not yet support markers, it will skip them
80  	 *
81  	 * @throws IOException
82  	 */
83  	protected final void decodeLog() throws IOException {
84  		final Scanner scan = new Scanner(new BufferedReader(new FileReader(getLogFile())));
85  		final String delimiter = scanForDelimiter();
86  
87  		String[] splitLine;
88  		String[] headers = new String[1];
89  
90  		int finalAndInitialLength = Utilities.countBytes(getLogFile(), (byte) '\n');
91  
92  		String line = "";
93  		boolean headerSet = false;
94  		while (scan.hasNextLine() && !headerSet) {
95  			line = scan.nextLine();
96  			splitLine = line.split(delimiter);
97  
98  			if (splitLine.length == fieldCount) {
99  				headers = splitLine;
100 				this.setDecodedLog(new GenericLog(splitLine, finalAndInitialLength, LOAD_FACTOR, labels));
101 				headerSet = true;
102 			}
103 		}
104 
105 		while (scan.hasNextLine()) {
106 			line = scan.nextLine();
107 			splitLine = line.split(delimiter);
108 			this.getDecodedLog().incrementPosition();
109 			if (splitLine.length == fieldCount) {
110 				for (int x = 0; x < splitLine.length; x++) {
111 					this.getDecodedLog().addValue(headers[x], Double.parseDouble(splitLine[x]));
112 				}
113 			}
114 		}
115 	}
116 
117 	/**
118 	 * detects the delimiter and if it finds a suitable delimiter it will return it.
119 	 * @return delimiter in string format
120 	 * @throws IOException
121 	 */
122 	private String scanForDelimiter() throws IOException {
123 		final FileReader reader = new FileReader(getLogFile());
124 		final Scanner scan = new Scanner(reader);
125 
126 		final int magicNumber = 10; // Remove the MAGIC!
127 		String delimiterFind = "";
128 		String[] split;
129 		int index = -1;
130 
131 		for (int i = 0; i < magicNumber && scan.hasNext(); i++) {
132 			delimiterFind = scan.nextLine();
133 			for (int j = 0; j < DELIMITERS.length; j++) {
134 				split = delimiterFind.split(DELIMITERS[j]);
135 				if (split.length > fieldCount) {
136 					fieldCount = split.length;
137 					index = j;
138 				}
139 			}
140 		}
141 
142 		scan.close();
143 		reader.close();
144 		return DELIMITERS[index];
145 	}
146 }