1 package org.opentrafficsim.editor;
2
3 import java.awt.Color;
4 import java.io.File;
5 import java.io.FileReader;
6 import java.io.FileWriter;
7 import java.io.IOException;
8 import java.util.ArrayList;
9 import java.util.Arrays;
10 import java.util.LinkedHashMap;
11 import java.util.List;
12 import java.util.Map;
13 import java.util.Optional;
14 import java.util.Properties;
15
16 import org.djutils.exceptions.Throw;
17
18
19
20
21
22
23
24
25
26 public class ApplicationStore
27 {
28
29
30 private static final int MAX_SAVED_FILES = 10;
31
32
33 private static final int MAX_TOOLTIP_LENGTH = 96;
34
35
36 private static final int MAX_DROPDOWN_ITEMS = 20;
37
38
39 private static final int MAX_NAVIGATE = 50;
40
41
42 private static final Color INVALID_COLOR = new Color(255, 240, 240);
43
44
45 private static final Color EXPRESSION_COLOR = new Color(252, 250, 239);
46
47
48 private final Properties store;
49
50
51 private final String applicationName;
52
53
54 private final String file;
55
56
57 private final Map<String, Color> colorCache = new LinkedHashMap<>();
58
59
60 private final Map<String, Integer> intCache = new LinkedHashMap<>();
61
62
63
64
65
66
67 public ApplicationStore(final String enterpriseName, final String applicationName)
68 {
69 Throw.whenNull(enterpriseName, "Enterprise may not bee null.");
70 this.store = new Properties();
71 this.store.put("expression_color", stringFromColor(EXPRESSION_COLOR));
72 this.store.put("invalid_color", stringFromColor(INVALID_COLOR));
73 this.store.put("max_tooltip_length", Integer.toString(MAX_TOOLTIP_LENGTH));
74 this.store.put("max_dropdown_items", Integer.toString(MAX_DROPDOWN_ITEMS));
75 this.store.put("max_navigate", Integer.toString(MAX_NAVIGATE));
76 this.applicationName = applicationName;
77 this.file =
78 System.getProperty("user.home") + File.separator + enterpriseName + File.separator + applicationName + ".ini";
79 if (new File(this.file).exists())
80 {
81 try
82 {
83 FileReader reader = new FileReader(this.file);
84 this.store.load(reader);
85 }
86 catch (IOException ex)
87 {
88
89 }
90 }
91 save();
92 }
93
94
95
96
97
98
99 public synchronized Optional<String> getProperty(final String key)
100 {
101 Throw.whenNull(key, "Key may not be null.");
102 return Optional.ofNullable((String) this.store.get(key));
103 }
104
105
106
107
108
109
110 public synchronized void setProperty(final String key, final String value)
111 {
112 Throw.whenNull(key, "Key may not be null.");
113 Throw.whenNull(value, "Value may not be null.");
114 this.store.put(key, value);
115 save();
116 }
117
118
119
120
121 private void save()
122 {
123 try
124 {
125 File f = new File(this.file);
126 f.getParentFile().mkdirs();
127 FileWriter writer = new FileWriter(f);
128 this.store.store(writer, this.applicationName + " user settings");
129 }
130 catch (IOException exception)
131 {
132
133 }
134 }
135
136
137
138
139
140
141 public List<String> getRecentFiles(final String key)
142 {
143 Throw.whenNull(key, "Key may not be null.");
144 List<String> out = new ArrayList<>();
145 if (this.store.containsKey(key))
146 {
147 String filesAll = (String) this.store.get(key);
148 String[] files = filesAll.split("\\|");
149 Arrays.stream(files).forEach(out::add);
150 }
151 return out;
152 }
153
154
155
156
157
158
159 public void addRecentFile(final String key, final String fileName)
160 {
161 Throw.whenNull(key, "Key may not be null.");
162 Throw.whenNull(fileName, "File may not be null.");
163 List<String> files = getRecentFiles(key);
164 if (files.contains(fileName))
165 {
166 if (files.get(0).equals(fileName))
167 {
168 return;
169 }
170 files.remove(fileName);
171 }
172 files.add(0, fileName);
173 setFiles(key, files);
174 }
175
176
177
178
179
180
181 public void removeRecentFile(final String key, final String fileName)
182 {
183 List<String> files = getRecentFiles(key);
184 files.remove(fileName);
185 setFiles(key, files);
186 }
187
188
189
190
191
192
193 private void setFiles(final String key, final List<String> files)
194 {
195 StringBuilder str = new StringBuilder();
196 int n = Math.min(files.size(), MAX_SAVED_FILES);
197 if (n > 0)
198 {
199 files.stream().limit(n - 1).forEach((f) -> str.append(f).append("|"));
200 str.append(files.get(n - 1));
201 setProperty(key, str.toString());
202 }
203 else
204 {
205 clearProperty(key);
206 }
207 }
208
209
210
211
212
213 public void clearProperty(final String key)
214 {
215 Throw.whenNull(key, "Key may not be null.");
216 this.store.remove(key);
217 save();
218 }
219
220
221
222
223
224
225 public Color getColor(final String key)
226 {
227 return this.colorCache.computeIfAbsent(key, (k) -> colorFromString(this.store.getProperty(k)));
228 }
229
230
231
232
233
234
235 private static Color colorFromString(final String colorString)
236 {
237 String value = colorString.replace(" ", "");
238 String[] channels = value.substring(1, value.length() - 1).split(",");
239 return new Color(Integer.valueOf(channels[0]), Integer.valueOf(channels[1]), Integer.valueOf(channels[2]));
240 }
241
242
243
244
245
246
247 private String stringFromColor(final Color color)
248 {
249 return String.format("[%d, %d, %d]", color.getRed(), color.getGreen(), color.getBlue());
250 }
251
252
253
254
255
256
257 public int getInt(final String key)
258 {
259 return this.intCache.computeIfAbsent(key, (k) -> Integer.valueOf(this.store.getProperty(k)));
260 }
261 }