1
2
3
4
5
6
7
8
9
10 package ch.qos.logback.classic.selector;
11
12 import static ch.qos.logback.classic.ClassicGlobal.JNDI_CONFIGURATION_RESOURCE;
13 import static ch.qos.logback.classic.ClassicGlobal.JNDI_CONTEXT_NAME;
14
15 import java.net.URL;
16 import java.util.ArrayList;
17 import java.util.Collections;
18 import java.util.HashMap;
19 import java.util.List;
20 import java.util.Map;
21
22 import javax.naming.Context;
23 import javax.naming.NamingException;
24
25 import ch.qos.logback.classic.LoggerContext;
26 import ch.qos.logback.classic.joran.JoranConfigurator;
27 import ch.qos.logback.classic.util.ContextInitializer;
28 import ch.qos.logback.classic.util.JNDIUtil;
29 import ch.qos.logback.core.joran.spi.JoranException;
30 import ch.qos.logback.core.status.InfoStatus;
31 import ch.qos.logback.core.status.StatusManager;
32 import ch.qos.logback.core.status.WarnStatus;
33 import ch.qos.logback.core.util.Loader;
34 import ch.qos.logback.core.util.StatusPrinter;
35
36
37
38
39
40
41
42
43
44
45
46
47 public class ContextJNDISelector implements ContextSelector {
48
49 private final Map<String, LoggerContext> synchronizedContextMap;
50 private final LoggerContext defaultContext;
51
52 private static final ThreadLocal<LoggerContext> threadLocal = new ThreadLocal<LoggerContext>();
53
54 public ContextJNDISelector(LoggerContext context) {
55 synchronizedContextMap = Collections
56 .synchronizedMap(new HashMap<String, LoggerContext>());
57 defaultContext = context;
58 }
59
60 public LoggerContext getDefaultLoggerContext() {
61 return defaultContext;
62 }
63
64 public LoggerContext detachLoggerContext(String loggerContextName) {
65 return synchronizedContextMap.remove(loggerContextName);
66 }
67
68 public LoggerContext getLoggerContext() {
69 String contextName = null;
70 Context ctx = null;
71
72
73 LoggerContext lc = threadLocal.get();
74 if (lc != null) {
75 return lc;
76 }
77
78 try {
79
80
81 ctx = JNDIUtil.getInitialContext();
82 contextName = (String) JNDIUtil.lookup(ctx, JNDI_CONTEXT_NAME);
83 } catch (NamingException ne) {
84
85 }
86
87 if (contextName == null) {
88
89 return defaultContext;
90 } else {
91
92 LoggerContext loggerContext = synchronizedContextMap.get(contextName);
93
94 if (loggerContext == null) {
95
96 loggerContext = new LoggerContext();
97 loggerContext.setName(contextName);
98 synchronizedContextMap.put(contextName, loggerContext);
99 URL url = findConfigFileURL(ctx, loggerContext);
100 if (url != null) {
101 configureLoggerContextByURL(loggerContext, url);
102 } else {
103 try {
104 new ContextInitializer(loggerContext).autoConfig();
105 } catch (JoranException je) {
106 }
107 }
108 StatusPrinter.printInCaseOfErrorsOrWarnings(loggerContext);
109 }
110 return loggerContext;
111 }
112 }
113
114 private String conventionalConfigFileName(String contextName) {
115 return "logback-" + contextName + ".xml";
116 }
117
118 private URL findConfigFileURL(Context ctx, LoggerContext loggerContext) {
119 StatusManager sm = loggerContext.getStatusManager();
120
121 String jndiEntryForConfigResource = JNDIUtil.lookup(ctx,
122 JNDI_CONFIGURATION_RESOURCE);
123
124 if (jndiEntryForConfigResource != null) {
125 sm.add(new InfoStatus("Searching for [" + jndiEntryForConfigResource
126 + "]", this));
127 URL url = urlByResourceName(sm, jndiEntryForConfigResource);
128 if (url == null) {
129 String msg = "The jndi resource [" + jndiEntryForConfigResource
130 + "] for context [" + loggerContext.getName()
131 + "] does not lead to a valid file";
132 sm.add(new WarnStatus(msg, this));
133 }
134 return url;
135 } else {
136 String resourceByConvention = conventionalConfigFileName(loggerContext
137 .getName());
138 return urlByResourceName(sm, resourceByConvention);
139 }
140 }
141
142 private URL urlByResourceName(StatusManager sm, String resourceName) {
143 sm.add(new InfoStatus("Searching for [" + resourceName + "]",
144 this));
145 URL url = Loader.getResource(resourceName, Loader.getTCL());
146 if (url != null) {
147 return url;
148 }
149 return Loader.getResourceBySelfClassLoader(resourceName);
150 }
151
152 private void configureLoggerContextByURL(LoggerContext context, URL url) {
153 try {
154 JoranConfigurator configurator = new JoranConfigurator();
155 context.reset();
156 configurator.setContext(context);
157 configurator.doConfigure(url);
158 } catch (JoranException e) {
159 }
160 StatusPrinter.printInCaseOfErrorsOrWarnings(context);
161 }
162
163 public List<String> getContextNames() {
164 List<String> list = new ArrayList<String>();
165 list.addAll(synchronizedContextMap.keySet());
166 return list;
167 }
168
169 public LoggerContext getLoggerContext(String name) {
170 return synchronizedContextMap.get(name);
171 }
172
173
174
175
176
177
178 public int getCount() {
179 return synchronizedContextMap.size();
180 }
181
182
183
184
185
186
187
188
189
190 public void setLocalContext(LoggerContext context) {
191 threadLocal.set(context);
192 }
193
194 public void removeLocalContext() {
195 threadLocal.remove();
196 }
197
198 }