1 /*
2  * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 import java.io.*;
25 import java.util.*;
26 import java.util.logging.*;
27 
28 /*
29  * Custom LogManager implementation to verify that the implementation delegates
30  * to the LogManager subclass to register both system logger and user logger.
31  *
32  * The LogManager implementation is the one configuring the logger's property
33  * such as level, handler, etc.
34  */
35 public class CustomLogManager extends LogManager {
36     static LogManager INSTANCE;
37     Map<String,Logger> namedLoggers = new HashMap<>();
38     Properties props = initConfig();
CustomLogManager()39     public CustomLogManager() {
40         if (INSTANCE != null) {
41             throw new RuntimeException("CustomLogManager already created");
42         }
43         INSTANCE = this;
44     }
45 
useParentHandlers(String loggerName)46     private boolean useParentHandlers(String loggerName) {
47         String s = props.getProperty(loggerName + ".useParentHandlers");
48         if (s == null)
49             return true;   // default is true
50 
51         s = s.toLowerCase();
52         if (s.equals("true") || s.equals("1")) {
53            return true;
54         } else if (s.equals("false") || s.equals("0")) {
55            return false;
56         }
57         return true;
58     }
59 
addLogger(Logger logger)60     public synchronized boolean addLogger(Logger logger) {
61         String name = logger.getName();
62         if (namedLoggers.containsKey(name)) {
63             return false;
64         }
65         namedLoggers.put(name, logger);
66         // set level
67         if (props.get(name + ".level") != null) {
68             logger.setLevel(Level.parse(props.getProperty(name + ".level")));
69         }
70         // add handlers
71         if (props.get(name + ".handlers") != null && logger.getHandlers().length == 0) {
72             logger.addHandler(new CustomHandler());
73         }
74         if (!useParentHandlers(name)) {
75             logger.setUseParentHandlers(false);
76         }
77         // add parent loggers
78         int ix = 1;
79         for (;;) {
80             int ix2 = name.indexOf(".", ix);
81             if (ix2 < 0) {
82                 break;
83             }
84             String pname = name.substring(0, ix2);
85             if (props.get(pname + ".level") != null ||
86                 props.get(pname + ".handlers") != null) {
87                 // This pname has a level/handlers definition.
88                 // Make sure it exists.
89                 //
90                 // The test doesn't set the parent for simplicity.
91                 if (!namedLoggers.containsKey(pname)) {
92                     Logger parent = Logger.getLogger(pname);
93                     if (!useParentHandlers(pname)) {
94                         parent.setUseParentHandlers(false);
95                     }
96                 }
97             }
98             ix = ix2 + 1;
99         }
100         return true;
101     }
102 
getLogger(String name)103     public synchronized Logger getLogger(String name) {
104         return namedLoggers.get(name);
105     }
106 
getLoggerNames()107     public synchronized Enumeration<String> getLoggerNames() {
108         return Collections.enumeration(namedLoggers.keySet());
109     }
110 
getProperty(String name)111     public String getProperty(String name) {
112         return props.getProperty(name);
113     }
114 
readConfiguration()115     public void readConfiguration() {
116         // do nothing
117     }
118 
readConfiguration(InputStream ins)119     public void readConfiguration(InputStream ins) {
120         // do nothing
121     }
122 
initConfig()123     private Properties initConfig() {
124         Properties props = new Properties();
125         props.put(".level", "CONFIG");
126         props.put("CustomLogManagerTest.level", "WARNING");
127         props.put("CustomLogManagerTest.handlers", "CustomLogManager$CustomHandler");
128         props.put("SimpleLogManager.level", "INFO");
129         props.put("SimpleLogManager.handlers", "CustomLogManager$CustomHandler");
130         props.put("CustomLogManager$CustomHandler.level", "WARNING");
131         props.put(".handlers", "CustomLogManager$CustomHandler");
132         props.put("org.foo.bar.level", "SEVERE");
133         props.put("org.foo.bar.useParentHandlers", "true");
134         props.put("org.foo.handlers", "CustomLogManager$CustomHandler");
135         props.put("org.foo.useParentHandlers", "false");
136         props.put("org.openjdk.level", "SEVERE");
137         props.put("org.openjdk.handlers", "CustomLogManager$CustomHandler");
138         props.put("org.openjdk.core.level", "INFO");
139         props.put("org.openjdk.core.useParentHandlers", "false");
140 
141         return props;
142     }
checkLogger(String name)143     public static void checkLogger(String name) {
144         checkLogger(name, null);
145     }
146 
checkLogger(String name, String resourceBundleName)147     public static void checkLogger(String name, String resourceBundleName) {
148         Logger logger = INSTANCE.getLogger(name);
149         if (logger == null) {
150             throw new RuntimeException("Logger \"" + name + "\" not exist");
151         }
152         System.out.format("Logger \"%s\" level=%s handlers=%s resourcebundle=%s useParentHandlers=%s%n",
153             name, logger.getLevel(),
154             Arrays.toString(logger.getHandlers()),
155             logger.getResourceBundleName(),
156             logger.getUseParentHandlers());
157         String rb = logger.getResourceBundleName();
158         if (rb != resourceBundleName && (rb == null || rb.equals(resourceBundleName))) {
159             throw new RuntimeException("Logger \"" + name +
160                 "\" unexpected resource bundle: " + rb);
161         }
162 
163         String value = INSTANCE.getProperty(name + ".level");
164         String level = logger.getLevel() != null ? logger.getLevel().getName() : null;
165         if (level != value && (level == null || level.equals(value))) {
166             throw new RuntimeException("Logger \"" + name + "\" unexpected level: " + level);
167         }
168 
169         Handler[] handlers = logger.getHandlers();
170         String hdl = INSTANCE.getProperty(name + ".handlers");
171         if ((hdl == null && handlers.length != 0) ||
172             (hdl != null && handlers.length != 1)) {
173             throw new RuntimeException("Logger \"" + name + "\" unexpected handler: " +
174                 Arrays.toString(handlers));
175         }
176 
177         String s = INSTANCE.getProperty(name + ".useParentHandlers");
178         boolean uph = (s != null && s.equals("false")) ? false : true;
179         if (logger.getUseParentHandlers() != uph) {
180             throw new RuntimeException("Logger \"" + name + "\" unexpected useParentHandlers: " +
181                 logger.getUseParentHandlers());
182         }
183         checkParents(name);
184     }
185 
checkParents(String name)186     private static void checkParents(String name) {
187         int ix = 1;
188         for (;;) {
189             int ix2 = name.indexOf(".", ix);
190             if (ix2 < 0) {
191                 break;
192             }
193             String pname = name.substring(0, ix2);
194             if (INSTANCE.getProperty(pname + ".level") != null ||
195                 INSTANCE.getProperty(pname + ".handlers") != null) {
196                 // This pname has a level/handlers definition.
197                 // Make sure it exists.
198                 checkLogger(pname);
199             }
200             ix = ix2 + 1;
201         }
202     }
203 
204     // only CustomLogManager can create an instance of CustomHandler
205     private class CustomHandler extends StreamHandler {
206     }
207 }
208