~ubuntu-branches/ubuntu/oneiric/ehcache/oneiric

« back to all changes in this revision

Viewing changes to core/src/main/java/net/sf/ehcache/config/ConfigurationFactory.java

  • Committer: Bazaar Package Importer
  • Author(s): Torsten Werner
  • Date: 2010-06-23 10:35:31 UTC
  • mfrom: (1.1.5 upstream) (2.1.6 sid)
  • Revision ID: james.westby@ubuntu.com-20100623103531-ra0qdpmotoz6ygct
Tags: 2.1.0-1
Merge changes from Thierry's PPA and upload to Debian.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
 *  Copyright 2003-2009 Terracotta, Inc.
3
 
 *
4
 
 *  Licensed under the Apache License, Version 2.0 (the "License");
5
 
 *  you may not use this file except in compliance with the License.
6
 
 *  You may obtain a copy of the License at
7
 
 *
8
 
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 
 *
10
 
 *  Unless required by applicable law or agreed to in writing, software
11
 
 *  distributed under the License is distributed on an "AS IS" BASIS,
12
 
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 
 *  See the License for the specific language governing permissions and
14
 
 *  limitations under the License.
15
 
 */
16
 
 
17
 
package net.sf.ehcache.config;
18
 
 
19
 
import net.sf.ehcache.CacheException;
20
 
import net.sf.ehcache.util.ClassLoaderUtil;
21
 
 
22
 
import javax.xml.parsers.SAXParser;
23
 
import javax.xml.parsers.SAXParserFactory;
24
 
import java.io.BufferedInputStream;
25
 
import java.io.ByteArrayInputStream;
26
 
import java.io.File;
27
 
import java.io.FileInputStream;
28
 
import java.io.IOException;
29
 
import java.io.InputStream;
30
 
import java.io.InputStreamReader;
31
 
import java.io.Reader;
32
 
import java.net.URL;
33
 
import java.util.HashSet;
34
 
import java.util.Set;
35
 
import java.util.logging.Level;
36
 
import java.util.logging.Logger;
37
 
import java.util.regex.Matcher;
38
 
import java.util.regex.Pattern;
39
 
 
40
 
/**
41
 
 * A utility class which configures beans from XML, using reflection.
42
 
 *
43
 
 * @author Greg Luck
44
 
 * @version $Id: ConfigurationFactory.java 1012 2009-08-20 04:23:00Z gregluck $
45
 
 */
46
 
public final class ConfigurationFactory {
47
 
 
48
 
    private static final Logger LOG = Logger.getLogger(ConfigurationFactory.class.getName());
49
 
 
50
 
    private static final String DEFAULT_CLASSPATH_CONFIGURATION_FILE = "/ehcache.xml";
51
 
    private static final String FAILSAFE_CLASSPATH_CONFIGURATION_FILE = "/ehcache-failsafe.xml";
52
 
 
53
 
    /**
54
 
     * Constructor.
55
 
     */
56
 
    private ConfigurationFactory() {
57
 
 
58
 
    }
59
 
 
60
 
    /**
61
 
     * Configures a bean from an XML file.
62
 
     */
63
 
    public static Configuration parseConfiguration(final File file) throws CacheException {
64
 
        if (file == null) {
65
 
            throw new CacheException("Attempt to configure ehcache from null file.");
66
 
        }
67
 
 
68
 
        if (LOG.isLoggable(Level.FINE)) {
69
 
            LOG.log(Level.FINE, "Configuring ehcache from file: " + file.toString());
70
 
        }
71
 
        Configuration configuration = null;
72
 
        InputStream input = null;
73
 
        try {
74
 
            input = new BufferedInputStream(new FileInputStream(file));
75
 
            configuration = parseConfiguration(input);
76
 
        } catch (Exception e) {
77
 
            throw new CacheException("Error configuring from " + file + ". Initial cause was " + e.getMessage(), e);
78
 
        } finally {
79
 
            try {
80
 
                if (input != null) {
81
 
                    input.close();
82
 
                }
83
 
            } catch (IOException e) {
84
 
                LOG.log(Level.SEVERE, "IOException while closing configuration input stream. Error was " + e.getMessage());
85
 
            }
86
 
        }
87
 
        return configuration;
88
 
    }
89
 
 
90
 
    /**
91
 
     * Configures a bean from an XML file available as an URL.
92
 
     */
93
 
    public static Configuration parseConfiguration(final URL url) throws CacheException {
94
 
        if (LOG.isLoggable(Level.FINE)) {
95
 
            LOG.log(Level.FINE, "Configuring ehcache from URL: " + url);
96
 
        }
97
 
        Configuration configuration;
98
 
        InputStream input = null;
99
 
        try {
100
 
            input = url.openStream();
101
 
            configuration = parseConfiguration(input);
102
 
        } catch (Exception e) {
103
 
            throw new CacheException("Error configuring from " + url + ". Initial cause was " + e.getMessage(), e);
104
 
        } finally {
105
 
            try {
106
 
                if (input != null) {
107
 
                    input.close();
108
 
                }
109
 
            } catch (IOException e) {
110
 
                LOG.log(Level.SEVERE, "IOException while closing configuration input stream. Error was " + e.getMessage());
111
 
            }
112
 
        }
113
 
        return configuration;
114
 
    }
115
 
 
116
 
