001 /* 002 * Copyright 2007, 2012 Stephen Fisher and Junhyong Kim, University of 003 * Pennsylvania. 004 * 005 * This file is part of Glo-DB. 006 * 007 * Glo-DB is free software: you can redistribute it and/or modify it 008 * under the terms of the GNU General Public License as published by 009 * the Free Software Foundation, either version 3 of the License, or 010 * (at your option) any later version. 011 * 012 * Glo-DB is distributed in the hope that it will be useful, but 013 * WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * General Public License for more details. 016 * 017 * You should have received a copy of the GNU General Public License 018 * along with Glo-DB. If not, see <http://www.gnu.org/licenses/>. 019 * 020 * @(#)GenBankTrack.java 021 */ 022 023 package edu.upenn.gloDB.io; 024 025 import edu.upenn.gloDB.*; 026 import edu.upenn.gloDB.gui.GUIUtils; 027 import java.io.*; 028 import javax.swing.filechooser.FileFilter; 029 030 /** 031 * Import/Export Track data from/to GenBank files. 032 * 033 * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 034 * THIS FILE IS A PLACE HOLDER 035 * xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 036 * 037 * @author Stephen Fisher 038 * @version $Id: GenBankTrack.java,v 1.1.2.13 2007/03/01 21:17:33 fisher Exp $ 039 */ 040 041 public class GenBankTrack implements TrackFile { 042 043 private final int ID = FileIO.GENBANK; 044 private final String DESC = "GenBank files (*.gb; *.genbank)"; 045 private final String[] EXT = {".gb", ".genbank"}; 046 private final FileFilter fileFilter = new GenBankFilter(); 047 048 //-------------------------------------------------------------------------- 049 // Setters and Getters 050 051 public int getID() { return ID; } 052 053 public String getDesc() { return DESC; } 054 055 public String[] getExt() { return EXT; } 056 057 public FileFilter getFileFilter() { return fileFilter; } 058 059 //-------------------------------------------------------------------------- 060 // Miscellaneous Methods 061 062 /** 063 * Load all Features in the GenBank file into a single Track and 064 * return the resulting Track object. 065 */ 066 public Track load(String filename) { 067 return load(filename, ""); 068 } 069 070 /** 071 * Load all Features in the GenBank file into a single Track and 072 * return the resulting Track object. 073 * 074 * @XXX need to throw FileIO exceptions, rather than just print 075 * errors. 076 */ 077 public Track load(String filename, String seqID) { 078 // when creating Track's ID, if necessary, remove ".gb" 079 // filename extension 080 String id = filename; 081 if (id.endsWith(".gb")) id = id.substring(1, id.length()-5); 082 if (id.endsWith(".genbank")) id = id.substring(1, id.length()-10); 083 Track track = new Track(false, id); 084 085 Sequence srcSequence = null; 086 if (seqID.length() > 0) srcSequence = ObjectHandles.getSequence(seqID); 087 088 try { 089 BufferedReader bReader = new BufferedReader(new FileReader(filename)); 090 091 String line; 092 boolean firstFeat = true; 093 094 Feature feature = null; // current Feature 095 096 while ((line = bReader.readLine()).trim() != null) { 097 // skip all comment lines 098 if (! line.startsWith("#")) { 099 if (! firstFeat) { 100 // not first Feature so append existing Feature 101 // before reseting the variables for the next 102 // Feature. 103 track.addFeature(feature); 104 } else { 105 firstFeat = false; 106 } 107 108 // split line at every space 109 String[] fields = line.split(" "); 110 111 // get a reference to the Sequence for this 112 // Feature. If no Sequence is found, then don't 113 // add this Feature. If srcSequence already 114 // exists, then just use that instead. 115 Sequence seqRef; 116 if (srcSequence == null) { 117 seqRef = ObjectHandles.getSequence(fields[0]); 118 if (seqRef == null) continue; 119 } else { 120 seqRef = srcSequence; 121 } 122 123 // create a new Feature object 124 feature = new ExactFeature(Integer.parseInt(fields[3]), 125 Integer.parseInt(fields[4]), seqRef); 126 127 // get Feature attributes 128 String attributes = ""; 129 attributes += "source=" + fields[1]; // add source 130 attributes += ";track=" + fields[2]; // add track 131 attributes += ";score=" + fields[5]; // add score 132 attributes += ";strand=" + fields[6]; // add strand 133 attributes += ";frame=" + fields[7]; // add frame 134 if (fields.length > 8) { 135 attributes += ";attribs=" + fields[8]; // get attributes 136 if (fields.length > 9) { 137 attributes += ";comments=" + fields[9]; // get comments 138 } 139 } 140 feature.setAttributes(attributes); 141 142 // add the Feature object to the Track 143 track.addFeature(feature); 144 } 145 146 // add last Features info 147 if (feature != null) track.addFeature(feature); 148 } 149 150 bReader.close(); 151 } catch (FileNotFoundException e) { 152 GloDBUtils.printError("File not found: " + e.getMessage()); 153 return null; 154 } catch (IOException e) { 155 GloDBUtils.printError("Error reading file: " + filename); 156 return null; 157 } 158 159 if (track.numFeatures() == 0) { 160 // this assumes an empty Track is a mistake, so return null 161 GloDBUtils.printError("Unable to load any features from the file: " + filename); 162 return null; 163 } 164 165 // add track to trackPool 166 try { 167 ObjectHandles.addTrack(track); 168 } catch (InvalidIDException e) { 169 String id_new = Track.randomID("_T"); 170 String msg = "ID \"" + track.getID() + "\" already exists, using ID \"" + id_new + "\" instead."; 171 GloDBUtils.printWarning(msg); 172 173 // add self to set of all Tracks, using new ID 174 track.setID(id_new, false); 175 ObjectHandles.addTrack(track); 176 } 177 178 GloDBUtils.printMsg("Loaded GenBank file: " + filename); 179 return track; 180 } 181 182 /** 183 * Save the Track to a file based on it's ID. This will 184 * overwrite any existing file and append ".gb" to the filename, 185 * if necessary. 186 */ 187 public void save(String id) { 188 // add ".gb" filename extension, if necessary 189 String filename = id; 190 if ((! filename.endsWith(".gb")) || (! filename.endsWith(".genbank"))) { 191 filename += ".gb"; 192 } 193 194 save(id, filename, true); 195 } 196 197 /** 198 * Save all Features in a GloDB file. 199 * 200 * @XXX need to throw FileIO exceptions, rather than just print 201 * errors. 202 * @XXX Should offer option to include Sequence data. 203 */ 204 public void save(String id, String filename, boolean overwrite) { 205 // add ".gb" filename extension, if necessary 206 if ((! filename.endsWith(".gb")) && (! filename.endsWith(".genbank"))) { 207 filename += ".gb"; 208 } 209 210 File file = new File(filename); 211 // if the file already exists and not supposed to overwrite 212 // it, then return on error. 213 if (file.exists() && (! overwrite)) { 214 GloDBUtils.printMsg("ERROR: file \"" + filename + "\" already exists."); 215 return; 216 } 217 218 try { 219 FileOutputStream fStream = new FileOutputStream(file); 220 ObjectOutputStream oStream = new ObjectOutputStream(fStream); 221 Track f = ObjectHandles.getTrack(id); 222 oStream.writeObject(f); 223 oStream.flush(); 224 oStream.close(); 225 } catch (FileNotFoundException e) { 226 // problem with FileOutputStream 227 GloDBUtils.printMsg("ERROR: file \"" + filename + "\" can not be opened."); 228 } catch (IOException e) { 229 // problem with ObjectOutputStream. XXX do we need to 230 // close 'oStream'? 231 GloDBUtils.printMsg("ERROR: writting output file \"" + filename + "\"."); 232 } 233 } 234 235 /** 236 * GenBank specific FileFilter. 237 * @XXX This should use EXT. 238 */ 239 private class GenBankFilter extends FileFilter { 240 public boolean accept(File f) { 241 // accept directories 242 if (f.isDirectory()) return true; 243 244 // if true, then don't filter by file extensions. 245 if (GUIUtils.showAllFiles()) return true; 246 247 // accept files ending in '.genbank' or '.gb' 248 if ((f.getName()).endsWith(".genbank")) return true; 249 if ((f.getName()).endsWith(".gb")) return true; 250 251 return false; 252 } 253 254 // set the filter's description 255 public String getDescription() { return DESC; } 256 } 257 258 } // GenBankTrack.java 259 260