001 package edu.nrao.sss.model.source.parser; 002 003 import java.io.FileNotFoundException; 004 import java.io.Reader; 005 import java.io.File; 006 import java.io.FileReader; 007 import java.io.InputStreamReader; 008 import java.io.InputStream; 009 import java.io.IOException; 010 011 import java.util.zip.ZipInputStream; 012 import java.util.zip.GZIPInputStream; 013 import java.util.List; 014 import java.util.ArrayList; 015 016 import edu.nrao.sss.model.source.SourceCatalog; 017 import edu.nrao.sss.util.FileCompressionFormat; 018 019 /** 020 * An abstract implementation of the common methods in the SourceCatalogReader interface. 021 * <p> 022 * <b>CVS Info:</b> 023 * <table style="margin-left:2em"> 024 * <tr><td>$Revision: 630 $</td></tr> 025 * <tr><td>$Date: 2007-05-18 14:12:55 -0600 (Fri, 18 May 2007) $</td></tr> 026 * <tr><td>$Author: dharland $</td></tr> 027 * </table></p> 028 */ 029 public abstract class AbstractSourceCatalogReader 030 implements SourceCatalogReader 031 { 032 protected SourceCatalog catalog; 033 protected boolean readWasSuccessful; 034 protected List<ParseError> errors; 035 036 protected String sourceInfoOrigin; 037 protected String histRecPrefix; 038 039 public AbstractSourceCatalogReader() 040 { 041 errors = new ArrayList<ParseError>(); 042 readWasSuccessful = false; 043 044 sourceInfoOrigin = null; 045 histRecPrefix = ""; 046 } 047 048 /** 049 * A default implementation of {@link SourceCatalogReader#read(String)}. This 050 * calls {@link #read(String, SourceCatalog)} with a null catalog. 051 */ 052 public boolean read(String fileName) 053 throws FileNotFoundException 054 { 055 return read(fileName, null); 056 } 057 058 /** 059 * A default implementation of {@link SourceCatalogReader#read(String, SourceCatalog)}. This 060 * calls {@link #read(Reader, SourceCatalog)}, wrapping <code>fileName</code> with a FileReader. 061 */ 062 public boolean read(String fileName, SourceCatalog destination) 063 throws FileNotFoundException 064 { 065 return read(new FileReader(new File(fileName)), destination); 066 } 067 068 /** 069 * A default implementation of {@link SourceCatalogReader#read(Reader)}. This 070 * calls {@link #read(Reader, SourceCatalog)} with a null catalog. 071 */ 072 public boolean read(Reader in) 073 { 074 return read (in, null); 075 } 076 077 /** 078 * A default implementation of {@link SourceCatalogReader#read(InputStream)}. 079 * This calls {@link #read(InputStream, SourceCatalog, FileCompressionFormat)} 080 * with a null catalog and a UNCOMPRESSED format. 081 */ 082 public boolean read(InputStream in) 083 { 084 return read(in, null, FileCompressionFormat.UNCOMPRESSED); 085 } 086 087 /** 088 * A default implementation of {@link SourceCatalogReader#read(InputStream, SourceCatalog)}. 089 * This calls {@link #read(InputStream, SourceCatalog, FileCompressionFormat)} 090 * with a UNCOMPRESSED format. 091 */ 092 public boolean read(InputStream in, SourceCatalog destination) 093 { 094 return read(in, destination, FileCompressionFormat.UNCOMPRESSED); 095 } 096 097 /** 098 * A default implementation of {@link SourceCatalogReader#read(InputStream, FileCompressionFormat)}. 099 * This calls {@link #read(InputStream, SourceCatalog, FileCompressionFormat)} 100 * with a null catalog. 101 */ 102 public boolean read(InputStream in, FileCompressionFormat format) 103 { 104 return read(in, null, format); 105 } 106 107 /** 108 * This method prepares the input stream {@code in} to be passed as an 109 * InputStreamReader to {@link #read(Reader, SourceCatalog)}. If {@code 110 * format} is ZIP or GZ, the InputStream is wrapped in a ZipInputStream or 111 * GZIPInputStream respectively before being wrapped in an InputStreamReader. 112 * This allows the primary read method (which is abstract in this class) to 113 * be unaware that the input was compressed. If {@code format} is null or 114 * UNCOMPRESSED, {@code in} is passed directly into the InputStreamReader 115 * constructor. 116 */ 117 public boolean read(InputStream in, SourceCatalog destination, FileCompressionFormat format) 118 { 119 InputStream wrappedIn = in; 120 121 //Wrap "in" in an appropriate compression filter if necessary, then wrap 122 //that in an InputStreamReader and call read(reader, destination); 123 if (format != null) 124 { 125 switch(format) 126 { 127 case ZIP: 128 try 129 { 130 wrappedIn = new ZipInputStream(in); 131 132 //Prepare the ZipInputStream to be reading the next (and hopefully 133 //only) file. 134 ((ZipInputStream)wrappedIn).getNextEntry(); 135 } 136 137 catch(IOException ioe) 138 { 139 putError(0, "Error reading catalog. Invalid ZIP format."); 140 return false; 141 } 142 break; 143 144 case GZ: 145 try 146 { 147 wrappedIn = new GZIPInputStream(in); 148 } 149 150 catch(IOException ioe) 151 { 152 putError(0, "Error reading catalog. Invalid GZIP format."); 153 return false; 154 } 155 break; 156 157 //These cases will just use the default value of wrappedIn (i.e. in 158 //itself) 159 //case UNCOMPRESSED: 160 //default: 161 } 162 } 163 164 boolean success = read(new InputStreamReader(wrappedIn), destination); 165 //wrappedIn.close(); 166 167 return success; 168 } 169 170 /** 171 * An abstract method that must be implemented by subclasses. All other read 172 * methods delegate to this one. 173 * 174 * @see #read(Reader, SourceCatalog) 175 */ 176 public abstract boolean read(Reader in, SourceCatalog destination); 177 178 /** 179 * @see SourceCatalogReader#getErrors() 180 */ 181 public StringBuilder getErrors() 182 { 183 StringBuilder errorMsg = new StringBuilder(); 184 185 for (ParseError error : errors) 186 error.appendTo(errorMsg); 187 188 return errorMsg; 189 } 190 191 /** 192 * @see SourceCatalogReader#getError(int) 193 */ 194 public String getError(int index) 195 { 196 return errors.get(index).toString(); 197 } 198 199 /** 200 * @see SourceCatalogReader#getErrorCount() 201 */ 202 public int getErrorCount() 203 { 204 return errors.size(); 205 } 206 207 /** 208 * @see SourceCatalogReader#getCatalog() 209 */ 210 public SourceCatalog getCatalog() 211 { 212 if (catalog == null) 213 catalog = new SourceCatalog(); 214 215 return catalog; 216 } 217 218 /** 219 * @see SourceCatalogReader#getSuccess() 220 */ 221 public boolean getSuccess() 222 { 223 return readWasSuccessful; 224 } 225 226 /** 227 * @see SourceCatalogReader#setOriginOfSourceInformation(String) 228 */ 229 public void setOriginOfSourceInformation(String origin) 230 { 231 sourceInfoOrigin = origin; 232 } 233 234 public String getOriginOfSourceInformation() 235 { 236 return sourceInfoOrigin; 237 } 238 239 /** 240 * @see SourceCatalogReader#setPrefixForHistoricalRecords(String) 241 */ 242 public void setPrefixForHistoricalRecords(String prefix) 243 { 244 histRecPrefix = (prefix == null) ? "" : prefix; 245 } 246 247 public String getPrefixForHistoricalRecords() 248 { 249 return histRecPrefix; 250 } 251 252 /** Adds a new parsing error to our list. */ 253 protected void putError(int lineNum, String message) 254 { 255 errors.add(new ParseError(lineNum, message)); 256 } 257 }