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;
public class ChannelProperties
{
- private static final String CHANNEL_PROPERTIES_FILENAME = "/channel_properties";
+ private static final String CHANNEL_PROPERTIES_FILENAME = "/channel.props";
- 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 Map<String, URL> urlMap = new HashMap<String, URL>();
- private boolean init()
+ private static final ArrayList<Image> iconList;
+
+ 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.28", "/default_images/barton_group-28.png");
+ defaultProps.put("bg_logo.30", "/default_images/barton_group-30.png");
+ defaultProps.put("bg_logo.32", "/default_images/barton_group-32.png");
+ defaultProps.put("uod_banner.28", "/default_images/UoD_banner-28.png");
+ defaultProps.put("uod_banner.30", "/default_images/UoD_banner-30.png");
+ defaultProps.put("uod_banner.32", "/default_images/UoD_banner-32.png");
+ defaultProps.put("default_appbase",
+ "https://www.jalview.org/getdown/release/1.8");
+ defaultProps.put("preferences.filename", ".jalview_properties");
+
// 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 at '"
+ + (channelPropsURL == null ? "null"
+ : channelPropsURL.toString())
+ + "'. Using class defaultProps.");
+ 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;
}
- public static String getProperty(String key)
+ private static Map<String, URL> urlMap()
{
- return getProperty(key, null);
+ return urlMap;
}
- private static Properties channelProps()
+ /*
+ * 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 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
{
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))
{
// 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
{
imageMap().put(key, img);
+ urlMap.put(key, imageURL);
}
}
return img;
}
-}
\ No newline at end of file
+
+ /*
+ * Public method to get the URL object pointing to a cached image.
+ */
+ public static URL getImageURL(String key)
+ {
+ if (getImage(key) != null)
+ {
+ if (urlMap().containsKey(key))
+ {
+ return urlMap().getOrDefault(key, null);
+ }
+ System.err.println(
+ "Do not use getImageURL(key) before using getImage(key...)");
+ }
+ return null;
+ }
+
+ /*
+ * Get a List of Icon images of different sizes.
+ */
+ public static ArrayList<Image> getIconList()
+ {
+ return iconList;
+ }
+}