158489e27f8224b481ee2b72d5b9c492485e3790
[jalview.git] / src / jalview / io / FileFormats.java
1 package jalview.io;
2
3 import java.util.ArrayList;
4 import java.util.HashSet;
5 import java.util.LinkedHashMap;
6 import java.util.List;
7 import java.util.Map;
8 import java.util.Set;
9
10 /**
11  * A singleton registry of alignment file formats known to Jalview. On startup,
12  * the 'built-in' formats are added (from the FileFormat enum). Additional
13  * formats can be registered (or formats deregistered) programmatically, for
14  * example with a Groovy script.
15  * 
16  * @author gmcarstairs
17  *
18  */
19 public class FileFormats
20 {
21   private static FileFormats instance = new FileFormats();
22
23   /*
24    * A lookup map of file formats by upper-cased name
25    */
26   private static Map<String, FileFormatI> formats;
27
28   /*
29    * Formats in this set are capable of being identified by IdentifyFile 
30    */
31   private static Set<FileFormatI> identifiable;
32
33   public static FileFormats getInstance()
34   {
35     return instance;
36   }
37
38   /**
39    * Private constructor registers Jalview's built-in file formats
40    */
41   private FileFormats()
42   {
43     reset();
44   }
45
46   /**
47    * Reset to just the built-in file formats packaged with Jalview. These are
48    * added (and will be shown in menus) in the order of their declaration in the
49    * FileFormat enum.
50    */
51   public synchronized void reset()
52   {
53     formats = new LinkedHashMap<String, FileFormatI>();
54     identifiable = new HashSet<FileFormatI>();
55     for (FileFormat format : FileFormat.values())
56     {
57       registerFileFormat(format, format.isIdentifiable());
58     }
59   }
60
61   /**
62    * Answers true if the format is one that can be identified by IdentifyFile.
63    * Answers false for a null value.
64    */
65   public boolean isIdentifiable(FileFormatI f)
66   {
67     return identifiable.contains(f);
68   }
69
70   /**
71    * Registers a file format for case-insensitive lookup by name
72    * 
73    * @param format
74    */
75   public void registerFileFormat(FileFormatI format)
76   {
77     registerFileFormat(format, false);
78   }
79
80   protected void registerFileFormat(FileFormatI format,
81           boolean isIdentifiable)
82   {
83     String name = format.getName().toUpperCase();
84     if (formats.containsKey(name))
85     {
86       System.err.println("Overwriting file format: " + format.getName());
87     }
88     formats.put(name, format);
89     if (isIdentifiable)
90     {
91       identifiable.add(format);
92     }
93   }
94
95   /**
96    * Deregisters a file format so it is no longer shown in menus
97    * 
98    * @param name
99    */
100   public void deregisterFileFormat(String name)
101   {
102     FileFormatI ff = formats.remove(name.toUpperCase());
103     identifiable.remove(ff);
104   }
105
106   /**
107    * Answers a list of writeable file formats (as strings, corresponding to the
108    * getName() and forName() methods)
109    * 
110    * @param textOnly
111    *          if true, only text (not binary) formats are included
112    * @return
113    */
114   public List<String> getWritableFormats(boolean textOnly)
115   {
116     List<String> l = new ArrayList<String>();
117     for (FileFormatI ff : formats.values())
118     {
119       if (ff.isWritable() && (!textOnly || ff.isTextFormat()))
120       {
121         l.add(ff.getName());
122       }
123     }
124     return l;
125   }
126
127   /**
128    * Answers a list of readable file formats (as strings, corresponding to the
129    * getName() and forName() methods)
130    * 
131    * @return
132    */
133   public List<String> getReadableFormats()
134   {
135     List<String> l = new ArrayList<String>();
136     for (FileFormatI ff : formats.values())
137     {
138       if (ff.isReadable())
139       {
140         l.add(ff.getName());
141       }
142     }
143     return l;
144   }
145
146   /**
147    * Returns the file format with the given name, or null if format is null or
148    * invalid. This is not case-sensitive.
149    * 
150    * @param format
151    * @return
152    */
153   public FileFormatI forName(String format)
154   {
155     return format == null ? null : formats.get(format.toUpperCase());
156   }
157
158   /**
159    * Returns an iterable collection of registered file formats (in the order in
160    * which they were registered)
161    * 
162    * @return
163    */
164   public Iterable<FileFormatI> getFormats()
165   {
166     return formats.values();
167   }
168 }