JAL-3594 JAL-3728 Added taskbar icons to desktop and Java console. Changed "Jalview...
[jalview.git] / src / jalview / util / ChannelProperties.java
index 5d7f795..2194c4d 100644 (file)
@@ -4,7 +4,10 @@ import java.awt.Image;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 
@@ -17,84 +20,139 @@ public class ChannelProperties
 
   private static final String CHANNEL_PROPERTIES_FILENAME = "/channel_properties";
 
-  private Properties channelProps = new Properties();
+  private static final Properties channelProps;
 
-  private Map<String, Image> imageMap = new HashMap<String, Image>();
+  private static final Properties defaultProps;
 
-  private static ChannelProperties instance;
+  private static Map<String, Image> imageMap = new HashMap<String, Image>();
 
-  private boolean initDone = false;
+  private static final ArrayList<Image> iconList;
 
-  private boolean init()
+  static
   {
-    if (initDone)
-    {
-      return initDone;
-    }
+    defaultProps = new Properties();
+    // these should be kept up to date, but in real life they should never
+    // actually be used anyway.
+    defaultProps.put("app_name", "Jalview");
+    defaultProps.put("banner", "/default_images/jalview_banner.png");
+    defaultProps.put("logo.16", "/default_images/jalview_logo-16.png");
+    defaultProps.put("logo.32", "/default_images/jalview_logo-32.png");
+    defaultProps.put("logo.38", "/default_images/jalview_logo-38.png");
+    defaultProps.put("logo.48", "/default_images/jalview_logo-48.png");
+    defaultProps.put("logo.64", "/default_images/jalview_logo-64.png");
+    defaultProps.put("logo.128", "/default_images/jalview_logo-128.png");
+    defaultProps.put("logo.256", "/default_images/jalview_logo-256.png");
+    defaultProps.put("logo.512", "/default_images/jalview_logo-512.png");
+    defaultProps.put("rotatable_logo.48",
+            "/default_images/rotatable_jalview_logo-38.png");
+    defaultProps.put("bg_logo.62", "/default_images/barton_group-62.png");
+    defaultProps.put("uod_banner", "/default_images/UoD_banner.png");
+    defaultProps.put("default_appbase",
+            "https://www.jalview.org/getdown/release/1.8");
+
     // load channel_properties
-    URL channelPropsURL = getClass()
+    Properties tryChannelProps = new Properties();
+    URL channelPropsURL = ChannelProperties.class
             .getResource(CHANNEL_PROPERTIES_FILENAME);
     if (channelPropsURL == null)
     {
-      // fallback
-      System.err.println(
-              "Failed to find '" + CHANNEL_PROPERTIES_FILENAME + "' file");
-      return false;
+      // complete failure of channel_properties, set all properties to defaults
+      System.err.println("Failed to find '" + CHANNEL_PROPERTIES_FILENAME
+              + "' file, using defaults");
+      tryChannelProps = defaultProps;
     }
     else
     {
       try
       {
         InputStream channelPropsIS = channelPropsURL.openStream();
-        channelProps.load(channelPropsIS);
+        tryChannelProps.load(channelPropsIS);
         channelPropsIS.close();
       } catch (IOException e)
       {
         Cache.log.warn(e.getMessage());
-        return false;
+        // return false;
+      }
+    }
+    channelProps = tryChannelProps;
+
+    /*
+     * The following slight palava for caching an icon list is so that all sizes of icons
+     * are the same. i.e. if there are /any/ channel_properties icons to use, then _only_
+     * use those channel_properties icons, don't mix in class default icons for missing
+     * sizes.  If there are _no_ (usable) channel icons then we can use the class default icons.
+     */
+    iconList = new ArrayList<Image>();
+    List<String> sizes = Arrays.asList("16", "32", "48", "64", "128", "256",
+            "512");
+    for (String size : sizes)
+    {
+      Image logo = null;
+      // not using defaults or class props first time through
+      logo = ChannelProperties.getImage("logo." + size, null, false);
+      if (logo != null)
+      {
+        iconList.add(logo);
+      }
+    }
+    // now add the class defaults if there were no channel icons defined
+    if (iconList.size() == 0)
+    {
+      for (String size : sizes)
+      {
+        Image logo = null;
+        String path = defaultProps.getProperty("logo." + size);
+        URL imageURL = ChannelProperties.class.getResource(path);
+        logo = new ImageIcon(imageURL).getImage();
+        if (logo != null)
+        {
+          iconList.add(logo);
+        }
       }
     }
-    initDone = true;
-    return initDone;
   }
 
