View Javadoc
1   package com.atlassian.refapp.sal;
2   
3   import com.atlassian.fugue.Pair;
4   import com.google.common.collect.ImmutableSet;
5   import org.slf4j.Logger;
6   import org.slf4j.LoggerFactory;
7   
8   import javax.annotation.Nonnull;
9   import java.io.File;
10  import java.io.FileOutputStream;
11  import java.io.IOException;
12  import java.io.OutputStream;
13  import java.util.AbstractMap;
14  import java.util.HashSet;
15  import java.util.Properties;
16  import java.util.Set;
17  
18  public abstract class FileBackedSettingsService {
19      private static final Logger log = LoggerFactory.getLogger(FileBackedSettingsService.class);
20  
21      protected final File file;
22      protected final Properties properties;
23  
24      public FileBackedSettingsService(Pair<File, Properties> fileAndProperties) {
25          this.file = fileAndProperties.left();
26          this.properties = fileAndProperties.right();
27      }
28  
29      /**
30       * In-memory settings, for testing only.
31       */
32      protected FileBackedSettingsService() {
33          this.file = null;
34          this.properties = new Properties();
35      }
36  
37      @SuppressWarnings("AccessToStaticFieldLockedOnInstance")
38      private synchronized void store() {
39          if (this.file == null || !this.file.canWrite()) {
40              // Read only settings
41              return;
42          }
43          OutputStream os = null;
44          try {
45              os = new FileOutputStream(file);
46              properties.storeToXML(os, "SAL Reference Implementation settings");
47          } catch (IOException ioe) {
48              log.error("Error storing properties", ioe);
49          } finally {
50              if (os != null) {
51                  try {
52                      os.close();
53                  } catch (IOException ioe) {
54                      log.error("Error closing output stream", ioe);
55                  }
56              }
57          }
58      }
59  
60      public class SettingsMap extends AbstractMap<String, String> {
61          private final String settingsKey;
62  
63          public SettingsMap(String settingsKey) {
64              if (settingsKey == null) {
65                  this.settingsKey = "global.";
66              } else {
67                  this.settingsKey = "keys." + settingsKey + ".";
68              }
69          }
70  
71          @Nonnull
72          public Set<Entry<String, String>> entrySet() {
73              Set<Entry<String, String>> set = new HashSet<Entry<String, String>>();
74  
75              for (Entry<Object, Object> entry : properties.entrySet()) {
76                  final String key = (String) entry.getKey();
77                  if (key.startsWith(this.settingsKey)) {
78                      set.add(new AbstractMap.SimpleEntry<String, String>(key.substring(this.settingsKey.length()), (String) entry.getValue()));
79                  }
80              }
81  
82              return set;
83          }
84  
85          public String get(Object key) {
86              return properties.getProperty(settingsKey + key);
87          }
88  
89          public String put(String key, String value) {
90              String result = (String) properties.setProperty(settingsKey + key, value);
91              store();
92              return result;
93          }
94  
95          public String remove(Object key) {
96              String result = (String) properties.remove(settingsKey + key);
97              store();
98              return result;
99          }
100 
101         public void clear() {
102             for (Object object : ImmutableSet.copyOf(properties.keySet())) {
103                 if (object instanceof String && ((String) object).startsWith(settingsKey)) {
104                     properties.remove(object);
105                 }
106             }
107             store();
108         }
109     }
110 }