JAL-3594 JAL-3728 Added taskbar icons to desktop and Java console. Changed "Jalview...
[jalview.git] / src / jalview / util / ChannelProperties.java
1 package jalview.util;
2
3 import java.awt.Image;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.net.URL;
7 import java.util.ArrayList;
8 import java.util.Arrays;
9 import java.util.HashMap;
10 import java.util.List;
11 import java.util.Map;
12 import java.util.Properties;
13
14 import javax.swing.ImageIcon;
15
16 import jalview.bin.Cache;
17
18 public class ChannelProperties
19 {
20
21   private static final String CHANNEL_PROPERTIES_FILENAME = "/channel_properties";
22
23   private static final Properties channelProps;
24
25   private static final Properties defaultProps;
26
27   private static Map<String, Image> imageMap = new HashMap<String, Image>();
28
29   private static final ArrayList<Image> iconList;
30
31   static
32   {
33     defaultProps = new Properties();
34     // these should be kept up to date, but in real life they should never
35     // actually be used anyway.
36     defaultProps.put("app_name", "Jalview");
37     defaultProps.put("banner", "/default_images/jalview_banner.png");
38     defaultProps.put("logo.16", "/default_images/jalview_logo-16.png");
39     defaultProps.put("logo.32", "/default_images/jalview_logo-32.png");
40     defaultProps.put("logo.38", "/default_images/jalview_logo-38.png");
41     defaultProps.put("logo.48", "/default_images/jalview_logo-48.png");
42     defaultProps.put("logo.64", "/default_images/jalview_logo-64.png");
43     defaultProps.put("logo.128", "/default_images/jalview_logo-128.png");
44     defaultProps.put("logo.256", "/default_images/jalview_logo-256.png");
45     defaultProps.put("logo.512", "/default_images/jalview_logo-512.png");
46     defaultProps.put("rotatable_logo.48",
47             "/default_images/rotatable_jalview_logo-38.png");
48     defaultProps.put("bg_logo.62", "/default_images/barton_group-62.png");
49     defaultProps.put("uod_banner", "/default_images/UoD_banner.png");
50     defaultProps.put("default_appbase",
51             "https://www.jalview.org/getdown/release/1.8");
52
53     // load channel_properties
54     Properties tryChannelProps = new Properties();
55     URL channelPropsURL = ChannelProperties.class
56             .getResource(CHANNEL_PROPERTIES_FILENAME);
57     if (channelPropsURL == null)
58     {
59       // complete failure of channel_properties, set all properties to defaults
60       System.err.println("Failed to find '" + CHANNEL_PROPERTIES_FILENAME
61               + "' file, using defaults");
62       tryChannelProps = defaultProps;
63     }
64     else
65     {
66       try
67       {
68         InputStream channelPropsIS = channelPropsURL.openStream();
69         tryChannelProps.load(channelPropsIS);
70         channelPropsIS.close();
71       } catch (IOException e)
72       {
73         Cache.log.warn(e.getMessage());
74         // return false;
75       }
76     }
77     channelProps = tryChannelProps;
78
79     /*
80      * The following slight palava for caching an icon list is so that all sizes of icons
81      * are the same. i.e. if there are /any/ channel_properties icons to use, then _only_
82      * use those channel_properties icons, don't mix in class default icons for missing
83      * sizes.  If there are _no_ (usable) channel icons then we can use the class default icons.
84      */
85     iconList = new ArrayList<Image>();
86     List<String> sizes = Arrays.asList("16", "32", "48", "64", "128", "256",
87             "512");
88     for (String size : sizes)
89     {
90       Image logo = null;
91       // not using defaults or class props first time through
92       logo = ChannelProperties.getImage("logo." + size, null, false);
93       if (logo != null)
94       {
95         iconList.add(logo);
96       }
97     }
98     // now add the class defaults if there were no channel icons defined
99     if (iconList.size() == 0)
100     {
101       for (String size : sizes)
102       {
103         Image logo = null;
104         String path = defaultProps.getProperty("logo." + size);
105         URL imageURL = ChannelProperties.class.getResource(path);
106         logo = new ImageIcon(imageURL).getImage();
107         if (logo != null)
108         {
109           iconList.add(logo);
110         }
111       }
112     }
113   }
114
115   private static Properties channelProps()
116   {
117     return channelProps;
118   }
119
120   private static Map<String, Image> imageMap()
121   {
122     return imageMap;
123   }
124
125   /*
126    * getProperty(key) will get property value from channel_properties for key.
127    * If no property for key is found, it will fall back to using the defaultProps defined for this class.
128    */
129   public static String getProperty(String key)
130   {
131     return getProperty(key, null, true);
132   }
133
134   /*
135    * getProperty(key, defaultVal) will get property value from channel_properties for key.
136    * If no property for key is found, it will return defaultVal and NOT fall back to the class defaultProps.
137    */
138   public static String getProperty(String key, String defaultVal)
139   {
140     return getProperty(key, defaultVal, false);
141   }
142
143   /*
144    * internal method.  note that setting useClassDefaultProps=true will ignore the provided defaultVal
145    */
146   private static String getProperty(String key, String defaultVal,
147           boolean useClassDefaultProps)
148   {
149     if (channelProps() != null)
150     {
151       if (channelProps().containsKey(key))
152       {
153         return channelProps().getProperty(key,
154                 useClassDefaultProps ? defaultProps.getProperty(key)
155                         : defaultVal);
156       }
157       else
158       {
159         System.err.println("Failed to get channel property '" + key + "'");
160       }
161     }
162     return null;
163   }
164
165   /*
166    * getImage(key) returns the channel defined image for property key. If that is null (e.g. due to
167    * no defined channel image or the image file being corrupt/unusable/missing) it uses the image
168    * defined in defaultChannelProps
169    */
170   public static Image getImage(String key)
171   {
172     return getImage(key, null, true);
173   }
174
175   /*
176    * getImage(key, defaultImg) will get image associated with value from channel_properties for key.
177    * If no property or associated image for key is found (or is usable), it will return defaultImg
178    * and NOT fall back to the class defaultProps.
179    */
180   public static Image getImage(String key, Image defaultImg)
181   {
182     return getImage(key, defaultImg, false);
183   }
184
185   /*
186    * internal method.  note that setting useClassDefaultImage=true will ignore the provided defaultImg
187    */
188   private static Image getImage(String key, Image defaultImg,
189           boolean useClassDefaultImage)
190   {
191     Image img = null;
192     if (imageMap().containsKey(key))
193     {
194       img = imageMap().get(key);
195     }
196     // Catch a previously untried or failed load
197     if (img == null)
198     {
199       String path = getProperty(key, null, useClassDefaultImage);
200       if (path == null) // no channel property or class default property (if
201                         // requested)
202       {
203         return useClassDefaultImage ? null : defaultImg;
204       }
205
206       URL imageURL = ChannelProperties.class.getResource(path);
207       img = new ImageIcon(imageURL).getImage();
208       if (img == null)
209       {
210         System.err.println(
211                 "Failed to load channel image " + key + "=" + path);
212         if (!useClassDefaultImage)
213         {
214           return defaultImg;
215         }
216       }
217       else
218       {
219         imageMap().put(key, img);
220       }
221     }
222     return img;
223   }
224
225   /*
226    * Get a List of Icon images of different sizes.
227    */
228   public static ArrayList<Image> getIconList()
229   {
230     return iconList;
231   }
232 }