-  private ChannelProperties()
+  private static Properties channelProps()
   {
-    init();
+    return channelProps;
   }
 
-  public static ChannelProperties getChannelProperties()
+  private static Map<String, Image> imageMap()
   {
-    if (instance == null)
-    {
-      instance = new ChannelProperties();
-    }
-    return instance;
+    return imageMap;
   }
 
+  /*
+   * getProperty(key) will get property value from channel_properties for key.
+   * If no property for key is found, it will fall back to using the defaultProps defined for this class.
+   */
   public static String getProperty(String key)
   {
-    return getProperty(key, null);
-  }
-
-  private static Properties channelProps()
-  {
-    return getChannelProperties().channelProps;
+    return getProperty(key, null, true);
   }
 
-  private static Map<String, Image> imageMap()
+  /*
+   * getProperty(key, defaultVal) will get property value from channel_properties for key.
+   * If no property for key is found, it will return defaultVal and NOT fall back to the class defaultProps.
+   */
+  public static String getProperty(String key, String defaultVal)
   {
-    return getChannelProperties().imageMap;
+    return getProperty(key, defaultVal, false);
   }
 
-  public static String getProperty(String key, String defaultVal)
+  /*
+   * internal method.  note that setting useClassDefaultProps=true will ignore the provided defaultVal
+   */
+  private static String getProperty(String key, String defaultVal,
+          boolean useClassDefaultProps)
   {
     if (channelProps() != null)
     {
       if (channelProps().containsKey(key))
       {
-        String val = channelProps().getProperty(key, "NOTFOUND");
-        return channelProps().getProperty(key, defaultVal);
+        return channelProps().getProperty(key,
+                useClassDefaultProps ? defaultProps.getProperty(key)
+                        : defaultVal);
       }
       else
       {
@@ -104,8 +162,32 @@ public class ChannelProperties
     return null;
   }
 
+  /*
+   * getImage(key) returns the channel defined image for property key. If that is null (e.g. due to
+   * no defined channel image or the image file being corrupt/unusable/missing) it uses the image
+   * defined in defaultChannelProps
+   */
   public static Image getImage(String key)
   {
+    return getImage(key, null, true);
+  }
+
+  /*
+   * getImage(key, defaultImg) will get image associated with value from channel_properties for key.
+   * If no property or associated image for key is found (or is usable), it will return defaultImg
+   * and NOT fall back to the class defaultProps.
+   */
+  public static Image getImage(String key, Image defaultImg)
+  {
+    return getImage(key, defaultImg, false);
+  }
+
+  /*
+   * internal method.  note that setting useClassDefaultImage=true will ignore the provided defaultImg
+   */
+  private static Image getImage(String key, Image defaultImg,
+          boolean useClassDefaultImage)
+  {
     Image img = null;
     if (imageMap().containsKey(key))
     {
@@ -114,17 +196,23 @@ public class ChannelProperties
     // Catch a previously untried or failed load
     if (img == null)
     {
-      String path = getProperty(key);
-      if (path == null)
+      String path = getProperty(key, null, useClassDefaultImage);
+      if (path == null) // no channel property or class default property (if
+                        // requested)
       {
-        return null;
+        return useClassDefaultImage ? null : defaultImg;
       }
-      URL imageURL = getChannelProperties().getClass().getResource(path);
+
+      URL imageURL = ChannelProperties.class.getResource(path);
       img = new ImageIcon(imageURL).getImage();
       if (img == null)
       {
         System.err.println(
                 "Failed to load channel image " + key + "=" + path);
+        if (!useClassDefaultImage)
+        {
+          return defaultImg;
+        }
       }
       else
       {
@@ -133,4 +221,12 @@ public class ChannelProperties
     }
     return img;
   }
+
+  /*
+   * Get a List of Icon images of different sizes.
+   */
+  public static ArrayList<Image> getIconList()
+  {
+    return iconList;
+  }
 }
\ No newline at end of file