FileSystemSourceFile.java

Go to the documentation of this file.
00001 
00002 //                                                                      //
00003 //  FileSystemSourceFile.java                                           //
00004 //                                                                      //
00005 //  experiment.source.SourceFile -- a source file contained in a file   //
00006 //  Last edited: January 29, 2001 at 12:21                              //
00007 //                                                                      //
00008 //  (c) Copyright 2002 Rice University. All rights reserved.            //
00009 //                                                                      //
00011 
00012 
00013 
00014 
00015 package edu.rice.cs.hpc.data.experiment.source;
00016 
00017 
00018 import edu.rice.cs.hpc.data.experiment.BaseExperiment;
00019 import edu.rice.cs.hpc.data.experiment.BaseExperimentWithMetrics;
00020 import edu.rice.cs.hpc.data.experiment.source.SourceFile;
00021 import edu.rice.cs.hpc.data.util.*;
00022 
00023 import java.io.*;
00024 
00025 
00026 
00027 
00028 
00030 //  CLASS SOURCE-FILE                                                   //
00032 
00040 public class FileSystemSourceFile implements SourceFile
00041 {
00043 public static final int STATICID = 1111;
00045 protected BaseExperiment experiment;
00046 
00048 protected File filename;
00049 
00051 protected boolean hasBeenSought;
00052 
00054 protected boolean contentsAvailable;
00055 
00058 protected File resolvedPath;
00059 
00062 protected int lineCount;
00063 
00064 protected boolean istext;
00065 
00066 protected String longName;
00067 
00071 protected int id;
00072 
00074 //  INITIALIZATION                                                      //
00076 
00077 
00078 
00079 
00080 /*************************************************************************
00081  *  Creates a SourceFile.
00082  ************************************************************************/
00083     
00084 public FileSystemSourceFile(BaseExperiment experiment, File filename, int idFile)
00085 {
00086     super();
00087 
00088     // creation arguments
00089     this.experiment = experiment;
00090     this.filename = filename;
00091 
00092     // lazily computed file properties
00093     this.hasBeenSought     = false;
00094     this.contentsAvailable = true;
00095     
00096     this.longName = null;
00097     //  laks: bug: default is a text file
00098     this.istext = true;
00099     // Note: 'this.resolvedPath' and 'this.lineCount' should not be accessed
00100     //       unless 'this.contentsAvailable'.
00101     this.id = idFile;
00102 }
00103 
00104 
00105 
00106 
00108 //  ACCESS TO CONTENTS                                                  //
00110 
00111 
00112 
00113 public int getFileID () {
00114     return this.id;
00115 }
00116 
00117 /*************************************************************************
00118  *  Returns the source file's user visible name.
00119  ************************************************************************/
00120     
00121 public String getName()
00122 {
00123     if (longName == null) {
00124         if (istext) {
00125             longName = filename.getName();
00126         }
00127         else {
00128             longName = "binary file " + filename.getName();
00129         }
00130     }
00131     return this.longName;
00132 }
00133 
00134 
00135 
00136 
00137 /*************************************************************************
00138  *  Returns the source file's filename.
00139  ************************************************************************/
00140     
00141 public File getFilename()
00142 {
00143     return this.filename;
00144 }
00145 
00146 
00147 
00148 
00149 /*************************************************************************
00150  *  Returns the number of lines in the source file.
00151  *
00152  *  <p>
00153  *  This method should only be called if <code>this.isAvailable()</code>.
00154  *
00155  ************************************************************************/
00156     
00157 public int getLineCount()
00158 {
00159     this.requireAvailable();
00160     if( this.lineCount == -1 )
00161         this.computeLineCount();
00162     return this.lineCount;
00163 }
00164 
00165 
00166 
00167 
00168 /*************************************************************************
00169  *  Counts and stores the number of lines in the source file.
00170  *
00171  *  <p>
00172  *  This method is only called if <code>this.isAvailable()</code>.
00173  *
00174  ************************************************************************/
00175 
00176 protected void computeLineCount()
00177 {
00178     Dialogs.Assert(this.contentsAvailable, "contents not available FileSystemSourceFile::Compute Line Count");
00179 
00180     InputStream inputStream = this.getStream();
00181     LineNumberReader reader = new LineNumberReader(new InputStreamReader(inputStream));
00182     try
00183     {
00184         boolean done = false;
00185         while( ! done)
00186         {
00187             String line = reader.readLine();
00188             done = (line == null);
00189         }
00190     }
00191     catch( IOException e)
00192     {
00193         Dialogs.fatalException(Strings.CANT_READ_SOURCEFILE, this.getName(), e);
00194     }
00195 
00196     this.lineCount = 1 + reader.getLineNumber();
00197 }
00198 
00199 
00200 
00201 
00202 /*************************************************************************
00203  *  Returns an open input stream for reading the source file's contents.
00204  *
00205  *  The stream will close itself on finalization.
00206  *  <p>
00207  *  This method should only be called if <code>this.isAvailable()</code>.
00208  *
00209  ************************************************************************/
00210     
00211 public InputStream getStream()
00212 {
00213     this.requireAvailable();
00214     InputStream stream;
00215 
00216     try
00217     {
00218         stream = new FileInputStream(this.resolvedPath);
00219     }
00220     catch( IOException e)
00221     {
00222         Dialogs.fatalException(Strings.CANT_OPEN_SOURCEFILE, this.getName(), e);
00223         stream = null;  // compiler can't see 'stream' is returned iff initialized
00224     }
00225 
00226     return stream;
00227 }
00228 
00229 
00230 
00231 
00233 //  AVAILABILITY OF SOURCE FILE CONTENTS                                //
00235 
00236 
00237 
00238 
00239 /*************************************************************************
00240  *  Returns whether the source file can be located and read.
00241  ************************************************************************/
00242     
00243 public boolean isAvailable()
00244 {
00245     if( ! this.hasBeenSought )
00246         this.searchForContents();
00247 
00248     return this.contentsAvailable;
00249 }
00250 
00251 
00252 
00253 public boolean isText()
00254  {
00255    return this.istext;
00256  }
00257 
00258 
00259 public void setIsText(boolean bi)
00260   { 
00261      this.istext=bi;
00262   }
00263 
00264 /*************************************************************************
00265  *  Returns whether this source file has a line with the given line number.
00266  ************************************************************************/
00267     
00268 public boolean hasLine(int lineNumber)
00269 {
00270     Dialogs.Assert(this.contentsAvailable, "contents not available FileSystemSourceFile::Compute Line Count");
00271 
00272     return (lineNumber >= 0) && (lineNumber <= this.getLineCount());
00273 }
00274 
00275 
00276 
00277 
00278 /*************************************************************************
00279  *  Demands that the source file be available.
00280  *
00281  *  Fails if it isn't.
00282  *
00283  ************************************************************************/
00284     
00285 protected void requireAvailable()
00286 {
00287     if( ! this.isAvailable() )
00288         Dialogs.fail2("Attempt to open an unavailable SourceFile", this.getName());
00289 }
00290 
00291 
00292 
00293 
00294 /*************************************************************************
00295  *  Searches for the source file's contents.
00296  *
00297  *  If the file's path is relative, it is sought at each path in the
00298  *  experiment's configuration and in the experiment's default directory.
00299  *  Once the file has been found in a directory the search ends, even if
00300  *  that file is not readable. Even if the file is found and readable,
00301  *  reading it to count its lines is deferred until the first time the line
00302  *  count is needed.
00303  *  <p>
00304  *  The search is performed even if <code>this.hasBeenSought</code>, so the
00305  *  search can be repeated under different conditions if necessary.
00306  *
00307  ************************************************************************/
00308 
00309 protected void searchForContents()
00310 {
00311     assert (this.experiment instanceof BaseExperimentWithMetrics);
00312     
00313     File resolved;
00314     boolean found;
00315 
00316     // first use empty search path -- handles absolute and default-dir-relative names
00317     resolved = this.makeSearchFile(null);
00318     found    = resolved.exists();
00319 
00320     // next look in each search path
00321     if( ! found )
00322     {
00323         final BaseExperimentWithMetrics exp = (BaseExperimentWithMetrics) this.experiment;
00324         int count = exp.getSearchPathCount();
00325         for( int k = 0;  (k < count) && (! found);  k++ )
00326         {
00327             File search = exp.getSearchPath(k);
00328             resolved    = this.makeSearchFile(search);
00329             found       = resolved.exists();
00330         }
00331     }
00332 
00333     // set instance variables to record search result
00334     this.hasBeenSought     = true;
00335     this.contentsAvailable = (found && resolved.canRead());
00336     this.resolvedPath      = resolved;
00337     this.lineCount         = -1;        // counting lines is deferred
00338 }
00339 
00340 
00341 
00342 
00343 /*************************************************************************
00344  *  Returns a <code>File</code> object for this source file's contents
00345  *  assuming it were at a given search path.
00346  *
00347  *  A relative search path is taken to be relative to the experiment's
00348  *  default directory.
00349  *
00350  ************************************************************************/
00351 
00352 protected File makeSearchFile(File search)
00353 {
00354     assert (this.experiment instanceof BaseExperimentWithMetrics);
00355     
00356     String filenamePath = this.filename.getPath();              // there is no 'File(File, File)' constructor, sigh!
00357     File file;
00358 
00359         file = new File(search, filenamePath);
00360         if( ! file.isAbsolute() )
00361         {
00362             File defaultDir = this.experiment.getDefaultDirectory();
00363             file = new File(defaultDir, file.getPath());        // there is no 'File(File, File)' constructor, sigh!
00364         }
00365 
00366     return file;
00367 }
00368 
00369 
00375 public String getCompleteFilename() {
00376     if(this.contentsAvailable) {
00377         if(this.resolvedPath != null)
00378             return this.resolvedPath.getAbsolutePath();
00379     } else
00380         return this.getFilename().getAbsolutePath();
00381     return null;
00382 }
00383 
00384 
00385 }
00386 
00387 
00388 
00389 
00390 
00391 
00392 
00393 

Generated on 5 May 2015 for HPCVIEWER by  doxygen 1.6.1