a18d4e82728e0253f202df0a7b8f828c87fddb94
[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 built in to Jalview and instantiated
30    * on startup, any others are added dynamically 
31    */
32   private static Set<FileFormatI> builtIn;
33
34   public static FileFormats getInstance()
35   {
36     return instance;
37   }
38
39   /**
40    * Private constructor registers Jalview's built-in file formats
41    */
42   private FileFormats()
43   {
44     reset();
45   }
46
47   /**
48    * Reset to just the built-in file formats packaged with Jalview. These are
49    * added (and will be shown in menus) in the order of their declaration in the
50    * FileFormat enum.
51    */
52   public synchronized void reset()
53   {
54     formats = new LinkedHashMap<String, FileFormatI>();
55     builtIn = new HashSet<FileFormatI>();
56     for (FileFormat format : FileFormat.values())
57     {
58       registerFileFormat(format, true);
59     }
60   }
61
62   /**
63    * Answers false if the format is one 'built in' to Jalview, or true if not
64    * (meaning it has been added dynamically at runtime). Only built-in formats
65    * can be validated by IdentifyFile. Answers true for a null input.
66    */
67   public boolean isDynamic(FileFormatI f)
68   {
69     return !builtIn.contains(f);
70   }
71
72   /**
73    * Registers a file format for case-insensitive lookup by name
74    * 
75    * @param format
76    */
77   public void registerFileFormat(FileFormatI format)
78   {
79     registerFileFormat(format, false);
80   }
81
82   protected void registerFileFormat(FileFormatI format,
83           boolean isBuiltIn)
84   {
85     String name = format.getName().toUpperCase();
86     if (formats.containsKey(name))
87     {
88       System.err.println("Overwriting file format: " + format.getName());
89     }
90     formats.put(name, format);
91     if (isBuiltIn)
92     {
93       builtIn.add(format);
94     }
95   }
96
97   /**
98    * Deregisters a file format so it is no longer shown in menus
99    * 
100    * @param name
101    */
102   public void deregisterFileFormat(String name)
103   {
104     FileFormatI ff = formats.remove(name.toUpperCase());
105     builtIn.remove(ff);
106   }
107
108   /**
109    * Answers a list of writeable file formats (as strings, corresponding to the
110    * getName() and forName() methods)
111    * 
112    * @param textOnly
113    *          if true, only text (not binary) formats are included
114    * @return
115    */
116   public List<String> getWritableFormats(boolean textOnly)
117   {
118     List<String> l = new ArrayList<String>();
119     for (FileFormatI ff : formats.values())
120     {
121       if (ff.isWritable() && (!textOnly || ff.isTextFormat()))
122       {
123         l.add(ff.getName());
124       }
125     }
126     return l;
127   }
128
129   /**
130    * Answers a list of readable file formats (as strings, corresponding to the
131    * getName() and forName() methods)
132    * 
133    * @return
134    */
135   public List<String> getReadableFormats()
136   {
137     List<String> l = new ArrayList<String>();
138     for (FileFormatI ff : formats.values())
139     {
140       if (ff.isReadable())
141       {
142         l.add(ff.getName());
143       }
144     }
145     return l;
146   }
147
148   /**
149    * Returns the file format with the given name, or null if format is null or
150    * invalid. This is not case-sensitive.
151    * 
152    * @param format
153    * @return
154    */
155   public FileFormatI forName(String format)
156   {
157     return format == null ? null : formats.get(format.toUpperCase());
158   }
159
160   /**
161    * Returns an iterable collection of registered file formats (in the order in
162    * which they were registered)
163    * 
164    * @return
165    */
166   public Iterable<FileFormatI> getFormats()
167   {
168     return formats.values();
169   }
170 }