View Javadoc

1   /**
2    * Logback: the generic, reliable, fast and flexible logging framework.
3    * 
4    * Copyright (C) 2000-2008, QOS.ch
5    * 
6    * This library is free software, you can redistribute it and/or modify it under
7    * the terms of the GNU Lesser General Public License as published by the Free
8    * Software Foundation.
9    */
10  package ch.qos.logback.core.joran.action;
11  
12  import org.xml.sax.Attributes;
13  
14  import ch.qos.logback.core.joran.spi.InterpretationContext;
15  import ch.qos.logback.core.pattern.util.RegularEscapeUtil;
16  import ch.qos.logback.core.util.Loader;
17  import ch.qos.logback.core.util.OptionHelper;
18  
19  import java.io.FileInputStream;
20  import java.io.IOException;
21  import java.io.InputStream;
22  import java.net.URL;
23  
24  import java.util.Properties;
25  
26  /**
27   * This class serves as a base for other actions, which similar to the ANT
28   * <property> task which add/set properties of a given object.
29   * 
30   * This action sets new substitution properties in the logging context by name,
31   * value pair, or adds all the properties passed in "file" or "resource"
32   * attribute.
33   * 
34   * @author Ceki G&uuml;lc&uuml;
35   */
36  public class PropertyAction extends Action {
37  
38    static final String RESOURCE_ATTRIBUTE = "resource";
39  
40    static String INVALID_ATTRIBUTES = "In <property> element, either the \"file\" attribute alone, or "
41        + "the \"resource\" element alone, or both the \"name\" and \"value\" attributes must be set.";
42  
43    /**
44     * Add all the properties found in the argument named 'props' to an
45     * InterpretationContext.
46     */
47    public void setProperties(InterpretationContext ec, Properties props) {
48      ec.addSubstitutionProperties(props);
49    }
50  
51    public void setProperty(InterpretationContext ec, String key, String value) {
52      ec.addSubstitutionProperty(key, value);
53    }
54  
55    /**
56     * Set a new property for the execution context by name, value pair, or adds
57     * all the properties found in the given file.
58     * 
59     */
60    public void begin(InterpretationContext ec, String localName,
61        Attributes attributes) {
62  
63      if ("substitutionProperty".equals(localName)) {
64        addWarn("[substitutionProperty] element has been deprecated. Plase use the [property] element instead.");
65      }
66  
67      String name = attributes.getValue(NAME_ATTRIBUTE);
68      String value = attributes.getValue(VALUE_ATTRIBUTE);
69  
70      if (checkFileAttributeSanity(attributes)) {
71        String file = attributes.getValue(FILE_ATTRIBUTE);
72        file = ec.subst(file);
73        try {
74          FileInputStream istream = new FileInputStream(file);
75          loadAndSetProperties(ec, istream);
76        } catch (IOException e) {
77          addError("Could not read properties file [" + file + "].", e);
78        }
79      } else if (checkResourceAttributeSanity(attributes)) {
80        String resource = attributes.getValue(RESOURCE_ATTRIBUTE);
81        resource = ec.subst(resource);
82        URL resourceURL = Loader.getResourceBySelfClassLoader(resource);
83        if (resourceURL == null) {
84          addError("Could not find resource [" + resource + "].");
85        } else {
86          try {
87            InputStream istream = resourceURL.openStream();
88            loadAndSetProperties(ec, istream);
89          } catch (IOException e) {
90            addError("Could not read resource file [" + resource + "].", e);
91          }
92        }
93      } else if (checkValueNameAttributesSanity(attributes)) {
94        value = RegularEscapeUtil.basicEscape(value);
95        // now remove both leading and trailing spaces
96        value = value.trim();
97        value = ec.subst(value);
98        setProperty(ec, name, value);
99  
100     } else {
101       addError(INVALID_ATTRIBUTES);
102     }
103   }
104 
105   void loadAndSetProperties(InterpretationContext ec, InputStream istream)
106       throws IOException {
107     Properties props = new Properties();
108     props.load(istream);
109     istream.close();
110     setProperties(ec, props);
111   }
112 
113   boolean checkFileAttributeSanity(Attributes attributes) {
114     String file = attributes.getValue(FILE_ATTRIBUTE);
115     String name = attributes.getValue(NAME_ATTRIBUTE);
116     String value = attributes.getValue(VALUE_ATTRIBUTE);
117     String resource = attributes.getValue(RESOURCE_ATTRIBUTE);
118 
119     return !(OptionHelper.isEmpty(file))
120         && (OptionHelper.isEmpty(name) && OptionHelper.isEmpty(value) && OptionHelper
121             .isEmpty(resource));
122   }
123 
124   boolean checkResourceAttributeSanity(Attributes attributes) {
125     String file = attributes.getValue(FILE_ATTRIBUTE);
126     String name = attributes.getValue(NAME_ATTRIBUTE);
127     String value = attributes.getValue(VALUE_ATTRIBUTE);
128     String resource = attributes.getValue(RESOURCE_ATTRIBUTE);
129 
130     return !(OptionHelper.isEmpty(resource))
131         && (OptionHelper.isEmpty(name) && OptionHelper.isEmpty(value) && OptionHelper
132             .isEmpty(file));
133   }
134 
135   boolean checkValueNameAttributesSanity(Attributes attributes) {
136     String file = attributes.getValue(FILE_ATTRIBUTE);
137     String name = attributes.getValue(NAME_ATTRIBUTE);
138     String value = attributes.getValue(VALUE_ATTRIBUTE);
139     String resource = attributes.getValue(RESOURCE_ATTRIBUTE);
140 
141     return (!(OptionHelper.isEmpty(name) || OptionHelper.isEmpty(value)) && (OptionHelper
142         .isEmpty(file) && OptionHelper.isEmpty(resource)));
143   }
144 
145   public void end(InterpretationContext ec, String name) {
146   }
147 
148   public void finish(InterpretationContext ec) {
149   }
150 }