1 /**
2  *  Copyright 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 java.io.File;
20 import java.util.regex.Matcher;
21 import java.util.regex.Pattern;
22
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25
26 /**
27  * A class to represent DiskStore configuration
28  * e.g. <diskStore path="${java.io.tmpdir}" />
29  *
30  * @author <a href="mailto:gluck@thoughtworks.com">Greg Luck</a>
31  * @version $Id: DiskStoreConfiguration.java 5631 2012-05-10 08:31:33Z teck $
32  */

33 public final class DiskStoreConfiguration {
34
35     private static final Pattern PROPERTY_SUBSTITUTION_PATTERN = Pattern.compile("\\$\\{(.+?)\\}");
36
37     private static final Logger LOG = LoggerFactory.getLogger(DiskStoreConfiguration.class.getName());
38
39     /**
40      * The path as specified in the config
41      */

42     private String originalPath;
43
44     /**
45      * The path to the directory where .data and .index files will be created.
46      */

47     private String path;
48
49     /**
50      * A constants class for environment variables used in disk store paths
51      */

52     private static enum Env {
53         USER_HOME("user.home"),
54         USER_DIR("user.dir"),
55         JAVA_IO_TMPDIR("java.io.tmpdir"),
56         EHCACHE_DISK_STORE_DIR("ehcache.disk.store.dir");
57
58         private final String variable;
59
60         Env(String variable) {
61             this.variable = variable;
62         }
63
64         String substitute(String string) {
65             String substitution = System.getProperty(variable);
66             if (substitution == null) {
67                 return string;
68             } else {
69                 return string.replaceFirst(Pattern.quote(variable), Matcher.quoteReplacement(substitution));
70             }
71         }
72     }
73
74     /**
75      * The diskStore path
76      */

77     public final String getPath() {
78         return path;
79     }
80
81     /**
82      * The diskStore default path, which is the system environment variable
83      * available on all Java virtual machines <code>java.io.tmpdir</code>
84      */

85     public static String getDefaultPath() {
86         return Env.JAVA_IO_TMPDIR.substitute(Env.JAVA_IO_TMPDIR.variable);
87     }
88
89     /**
90      * Builder method to set the disk store path, see {@link #setPath(String)}
91      *
92      * @return this configuration instance
93      */

94     public final DiskStoreConfiguration path(final String path) {
95         setPath(path);
96         return this;
97     }
98
99     /**
100      * Translates and sets the path.
101      * <p>
102      * Two forms of path substitution are supported:
103      * <ol>
104      * <li>To support legacy configurations, four explicit string tokens are replaced with their associated Java system property values.
105      * This substitution happens for the <em>first matching token only</em> (e.g. <code>java.io.tmpdir/ehcache/java.io.tmpdir</code> &rarr;
106      * <code>/var/tmp/ehcache/java.io.tmpdir</code>).
107      * <ul>
108      * <li><code>user.home</code> - the user's home directory</li>
109      * <li><code>user.dir</code> - the current working directory</li>
110      * <li><code>java.io.tmpdir</code> - the default temp file path</li>
111      * <li><code>ehcache.disk.store.dir</code> - a system property you would normally specify on the command line, e.g.
112      * <code>java -Dehcache.disk.store.dir=/u01/myapp/diskdir</code></li>
113      * </ul>
114      * </li>
115      * <li>These, and all other system properties can also be substituted using the familiar syntax: <code>${property-name}</code>. Using
116      * this syntax all token instances are replaced (e.g. <code>${java.io.tmpdir}/ehcache/${java.io.tmpdir}</code> &rarr;
117      * <code>/var/tmp/ehcache/var/tmp</code>).</li>
118      * </ol>
119      *
120      * @param path disk store path
121      */

122     public final void setPath(final String path) {
123         this.originalPath = path;
124         this.path = translatePath(path);
125     }
126
127     /**
128      * @return the originalPath
129      */

130     public String getOriginalPath() {
131         return originalPath;
132     }
133
134     private static String translatePath(String path) {
135         String translatedPath = substituteProperties(path);
136         for (Env e : Env.values()) {
137             translatedPath = e.substitute(translatedPath);
138         }
139         // Remove duplicate separators: Windows and Solaris
140         translatedPath = translatedPath.replace(File.separator + File.separator, File.separator);
141         LOG.debug("Disk Store Path: " + translatedPath);
142         return translatedPath;
143     }
144
145     private static String substituteProperties(String string) {
146         Matcher matcher = PROPERTY_SUBSTITUTION_PATTERN.matcher(string);
147
148         StringBuffer eval = new StringBuffer();
149         while (matcher.find()) {
150             String substitution = System.getProperty(matcher.group(1));
151             if (substitution != null) {
152                 matcher.appendReplacement(eval, Matcher.quoteReplacement(substitution));
153             }
154         }
155         matcher.appendTail(eval);
156
157         return eval.toString();
158     }
159 }
160