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     * @(#)ObjectHandles.java
021     */
022    
023    package edu.upenn.gloDB;
024    
025    import java.util.HashMap;
026    import java.util.HashSet;
027    import java.util.Set;
028    import java.util.TreeSet;
029    import java.util.Iterator;
030    import javax.swing.*;
031    
032    /**
033     * ObjectHandles.
034     *
035     * @author  Stephen Fisher
036     * @version $Id: ObjectHandles.java,v 1.15.2.13 2007/03/01 21:17:33 fisher Exp $
037     */
038    
039    public class ObjectHandles { 
040    
041             /** 
042              * The HashMap of all existing Tracks.  It is made public so that
043              * the user can directly access the Tracks to test if a specific
044              * Track is in the set and to remove Tracks from the HashMap in
045              * the case of deleting the Track.  When deleting Tracks, it is
046              * necessary to remove the Track from the trackPool.  While new
047              * Tracks are added to the trackPool by default, it is possible to
048              * create a Track and not have it added to the trackPool.  This
049              * should be avoided as certain functions require the Track to
050              * exist in the trackPool.
051              */
052             public static HashMap trackPool = new HashMap();
053    
054             /**
055              * The set of all existing Feature objects (Fuzzy and Exact).  It
056              * is made public so that the user can directly access the
057              * Features to test if a specific Feature is in the set and to
058              * remove Features from the set in the case of deleting the
059              * Feature. When removing Features, they must be removed from the
060              * featurePool.  While new Features are added to the featurePool
061              * by default, it is possible to create a Feature and not have it
062              * added to the featurePool. This should be avoided as certain
063              * functions require the Feature to exist in the featurePool.
064              */
065             //      private static HashSet featurePool = new HashSet();
066    
067             /** 
068              * The set of all existing Sequences.  It is made public so that
069              * the user can directly access the tracks to test if a specific
070              * Sequence is in the set and to remove Sequences from the set in
071              * the case of deleting the Sequence.  When removing Sequences,
072              * they must be removed from the sequencePool.  While new
073              * Sequences are added to the sequencePool by default, it is
074              * possible to create a Sequence and not have it added to the
075              * sequencePool. This should be avoided as certain functions
076              * require the Sequence to exist in the sequencePool.
077              */
078             public static HashMap sequencePool = new HashMap();
079    
080             /**
081              * This is a duplicate list of Tracks in the trackPool.  It is
082              * used by the GUI.
083              */
084             private static DefaultComboBoxModel trackList = new DefaultComboBoxModel();
085    
086             /**
087              * This is a duplicate list of Features in the featurePool.  It is
088              * used by the GUI.
089              */
090             //      private static DefaultListModel featureList = new DefaultListModel();
091    
092             /**
093              * This is a duplicate list of Sequences in the sequencePool.  It is
094              * used by the GUI.
095              */
096             private static DefaultComboBoxModel sequenceList = new DefaultComboBoxModel();
097    
098             /**
099              * This is a list of all Tracks in the trackPool, that contain
100              * each Sequence.  It is used by the GUI.
101              */
102             public static HashMap trackBySequenceList = new HashMap();
103    
104        //--------------------------------------------------------------------------
105        // Setters and Getters
106       
107        /** Get the trackPool. */
108        public static HashMap getTrackPool() { return trackPool; }
109    
110        /** Get the trackList. */
111        public static DefaultComboBoxModel getTrackList() { return trackList; }
112    
113        /** Get the featurePool. */
114             //    public static HashSet getFeaturePool() { return featurePool; }
115    
116        /** Get the featureList. */
117             //    public static DefaultListModel getFeatureList() { return featureList; }
118    
119        /** Get the sequencePool. */
120        public static HashMap getSequencePool() { return sequencePool; }
121    
122        /** Get the sequenceList. */
123        public static DefaultComboBoxModel getSequenceList() { return sequenceList; }
124    
125        //--------------------------------------------------------------------------
126        // Miscellaneous Methods
127    
128             /** Add a Tracks to the trackPool. */
129             public static void addTrack(Track track) throws InvalidIDException { 
130                      String id = track.getID();
131                      if (trackPool.containsKey(id)) {
132                                    String msg = "ID \"" + id + "\" already exists in trackPool.";
133                                    throw new InvalidIDException(msg);
134                      }
135    
136                      // add Track to trackPool
137                      trackPool.put(id, track); 
138    
139                      // add Track to trackList, for GUI
140                      trackList.addElement(id);
141    
142                      // add Track to appropriate trackLists in
143                      // trackBySequenceList
144                      Set sources = track.getSourceSet();
145                      if (sources != null) {
146                                    TreeSet trackSet;
147                                    for (Iterator i = sources.iterator(); i.hasNext();) {
148                                             String sequence = (String) i.next(); 
149                                             if (trackBySequenceList.containsKey(sequence)) {
150                                                      trackSet = (TreeSet) trackBySequenceList.get(sequence);
151                                             } else {
152                                                      // we should never reach this point -- empty DLMs
153                                                      // should be created when Sequences are added to
154                                                      // sequencePool.
155                                                      trackSet = new TreeSet();
156                                             }
157                                             trackSet.add(id);
158                                             trackBySequenceList.put(sequence, trackSet);
159                                    }
160                      }
161             }
162    
163             /** Removes the Track object for trackPool and other relevant lists. */
164             public static void removeTrack(String id) {
165                      Track track = getTrack(id);
166                      if (track != null) removeTrack(track);
167             }
168    
169             /** Removes the Track object for trackPool and other relevant lists. */
170             public static void removeTrack(Track track) {
171                      String id = track.getID();
172    
173                      // if not in trackPool, then not in any lists
174                      if (trackPool.containsKey(id)) {
175                                    // remove from trackPool
176                                    trackPool.remove(id);
177    
178                                    // remove from trackList
179                                    trackList.removeElement(id);
180    
181                                    // remove from trackBySequenceList
182                                    Set sources = track.getSourceSet();
183                                    if (sources != null) {
184                                             TreeSet trackSet;
185                                             for (Iterator i = sources.iterator(); i.hasNext();) {
186                                                      String sequence = (String) i.next(); 
187                                                      // this test should be unnecessary, as must be in
188                                                      // trackList if in trackPool
189                                                      if (trackBySequenceList.containsKey(sequence)) {
190                                                                    trackSet = (TreeSet) trackBySequenceList.get(sequence);
191                                                                    trackSet.remove(id);
192                                                                    trackBySequenceList.put(sequence, trackSet);
193                                                      }
194                                             }
195                                    }
196                      }
197             }
198    
199             /** Rebuilds the Track relevant lists. */
200             public static void rebuildTrack(Track track) {
201                      removeTrack(track);
202                      addTrack(track);
203             }
204    
205             /** 
206              * Returns true if the Track object exists in the trackPool.
207              */
208             public static boolean containsTrack(String id) { 
209                      if (id == "") return false;
210                      else return trackPool.containsKey(id); 
211             }
212    
213             /** 
214              * Returns the Track object for the given ID. 
215              * @XXX Should throw an exception if 'id' is not found.
216              */
217             public static Track getTrack(String id) { 
218                      if (id == "") return null;
219                      else return (Track) trackPool.get(id); 
220             }
221    
222             /** Returns a iterator over all Tracks in trackPool. */
223             public static Iterator trackIterator() { return trackPool.values().iterator(); }
224    
225             /** 
226              * Changes the Track's ID in trackPool, trackList, and
227              * trackBySequenceList.
228              */
229             public static void renameTrack(String oldID, String newID) { 
230                      Track track = getTrack(oldID);
231    
232                      // make sure track exists
233                      if (track == null) {
234                                    GloDBUtils.printError("Track \"" + oldID + "\" not found.");
235                                    return;
236                      }
237    
238                      renameTrack(track, newID);
239             }
240    
241             /** 
242              * Changes the Track's ID in trackPool, trackList, and
243              * trackBySequenceList.
244              */
245             public static void renameTrack(Track track, String newID) { 
246                      // make sure track exists
247                      if (track == null) {
248                                    GloDBUtils.printError("Null track, can not be renamed.");
249                                    return;
250                      }
251    
252                      // check to make sure ID doesn't already exist in trackPool
253                      if (trackPool.containsKey(newID)) {
254                                    String msg = "ID \"" + newID + "\" already exists in trackPool.";
255                                    throw new InvalidIDException(msg);
256                      }
257    
258                      // remove the Track from trackPool and other relevant lists.
259                      removeTrack(track);
260    
261                      // change ID and add to trackPool
262                      track.id = newID;
263                      addTrack(track);
264             }
265    
266        /** 
267              * Get the trackList that contains all Tracks with the given
268              * Sequence.
269              */
270        public static TreeSet getTrackBySequenceList(String id) { 
271                      return (TreeSet) trackBySequenceList.get(id); 
272             }
273    
274    
275             /** Add a Feature to the featurePool. */
276             public static void addFeature(Feature feature) { 
277                      //              featurePool.add(feature); 
278                      //              featureList.addElement(feature);
279             }
280    
281             /** Returns a iterator over all Features in featurePool. */
282             //      public static Iterator featureIterator() { return featurePool.iterator(); }
283    
284    
285             /** Add a Sequence to the sequencePool. */
286             public static void addSequence(Sequence sequence) throws InvalidIDException {
287                      String id = sequence.getID();
288                      if (sequencePool.containsKey(id)) {
289                                    String msg = "ID \"" + id + "\" already exists in sequencePool.";
290                                    throw new InvalidIDException(msg);
291                      }
292                              
293                      // add Sequence to sequencePool
294                      sequencePool.put(id, sequence);
295    
296                      // add Sequence to sequenceList, for GUI
297                      sequenceList.addElement(id);
298    
299                      // make sure the Sequence is represented in trackBySequenceList
300                      if (! trackBySequenceList.containsKey(id)) {
301                                    trackBySequenceList.put(id, new TreeSet());
302                      }
303             }
304    
305             /** Removes the Sequence object for sequencePool and other relevant lists. */
306             public static void removeSequence(Sequence sequence) {
307                      String id = sequence.getID();
308    
309                      // if not in sequencePool, then not in any lists
310                      if (sequencePool.containsKey(id)) {
311                                    // remove from sequencePool
312                                    sequencePool.remove(id);
313    
314                                    // remove from sequenceList
315                                    sequenceList.removeElement(id);
316                      }
317             }
318    
319             /** 
320              * Returns true if the Sequence object exists in the sequencePool.
321              */
322             public static boolean containsSequence(String id) { 
323                      if (id == "") return false;
324                      else return sequencePool.containsKey(id); 
325             }
326    
327             /** Returns a iterator over all Sequences in sequencePool. */
328             public static Iterator sequenceIterator() { return sequencePool.values().iterator(); }
329    
330             /** 
331              * Returns the Sequence object for the given ID. 
332              * @XXX Should throw an exception if 'id' is not found.
333              */
334             public static Sequence getSequence(String id) { 
335                      if (id == "") return null;
336                      else return (Sequence) sequencePool.get(id); 
337             }
338    
339             /*
340              * Changes the Sequence's ID in sequencePool, sequenceList, and
341              * trackBySequenceList.
342              * @XXX WARNING, this needs to change the relevant Feature.source
343              * values when the sequence ID changes.
344              * @XXX could only allow this if trackSet is empty but that might
345              * be confusing
346              */
347             /*
348             public static void renameSequence(Sequence sequence, String newID) { 
349                      // check to make sure ID doesn't already exist in sequencePool
350                      if (sequencePool.containsKey(newID)) {
351                                    String msg = "ID \"" + newID + "\" already exists in sequencePool.";
352                                    throw new InvalidIDException(msg);
353                      }
354    
355                      // remove the Sequence from sequencePool and other relevant lists
356                      removeSequence(sequence);
357    
358                      // update the sequence reference in trackBySequenceList
359                      String oldID = sequence.getID();
360                      if (trackBySequenceList.containsKey(oldID)) {
361                                    TreeSet trackSet = (TreeSet) trackBySequenceList.get(oldID);
362                                    trackBySequenceList.remove(oldID);
363                                    trackBySequenceList.put(newID, trackSet);
364                      }
365                                    
366                      // change ID and add to sequencePool
367                      sequence.id = newID;
368                      addSequence(sequence);
369             }
370             */
371    } // ObjectHandles.java