View Javadoc
1   /*
2    * Licensed under the GPL License. You may not use this file except in compliance with the License.
3    * You may obtain a copy of the License at
4    *
5    *   https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
6    *
7    * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
8    * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
9    * PURPOSE.
10   */
11  package psiprobe.tools.logging.jdk;
12  
13  import com.google.common.base.Strings;
14  
15  import java.lang.reflect.Method;
16  import java.util.ArrayList;
17  import java.util.List;
18  
19  import org.apache.commons.lang3.reflect.MethodUtils;
20  
21  import psiprobe.tools.logging.DefaultAccessor;
22  import psiprobe.tools.logging.LogDestination;
23  
24  /**
25   * The Class Jdk14LoggerAccessor.
26   */
27  public class Jdk14LoggerAccessor extends DefaultAccessor {
28  
29    /** The context. */
30    private boolean context;
31  
32    /**
33     * Gets the handlers.
34     *
35     * @return the handlers
36     */
37    public List<LogDestination> getHandlers() {
38      List<LogDestination> handlerAccessors = new ArrayList<>();
39      try {
40        Object[] handlers = (Object[]) MethodUtils.invokeMethod(getTarget(), "getHandlers");
41        for (int h = 0; h < handlers.length; h++) {
42          Object handler = handlers[h];
43          Jdk14HandlerAccessor handlerAccessor = wrapHandler(handler, h);
44          if (handlerAccessor != null) {
45            handlerAccessors.add(handlerAccessor);
46          }
47        }
48      } catch (Exception e) {
49        logger.error("{}#handlers inaccessible", getTarget().getClass().getName(), e);
50      }
51      return handlerAccessors;
52    }
53  
54    /**
55     * Checks if is context.
56     *
57     * @return true, if is context
58     */
59    public boolean isContext() {
60      return context;
61    }
62  
63    /**
64     * Sets the context.
65     *
66     * @param context the new context
67     */
68    public void setContext(boolean context) {
69      this.context = context;
70    }
71  
72    /**
73     * Checks if is root.
74     *
75     * @return true, if is root
76     */
77    public boolean isRoot() {
78      return Strings.isNullOrEmpty(getName()) || isJuliRoot();
79    }
80  
81    /**
82     * Checks if is juli root.
83     *
84     * @return true, if is juli root
85     */
86    public boolean isJuliRoot() {
87      return "org.apache.juli.ClassLoaderLogManager$RootLogger".equals(getTargetClass());
88    }
89  
90    /**
91     * Gets the name.
92     *
93     * @return the name
94     */
95    public String getName() {
96      return (String) getProperty(getTarget(), "name", null);
97    }
98  
99    /**
100    * Gets the handler.
101    *
102    * @param logIndex the log index
103    *
104    * @return the handler
105    */
106   public Jdk14HandlerAccessor getHandler(String logIndex) {
107     int index = 0;
108     try {
109       index = Integer.parseInt(logIndex);
110     } catch (Exception e) {
111       logger.info("Could not parse integer from: {}.  Assuming 0.", logIndex);
112       logger.trace("", e);
113     }
114     return getHandler(index);
115   }
116 
117   /**
118    * Gets the handler.
119    *
120    * @param index the index
121    *
122    * @return the handler
123    */
124   public Jdk14HandlerAccessor getHandler(int index) {
125     try {
126       Object[] handlers = (Object[]) MethodUtils.invokeMethod(getTarget(), "getHandlers");
127       return wrapHandler(handlers[index], index);
128     } catch (Exception e) {
129       logger.error("{}#handlers inaccessible", getTarget().getClass().getName(), e);
130     }
131     return null;
132   }
133 
134   /**
135    * Gets the level.
136    *
137    * @return the level
138    */
139   public String getLevel() {
140     try {
141       Object level = null;
142       Object target = getTarget();
143       while (level == null && target != null) {
144         level = getLevelInternal(target);
145         target = MethodUtils.invokeMethod(target, "getParent");
146       }
147       if (level == null && isJuliRoot()) {
148         return "INFO";
149       }
150       return (String) MethodUtils.invokeMethod(level, "getName");
151     } catch (Exception e) {
152       logger.error("{}#getLevel() failed", getTarget().getClass().getName(), e);
153     }
154     return null;
155   }
156 
157   /**
158    * Sets the level.
159    *
160    * @param newLevelStr the new level
161    */
162   public void setLevel(String newLevelStr) {
163     try {
164       Class<?> levelClass =
165           getTarget().getClass().getClassLoader().loadClass("java.util.logging.Level");
166       Method parse = MethodUtils.getAccessibleMethod(levelClass, "parse", String.class);
167       Object newLevel = parse.invoke(null, newLevelStr);
168       MethodUtils.invokeMethod(getTarget(), "setLevel", newLevel);
169     } catch (Exception e) {
170       logger.error("{}#setLevel('{}') failed", getTarget().getClass().getName(), newLevelStr, e);
171     }
172   }
173 
174   /**
175    * Gets the level internal.
176    *
177    * @param target the target
178    *
179    * @return the level internal
180    *
181    * @throws Exception the exception
182    */
183   private Object getLevelInternal(Object target) throws Exception {
184     return MethodUtils.invokeMethod(target, "getLevel");
185   }
186 
187   /**
188    * Wrap handler.
189    *
190    * @param handler the handler
191    * @param index the index
192    *
193    * @return the jdk14 handler accessor
194    */
195   private Jdk14HandlerAccessor wrapHandler(Object handler, int index) {
196     try {
197       if (handler == null) {
198         throw new IllegalArgumentException("handler is null");
199       }
200       Jdk14HandlerAccessor handlerAccessor = null;
201       String className = handler.getClass().getName();
202       if ("org.apache.juli.FileHandler".equals(className)) {
203         handlerAccessor = new JuliHandlerAccessor();
204       } else if ("java.util.logging.ConsoleHandler".equals(className)) {
205         handlerAccessor = new Jdk14HandlerAccessor();
206       } else if ("java.util.logging.FileHandler".equals(className)) {
207         handlerAccessor = new Jdk14FileHandlerAccessor();
208       }
209 
210       if (handlerAccessor != null) {
211         handlerAccessor.setLoggerAccessor(this);
212         handlerAccessor.setTarget(handler);
213         handlerAccessor.setIndex(Integer.toString(index));
214         handlerAccessor.setApplication(getApplication());
215       }
216       return handlerAccessor;
217     } catch (Exception e) {
218       logger.error("Could not wrap handler: '{}'", handler, e);
219     }
220     return null;
221   }
222 
223 }