View Javadoc
1 /* 2 * STFFile.java 3 * 4 * Created on 26. November 2001, 17:40 5 * 6 * Copyright 2001 by Flo Ledermann flo@subnet.at 7 * 8 * Licensed under GNU General Public License (GPL). 9 * See http://www.gnu.org/copyleft/gpl.html 10 */ 11 12 package edu.psu.geovista.app.parvis.file; 13 14 import edu.psu.geovista.app.parvis.model.*; 15 import edu.psu.geovista.app.parvis.gui.ProgressEvent; 16 import edu.psu.geovista.app.parvis.gui.ProgressListener; 17 18 import java.io.*; 19 import java.net.*; 20 import java.util.*; 21 22 23 /*** 24 * A Simple file parser for reading STF (Simple Table Fomrat) files from URLs. 25 * 26 * The STF File format is defined as follows: 27 <pre> 28 # test.stf 29 # Comments have # in the first column. 30 # Type the number of fields, on a line by itself. 31 3 32 # Then type field names and types. Field names must not contain 33 # spaces. 34 # 35 PersonName String 36 Age Integer 37 HourlyWage Real 38 # 39 # Data type is case-insensitive. 40 # Default data delimiters are tabs and spaces. 41 # Here's the data, tab-delimited. Notice that the data columns are 42 # in the order they are listed above. 43 # 44 Joe 23 5.75 45 Mary 18 4.75 46 Fred 54 100.00 47 Ginger 48 100.00 48 # 49 # Nothing special is required to end the file. 50 51 </pre> 52 * 53 * Once the file is read and parsed, the data can be accessed with the methods 54 * defined in the ParallelSpaceModel interface. 55 * 56 * @author Flo Ledermann flo@subnet.at 57 * @version 0.1 58 */ 59 public class STFFile extends SimpleParallelSpaceModel { 60 61 /*** The url of the file. */ 62 URL url; 63 64 private int tempNumDimensions; 65 66 private int bytesRead = 0; 67 private int filesize = 0; 68 69 private Vector stringLabels = new Vector(); 70 private boolean isStringLabel[]; 71 72 /*** 73 * Creates a new STFFile with the given url. The content is not read until 74 * readContents() is called. 75 * 76 * @param url The url of the file to read. 77 */ 78 public STFFile(URL url) { 79 this.url = url; 80 } 81 82 /*** 83 * Reads the contents of the file and exposes them vis the ParallelSpaceModel 84 * interface of the class. String values are stripped out of the model and 85 * set as record labels. 86 */ 87 public void readContents() throws IOException{ 88 89 fireProgressEvent(new ProgressEvent(this, ProgressEvent.PROGRESS_START, 0.0f, "loading file")); 90 91 URLConnection conn = url.openConnection(); 92 conn.connect(); 93 94 filesize = conn.getContentLength(); 95 //System.out.println("filesize: " + filesize); 96 97 InputStreamReader in = new InputStreamReader(conn.getInputStream()); 98 99 readFirstLine(in); 100 readHeaderLines(in); 101 readData(in); 102 103 fireProgressEvent(new ProgressEvent(this, ProgressEvent.PROGRESS_FINISH, 1.0f, "loading file")); 104 105 } 106 107 /*** 108 * Reads the first data line of the file and sets up the number of dimensions. 109 */ 110 protected void readFirstLine(Reader in) throws IOException{ 111 String line = readLine(in); 112 bytesRead += line.length(); 113 114 if (line.indexOf(' ') != -1) 115 tempNumDimensions = Integer.parseInt(line.substring(0,line.indexOf(' '))); 116 else 117 tempNumDimensions = Integer.parseInt(line); 118 119 ////System.out.println("num dimensions: " + tempNumDimensions); 120 121 isStringLabel = new boolean[tempNumDimensions]; 122 for (int i=0; i<tempNumDimensions; i++){ 123 isStringLabel[i] = false; 124 } 125 } 126 127 /*** 128 * Reads the header lines and sets up the variable types. 129 */ 130 protected void readHeaderLines(Reader in) throws IOException{ 131 int i; 132 int j=0; 133 String line; 134 135 int numDimensions = tempNumDimensions; 136 Vector labels = new Vector(); 137 138 for (i=0; i<tempNumDimensions; i++){ 139 line = readLine(in); 140 bytesRead += line.length(); 141 142 StringTokenizer str = new StringTokenizer(line); 143 String label = str.nextToken(); 144 String type = str.nextToken(); 145 146 if (type.equalsIgnoreCase("string")){ 147 isStringLabel[i] = true; 148 stringLabels.addElement(label); 149 150 numDimensions--; 151 ////System.out.println("Recordlabel " + label); 152 } 153 else { 154 labels.addElement(label); 155 //System.out.println("Axis " + j++ + " label " + label + " type " + type + "."); 156 } 157 158 } 159 160 this.initNumDimensions(numDimensions); 161 String tempLabels[] = (String[])labels.toArray(new String[numDimensions]); 162 this.setAxisLabels(tempLabels); 163 } 164 165 /*** 166 * Reads the data lines. 167 */ 168 protected void readData(Reader in) throws IOException{ 169 String line, value; 170 int i, j, s; 171 172 String label; 173 174 float curVal[]; 175 176 while ((line = readLine(in)) != null){ 177 bytesRead += line.length(); 178 179 float progress = (float)bytesRead / filesize; 180 fireProgressEvent(new ProgressEvent(this, ProgressEvent.PROGRESS_UPDATE, progress, "loading file")); 181 182 StringTokenizer str = new StringTokenizer(line); 183 curVal = new float[numDimensions]; 184 185 j=0; 186 s=0; 187 label = null; 188 189 for (i = 0; i<tempNumDimensions; i++){ 190 value = str.nextToken(); 191 // //System.out.println("value " + i + ": " + value); 192 193 if (!isStringLabel[i]) { 194 try { 195 float val = Float.parseFloat(value); 196 curVal[j++] = val; 197 } 198 catch (NumberFormatException nfe){ 199 //System.out.println("Invalid Number Format: " + nfe.getMessage() + " -> dicarding & setting 0.0f"); 200 curVal[j++] = 0.0f; 201 } 202 } 203 else { 204 if (label == null) { 205 label = stringLabels.elementAt(s++) + ": " + value; 206 } 207 else { 208 label += "\n" + stringLabels.elementAt(s++) + ": " + value; 209 } 210 } 211 212 } 213 214 addRecord(curVal, label); 215 216 } 217 } 218 219 /*** 220 * Reads on line, skipping comments and empty lines. 221 */ 222 protected String readLine(Reader in) throws IOException{ 223 char buf[] = new char[128]; 224 int offset = 0; 225 int ch; 226 227 boolean skip = false; 228 229 for (;;) { 230 ch = in.read(); 231 232 if (ch == -1){ 233 break; 234 } 235 236 if (ch == '\n' || ch == '\r') { 237 if (offset == 0 && !skip){ 238 //skip empty line -> do nothing 239 skip = true; 240 // //System.out.println("skipping line: empty"); 241 } 242 243 if (skip){ 244 // next line reached -> stop skipping 245 skip = false; 246 } 247 else { 248 // line finished -> break and return 249 break; 250 } 251 } 252 else if(ch == '#' && offset == 0){ 253 // skip this line 254 skip = true; 255 // //System.out.println("skipping line: comment"); 256 } 257 else if (!skip){ 258 if (offset == buf.length) { 259 char tmpbuf[] = buf; 260 buf = new char[tmpbuf.length * 2]; 261 System.arraycopy(tmpbuf, 0, buf, 0, offset); 262 } 263 buf[offset++] = (char) ch; 264 } 265 266 } 267 268 if ((offset == 0) || skip){ //eof 269 return null; 270 } 271 return String.copyValueOf(buf, 0, offset); 272 } 273 274 private Vector progressListeners = new Vector(); 275 276 public void addProgressListener(ProgressListener l){ 277 progressListeners.add(l); 278 } 279 280 public void removeProgressListener(ProgressListener l){ 281 progressListeners.remove(l); 282 } 283 284 public void fireProgressEvent(ProgressEvent e){ 285 Vector list = (Vector)progressListeners.clone(); 286 for (int i=0; i<list.size(); i++){ 287 ProgressListener l = (ProgressListener)list.elementAt(i); 288 l.processProgressEvent(e); 289 } 290 } 291 292 /*** 293 * Main method for testing purposes. 294 */ 295 public static void main(String args[]){ 296 try { 297 STFFile f = new STFFile(new URL("file:///d:/uni/visualisierung/datasets/table1.stf")); 298 299 f.readContents(); 300 } 301 catch (MalformedURLException e){ 302 //System.out.println("malformed url!"); 303 } 304 catch (IOException ex){ 305 //System.out.println("IOException: " + ex.getMessage()); 306 } 307 308 } 309 310 }

This page was automatically generated by Maven