20 package net.sf.gridarta.preferences;
22 import java.io.BufferedWriter;
24 import java.io.FileInputStream;
25 import java.io.FileNotFoundException;
26 import java.io.FileOutputStream;
27 import java.io.IOException;
28 import java.io.InputStreamReader;
29 import java.io.LineNumberReader;
30 import java.io.OutputStreamWriter;
31 import java.nio.charset.StandardCharsets;
33 import java.util.Map.Entry;
35 import java.util.TreeMap;
36 import java.util.TreeSet;
37 import java.util.prefs.BackingStoreException;
38 import java.util.regex.Pattern;
39 import net.
sf.japi.swing.action.ActionBuilder;
40 import net.
sf.japi.swing.action.ActionBuilderFactory;
41 import org.apache.log4j.Category;
42 import org.apache.log4j.Logger;
43 import org.jetbrains.annotations.NotNull;
44 import org.jetbrains.annotations.Nullable;
62 private static final Category
LOG = Logger.getLogger(
Storage.class);
91 private final Map<String, Map<String, String>>
values =
new TreeMap<>();
100 if (
LOG.isDebugEnabled()) {
115 public void newNode(@NotNull
final String path) {
116 if (
LOG.isDebugEnabled()) {
117 LOG.debug(
"newNode(" + path +
")");
120 if (!
values.containsKey(path)) {
121 values.put(path,
new TreeMap<>());
133 if (
LOG.isDebugEnabled()) {
134 LOG.debug(
"childrenNames(" + path +
")");
137 final String prefix = path +
"/";
138 final Set<String> result =
new TreeSet<>();
139 for (
final String key :
values.keySet()) {
140 if (key.startsWith(prefix)) {
141 result.add(key.substring(prefix.length()));
144 return result.toArray(
new String[0]);
155 public String
getValue(@NotNull
final String path, @NotNull
final String key) {
156 if (
LOG.isDebugEnabled()) {
157 LOG.debug(
"getValue(" + path +
", " + key +
")");
160 final Map<String, String> map =
values.get(path);
172 public String @NotNull []
getKeys(@NotNull
final String path) {
173 if (
LOG.isDebugEnabled()) {
174 LOG.debug(
"getKeys(" + path +
")");
177 final Map<String, String> map =
values.get(path);
179 final Set<String> keys = map.keySet();
180 return keys.toArray(
new String[0]);
189 public void putValue(@NotNull
final String path, @NotNull
final String key, @NotNull
final String value) {
190 if (
LOG.isDebugEnabled()) {
191 LOG.debug(
"putValue(" + path +
", " + key +
", " + value +
")");
194 final Map<String, String> map =
values.get(path);
196 final String oldValue = map.put(key, value);
197 if (oldValue ==
null || !oldValue.equals(value)) {
207 if (
LOG.isDebugEnabled()) {
208 LOG.debug(
"removeNode(" + path +
")");
211 if (
values.remove(path) !=
null) {
221 public void removeValue(@NotNull
final String path, @NotNull
final String key) {
222 if (
LOG.isDebugEnabled()) {
223 LOG.debug(
"removeValue(" + path +
", " + key +
")");
226 final Map<String, String> map =
values.get(path);
228 if (map.remove(key) !=
null) {
239 public void sync(
final boolean sync)
throws BackingStoreException {
240 if (
LOG.isDebugEnabled()) {
241 LOG.debug(
"sync(" +
sync +
")");
246 }
catch (
final IOException ex) {
247 throw new BackingStoreException(ex);
262 }
catch (
final IOException ex) {
263 LOG.warn(
file +
": " + ex.getMessage());
275 if (
LOG.isDebugEnabled()) {
276 LOG.debug(
"loadValues: " +
file);
282 try (FileInputStream fis =
new FileInputStream(
file)) {
283 try (InputStreamReader isr =
new InputStreamReader(fis, StandardCharsets.UTF_8)) {
284 try (LineNumberReader lnr =
new LineNumberReader(isr)) {
289 }
catch (
final FileNotFoundException ignored) {
291 }
catch (
final IOException ex) {
292 LOG.warn(
file +
": " + ex.getMessage());
301 private void loadValues(@NotNull
final LineNumberReader lnr)
throws IOException {
304 final String line2 = lnr.readLine();
309 if (line.startsWith(
"#") || line.isEmpty()) {
313 if (line.startsWith(
"[") && line.endsWith(
"]")) {
314 path = line.substring(1, line.length() - 1);
319 if (tmp.length != 2) {
320 LOG.warn(
file +
":" + lnr.getLineNumber() +
": syntax error");
323 final String key = tmp[0];
324 final String value = tmp[1];
340 if (
LOG.isDebugEnabled()) {
341 LOG.debug(
"saveValues: " +
file);
344 final File tmpFile =
new File(
file.getPath() +
".tmp");
345 try (FileOutputStream fos =
new FileOutputStream(tmpFile)) {
346 try (OutputStreamWriter osw =
new OutputStreamWriter(fos, StandardCharsets.UTF_8)) {
347 try (BufferedWriter bw =
new BufferedWriter(osw)) {
349 if (defaultNode !=
null) {
353 for (
final Entry<String, Map<String, String>> e :
values.entrySet()) {
355 saveNode(bw, e.getKey(), e.getValue());
364 if (!tmpFile.renameTo(
file)) {
365 throw new IOException(
"cannot rename " + tmpFile +
" to " +
file);
376 private static void saveNode(@NotNull
final BufferedWriter writer, @Nullable
final String path, @NotNull
final Map<String, String> node)
throws IOException {
377 if (node.isEmpty()) {
381 final ActionBuilder actionBuilder = ActionBuilderFactory.getInstance().getActionBuilder(
"net.sf.gridarta");
391 for (
final Entry<String, String> entry : node.entrySet()) {
394 final String comment = actionBuilder.getString(
"prefs." +
PATTERN_IGNORE.matcher(entry.getKey()).replaceAll(
""));
395 if (comment !=
null) {
397 writer.write(comment);