blob: 4f8733bd1433661e17ae24ae326af56ac5d655fc [file] [log] [blame]
Dave Borowitz9de65952012-08-13 16:09:45 -07001// Copyright 2012 Google Inc. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package com.google.gitiles;
16
17import com.google.common.base.Predicates;
18import com.google.common.cache.CacheBuilder;
19import com.google.common.collect.ImmutableList;
20import com.google.common.collect.Iterables;
21
22import org.eclipse.jgit.lib.Config;
23import org.joda.time.Duration;
24
25import java.util.concurrent.TimeUnit;
26import java.util.regex.Matcher;
27import java.util.regex.Pattern;
28
29/** Utilities for working with {@link Config} objects. */
30public class ConfigUtil {
31 /**
32 * Read a duration value from the configuration.
33 * <p>
34 * Durations can be written as expressions, for example {@code "1 s"} or
35 * {@code "5 days"}. If units are not specified, milliseconds are assumed.
36 *
37 * @param config JGit config object.
38 * @param section section to read, e.g. "google"
39 * @param subsection subsection to read, e.g. "bigtable"
40 * @param name variable to read, e.g. "deadline".
41 * @param defaultValue value to use when the value is not assigned.
42 * @return a standard duration representing the time read, or defaultValue.
43 */
44 public static Duration getDuration(Config config, String section, String subsection, String name,
45 Duration defaultValue) {
46 String valStr = config.getString(section, subsection, name);
47 if (valStr == null) {
48 return defaultValue;
49 }
50
51 valStr = valStr.trim();
52 if (valStr.length() == 0) {
53 return defaultValue;
54 }
55
56 Matcher m = matcher("^([1-9][0-9]*(?:\\.[0-9]*)?)\\s*(.*)$", valStr);
57 if (!m.matches()) {
58 String key = section + (subsection != null ? "." + subsection : "") + "." + name;
59 throw new IllegalStateException("Not time unit: " + key + " = " + valStr);
60 }
61
62 String digits = m.group(1);
63 String unitName = m.group(2).trim();
64
65 TimeUnit unit;
66 if ("".equals(unitName)) {
67 unit = TimeUnit.MILLISECONDS;
68 } else if (anyOf(unitName, "ms", "millis", "millisecond", "milliseconds")) {
69 unit = TimeUnit.MILLISECONDS;
70 } else if (anyOf(unitName, "s", "sec", "second", "seconds")) {
71 unit = TimeUnit.SECONDS;
72 } else if (anyOf(unitName, "m", "min", "minute", "minutes")) {
73 unit = TimeUnit.MINUTES;
74 } else if (anyOf(unitName, "h", "hr", "hour", "hours")) {
75 unit = TimeUnit.HOURS;
76 } else if (anyOf(unitName, "d", "day", "days")) {
77 unit = TimeUnit.DAYS;
78 } else {
79 String key = section + (subsection != null ? "." + subsection : "") + "." + name;
80 throw new IllegalStateException("Not time unit: " + key + " = " + valStr);
81 }
82
83 try {
84 if (digits.indexOf('.') == -1) {
85 long val = Long.parseLong(digits);
86 return new Duration(val * TimeUnit.MILLISECONDS.convert(1, unit));
87 } else {
88 double val = Double.parseDouble(digits);
89 return new Duration((long) (val * TimeUnit.MILLISECONDS.convert(1, unit)));
90 }
91 } catch (NumberFormatException nfe) {
92 String key = section + (subsection != null ? "." + subsection : "") + "." + name;
93 throw new IllegalStateException("Not time unit: " + key + " = " + valStr, nfe);
94 }
95 }
96
97 /**
98 * Get a {@link CacheBuilder} from a config.
99 *
100 * @param config JGit config object.
101 * @param name name of the cache subsection under the "cache" section.
102 * @return a new cache builder.
103 */
104 public static CacheBuilder<Object, Object> getCacheBuilder(Config config, String name) {
105 CacheBuilder<Object, Object> b = CacheBuilder.newBuilder();
106 try {
107 if (config.getString("cache", name, "maximumWeight") != null) {
108 b.maximumWeight(config.getLong("cache", name, "maximumWeight", 20 << 20));
109 }
110 if (config.getString("cache", name, "maximumSize") != null) {
111 b.maximumSize(config.getLong("cache", name, "maximumSize", 16384));
112 }
113 Duration expireAfterWrite = getDuration(config, "cache", name, "expireAfterWrite", null);
114 if (expireAfterWrite != null) {
115 b.expireAfterWrite(expireAfterWrite.getMillis(), TimeUnit.MILLISECONDS);
116 }
117 Duration expireAfterAccess = getDuration(config, "cache", name, "expireAfterAccess", null);
118 if (expireAfterAccess != null) {
119 b.expireAfterAccess(expireAfterAccess.getMillis(), TimeUnit.MILLISECONDS);
120 }
121 // Add other methods as needed.
122 } catch (IllegalArgumentException e) {
123 throw new IllegalArgumentException("Error getting CacheBuilder for " + name, e);
124 } catch (IllegalStateException e) {
125 throw new IllegalStateException("Error getting CacheBuilder for " + name, e);
126 }
127 return b;
128 }
129
130 private static Matcher matcher(String pattern, String valStr) {
131 return Pattern.compile(pattern).matcher(valStr);
132 }
133
134 private static boolean anyOf(String a, String... cases) {
135 return Iterables.any(ImmutableList.copyOf(cases),
136 Predicates.equalTo(a.toLowerCase()));
137 }
138
139 private ConfigUtil() {
140 }
141}