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