2727import java .util .stream .Collectors ;
2828import java .util .stream .IntStream ;
2929
30+ /**
31+ * This class is a replacement for <code>java.util.Properties</code>, with the difference that it
32+ * properly supports comments both for reading and writing. It also maintains an exact
33+ * representation of the input, meaning that when an input is read and later written out again the
34+ * output will match the input exactly. Methods exist for obtaining and setting comments on
35+ * key-value pairs.
36+ */
3037public class Properties extends AbstractMap <String , String > {
3138 private final LinkedHashMap <String , String > values = new LinkedHashMap <>();
3239 private final List <PropertiesParser .Token > tokens = new ArrayList <>();
@@ -64,13 +71,25 @@ public int size() {
6471 };
6572 }
6673
74+ /**
75+ * Works like <code>keySet()</code> but returning the keys' raw values. Meaning that the keys
76+ * haven't been unescaped before being returned.
77+ *
78+ * @return A set of raw key values
79+ */
6780 public Set <String > rawKeySet () {
6881 return tokens .stream ()
6982 .filter (t -> t .type == PropertiesParser .Type .KEY )
7083 .map (PropertiesParser .Token ::getRaw )
7184 .collect (Collectors .toCollection (LinkedHashSet ::new ));
7285 }
7386
87+ /**
88+ * Works like <code>values()</code> but returning the raw values. Meaning that the values have
89+ * not been unescaped before being returned.
90+ *
91+ * @return a collection of raw values.
92+ */
7493 public Collection <String > rawValues () {
7594 return IntStream .range (0 , tokens .size ())
7695 .filter (idx -> tokens .get (idx ).type == PropertiesParser .Type .KEY )
@@ -83,6 +102,13 @@ public String get(Object key) {
83102 return values .get (key );
84103 }
85104
105+ /**
106+ * Works like <code>get()</code> but returns the raw value associated with the given raw key.
107+ * This means that the value won't be unescaped before being returned.
108+ *
109+ * @param rawKey The key too look up in raw format
110+ * @return A raw value or <code>null</code> if the key wasn't found
111+ */
86112 public String getRaw (String rawKey ) {
87113 int idx = indexOf (unescape (rawKey ));
88114 if (idx >= 0 ) {
@@ -105,8 +131,8 @@ public String put(String key, String value) {
105131 }
106132
107133 /**
108- * Works like ` put()` but uses raw values for keys and values. This means these keys and values
109- * will not be escaped before being serialized .
134+ * Works like <code> put()</code> but uses raw values for keys and values. This means these keys
135+ * and values will not be escaped before being stored .
110136 *
111137 * @param rawKey key with which the specified value is to be associated
112138 * @param rawValue value to be associated with the specified key
@@ -155,7 +181,8 @@ public String remove(Object key) {
155181 /**
156182 * Gather all the comments directly before the given key and return them as a list. The list
157183 * will only contain those lines that immediately follow one another, once a non-comment line is
158- * encountered gathering will stop.
184+ * encountered gathering will stop. The returned values will include the comment character that
185+ * the line started with in the original input.
159186 *
160187 * @param key The key to look for
161188 * @return A list of comment strings or an empty list if no comments lines were found or the key
@@ -172,10 +199,34 @@ private List<String> getComment(List<Integer> indices) {
172199 .collect (Collectors .toList ()));
173200 }
174201
202+ /**
203+ * Adds the given comments to the item indicated by the given key. Each comment will be put on a
204+ * separate line. Each comment should start with one of the valid comment symbols <code>#</code>
205+ * or <code>!</code>, but if none is encountered the code will select one for you (it will look
206+ * at any existing comments, or at symbols found on previous items and as a last result will use
207+ * <code># </code>).
208+ *
209+ * @param key The key to look for
210+ * @param comments The comments to add to the item
211+ * @return The previous list of comments, if any
212+ * @throws NoSuchElementException Thrown when they key couldn't be found
213+ */
175214 public List <String > setComment (String key , String ... comments ) {
176215 return setComment (key , Arrays .asList (comments ));
177216 }
178217
218+ /**
219+ * Adds the list of comments to the item indicated by the given key. Each comment will be put on
220+ * a separate line. Each comment should start with one of the valid comment symbols <code>#
221+ * </code> or <code>!</code>, but if none is encountered the code will select one for you (it
222+ * will look at any existing comments, or at symbols found on previous items and as a last
223+ * result will use <code># </code>).
224+ *
225+ * @param key The key to look for
226+ * @param comments The list of comments to add to the item
227+ * @return The previous list of comments, if any
228+ * @throws NoSuchElementException Thrown when they key couldn't be found
229+ */
179230 public List <String > setComment (String key , List <String > comments ) {
180231 int idx = indexOf (key );
181232 if (idx < 0 ) {
@@ -315,22 +366,49 @@ private static String replace(String input, Pattern regex, Function<Matcher, Str
315366 return resultString .toString ();
316367 }
317368
369+ /**
370+ * Returns a <code>java.util.Properties</code> with the same contents as this object. The
371+ * information is a copy, changes to one Properties object will not affect the other.
372+ *
373+ * @return a <code>java.util.Properties</code> object
374+ */
318375 public java .util .Properties asJUProperties () {
319376 return asJUProperties (null );
320377 }
321378
379+ /**
380+ * Returns a <code>java.util.Properties</code> with the same contents as this object and with
381+ * the given <code>java.util.Properties</code> object as fallback. The information is a copy,
382+ * changes to one Properties object will not affect the other.
383+ *
384+ * @return a <code>java.util.Properties</code> object
385+ */
322386 public java .util .Properties asJUProperties (java .util .Properties defaults ) {
323387 java .util .Properties p = new java .util .Properties (defaults );
324388 p .putAll (this );
325389 return p ;
326390 }
327391
392+ /**
393+ * Loads the contents from the given file and stores it in this object. This includes not only
394+ * key-value pairs but also all whitespace and any comments that are encountered.
395+ *
396+ * @param file a path to the file to load
397+ * @throws IOException Thrown when any IO error occurs during loading
398+ */
328399 public void load (Path file ) throws IOException {
329400 try (Reader br = Files .newBufferedReader (file )) {
330401 load (br );
331402 }
332403 }
333404
405+ /**
406+ * Loads the contents from the reader and stores it in this object. This includes not only
407+ * key-value pairs but also all whitespace and any comments that are encountered.
408+ *
409+ * @param reader a <code>Reader</code> object
410+ * @throws IOException Thrown when any IO error occurs during loading
411+ */
334412 public void load (Reader reader ) throws IOException {
335413 tokens .clear ();
336414 BufferedReader br =
@@ -349,24 +427,50 @@ public void load(Reader reader) throws IOException {
349427 }
350428 }
351429
430+ /**
431+ * Returns a <code>Properties</code> with the contents read from the given file. This includes
432+ * not only key-value pairs but also all whitespace and any comments that are encountered.
433+ *
434+ * @param file a path to the file to load
435+ * @throws IOException Thrown when any IO error occurs during loading
436+ */
352437 public static Properties loadProperties (Path file ) throws IOException {
353438 Properties props = new Properties ();
354439 props .load (file );
355440 return props ;
356441 }
357442
443+ /**
444+ * Returns a <code>Properties</code> with the contents read from the given file. This includes
445+ * not only key-value pairs but also all whitespace and any comments that are encountered.
446+ *
447+ * @param reader a <code>Reader</code> object
448+ * @throws IOException Thrown when any IO error occurs during loading
449+ */
358450 public static Properties loadProperties (Reader reader ) throws IOException {
359451 Properties props = new Properties ();
360452 props .load (reader );
361453 return props ;
362454 }
363455
456+ /**
457+ * Stores the contents of this object to the given file.
458+ *
459+ * @param file a path to the file to write
460+ * @throws IOException
461+ */
364462 public void store (Path file ) throws IOException {
365463 try (Writer bw = Files .newBufferedWriter (file , StandardOpenOption .TRUNCATE_EXISTING )) {
366464 store (bw );
367465 }
368466 }
369467
468+ /**
469+ * Stores the contents of this object to the given file.
470+ *
471+ * @param writer a <code>Writer</code> object
472+ * @throws IOException
473+ */
370474 public void store (Writer writer ) throws IOException {
371475 for (PropertiesParser .Token token : tokens ) {
372476 writer .write (token .getRaw ());
0 commit comments