1
14 package ch.qos.logback.core.joran.action;
15
16 import org.xml.sax.Attributes;
17
18 import ch.qos.logback.core.CoreConstants;
19 import ch.qos.logback.core.hook.ShutdownHookBase;
20 import ch.qos.logback.core.joran.spi.ActionException;
21 import ch.qos.logback.core.joran.spi.InterpretationContext;
22 import ch.qos.logback.core.util.OptionHelper;
23
24
29 public class ShutdownHookAction extends Action {
30
31 ShutdownHookBase hook;
32 private boolean inError;
33
34
40 @Override
41 public void begin(InterpretationContext ic, String name, Attributes attributes) throws ActionException {
42 hook = null;
43 inError = false;
44
45 String className = attributes.getValue(CLASS_ATTRIBUTE);
46 if (OptionHelper.isEmpty(className)) {
47 addError("Missing class name for shutdown hook. Near [" + name + "] line " + getLineNumber(ic));
48 inError = true;
49 return;
50 }
51
52 try {
53 addInfo("About to instantiate shutdown hook of type [" + className + "]");
54
55 hook = (ShutdownHookBase) OptionHelper.instantiateByClassName(className, ShutdownHookBase.class, context);
56 hook.setContext(context);
57
58 ic.pushObject(hook);
59 } catch (Exception e) {
60 inError = true;
61 addError("Could not create a shutdown hook of type [" + className + "].", e);
62 throw new ActionException(e);
63 }
64 }
65
66
70 @Override
71 public void end(InterpretationContext ic, String name) throws ActionException {
72 if (inError) {
73 return;
74 }
75
76 Object o = ic.peekObject();
77 if (o != hook) {
78 addWarn("The object at the of the stack is not the hook pushed earlier.");
79 } else {
80 ic.popObject();
81
82 Thread hookThread = new Thread(hook, "Logback shutdown hook [" + context.getName() + "]");
83
84 context.putObject(CoreConstants.SHUTDOWN_HOOK_THREAD, hookThread);
85 Runtime.getRuntime().addShutdownHook(hookThread);
86 }
87 }
88 }
89