JAL-2994 put ‘\’ first in character class clause of regex - otherwise doesn’t compile...
[jalview.git] / src / jalview / io / FileFormats.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.io;
22
23 import java.util.ArrayList;
24 import java.util.HashSet;
25 import java.util.LinkedHashMap;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Set;
29
30 /**
31  * A singleton registry of alignment file formats known to Jalview. On startup,
32  * the 'built-in' formats are added (from the FileFormat enum). Additional
33  * formats can be registered (or formats deregistered) programmatically, for
34  * example with a Groovy script.
35  * 
36  * @author gmcarstairs
37  *
38  */
39 public class FileFormats
40 {
41   private static FileFormats instance = new FileFormats();
42
43   /*
44    * A lookup map of file formats by upper-cased name
45    */
46   private static Map<String, FileFormatI> formats;
47
48   /*
49    * Formats in this set are capable of being identified by IdentifyFile 
50    */
51   private static Set<FileFormatI> identifiable;
52
53   public static FileFormats getInstance()
54   {
55     return instance;
56   }
57
58   /**
59    * Private constructor registers Jalview's built-in file formats
60    */
61   private FileFormats()
62   {
63     reset();
64   }
65
66   /**
67    * Reset to just the built-in file formats packaged with Jalview. These are
68    * added (and will be shown in menus) in the order of their declaration in the
69    * FileFormat enum.
70    */
71   public synchronized void reset()
72   {
73     formats = new LinkedHashMap<String, FileFormatI>();
74     identifiable = new HashSet<FileFormatI>();
75     for (FileFormat format : FileFormat.values())
76     {
77       registerFileFormat(format, format.isIdentifiable());
78     }
79   }
80
81   /**
82    * Answers true if the format is one that can be identified by IdentifyFile.
83    * Answers false for a null value.
84    */
85   public boolean isIdentifiable(FileFormatI f)
86   {
87     return identifiable.contains(f);
88   }
89
90   /**
91    * Registers a file format for case-insensitive lookup by name
92    * 
93    * @param format
94    */
95   public void registerFileFormat(FileFormatI format)
96   {
97     boolean isIdentifiable = format instanceof FileFormat
98             && ((FileFormat) format).isIdentifiable();
99     registerFileFormat(format, isIdentifiable);
100   }
101
102   protected void registerFileFormat(FileFormatI format,
103           boolean isIdentifiable)
104   {
105     String name = format.getName().toUpperCase();
106     if (formats.containsKey(name))
107     {
108       System.err.println("Overwriting file format: " + format.getName());
109     }
110     formats.put(name, format);
111     if (isIdentifiable)
112     {
113       identifiable.add(format);
114     }
115   }
116
117   /**
118    * Deregisters a file format so it is no longer shown in menus
119    * 
120    * @param name
121    */
122   public void deregisterFileFormat(String name)
123   {
124     FileFormatI ff = formats.remove(name.toUpperCase());
125     identifiable.remove(ff);
126   }
127
128   /**
129    * Answers a list of writeable file formats (as strings, corresponding to the
130    * getName() and forName() methods)
131    * 
132    * @param textOnly
133    *          if true, only text (not binary) formats are included
134    * @return
135    */
136   public List<String> getWritableFormats(boolean textOnly)
137   {
138     List<String> l = new ArrayList<String>();
139     for (FileFormatI ff : formats.values())
140     {
141       if (ff.isWritable() && (!textOnly || ff.isTextFormat()))
142       {
143         l.add(ff.getName());
144       }
145     }
146     return l;
147   }
148
149   /**
150    * Answers a list of readable file formats (as strings, corresponding to the
151    * getName() and forName() methods)
152    * 
153    * @return
154    */
155   public List<String> getReadableFormats()
156   {
157     List<String> l = new ArrayList<String>();
158     for (FileFormatI ff : formats.values())
159     {
160       if (ff.isReadable())
161       {
162         l.add(ff.getName());
163       }
164     }
165     return l;
166   }
167
168   /**
169    * Returns the file format with the given name, or null if format is null or
170    * invalid. This is not case-sensitive.
171    * 
172    * @param format
173    * @return
174    */
175   public FileFormatI forName(String format)
176   {
177     return format == null ? null : formats.get(format.toUpperCase());
178   }
179
180   /**
181    * Returns an iterable collection of registered file formats (in the order in
182    * which they were registered)
183    * 
184    * @return
185    */
186   public Iterable<FileFormatI> getFormats()
187   {
188     return formats.values();
189   }
190 }