    /**
117
 
     * Configures a bean from an XML file in the classpath.
118
 
     */
119
 
    public static Configuration parseConfiguration() throws CacheException {
120
 
        ClassLoader standardClassloader = ClassLoaderUtil.getStandardClassLoader();
121
 
        URL url = null;
122
 
        if (standardClassloader != null) {
123
 
            url = standardClassloader.getResource(DEFAULT_CLASSPATH_CONFIGURATION_FILE);
124
 
        }
125
 
        if (url == null) {
126
 
            url = ConfigurationFactory.class.getResource(DEFAULT_CLASSPATH_CONFIGURATION_FILE);
127
 
        }
128
 
        if (url != null) {
129
 
            if (LOG.isLoggable(Level.FINE)) {
130
 
                LOG.log(Level.FINE, "Configuring ehcache from ehcache.xml found in the classpath: " + url);
131
 
            }
132
 
        } else {
133
 
            url = ConfigurationFactory.class.getResource(FAILSAFE_CLASSPATH_CONFIGURATION_FILE);
134
 
            if (LOG.isLoggable(Level.WARNING)) {
135
 
                LOG.log(Level.WARNING, "No configuration found. Configuring ehcache from ehcache-failsafe.xml "
136
 
                        + " found in the classpath: " + url);
137
 
            }
138
 
        }
139
 
        return parseConfiguration(url);
140
 
    }
141
 
 
142
 
    /**
143
 
     * Configures a bean from an XML input stream.
144
 
     */
145
 
    public static Configuration parseConfiguration(final InputStream inputStream) throws CacheException {
146
 
        if (LOG.isLoggable(Level.FINE)) {
147
 
            LOG.log(Level.FINE, "Configuring ehcache from InputStream");
148
 
        }
149
 
 
150
 
        Configuration configuration = new Configuration();
151
 
        try {
152
 
            InputStream translatedInputStream = translateSystemProperties(inputStream);
153
 
            final SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
154
 
            final BeanHandler handler = new BeanHandler(configuration);
155
 
            parser.parse(translatedInputStream, handler);
156
 
        } catch (Exception e) {
157
 
            throw new CacheException("Error configuring from input stream. Initial cause was " + e.getMessage(), e);
158
 
        }
159
 
        return configuration;
160
 
    }
161
 
 
162
 
    /**
163
 
     * Translates system properties which can be added as tokens to the config file using ${token} syntax.
164
 
     * <p/>
165
 
     * So, if the config file contains a character sequence "multicastGroupAddress=${multicastAddress}", and there is a system property
166
 
     * multicastAddress=230.0.0.12 then the translated sequence becomes "multicastGroupAddress=230.0.0.12"
167
 
     *
168
 
     * @param inputStream
169
 
     * @return a translated stream
170
 
     */
171
 
    private static InputStream translateSystemProperties(InputStream inputStream) throws IOException {
172
 
 
173
 
        StringBuffer stringBuffer = new StringBuffer();
174
 
        int c;
175
 
        Reader reader = new InputStreamReader(inputStream, "UTF-8");
176
 
        while ((c = reader.read()) != -1) {
177
 
            stringBuffer.append((char) c);
178
 
        }
179
 
        String configuration = stringBuffer.toString();
180
 
 
181
 
        Set tokens = extractPropertyTokens(configuration);
182
 
        for (Object tokenObject : tokens) {
183
 
            String token = (String) tokenObject;
184
 
            String leftTrimmed = token.replaceAll("\\$\\{", "");
185
 
            String trimmedToken = leftTrimmed.replaceAll("\\}", "");
186
 
 
187
 
            String property = System.getProperty(trimmedToken);
188
 
            if (property == null) {
189
 
                if (LOG.isLoggable(Level.FINE)) {
190
 
                    LOG.log(Level.FINE, "Did not find a system property for the " + token +
191
 
                            " token specified in the configuration.Replacing with \"\"");
192
 
                }
193
 
            } else {
194
 
                //replaceAll by default clobbers \ and $
195
 
                String propertyWithQuotesProtected = Matcher.quoteReplacement(property);
196
 
                configuration = configuration.replaceAll("\\$\\{" + trimmedToken + "\\}", propertyWithQuotesProtected);
197
 
                if (LOG.isLoggable(Level.FINE)) {
198
 
                    LOG.log(Level.FINE, "Found system property value of " + property + " for the " + token +
199
 
                            " token specified in the configuration.");
200
 
                }
201
 
            }
202
 
        }
203
 
        return new ByteArrayInputStream(configuration.getBytes());
204
 
    }
205
 
 
206
 
    /**
207
 
     * Extracts properties of the form ${...}
208
 
     *
209
 
     * @param sourceDocument the source document
210
 
     * @return a Set of properties. So, duplicates are only counted once.
211
 
     */
212
 
    static Set extractPropertyTokens(String sourceDocument) {
213
 
        Set propertyTokens = new HashSet();
214
 
        Pattern pattern = Pattern.compile("\\$\\{.+?\\}");
215
 
        Matcher matcher = pattern.matcher(sourceDocument);
216
 
        while (matcher.find()) {
217
 
            String token = matcher.group();
218
 
            propertyTokens.add(token);
219
 
        }
220
 
        return propertyTokens;
221
 
    }
222
 
 
223
 
 
224
 
}