Class |
Line # |
Actions |
|||
---|---|---|---|---|---|
ChannelProperties | 39 | 90 | 37 |
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.util; | |
22 | ||
23 | import java.awt.Image; | |
24 | import java.io.File; | |
25 | import java.io.FileInputStream; | |
26 | import java.io.FileNotFoundException; | |
27 | import java.io.IOException; | |
28 | import java.io.InputStream; | |
29 | import java.net.URL; | |
30 | import java.util.ArrayList; | |
31 | import java.util.Arrays; | |
32 | import java.util.HashMap; | |
33 | import java.util.List; | |
34 | import java.util.Map; | |
35 | import java.util.Properties; | |
36 | ||
37 | import javax.swing.ImageIcon; | |
38 | ||
39 | public class ChannelProperties | |
40 | { | |
41 | ||
42 | public static final String CHANNEL_PROPERTIES_FILENAME = "channel.props"; | |
43 | ||
44 | private static Properties channelProps; | |
45 | ||
46 | private static final Properties defaultProps; | |
47 | ||
48 | private static Map<String, Image> imageMap = new HashMap<String, Image>(); | |
49 | ||
50 | private static Map<String, URL> urlMap = new HashMap<String, URL>(); | |
51 | ||
52 | private static final ArrayList<Image> iconList; | |
53 | ||
54 | public static final String FALLBACK_APPNAME = "Jalview"; | |
55 | ||
56 | 55 | static |
57 | { | |
58 | 55 | defaultProps = new Properties(); |
59 | // these should be kept up to date, but in real life they should never | |
60 | // actually be used anyway. | |
61 | 55 | defaultProps.put("app_name", FALLBACK_APPNAME); |
62 | 55 | defaultProps.put("banner", "/default_images/jalview_banner.png"); |
63 | 55 | defaultProps.put("logo.16", "/default_images/jalview_logo-16.png"); |
64 | 55 | defaultProps.put("logo.32", "/default_images/jalview_logo-32.png"); |
65 | 55 | defaultProps.put("logo.38", "/default_images/jalview_logo-38.png"); |
66 | 55 | defaultProps.put("logo.48", "/default_images/jalview_logo-48.png"); |
67 | 55 | defaultProps.put("logo.64", "/default_images/jalview_logo-64.png"); |
68 | 55 | defaultProps.put("logo.128", "/default_images/jalview_logo-128.png"); |
69 | 55 | defaultProps.put("logo.256", "/default_images/jalview_logo-256.png"); |
70 | 55 | defaultProps.put("logo.512", "/default_images/jalview_logo-512.png"); |
71 | 55 | defaultProps.put("rotatable_logo.48", |
72 | "/default_images/rotatable_jalview_logo-38.png"); | |
73 | 55 | defaultProps.put("bg_logo.28", "/default_images/barton_group-28.png"); |
74 | 55 | defaultProps.put("bg_logo.30", "/default_images/barton_group-30.png"); |
75 | 55 | defaultProps.put("bg_logo.32", "/default_images/barton_group-32.png"); |
76 | 55 | defaultProps.put("uod_banner.28", "/default_images/UoD_banner-28.png"); |
77 | 55 | defaultProps.put("uod_banner.30", "/default_images/UoD_banner-30.png"); |
78 | 55 | defaultProps.put("uod_banner.32", "/default_images/UoD_banner-32.png"); |
79 | 55 | defaultProps.put("default_appbase", |
80 | "https://www.jalview.org/getdown/release/1.8"); | |
81 | 55 | defaultProps.put("preferences.filename", ".jalview_properties"); |
82 | 55 | defaultProps.put("channel", "none"); |
83 | ||
84 | // load channel_properties | |
85 | 55 | Properties tryChannelProps = new Properties(); |
86 | 55 | URL channelPropsURL = ChannelProperties.class |
87 | .getResource("/" + CHANNEL_PROPERTIES_FILENAME); | |
88 | 55 | if (channelPropsURL == null) |
89 | { | |
90 | // complete failure of channel_properties, set all properties to defaults | |
91 | 0 | ErrorLog.errPrintln("Failed to find '/" + CHANNEL_PROPERTIES_FILENAME |
92 | + "' file at '" | |
93 | 0 | + (channelPropsURL == null ? "null" |
94 | : channelPropsURL.toString()) | |
95 | + "'. Using class defaultProps."); | |
96 | 0 | tryChannelProps = defaultProps; |
97 | } | |
98 | else | |
99 | { | |
100 | 55 | try |
101 | { | |
102 | 55 | InputStream channelPropsIS = HttpUtils.openStream(channelPropsURL); |
103 | 55 | tryChannelProps.load(channelPropsIS); |
104 | 55 | channelPropsIS.close(); |
105 | } catch (IOException e) | |
106 | { | |
107 | 0 | ErrorLog.errPrintln(e.getMessage()); |
108 | // return false; | |
109 | } | |
110 | } | |
111 | 55 | channelProps = tryChannelProps; |
112 | ||
113 | /* | |
114 | * The following slight palava for caching an icon list is so that all sizes of icons | |
115 | * are the same. i.e. if there are /any/ channel_properties icons to use, then _only_ | |
116 | * use those channel_properties icons, don't mix in class default icons for missing | |
117 | * sizes. If there are _no_ (usable) channel icons then we can use the class default icons. | |
118 | */ | |
119 | 55 | iconList = new ArrayList<Image>(); |
120 | 55 | List<String> sizes = Arrays.asList("16", "32", "48", "64", "128", "256", |
121 | "512"); | |
122 | 55 | for (String size : sizes) |
123 | { | |
124 | 385 | Image logo = null; |
125 | // not using defaults or class props first time through | |
126 | 385 | logo = ChannelProperties.getImage("logo." + size, null, false); |
127 | 385 | if (logo != null) |
128 | { | |
129 | 385 | iconList.add(logo); |
130 | } | |
131 | } | |
132 | // now add the class defaults if there were no channel icons defined | |
133 | 55 | if (iconList.size() == 0) |
134 | { | |
135 | 0 | for (String size : sizes) |
136 | { | |
137 | 0 | Image logo = null; |
138 | 0 | String path = defaultProps.getProperty("logo." + size); |
139 | 0 | URL imageURL = ChannelProperties.class.getResource(path); |
140 | 0 | ImageIcon imgIcon = imageURL == null ? null |
141 | : new ImageIcon(imageURL); | |
142 | 0 | logo = imgIcon == null ? null : imgIcon.getImage(); |
143 | 0 | if (logo != null) |
144 | { | |
145 | 0 | iconList.add(logo); |
146 | } | |
147 | } | |
148 | } | |
149 | } | |
150 | ||
151 | 0 | protected static void loadProps(File dir) |
152 | { | |
153 | 0 | File channelPropsFile = new File(dir, CHANNEL_PROPERTIES_FILENAME); |
154 | 0 | if (channelPropsFile.exists()) |
155 | { | |
156 | 0 | try |
157 | { | |
158 | 0 | InputStream is = new FileInputStream(channelPropsFile); |
159 | 0 | channelProps.load(is); |
160 | } catch (FileNotFoundException e) | |
161 | { | |
162 | 0 | ErrorLog.errPrintln(e.getMessage()); |
163 | } catch (IOException e) | |
164 | { | |
165 | 0 | ErrorLog.errPrintln(e.getMessage()); |
166 | } | |
167 | } | |
168 | } | |
169 | ||
170 | 6480 | private static Properties channelProps() |
171 | { | |
172 | 6480 | return channelProps; |
173 | } | |
174 | ||
175 | 1186 | private static Map<String, Image> imageMap() |
176 | { | |
177 | 1186 | return imageMap; |
178 | } | |
179 | ||
180 | 216 | private static Map<String, URL> urlMap() |
181 | { | |
182 | 216 | return urlMap; |
183 | } | |
184 | ||
185 | /* | |
186 | * getProperty(key) will get property value from channel_properties for key. | |
187 | * If no property for key is found, it will fall back to using the defaultProps defined for this class. | |
188 | */ | |
189 | 1662 | public static String getProperty(String key) |
190 | { | |
191 | 1662 | return getProperty(key, null, true); |
192 | } | |
193 | ||
194 | /* | |
195 | * getProperty(key, defaultVal) will get property value from channel_properties for key. | |
196 | * If no property for key is found, it will return defaultVal and NOT fall back to the class defaultProps. | |
197 | */ | |
198 | 0 | public static String getProperty(String key, String defaultVal) |
199 | { | |
200 | 0 | return getProperty(key, defaultVal, false); |
201 | } | |
202 | ||
203 | /* | |
204 | * internal method. note that setting useClassDefaultProps=true will ignore the provided defaultVal | |
205 | */ | |
206 | 2160 | private static String getProperty(String key, String defaultVal, |
207 | boolean useClassDefaultProps) | |
208 | { | |
209 | 2160 | if (channelProps() != null) |
210 | { | |
211 | 2160 | if (channelProps().containsKey(key)) |
212 | { | |
213 | 2160 | return channelProps().getProperty(key, |
214 | 2160 | useClassDefaultProps ? defaultProps.getProperty(key) |
215 | : defaultVal); | |
216 | } | |
217 | else | |
218 | { | |
219 | 0 | ErrorLog.errPrintln("Failed to get channel property '" + key + "'"); |
220 | } | |
221 | } | |
222 | 0 | return null; |
223 | } | |
224 | ||
225 | /* | |
226 | * getImage(key) returns the channel defined image for property key. If that is null (e.g. due to | |
227 | * no defined channel image or the image file being corrupt/unusable/missing) it uses the image | |
228 | * defined in defaultChannelProps | |
229 | */ | |
230 | 208 | public static Image getImage(String key) |
231 | { | |
232 | 208 | return getImage(key, null, true); |
233 | } | |
234 | ||
235 | /* | |
236 | * getImage(key, defaultImg) will get image associated with value from channel_properties for key. | |
237 | * If no property or associated image for key is found (or is usable), it will return defaultImg | |
238 | * and NOT fall back to the class defaultProps. | |
239 | */ | |
240 | 0 | public static Image getImage(String key, Image defaultImg) |
241 | { | |
242 | 0 | return getImage(key, defaultImg, false); |
243 | } | |
244 | ||
245 | /* | |
246 | * internal method. note that setting useClassDefaultImage=true will ignore the provided defaultImg | |
247 | */ | |
248 | 593 | private static Image getImage(String key, Image defaultImg, |
249 | boolean useClassDefaultImage) | |
250 | { | |
251 | 593 | Image img = null; |
252 | 593 | if (imageMap().containsKey(key)) |
253 | { | |
254 | 95 | img = imageMap().get(key); |
255 | } | |
256 | // Catch a previously untried or failed load | |
257 | 593 | if (img == null) |
258 | { | |
259 | 498 | String path = getProperty(key, null, useClassDefaultImage); |
260 | 498 | if (path == null) // no channel property or class default property (if |
261 | // requested) | |
262 | { | |
263 | 0 | return useClassDefaultImage ? null : defaultImg; |
264 | } | |
265 | ||
266 | 498 | URL imageURL = ChannelProperties.class.getResource(path); |
267 | 498 | ImageIcon imgIcon = imageURL == null ? null : new ImageIcon(imageURL); |
268 | 498 | img = imgIcon == null ? null : imgIcon.getImage(); |
269 | 498 | if (img == null) |
270 | { | |
271 | 0 | ErrorLog.errPrintln( |
272 | "Failed to load channel image " + key + "=" + path); | |
273 | 0 | if (!useClassDefaultImage) |
274 | { | |
275 | 0 | return defaultImg; |
276 | } | |
277 | } | |
278 | else | |
279 | { | |
280 | 498 | imageMap().put(key, img); |
281 | 498 | urlMap.put(key, imageURL); |
282 | } | |
283 | } | |
284 | 593 | return img; |
285 | } | |
286 | ||
287 | /* | |
288 | * Public method to get the URL object pointing to a cached image. | |
289 | */ | |
290 | 108 | public static URL getImageURL(String key) |
291 | { | |
292 | 108 | if (getImage(key) != null) |
293 | { | |
294 | 108 | if (urlMap().containsKey(key)) |
295 | { | |
296 | 108 | return urlMap().getOrDefault(key, null); |
297 | } | |
298 | 0 | ErrorLog.errPrintln( |
299 | "Do not use getImageURL(key) before using getImage(key...)"); | |
300 | } | |
301 | 0 | return null; |
302 | } | |
303 | ||
304 | /* | |
305 | * Get a List of Icon images of different sizes. | |
306 | */ | |
307 | 201 | public static ArrayList<Image> getIconList() |
308 | { | |
309 | 201 | return iconList; |
310 | } | |
311 | } |