1 /**
2  * Logback: the reliable, generic, fast and flexible logging framework.
3  * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
4  *
5  * This program and the accompanying materials are dual-licensed under
6  * either the terms of the Eclipse Public License v1.0 as published by
7  * the Eclipse Foundation
8  *
9  *   or (per the licensee's choosing)
10  *
11  * under the terms of the GNU Lesser General Public License version 2.1
12  * as published by the Free Software Foundation.
13  */

14 package ch.qos.logback.core.joran.action;
15
16 import ch.qos.logback.core.joran.action.ActionUtil.Scope;
17 import ch.qos.logback.core.joran.spi.InterpretationContext;
18 import ch.qos.logback.core.joran.spi.ActionException;
19 import ch.qos.logback.core.spi.LifeCycle;
20 import ch.qos.logback.core.util.OptionHelper;
21 import ch.qos.logback.core.spi.PropertyDefiner;
22 import org.xml.sax.Attributes;
23
24 /**
25  * Instantiate class for define property value. Get future property name and
26  * property definer class from attributes. Some property definer properties
27  * could be used. After defining put new property to context.
28  * 
29  * @author Aleksey Didik
30  */

31 public class DefinePropertyAction extends Action {
32
33     String scopeStr;
34     Scope scope;
35     String propertyName;
36     PropertyDefiner definer;
37     boolean inError;
38
39     public void begin(InterpretationContext ec, String localName, Attributes attributes) throws ActionException {
40         // reset variables
41         scopeStr = null;
42         scope = null;
43         propertyName = null;
44         definer = null;
45         inError = false;
46
47         // read future property name
48         propertyName = attributes.getValue(NAME_ATTRIBUTE);
49         scopeStr = attributes.getValue(SCOPE_ATTRIBUTE);
50
51         scope = ActionUtil.stringToScope(scopeStr);
52         if (OptionHelper.isEmpty(propertyName)) {
53             addError("Missing property name for property definer. Near [" + localName + "] line " + getLineNumber(ec));
54             inError = true;
55             return;
56         }
57
58         // read property definer class name
59         String className = attributes.getValue(CLASS_ATTRIBUTE);
60         if (OptionHelper.isEmpty(className)) {
61             addError("Missing class name for property definer. Near [" + localName + "] line " + getLineNumber(ec));
62             inError = true;
63             return;
64         }
65
66         // try to instantiate property definer
67         try {
68             addInfo("About to instantiate property definer of type [" + className + "]");
69             definer = (PropertyDefiner) OptionHelper.instantiateByClassName(className, PropertyDefiner.class, context);
70             definer.setContext(context);
71             if (definer instanceof LifeCycle) {
72                 ((LifeCycle) definer).start();
73             }
74             ec.pushObject(definer);
75         } catch (Exception oops) {
76             inError = true;
77             addError("Could not create an PropertyDefiner of type [" + className + "].", oops);
78             throw new ActionException(oops);
79         }
80     }
81
82     /**
83      * Now property definer is initialized by all properties and we can put
84      * property value to context
85      */

86     public void end(InterpretationContext ec, String name) {
87         if (inError) {
88             return;
89         }
90
91         Object o = ec.peekObject();
92
93         if (o != definer) {
94             addWarn("The object at the of the stack is not the property definer for property named [" + propertyName + "] pushed earlier.");
95         } else {
96             addInfo("Popping property definer for property named [" + propertyName + "] from the object stack");
97             ec.popObject();
98             // let's put defined property and value to context but only if it is
99             // not null
100             String propertyValue = definer.getPropertyValue();
101             if (propertyValue != null) {
102                 ActionUtil.setProperty(ec, propertyName, propertyValue, scope);
103             }
104         }
105     }
106 }
107