+ public static void storeAsProperties(Dictionary<String, Object> props, Path path) throws IOException {
+ if (props == null)
+ throw new IllegalArgumentException("Props cannot be null");
+ Properties toStore = new Properties();
+ for (Enumeration<String> keys = props.keys(); keys.hasMoreElements();) {
+ String key = keys.nextElement();
+ toStore.setProperty(key, props.get(key).toString());
+ }
+ try (OutputStream out = Files.newOutputStream(path)) {
+ toStore.store(out, null);
+ }
+ }
+
+ public static void appendAsLdif(String dnBase, String dnKey, Dictionary<String, Object> props, Path path)
+ throws IOException {
+ if (props == null)
+ throw new IllegalArgumentException("Props cannot be null");
+ Object dnValue = props.get(dnKey);
+ String dnStr = dnKey + '=' + dnValue + ',' + dnBase;
+ LdapName dn;
+ try {
+ dn = new LdapName(dnStr);
+ } catch (InvalidNameException e) {
+ throw new IllegalArgumentException("Cannot interpret DN " + dnStr, e);
+ }
+ if (dnValue == null)
+ throw new IllegalArgumentException("DN key " + dnKey + " must have a value");
+ try (Writer writer = Files.newBufferedWriter(path, StandardOpenOption.APPEND, StandardOpenOption.CREATE)) {
+ writer.append("\ndn: ");
+ writer.append(dn.toString());
+ writer.append('\n');
+ for (Enumeration<String> keys = props.keys(); keys.hasMoreElements();) {
+ String key = keys.nextElement();
+ Object value = props.get(key);
+ writer.append(key);
+ writer.append(": ");
+ // FIXME deal with binary and multiple values
+ writer.append(value.toString());
+ writer.append('\n');
+ }
+ }
+ }
+
+ public static Dictionary<String, Object> loadFromProperties(Path path) throws IOException {
+ Properties toLoad = new Properties();
+ try (InputStream in = Files.newInputStream(path)) {
+ toLoad.load(in);
+ }
+ Dictionary<String, Object> res = new Hashtable<String, Object>();
+ for (Object key : toLoad.keySet())
+ res.put(key.toString(), toLoad.get(key));
+ return res;
+ }
+
+ /*
+ * EXCEPTIONS
+ */
+ /**
+ * Chain the messages of all causes (one per line, <b>starts with a line
+ * return</b>) without all the stack
+ */
+ public static String chainCausesMessages(Throwable t) {
+ StringBuffer buf = new StringBuffer();
+ chainCauseMessage(buf, t);
+ return buf.toString();
+ }
+
+ /** Recursive chaining of messages */
+ private static void chainCauseMessage(StringBuffer buf, Throwable t) {
+ buf.append('\n').append(' ').append(t.getClass().getCanonicalName())
+ .append(": ").append(t.getMessage());
+ if (t.getCause() != null)
+ chainCauseMessage(buf, t.getCause());
+ }
+