]>
git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.util/src/org/argeo/util/LangUtils.java
1 package org
.argeo
.util
;
3 import java
.io
.IOException
;
4 import java
.io
.InputStream
;
5 import java
.io
.OutputStream
;
7 import java
.nio
.file
.Files
;
8 import java
.nio
.file
.Path
;
9 import java
.nio
.file
.StandardOpenOption
;
10 import java
.time
.ZonedDateTime
;
11 import java
.time
.temporal
.ChronoUnit
;
12 import java
.time
.temporal
.Temporal
;
13 import java
.util
.Dictionary
;
14 import java
.util
.Enumeration
;
15 import java
.util
.Hashtable
;
16 import java
.util
.Properties
;
18 import javax
.naming
.InvalidNameException
;
19 import javax
.naming
.ldap
.LdapName
;
21 public class LangUtils
{
26 * Returns an array with the names of the provided classes. Useful when
27 * registering services with multiple interfaces in OSGi.
29 public static String
[] names(Class
<?
>... clzz
) {
30 String
[] res
= new String
[clzz
.length
];
31 for (int i
= 0; i
< clzz
.length
; i
++)
32 res
[i
] = clzz
[i
].getName();
41 * Creates a new {@link Dictionary} with one key-value pair (neither key not
42 * value should be null)
44 public static Dictionary
<String
, Object
> dico(String key
, Object value
) {
47 Hashtable
<String
, Object
> props
= new Hashtable
<>();
48 props
.put(key
, value
);
53 * Wraps the keys of the provided {@link Dictionary} as an {@link Iterable}.
55 public static Iterable
<String
> keys(Dictionary
<String
, ?
> props
) {
57 return new DictionaryKeys(props
);
60 static String
toJson(Dictionary
<String
, ?
> props
) {
61 return toJson(props
, false);
64 static String
toJson(Dictionary
<String
, ?
> props
, boolean pretty
) {
65 StringBuilder sb
= new StringBuilder();
69 Enumeration
<String
> keys
= props
.keys();
70 while (keys
.hasMoreElements()) {
71 String key
= keys
.nextElement();
74 sb
.append('\"').append(key
).append('\"');
79 sb
.append('\"').append(props
.get(key
)).append('\"');
80 if (keys
.hasMoreElements())
89 static void storeAsProperties(Dictionary
<String
, Object
> props
, Path path
) throws IOException
{
91 throw new IllegalArgumentException("Props cannot be null");
92 Properties toStore
= new Properties();
93 for (Enumeration
<String
> keys
= props
.keys(); keys
.hasMoreElements();) {
94 String key
= keys
.nextElement();
95 toStore
.setProperty(key
, props
.get(key
).toString());
97 try (OutputStream out
= Files
.newOutputStream(path
)) {
98 toStore
.store(out
, null);
102 static void appendAsLdif(String dnBase
, String dnKey
, Dictionary
<String
, Object
> props
, Path path
)
105 throw new IllegalArgumentException("Props cannot be null");
106 Object dnValue
= props
.get(dnKey
);
107 String dnStr
= dnKey
+ '=' + dnValue
+ ',' + dnBase
;
110 dn
= new LdapName(dnStr
);
111 } catch (InvalidNameException e
) {
112 throw new IllegalArgumentException("Cannot interpret DN " + dnStr
, e
);
115 throw new IllegalArgumentException("DN key " + dnKey
+ " must have a value");
116 try (Writer writer
= Files
.newBufferedWriter(path
, StandardOpenOption
.APPEND
, StandardOpenOption
.CREATE
)) {
117 writer
.append("\ndn: ");
118 writer
.append(dn
.toString());
120 for (Enumeration
<String
> keys
= props
.keys(); keys
.hasMoreElements();) {
121 String key
= keys
.nextElement();
122 Object value
= props
.get(key
);
125 // FIXME deal with binary and multiple values
126 writer
.append(value
.toString());
132 static Dictionary
<String
, Object
> loadFromProperties(Path path
) throws IOException
{
133 Properties toLoad
= new Properties();
134 try (InputStream in
= Files
.newInputStream(path
)) {
137 Dictionary
<String
, Object
> res
= new Hashtable
<String
, Object
>();
138 for (Object key
: toLoad
.keySet())
139 res
.put(key
.toString(), toLoad
.get(key
));
147 * Chain the messages of all causes (one per line, <b>starts with a line
148 * return</b>) without all the stack
150 public static String
chainCausesMessages(Throwable t
) {
151 StringBuffer buf
= new StringBuffer();
152 chainCauseMessage(buf
, t
);
153 return buf
.toString();
156 /** Recursive chaining of messages */
157 private static void chainCauseMessage(StringBuffer buf
, Throwable t
) {
158 buf
.append('\n').append(' ').append(t
.getClass().getCanonicalName()).append(": ").append(t
.getMessage());
159 if (t
.getCause() != null)
160 chainCauseMessage(buf
, t
.getCause());
166 /** Formats time elapsed since start. */
167 public static String
since(ZonedDateTime start
) {
168 ZonedDateTime now
= ZonedDateTime
.now();
169 return duration(start
, now
);
172 /** Formats a duration. */
173 public static String
duration(Temporal start
, Temporal end
) {
174 long count
= ChronoUnit
.DAYS
.between(start
, end
);
176 return count
> 1 ? count
+ " days" : count
+ " day";
177 count
= ChronoUnit
.HOURS
.between(start
, end
);
179 return count
> 1 ? count
+ " hours" : count
+ " hours";
180 count
= ChronoUnit
.MINUTES
.between(start
, end
);
182 return count
> 1 ? count
+ " minutes" : count
+ " minute";
183 count
= ChronoUnit
.SECONDS
.between(start
, end
);
184 return count
> 1 ? count
+ " seconds" : count
+ " second";
187 /** Singleton constructor. */
188 private LangUtils() {