--- /dev/null
+package jalview.schemes;
+
+import jalview.binding.JalviewUserColours;
+import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.SequenceCollectionI;
+import jalview.datamodel.SequenceI;
+
+import java.awt.Color;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class ColourSchemes
+{
+ /*
+ * singleton instance of this class
+ */
+ private static ColourSchemes instance = new ColourSchemes();
+
+ /*
+ * a map from scheme name to an instance of it
+ */
+ private Map<String, ColourSchemeI> schemes;
+
+ /**
+ * Returns the singleton instance of this class
+ *
+ * @return
+ */
+ public static ColourSchemes getInstance()
+ {
+ return instance;
+ }
+
+ private ColourSchemes()
+ {
+ loadColourSchemes();
+ }
+
+ /**
+ * Loads an instance of each standard or user-defined colour scheme
+ *
+ * @return
+ */
+ void loadColourSchemes()
+ {
+ /*
+ * store in an order-preserving map, so items can be added to menus
+ * in the order in which they are 'discovered'
+ */
+ schemes = new LinkedHashMap<String, ColourSchemeI>();
+
+ for (JalviewColourScheme cs : JalviewColourScheme.values())
+ {
+ try
+ {
+ registerColourScheme(cs.getSchemeClass().newInstance());
+ } catch (InstantiationException | IllegalAccessException e)
+ {
+ System.err.println("Error instantiating colour scheme for "
+ + cs.toString() + " " + e.getMessage());
+ }
+ }
+ }
+
+ /**
+ * Registers a colour scheme
+ *
+ * @param cs
+ */
+ public void registerColourScheme(ColourSchemeI cs)
+ {
+ String name = cs.getSchemeName();
+ if (name == null)
+ {
+ System.err.println("ColourScheme name may not be null");
+ return;
+ }
+
+ /*
+ * name is lower-case for non-case-sensitive lookup
+ * (name in the colour keeps its true case)
+ */
+ String lower = name.toLowerCase();
+ if (schemes.containsKey(lower))
+ {
+ System.err
+ .println("Warning: overwriting colour scheme named " + name);
+ }
+ schemes.put(lower, cs);
+ }
+
+ /**
+ * Removes a colour scheme by name
+ *
+ * @param name
+ */
+ public void removeColourScheme(String name)
+ {
+ schemes.remove(name);
+ }
+
+ /**
+ * Returns an instance of the colour scheme with which the given view may be
+ * coloured
+ *
+ * @param name
+ * name of the colour scheme
+ * @param forData
+ * the data to be coloured
+ * @param optional
+ * map from hidden representative sequences to the sequences they
+ * represent
+ * @return
+ */
+ public ColourSchemeI getColourScheme(String name,
+ AnnotatedCollectionI forData,
+ Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
+ {
+ if (name == null)
+ {
+ return null;
+ }
+ ColourSchemeI cs = schemes.get(name.toLowerCase());
+ return cs == null ? null : cs.getInstance(forData, hiddenRepSequences);
+ }
+
+ /**
+ * Returns an instance of the colour scheme with which the given view may be
+ * coloured
+ *
+ * @param name
+ * name of the colour scheme
+ * @param forData
+ * the data to be coloured
+ * @return
+ */
+ public ColourSchemeI getColourScheme(String name,
+ AnnotatedCollectionI forData)
+ {
+ return getColourScheme(name, forData, null);
+ }
+
+ /**
+ * Returns an iterable set of the colour schemes, in the order in which they
+ * were added
+ *
+ * @return
+ */
+ public Iterable<ColourSchemeI> getColourSchemes()
+ {
+ return schemes.values();
+ }
+
+ /**
+ * Answers true if there is a scheme with the given name, else false. The test
+ * is not case-sensitive.
+ *
+ * @param name
+ * @return
+ */
+ public boolean nameExists(String name)
+ {
+ if (name == null)
+ {
+ return false;
+ }
+ name = name.toLowerCase();
+ for (ColourSchemeI scheme : getColourSchemes())
+ {
+ if (name.equals(scheme.getSchemeName().toLowerCase()))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Loads a user defined colour scheme from file. The file should contain a
+ * definition of residue colours in XML format as defined in
+ * JalviewUserColours.xsd.
+ *
+ * @param filePath
+ *
+ * @return
+ */
+ public static UserColourScheme loadColourScheme(String filePath)
+ {
+ UserColourScheme ucs = null;
+ Color[] newColours = null;
+ File file = new File(filePath);
+ try
+ {
+ InputStreamReader in = new InputStreamReader(
+ new FileInputStream(file), "UTF-8");
+
+ jalview.schemabinding.version2.JalviewUserColours jucs = new jalview.schemabinding.version2.JalviewUserColours();
+
+ org.exolab.castor.xml.Unmarshaller unmar = new org.exolab.castor.xml.Unmarshaller(
+ jucs);
+ jucs = (jalview.schemabinding.version2.JalviewUserColours) unmar
+ .unmarshal(in);
+
+ /*
+ * non-case-sensitive colours are for 20 amino acid codes,
+ * B, Z, X and Gap
+ * optionally, lower-case alternatives for all except Gap
+ */
+ newColours = new Color[24];
+ Color[] lowerCase = new Color[23];
+ boolean caseSensitive = false;
+
+ String name;
+ int index;
+ for (int i = 0; i < jucs.getColourCount(); i++)
+ {
+ name = jucs.getColour(i).getName();
+ if (ResidueProperties.aa3Hash.containsKey(name))
+ {
+ index = ResidueProperties.aa3Hash.get(name).intValue();
+ }
+ else
+ {
+ index = ResidueProperties.aaIndex[name.charAt(0)];
+ }
+ if (index == -1)
+ {
+ continue;
+ }
+
+ Color color = new Color(Integer.parseInt(jucs.getColour(i)
+ .getRGB(), 16));
+ if (name.toLowerCase().equals(name))
+ {
+ caseSensitive = true;
+ lowerCase[index] = color;
+ }
+ else
+ {
+ newColours[index] = color;
+ }
+ }
+
+ /*
+ * instantiate the colour scheme
+ */
+ ucs = new UserColourScheme(newColours);
+ ucs.setName(jucs.getSchemeName());
+ if (caseSensitive)
+ {
+ ucs.setLowerCaseColours(lowerCase);
+ }
+ } catch (Exception ex)
+ {
+ // Could be old Jalview Archive format
+ try
+ {
+ InputStreamReader in = new InputStreamReader(new FileInputStream(
+ file), "UTF-8");
+
+ jalview.binding.JalviewUserColours jucs = new jalview.binding.JalviewUserColours();
+
+ jucs = JalviewUserColours.unmarshal(in);
+
+ newColours = new Color[jucs.getColourCount()];
+
+ for (int i = 0; i < 24; i++)
+ {
+ newColours[i] = new Color(Integer.parseInt(jucs.getColour(i)
+ .getRGB(), 16));
+ }
+ ucs = new UserColourScheme(newColours);
+ ucs.setName(jucs.getSchemeName());
+ } catch (Exception ex2)
+ {
+ ex2.printStackTrace();
+ }
+
+ if (newColours == null)
+ {
+ System.out.println("Error loading User ColourFile\n" + ex);
+ }
+ }
+
+ return ucs;
+ }
+}