typo for AXISLOGLEVEL constant
[jalview.git] / src / jalview / bin / Cache.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer
3  * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18  */
19 package jalview.bin;
20
21 import java.io.*;
22 import java.util.*;
23
24 import org.apache.log4j.*;
25
26 /**
27  * Stores and retrieves Jalview Application Properties
28  * Lists and fields within list entries are separated by '|' symbols unless otherwise stated
29  * (|) clauses are alternative values for a tag.
30  * <br><br>Current properties include:
31  * <ul>
32  * <br>logs.Axis.Level - one of the stringified Levels for log4j controlling the logging level for axis (used for web services)
33  * <br>
34  * </li><li>logs.Castor.Level - one of the stringified Levels for log4j controlling the logging level for castor (used for serialization)
35  * <br>
36  * </li><li>logs.Jalview.Level - Cache.log stringified level.
37  * <br>
38  * </li><li>DISCOVERY_START - Boolean - controls if discovery services are queried on startup
39  * </li><li>DISCOVERY_URLS - comma separated list of Discovery Service endpoints.
40  * </li><li>SCREEN_WIDTH
41  * </li><li>SCREEN_HEIGHT
42  * </li><li>SCREEN_Y=285
43  * </li><li>SCREEN_X=371
44  * </li><li>SHOW_FULLSCREEN boolean
45  * </li><li>FONT_NAME java font name for alignment text display
46  * </li><li>FONT_SIZE size of displayed alignment text
47  * </li><li>FONT_STYLE style of font displayed (sequence labels are always italic)
48  * </li><li>GAP_SYMBOL character to treat as gap symbol (usually -,.,' ')
49  * </li><li>LAST_DIRECTORY last directory for browsing alignment
50  * </li><li>USER_DEFINED_COLOURS list of user defined colour scheme files
51  * </li><li>SHOW_FULL_ID show id with '/start-end' numbers appended
52  * </li><li>SHOW_IDENTITY show percentage identity annotation
53  * </li><li>SHOW_QUALITY show alignment quality annotation
54  * </li><li>SHOW_ANNOTATIONS show alignment annotation rows
55  * </li><li>SHOW_CONSERVATION show alignment conservation annotation
56  * </li><li>DEFAULT_COLOUR default colour scheme to apply for a new alignment
57  * </li><li>DEFAULT_FILE_FORMAT file format used to save 
58  * </li><li>STARTUP_FILE file loaded on startup (may be a fully qualified url)
59  * </li><li>SHOW_STARTUP_FILE flag to control loading of startup file
60  * </li><li>VERSION the version of the jalview build
61  * </li><li>BUILD_DATE date of this build
62  * </li><li>LATEST_VERSION the latest jalview version advertised on the www.jalview.org
63  * </li><li>PIR_MODELLER boolean indicating if PIR files are written with MODELLER descriptions
64  * </li><li>(FASTA,MSF,PILEUP,CLUSTAL,BLC,PIR,PFAM)_JVSUFFIX boolean for adding jv suffix to file
65  * </li><li>RECENT_URL list of recently retrieved URLs
66  * </li><li>RECENT_FILE list of recently opened files
67  * </li><li>USE_PROXY flag for whether a http proxy is to be used
68  * </li><li>PROXY_SERVER the proxy
69  * </li><li>PROXY_PORT
70  * </li><li>NOQUESTIONNAIRES true to prevent jalview from checking the questionnaire service
71  * </li><li>QUESTIONNAIRE last questionnaire:responder id string from questionnaire service
72  * </li><li>DAS_LOCAL_SOURCE list of local das sources
73  * </li><li>SHOW_OVERVIEW boolean for overview window display
74  * </li><li>ANTI_ALIAS boolean for smooth fonts
75  * </li><li>RIGHT_ALIGN_IDS boolean
76  * </li><li>AUTO_CALC_CONSENSUS boolean for automatic recalculation of consensus
77  * </li><li>PAD_GAPS boolean
78  * </li><li>ID_ITALICS boolean 
79  * </li><li>SHOW_JV_SUFFIX
80  * </li><li>WRAP_ALIGNMENT
81  * </li><li>EPS_RENDERING (Prompt each time|Lineart|Text) default for EPS rendering style check
82  * </li><li>SORT_ALIGNMENT (No sort|Id|Pairwise Identity)
83  * </li><li>SEQUENCE_LINKS list of name|URL pairs for opening a url with $SEQUENCE_ID$
84  * </li><li>DAS_REGISTRY_URL the registry to query
85  * </li><li>DEFAULT_BROWSER for unix
86  * </li><li>DAS_ACTIVE_SOURCE list of active sources
87  * </li><li>SHOW_MEMUSAGE boolean show memory usage and warning indicator on desktop (false) 
88  * </li><li> 
89  * </li>
90  * 
91  * </ul>
92
93  * @author $author$
94  * @version $Revision$
95  */
96 public class Cache
97 {
98   /**
99    * property giving log4j level for CASTOR loggers
100    */
101   public static final String CASTORLOGLEVEL = "logs.Castor.level";
102   /**
103    * property giving log4j level for AXIS loggers
104    */
105   public static final String AXISLOGLEVEL = "logs.Axis.level";
106   /**
107    * property giving log4j level for Jalview Log
108    */
109   public static final String JALVIEWLOGLEVEL = "logs.Jalview.level";
110   public static final String DAS_LOCAL_SOURCE = "DAS_LOCAL_SOURCE";
111
112   /**
113    * Initialises the Jalview Application Log
114    */
115   public static Logger log;
116
117   /** Jalview Properties */
118   public static Properties applicationProperties = new Properties();
119
120   /** Default file is  ~/.jalview_properties */
121   static String propertiesFile;
122
123   public static void initLogger()
124   {
125     try
126     {
127       ConsoleAppender ap = new ConsoleAppender(new SimpleLayout(),
128       "System.err");
129       ap.setName("JalviewLogger");
130       org.apache.log4j.Logger.getRootLogger().addAppender(ap); // catch all for log output
131       Logger laxis = Logger.getLogger("org.apache.axis");
132       Logger lcastor = Logger.getLogger("org.exolab.castor");
133       jalview.bin.Cache.log = Logger.getLogger("jalview.bin.Jalview");
134
135       laxis.setLevel(Level.toLevel(Cache.getDefault("logs.Axis.Level",
136           Level.INFO.toString())));
137       lcastor.setLevel(Level.toLevel(Cache.getDefault("logs.Castor.Level",
138           Level.INFO.toString())));
139       lcastor = Logger.getLogger("org.exolab.castor.xml");
140       lcastor.setLevel(Level.toLevel(Cache.getDefault("logs.Castor.Level",
141               Level.INFO.toString())));
142       //lcastor = Logger.getLogger("org.exolab.castor.xml.Marshaller");
143       //lcastor.setLevel(Level.toLevel(Cache.getDefault("logs.Castor.Level",
144       //        Level.INFO.toString())));
145       jalview.bin.Cache.log.setLevel(Level.toLevel(Cache.getDefault(
146           "logs.Jalview.level",
147           Level.INFO.toString())));
148       //laxis.addAppender(ap);
149       //lcastor.addAppender(ap);
150       //jalview.bin.Cache.log.addAppender(ap);
151       // Tell the user that debug is enabled
152       jalview.bin.Cache.log.debug("Jalview Debugging Output Follows.");
153     }
154     catch (Exception ex)
155     {
156       System.err.println("Problems initializing the log4j system\n");
157       ex.printStackTrace(System.err);
158     }
159   }
160
161   /** Called when Jalview is started */
162   public static void loadProperties(String propsFile)
163   {
164     propertiesFile = propsFile;
165     if (propsFile == null)
166     {
167       propertiesFile = System.getProperty("user.home") + File.separatorChar +
168           ".jalview_properties";
169     }
170
171     try
172     {
173       FileInputStream fis = new FileInputStream(propertiesFile);
174       applicationProperties.load(fis);
175       applicationProperties.remove("LATEST_VERSION");
176       applicationProperties.remove("VERSION");
177       fis.close();
178     }
179     catch (Exception ex)
180     {
181       System.out.println("Error reading properties file: " + ex);
182     }
183
184     if (getDefault("USE_PROXY", false))
185     {
186       System.out.println("Using proxyServer: " + getDefault("PROXY_SERVER", null) +
187                          " proxyPort: " + getDefault("PROXY_PORT", null));
188       System.setProperty("http.proxyHost", getDefault("PROXY_SERVER", null));
189       System.setProperty("http.proxyPort", getDefault("PROXY_PORT", null));
190     }
191
192     // FIND THE VERSION NUMBER AND BUILD DATE FROM jalview.jar
193     // MUST FOLLOW READING OF LOCAL PROPERTIES FILE AS THE
194     // VERSION MAY HAVE CHANGED SINCE LAST USING JALVIEW
195     try
196     {
197       String buildDetails = "jar:"
198           .concat(
199               Cache.class.getProtectionDomain().getCodeSource().getLocation().
200               toString()
201               .concat("!/.build_properties")
202           );
203
204       java.net.URL localJarFileURL = new java.net.URL(buildDetails);
205
206       InputStream in = localJarFileURL.openStream();
207       applicationProperties.load(in);
208       in.close();
209     }
210     catch (Exception ex)
211     {
212       System.out.println("Error reading build details: " + ex);
213       applicationProperties.remove("VERSION");
214     }
215
216     String jnlpVersion = System.getProperty("jalview.version");
217     String codeVersion = getProperty("VERSION");
218
219     if (codeVersion == null)
220     {
221       // THIS SHOULD ONLY BE THE CASE WHEN TESTING!!
222       codeVersion = "Test";
223       jnlpVersion = "Test";
224     }
225
226     System.out.println("Jalview Version: " + codeVersion);
227
228     // jnlpVersion will be null if we're using InstallAnywhere
229     // Dont do this check if running in headless mode
230     if (jnlpVersion == null && (
231         System.getProperty("java.awt.headless") == null
232         || System.getProperty("java.awt.headless").equals("false")))
233     {
234
235       class VersionChecker
236           extends Thread
237       {
238         public void run()
239         {
240           String jnlpVersion = null;
241           try
242           {
243             java.net.URL url = new java.net.URL(
244                 "http://www.jalview.org/webstart/jalview.jnlp");
245             BufferedReader in = new BufferedReader(new InputStreamReader(url.
246                 openStream()));
247             String line = null;
248             while ( (line = in.readLine()) != null)
249             {
250               if (line.indexOf("jalview.version") == -1)
251               {
252                 continue;
253               }
254
255               line = line.substring(line.indexOf("value=") + 7);
256               line = line.substring(0, line.lastIndexOf("\""));
257               jnlpVersion = line;
258               break;
259             }
260           }
261           catch (Exception ex)
262           {
263             System.out.println(ex);
264             jnlpVersion = getProperty("VERSION");
265           }
266
267           setProperty("LATEST_VERSION", jnlpVersion);
268         }
269       }
270
271       VersionChecker vc = new VersionChecker();
272       vc.start();
273     }
274     else
275     {
276       if (jnlpVersion != null)
277       {
278         setProperty("LATEST_VERSION", jnlpVersion);
279       }
280       else
281       {
282         applicationProperties.remove("LATEST_VERSION");
283       }
284     }
285
286     setProperty("VERSION", codeVersion);
287
288     //LOAD USERDEFINED COLOURS
289     jalview.gui.UserDefinedColours.initUserColourSchemes(getProperty(
290         "USER_DEFINED_COLOURS"));
291     jalview.io.PIRFile.useModellerOutput = Cache.getDefault("PIR_MODELLER", false);
292   }
293
294   /**
295    * Gets Jalview application property of given key. Returns null
296    * if key not found
297    *
298    * @param key Name of property
299    *
300    * @return Property value
301    */
302   public static String getProperty(String key)
303   {
304     return applicationProperties.getProperty(key);
305   }
306
307   /** These methods are used when checking if the saved preference
308    * is different to the default setting
309    */
310
311   public static boolean getDefault(String property, boolean def)
312   {
313     String string = getProperty(property);
314     if (string != null)
315     {
316       def = Boolean.valueOf(string).booleanValue();
317     }
318
319     return def;
320   }
321
322   /** These methods are used when checking if the saved preference
323    * is different to the default setting
324    */
325   public static String getDefault(String property, String def)
326   {
327     String string = getProperty(property);
328     if (string != null)
329     {
330       return string;
331     }
332
333     return def;
334   }
335
336   /**
337    * Stores property in the file "HOME_DIR/.jalview_properties"
338    *
339    * @param key Name of object
340    * @param obj String value of property
341    *
342    * @return String value of property
343    */
344   public static String setProperty(String key, String obj)
345   {
346     try
347     {
348       FileOutputStream out = new FileOutputStream(propertiesFile);
349       applicationProperties.setProperty(key, obj);
350       applicationProperties.store(out, "---JalviewX Properties File---");
351       out.close();
352     }
353     catch (Exception ex)
354     {
355       System.out.println("Error setting property: " + key + " " + obj + "\n" +
356                          ex);
357     }
358     return obj;
359   }
360
361   public static void saveProperties()
362   {
363     try
364     {
365       FileOutputStream out = new FileOutputStream(propertiesFile);
366       applicationProperties.store(out, "---JalviewX Properties File---");
367       out.close();
368     }
369     catch (Exception ex)
370     {
371       System.out.println("Error saving properties: " + ex);
372     }
373   }
374
375   /**
376    * internal vamsas class discovery state
377    */
378   private static int vamsasJarsArePresent = -1;
379   /**
380    * Searches for vamsas client classes on class path.
381    * @return true if vamsas client is present on classpath
382    */
383   public static boolean vamsasJarsPresent()
384   {
385     if (vamsasJarsArePresent == -1)
386     {
387       try
388       {
389         if (jalview.jbgui.GDesktop.class.getClassLoader().loadClass(
390             "uk.ac.vamsas.client.VorbaId") != null)
391         {
392           jalview.bin.Cache.log.debug(
393               "Found Vamsas Classes (uk.ac..vamsas.client.VorbaId can be loaded)");
394           vamsasJarsArePresent = 1;
395           Logger lvclient = Logger.getLogger("uk.ac.vamsas");
396           lvclient.setLevel(Level.toLevel(Cache.getDefault("logs.Vamsas.Level",
397               Level.INFO.toString())));
398
399           lvclient.addAppender(log.getAppender("JalviewLogger"));
400           // Tell the user that debug is enabled
401           lvclient.debug("Jalview Vamsas Client Debugging Output Follows.");
402         }
403       }
404       catch (Exception e)
405       {
406         vamsasJarsArePresent = 0;
407         jalview.bin.Cache.log.debug("Vamsas Classes are not present");
408       }
409     }
410     return (vamsasJarsArePresent > 0);
411   }
412   /**
413    * internal vamsas class discovery state
414    */
415   private static int groovyJarsArePresent = -1;
416   /**
417    * Searches for vamsas client classes on class path.
418    * @return true if vamsas client is present on classpath
419    */
420   public static boolean groovyJarsPresent()
421   {
422     if (groovyJarsArePresent == -1)
423     {
424       try
425       {
426         if (Cache.class.getClassLoader().loadClass(
427             "groovy.lang.GroovyObject") != null)
428         {
429           jalview.bin.Cache.log.debug(
430               "Found Groovy (groovy.lang.GroovyObject can be loaded)");
431           groovyJarsArePresent = 1;
432           Logger lgclient = Logger.getLogger("groovy");
433           lgclient.setLevel(Level.toLevel(Cache.getDefault("logs.Groovy.Level",
434               Level.INFO.toString())));
435
436           lgclient.addAppender(log.getAppender("JalviewLogger"));
437           // Tell the user that debug is enabled
438           lgclient.debug("Jalview Groovy Client Debugging Output Follows.");
439         }
440       }
441       catch (Exception e)
442       {
443         groovyJarsArePresent = 0;
444         jalview.bin.Cache.log.debug("Groovy Classes are not present");
445       }
446     }
447     return (groovyJarsArePresent > 0);
448   }
449
450 }