1
17 package org.apache.catalina.mapper;
18
19 import java.util.ArrayList;
20 import java.util.List;
21
22 import org.apache.catalina.Container;
23 import org.apache.catalina.ContainerEvent;
24 import org.apache.catalina.ContainerListener;
25 import org.apache.catalina.Context;
26 import org.apache.catalina.Engine;
27 import org.apache.catalina.Host;
28 import org.apache.catalina.Lifecycle;
29 import org.apache.catalina.LifecycleEvent;
30 import org.apache.catalina.LifecycleException;
31 import org.apache.catalina.LifecycleListener;
32 import org.apache.catalina.LifecycleState;
33 import org.apache.catalina.Service;
34 import org.apache.catalina.WebResourceRoot;
35 import org.apache.catalina.Wrapper;
36 import org.apache.catalina.util.LifecycleMBeanBase;
37 import org.apache.juli.logging.Log;
38 import org.apache.juli.logging.LogFactory;
39 import org.apache.tomcat.util.res.StringManager;
40
41
42
48 public class MapperListener extends LifecycleMBeanBase
49 implements ContainerListener, LifecycleListener {
50
51
52 private static final Log log = LogFactory.getLog(MapperListener.class);
53
54
55
56
59 private final Mapper mapper;
60
61
64 private final Service service;
65
66
67
70 private static final StringManager sm =
71 StringManager.getManager(Constants.Package);
72
73
76 private final String domain = null;
77
78
79
80
81
86 public MapperListener(Service service) {
87 this.service = service;
88 this.mapper = service.getMapper();
89 }
90
91
92
93
94 @Override
95 public void startInternal() throws LifecycleException {
96
97 setState(LifecycleState.STARTING);
98
99 Engine engine = service.getContainer();
100 if (engine == null) {
101 return;
102 }
103
104 findDefaultHost();
105
106 addListeners(engine);
107
108 Container[] conHosts = engine.findChildren();
109 for (Container conHost : conHosts) {
110 Host host = (Host) conHost;
111 if (!LifecycleState.NEW.equals(host.getState())) {
112
113 registerHost(host);
114 }
115 }
116 }
117
118
119 @Override
120 public void stopInternal() throws LifecycleException {
121 setState(LifecycleState.STOPPING);
122
123 Engine engine = service.getContainer();
124 if (engine == null) {
125 return;
126 }
127 removeListeners(engine);
128 }
129
130
131 @Override
132 protected String getDomainInternal() {
133 if (service instanceof LifecycleMBeanBase) {
134 return service.getDomain();
135 } else {
136 return null;
137 }
138 }
139
140
141 @Override
142 protected String getObjectNameKeyProperties() {
143
144 return "type=Mapper";
145 }
146
147
148
149 @Override
150 public void containerEvent(ContainerEvent event) {
151
152 if (Container.ADD_CHILD_EVENT.equals(event.getType())) {
153 Container child = (Container) event.getData();
154 addListeners(child);
155
156
157 if (child.getState().isAvailable()) {
158 if (child instanceof Host) {
159 registerHost((Host) child);
160 } else if (child instanceof Context) {
161 registerContext((Context) child);
162 } else if (child instanceof Wrapper) {
163
164
165 if (child.getParent().getState().isAvailable()) {
166 registerWrapper((Wrapper) child);
167 }
168 }
169 }
170 } else if (Container.REMOVE_CHILD_EVENT.equals(event.getType())) {
171 Container child = (Container) event.getData();
172 removeListeners(child);
173
174
175 } else if (Host.ADD_ALIAS_EVENT.equals(event.getType())) {
176
177 mapper.addHostAlias(((Host) event.getSource()).getName(),
178 event.getData().toString());
179 } else if (Host.REMOVE_ALIAS_EVENT.equals(event.getType())) {
180
181 mapper.removeHostAlias(event.getData().toString());
182 } else if (Wrapper.ADD_MAPPING_EVENT.equals(event.getType())) {
183
184 Wrapper wrapper = (Wrapper) event.getSource();
185 Context context = (Context) wrapper.getParent();
186 String contextPath = context.getPath();
187 if ("/".equals(contextPath)) {
188 contextPath = "";
189 }
190 String version = context.getWebappVersion();
191 String hostName = context.getParent().getName();
192 String wrapperName = wrapper.getName();
193 String mapping = (String) event.getData();
194 boolean jspWildCard = ("jsp".equals(wrapperName)
195 && mapping.endsWith("));
196 mapper.addWrapper(hostName, contextPath, version, mapping, wrapper,
197 jspWildCard, context.isResourceOnlyServlet(wrapperName));
198 } else if (Wrapper.REMOVE_MAPPING_EVENT.equals(event.getType())) {
199
200 Wrapper wrapper = (Wrapper) event.getSource();
201
202 Context context = (Context) wrapper.getParent();
203 String contextPath = context.getPath();
204 if ("/".equals(contextPath)) {
205 contextPath = "";
206 }
207 String version = context.getWebappVersion();
208 String hostName = context.getParent().getName();
209
210 String mapping = (String) event.getData();
211
212 mapper.removeWrapper(hostName, contextPath, version, mapping);
213 } else if (Context.ADD_WELCOME_FILE_EVENT.equals(event.getType())) {
214
215 Context context = (Context) event.getSource();
216
217 String hostName = context.getParent().getName();
218
219 String contextPath = context.getPath();
220 if ("/".equals(contextPath)) {
221 contextPath = "";
222 }
223
224 String welcomeFile = (String) event.getData();
225
226 mapper.addWelcomeFile(hostName, contextPath,
227 context.getWebappVersion(), welcomeFile);
228 } else if (Context.REMOVE_WELCOME_FILE_EVENT.equals(event.getType())) {
229
230 Context context = (Context) event.getSource();
231
232 String hostName = context.getParent().getName();
233
234 String contextPath = context.getPath();
235 if ("/".equals(contextPath)) {
236 contextPath = "";
237 }
238
239 String welcomeFile = (String) event.getData();
240
241 mapper.removeWelcomeFile(hostName, contextPath,
242 context.getWebappVersion(), welcomeFile);
243 } else if (Context.CLEAR_WELCOME_FILES_EVENT.equals(event.getType())) {
244
245 Context context = (Context) event.getSource();
246
247 String hostName = context.getParent().getName();
248
249 String contextPath = context.getPath();
250 if ("/".equals(contextPath)) {
251 contextPath = "";
252 }
253
254 mapper.clearWelcomeFiles(hostName, contextPath,
255 context.getWebappVersion());
256 }
257 }
258
259
260
261
262 private void findDefaultHost() {
263
264 Engine engine = service.getContainer();
265 String defaultHost = engine.getDefaultHost();
266
267 boolean found = false;
268
269 if (defaultHost != null && defaultHost.length() > 0) {
270 Container[] containers = engine.findChildren();
271
272 for (Container container : containers) {
273 Host host = (Host) container;
274 if (defaultHost.equalsIgnoreCase(host.getName())) {
275 found = true;
276 break;
277 }
278
279 String[] aliases = host.findAliases();
280 for (String alias : aliases) {
281 if (defaultHost.equalsIgnoreCase(alias)) {
282 found = true;
283 break;
284 }
285 }
286 }
287 }
288
289 if (found) {
290 mapper.setDefaultHostName(defaultHost);
291 } else {
292 log.error(sm.getString("mapperListener.unknownDefaultHost", defaultHost, service));
293 }
294 }
295
296
297 /**
298 * Register host.
299 */
300 private void registerHost(Host host) {
301
302 String[] aliases = host.findAliases();
303 mapper.addHost(host.getName(), aliases, host);
304
305 for (Container container : host.findChildren()) {
306 if (container.getState().isAvailable()) {
307 registerContext((Context) container);
308 }
309 }
310
311
312 findDefaultHost();
313
314 if(log.isDebugEnabled()) {
315 log.debug(sm.getString("mapperListener.registerHost",
316 host.getName(), domain, service));
317 }
318 }
319
320
321
324 private void unregisterHost(Host host) {
325
326 String hostname = host.getName();
327
328 mapper.removeHost(hostname);
329
330
331 findDefaultHost();
332
333 if(log.isDebugEnabled()) {
334 log.debug(sm.getString("mapperListener.unregisterHost", hostname,
335 domain, service));
336 }
337 }
338
339
340
343 private void unregisterWrapper(Wrapper wrapper) {
344
345 Context context = ((Context) wrapper.getParent());
346 String contextPath = context.getPath();
347 String wrapperName = wrapper.getName();
348
349 if ("/".equals(contextPath)) {
350 contextPath = "";
351 }
352 String version = context.getWebappVersion();
353 String hostName = context.getParent().getName();
354
355 String[] mappings = wrapper.findMappings();
356
357 for (String mapping : mappings) {
358 mapper.removeWrapper(hostName, contextPath, version, mapping);
359 }
360
361 if(log.isDebugEnabled()) {
362 log.debug(sm.getString("mapperListener.unregisterWrapper",
363 wrapperName, contextPath, service));
364 }
365 }
366
367
368
371 private void registerContext(Context context) {
372
373 String contextPath = context.getPath();
374 if ("/".equals(contextPath)) {
375 contextPath = "";
376 }
377 Host host = (Host)context.getParent();
378
379 WebResourceRoot resources = context.getResources();
380 String[] welcomeFiles = context.findWelcomeFiles();
381 List<WrapperMappingInfo> wrappers = new ArrayList<>();
382
383 for (Container container : context.findChildren()) {
384 prepareWrapperMappingInfo(context, (Wrapper) container, wrappers);
385
386 if(log.isDebugEnabled()) {
387 log.debug(sm.getString("mapperListener.registerWrapper",
388 container.getName(), contextPath, service));
389 }
390 }
391
392 mapper.addContextVersion(host.getName(), host, contextPath,
393 context.getWebappVersion(), context, welcomeFiles, resources,
394 wrappers);
395
396 if(log.isDebugEnabled()) {
397 log.debug(sm.getString("mapperListener.registerContext",
398 contextPath, service));
399 }
400 }
401
402
403
406 private void unregisterContext(Context context) {
407
408 String contextPath = context.getPath();
409 if ("/".equals(contextPath)) {
410 contextPath = "";
411 }
412 String hostName = context.getParent().getName();
413
414 if (context.getPaused()) {
415 if (log.isDebugEnabled()) {
416 log.debug(sm.getString("mapperListener.pauseContext",
417 contextPath, service));
418 }
419
420 mapper.pauseContextVersion(context, hostName, contextPath,
421 context.getWebappVersion());
422 } else {
423 if (log.isDebugEnabled()) {
424 log.debug(sm.getString("mapperListener.unregisterContext",
425 contextPath, service));
426 }
427
428 mapper.removeContextVersion(context, hostName, contextPath,
429 context.getWebappVersion());
430 }
431 }
432
433
434
437 private void registerWrapper(Wrapper wrapper) {
438
439 Context context = (Context) wrapper.getParent();
440 String contextPath = context.getPath();
441 if ("/".equals(contextPath)) {
442 contextPath = "";
443 }
444 String version = context.getWebappVersion();
445 String hostName = context.getParent().getName();
446
447 List<WrapperMappingInfo> wrappers = new ArrayList<>();
448 prepareWrapperMappingInfo(context, wrapper, wrappers);
449 mapper.addWrappers(hostName, contextPath, version, wrappers);
450
451 if(log.isDebugEnabled()) {
452 log.debug(sm.getString("mapperListener.registerWrapper",
453 wrapper.getName(), contextPath, service));
454 }
455 }
456
457
461 private void prepareWrapperMappingInfo(Context context, Wrapper wrapper,
462 List<WrapperMappingInfo> wrappers) {
463 String wrapperName = wrapper.getName();
464 boolean resourceOnly = context.isResourceOnlyServlet(wrapperName);
465 String[] mappings = wrapper.findMappings();
466 for (String mapping : mappings) {
467 boolean jspWildCard = (wrapperName.equals("jsp")
468 && mapping.endsWith("));
469 wrappers.add(new WrapperMappingInfo(mapping, wrapper, jspWildCard,
470 resourceOnly));
471 }
472 }
473
474 @Override
475 public void lifecycleEvent(LifecycleEvent event) {
476 if (event.getType().equals(Lifecycle.AFTER_START_EVENT)) {
477 Object obj = event.getSource();
478 if (obj instanceof Wrapper) {
479 Wrapper w = (Wrapper) obj;
480
481
482 if (w.getParent().getState().isAvailable()) {
483 registerWrapper(w);
484 }
485 } else if (obj instanceof Context) {
486 Context c = (Context) obj;
487
488
489 if (c.getParent().getState().isAvailable()) {
490 registerContext(c);
491 }
492 } else if (obj instanceof Host) {
493 registerHost((Host) obj);
494 }
495 } else if (event.getType().equals(Lifecycle.BEFORE_STOP_EVENT)) {
496 Object obj = event.getSource();
497 if (obj instanceof Wrapper) {
498 unregisterWrapper((Wrapper) obj);
499 } else if (obj instanceof Context) {
500 unregisterContext((Context) obj);
501 } else if (obj instanceof Host) {
502 unregisterHost((Host) obj);
503 }
504 }
505 }
506
507
508 /**
509 * Add this mapper to the container and all child containers
510 *
511 * @param container
512 */
513 private void addListeners(Container container) {
514 container.addContainerListener(this);
515 container.addLifecycleListener(this);
516 for (Container child : container.findChildren()) {
517 addListeners(child);
518 }
519 }
520
521
522
527 private void removeListeners(Container container) {
528 container.removeContainerListener(this);
529 container.removeLifecycleListener(this);
530 for (Container child : container.findChildren()) {
531 removeListeners(child);
532 }
533 }
534 }
535