Initial import
[jpf-core.git] / src / main / gov / nasa / jpf / util / LogManager.java
1 /*
2  * Copyright (C) 2014, United States Government, as represented by the
3  * Administrator of the National Aeronautics and Space Administration.
4  * All rights reserved.
5  *
6  * The Java Pathfinder core (jpf-core) platform is licensed under the
7  * Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  * 
10  *        http://www.apache.org/licenses/LICENSE-2.0. 
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and 
16  * limitations under the License.
17  */
18 package gov.nasa.jpf.util;
19
20 import gov.nasa.jpf.Config;
21
22 import java.io.OutputStream;
23 import java.util.HashMap;
24 import java.util.logging.Handler;
25 import java.util.logging.Level;
26 import java.util.logging.Logger;
27
28 /**
29  * this class is responsible for returning properly JPF-configured
30  * Loggers. It is not supposed to be used directly by clients, but rather
31  * is a JPF delegatee.
32  * 
33  * While we could modify/replace the standard java.util.logging facility
34  * at various levels (own LogManager, own initialization class etc.), we choose
35  * the approach to piggyback on it, because these mechanisms either require
36  * changing system properties, rely on only partly documented features, or
37  * don't give us the full functionality we need. By having our own log
38  * encapsulator, we could also replace the underlying mechanism if we really
39  * want to
40  */
41 public class LogManager {
42     
43   static HashMap<String,JPFLogger> loggers = new HashMap<String, JPFLogger>(); // our own set
44   
45   static Level defaultLevel = Level.WARNING;
46   static Handler handler;  // we have only one
47   
48   // I don't like these categories too much, but we want to act as a stand in
49   static String[] activeSevere;
50   static String[] activeWarning;
51   static String[] activeInfo;
52   static String[] activeConfig;
53   static String[] activeFine;
54   static String[] activeFiner;
55   static String[] activeFinest;
56   
57   /**
58    * note - this is not allowed to fail, since we couldn't log that. Hardcoded default
59    * values have to do in this case (make sure we catch the proper Config exceptions)
60    */
61   public static void init (Config conf) {
62     try {
63       defaultLevel = Level.parse( conf.getString("log.level", "INFO").toUpperCase());
64     } catch (Throwable x) {
65       defaultLevel = Level.WARNING;
66     }
67     
68     activeSevere = conf.getStringArray("log.severe");
69     activeWarning = conf.getStringArray("log.warning");
70     activeInfo = conf.getStringArray("log.info");
71     activeConfig = conf.getStringArray("log.config");
72     activeFine = conf.getStringArray("log.fine");
73     activeFiner = conf.getStringArray("log.finer");
74     activeFinest = conf.getStringArray("log.finest");
75     
76     handler = conf.getInstance("log.handler.class", Handler.class);
77   }
78   
79   static boolean checkInclusion (String[] actives, String name) {
80     if (actives == null) {
81       return false;
82     }
83     
84     for (int i=0; i<actives.length; i++) {
85       if (name.matches(actives[i])) {
86         return true;
87       }
88     }
89     
90     return false;
91   }
92   
93   static Level getLevel (String name) {
94     if (checkInclusion(activeSevere, name)) return Level.SEVERE;
95     if (checkInclusion(activeWarning, name)) return Level.WARNING;
96     if (checkInclusion(activeInfo, name)) return Level.INFO;
97     if (checkInclusion(activeConfig, name)) return Level.CONFIG;
98     if (checkInclusion(activeFine, name)) return Level.FINE;
99     if (checkInclusion(activeFiner, name)) return Level.FINER;
100     if (checkInclusion(activeFinest, name)) return Level.FINEST;
101     
102     return defaultLevel;
103   }
104   
105   public static JPFLogger getLogger (String name) {
106     if (handler == null){
107       // <2do> this is only a band aid for missing LogManager.init(conf) calls
108       handler = new LogHandler.DefaultConsoleHandler();
109     }
110
111     // how often can you say 'Logger' in one method..
112     JPFLogger logger = loggers.get(name);
113     
114     if (logger == null) {
115       // we haven't had this one yet - create and init a new one from the host logging system
116       Logger baseLogger = Logger.getLogger(name);
117       baseLogger.setLevel( getLevel(name));
118       baseLogger.addHandler(handler);
119       baseLogger.setUseParentHandlers(false); // we don't want to pass this up
120       
121       // wrap it
122       logger = new JPFLogger(baseLogger);
123       loggers.put(name, logger);
124     }
125     
126     return logger;
127   }
128   
129   public static void setOutput(OutputStream out) {
130     // need to have init() called first
131     if (handler instanceof LogHandler){
132       ((LogHandler)handler).setOutput(out);
133     }
134   }
135   
136   public static void printStatus (Logger log) {
137     if (handler instanceof LogHandler){
138       ((LogHandler)handler).printStatus(log);
139     }
140   }
141 }