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> →
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> →
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