/** * Semi-Generic Loader * @author Robert J Morton YE572246C * @version 04 December 2007 * @copyright Robert J Morton (all rights reserved) */ import java.io.*; // file input/output handling import java.net.*; // for downloading data from the remote server class loader { // TO LOAD AND DISPLAY ROUTE NAMES AND GEOGRAPHIC FEATURES private boolean connectFTT = true, // first-time-through flag loadingFTT = true, // first-time-through flag dataLoaded = false; // hits data not yet loaded private int ls = 0, // load switch [see navstart.java] lp = 0, // 0=idle 1=connecting 2=loading 3=connect error 4=load error l = 0, // number of bytes of the above successfully downloaded L = 0; // length of the remote item being loaded private byte B[]; // gigantic byte array to hold the downloaded index data private String fn = "", // name of the route names file cb; // URL path to data files private BufferedReader R; // for reading route & waypoint lists from files private InputStream I; // input stream for downloading file loader(int ls, String cb) { this.ls = ls; // load switch this.cb = cb; // URL (less file name) from where this applet came lp = 1; // start the route names loading process } boolean dataLoaded() { // RUN THE AUXILIARY THREAD switch(lp) { // THE 2 DOWNLOADING PHASES case 1: fileConnect(); break; // connect to index resource on server case 2: fileLoad(); // manage the downloading of its content } return dataLoaded; } private void fileConnect() { // CONNECT TO APPROPRIATE DATA FILE ON SERVER if(!connectFTT) return; System.out.println("Connecting to data file..."); connectFTT = false; try { // set to capture any exceptions locally switch(ls) { case 0: // Create an input stream to load local file L = (int)(new File(fn)).length(); I = new FileInputStream(fn); break; case 1: // Create an input stream to load file from jar file I = getClass().getResourceAsStream(fn); L = 4096; // default maximum content length break; case 2: // Create an input stream to load file from server URLConnection u = new URL(cb+fn).openConnection(); I = u.getInputStream(); L = (int)u.getContentLength(); } System.out.println("File size = " + L); B = new byte[L]; // create the gigantic buffer for the data l = 0; // number of bytes so far successfully downloaded lp = 2; // advance to the index loading phase } /* If any exception at all occurs, note what kind of exception it was and where it occurred. */ catch(Exception e) { System.out.println("fileConnect() " + e); System.out.println("Couldn't find data file."); lp = 4; // reset loader to its idle state } } private void fileLoad() { // DOWNLOAD THE APPROPRIATE DATA FILE if(loadingFTT) { System.out.println("Loading data file..."); loadingFTT = false; } int k; // content of current byte being read() /* NOTE: Multiple passes of this fileLoad() are only necessary for downloading across the Internet [ls = 2]. Loading from a file in the local directory or from a jar file only need to pass once through this method.*/ try { if(ls == 1) { // L is unknown for jarred data files /* While the entire file has not yet been downloaded, add each new byte to the big byte array. */ while((k = I.read()) != -1) B[l++] = (byte)k; L = l; // marks the end point of the data } else // L is known for local and remote files /* While the entire file has not yet been downloaded, add each new byte to the big byte array. */ while(l < L && (k = I.read()) != -1) B[l++] = (byte)k; if(l >= L) { I.close(); // close URL Connection [or local file] dataLoaded = true; System.out.println("Data file loaded."); lp = 3; // go to post-loading phase } } // catch any data transmission or file loading error conditions catch(Exception e) { /* note the kind of exception and where it occurred then display it in the terminal. */ System.out.println("fileLoad() " + e + L + " " + l); System.out.println("Couldn't load data file."); lp = 5; // reset loader to its idle state } } /* The following 3 methods are provided to allow an external class to read from the loader's byte aray B[] but not to write to it. This is more secure than allowing external access to B[] and L. */ int getLength() {return L;} // return lengh of the valid data byte getByte(int i) {return B[i];} // return an element of the byte array byte[] getArray() {return B;} // reference to the byte array /* The following method is used to initiate the downloading of a new data file. */ void setFileName(String s) { fn = s; connectFTT = true; // first-time-through flag loadingFTT = true; // first-time-through flag dataLoaded = false; // hits data not yet loaded lp = 1; } }