-
Notifications
You must be signed in to change notification settings - Fork 963
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add ConfigDocument API #280
Merged
+2,491
−220
Merged
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
13f2cb3
Add ConfigNode classes
MSLilah faf8d42
Remove repeats when setting value in ConfigNode
MSLilah fa0aaea
Add path to ConfigNodeComplexValue if nonexistent
MSLilah 3166db4
Add more robust ConfigNode tests
MSLilah e695543
Address ConfigNode PR feedback
MSLilah cce8c20
Keep tokens in Path
MSLilah 0a804de
Add docs and copyright information
MSLilah b19e38f
Extract Path parsing into new class
MSLilah 2e6bc40
Address further PR feedback
MSLilah 4101f94
Create ConfigDocumentParser
MSLilah f115731
Add ConfigDocumentParser JSON tests
MSLilah d3b33cc
Refactor parseConcatenation() method
MSLilah c44ef1c
Add new subclasses of ConfigNodeComplexValue
MSLilah 639a3ea
Add ConfigDocument tests
MSLilah 4b61790
Improve field addition in node replacement
MSLilah 28a096f
Cleanup based on findbugs
MSLilah c3a2e07
Address some more PR feedback
MSLilah 1639a91
Address further PR feedback before merge
MSLilah b70d4c1
Update single value parsing
MSLilah File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
58 changes: 58 additions & 0 deletions
58
config/src/main/java/com/typesafe/config/ConfigDocument.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package com.typesafe.config; | ||
|
||
/** | ||
* An object parsed from the original input text, which can be used to | ||
* replace individual values and exactly render the original text of the | ||
* input. | ||
* | ||
* <p> | ||
* Because this object is immutable, it is safe to use from multiple threads and | ||
* there's no need for "defensive copies." | ||
* | ||
* <p> | ||
* <em>Do not implement interface {@code ConfigNode}</em>; it should only be | ||
* implemented by the config library. Arbitrary implementations will not work | ||
* because the library internals assume a specific concrete implementation. | ||
* Also, this interface is likely to grow new methods over time, so third-party | ||
* implementations will break. | ||
*/ | ||
public interface ConfigDocument { | ||
/** | ||
* Returns a new ConfigDocument that is a copy of the current ConfigDocument, | ||
* but with the desired value set at the desired path. If the path exists, it will | ||
* remove all duplicates before the final occurrence of the path, and replace the value | ||
* at the final occurrence of the path. If the path does not exist, it will be added. | ||
* | ||
* @param path the path at which to set the desired value | ||
* @param newValue the value to set at the desired path, represented as a string. This | ||
* string will be parsed into a ConfigNode using the same options used to | ||
* parse the entire document, and the text will be inserted | ||
* as-is into the document. Leading and trailing comments, whitespace, or | ||
* newlines are not allowed, and if present an exception will be thrown. | ||
* If a concatenation is passed in for newValue but the document was parsed | ||
* with JSON, the first value in the concatenation will be parsed and inserted | ||
* into the ConfigDocument. | ||
* @return a copy of the ConfigDocument with the desired value at the desired path | ||
*/ | ||
ConfigDocument setValue(String path, String newValue); | ||
|
||
/** | ||
* Returns a new ConfigDocument that is a copy of the current ConfigDocument, | ||
* but with the desired value set at the desired path as with {@link #setValue(String, String)}, | ||
* but takes a ConfigValue instead of a string. | ||
* | ||
* @param path the path at which to set the desired value | ||
* @param newValue the value to set at the desired path, represented as a ConfigValue. | ||
* The rendered text of the ConfigValue will be inserted into the | ||
* ConfigDocument. | ||
* @return a copy of the ConfigDocument with the desired value at the desired path | ||
*/ | ||
ConfigDocument setValue(String path, ConfigValue newValue); | ||
|
||
/** | ||
* The original text of the input, modified if necessary with | ||
* any replaced or added values. | ||
* @return the modified original text | ||
*/ | ||
String render(); | ||
} |
92 changes: 92 additions & 0 deletions
92
config/src/main/java/com/typesafe/config/ConfigDocumentFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package com.typesafe.config; | ||
|
||
import com.typesafe.config.impl.ConfigImpl; | ||
import com.typesafe.config.impl.Parseable; | ||
|
||
import java.io.File; | ||
import java.io.Reader; | ||
|
||
/** | ||
* Factory for automatically creating a ConfigDocument from a given input. Currently | ||
* only supports files and strings. | ||
*/ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we might want Reader too I suppose. Then people can plug in other kinds of stream. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Alright, I'll add support for a Reader as well. |
||
public final class ConfigDocumentFactory { | ||
|
||
/** | ||
* Parses a Reader into a ConfigDocument instance. | ||
* | ||
* @param reader | ||
* the reader to parse | ||
* @param options | ||
* parse options to control how the reader is interpreted | ||
* @return the parsed configuration | ||
* @throws ConfigException on IO or parse errors | ||
*/ | ||
public static ConfigDocument parseReader(Reader reader, ConfigParseOptions options) { | ||
return Parseable.newReader(reader, options).parseConfigDocument(); | ||
} | ||
|
||
/** | ||
* Parses a reader into a Config instance as with | ||
* {@link #parseReader(Reader,ConfigParseOptions)} but always uses the | ||
* default parse options. | ||
* | ||
* @param reader | ||
* the reader to parse | ||
* @return the parsed configuration | ||
* @throws ConfigException on IO or parse errors | ||
*/ | ||
public static ConfigDocument parseReader(Reader reader) { | ||
return parseReader(reader, ConfigParseOptions.defaults()); | ||
} | ||
|
||
/** | ||
* Parses a file into a ConfigDocument instance. | ||
* | ||
* @param file | ||
* the file to parse | ||
* @param options | ||
* parse options to control how the file is interpreted | ||
* @return the parsed configuration | ||
* @throws ConfigException on IO or parse errors | ||
*/ | ||
public static ConfigDocument parseFile(File file, ConfigParseOptions options) { | ||
return Parseable.newFile(file, options).parseConfigDocument(); | ||
} | ||
|
||
/** | ||
* Parses a file into a ConfigDocument instance as with | ||
* {@link #parseFile(File,ConfigParseOptions)} but always uses the | ||
* default parse options. | ||
* | ||
* @param file | ||
* the file to parse | ||
* @return the parsed configuration | ||
* @throws ConfigException on IO or parse errors | ||
*/ | ||
public static ConfigDocument parseFile(File file) { | ||
return parseFile(file, ConfigParseOptions.defaults()); | ||
} | ||
|
||
/** | ||
* Parses a string which should be valid HOCON or JSON. | ||
* | ||
* @param s string to parse | ||
* @param options parse options | ||
* @return the parsed configuration | ||
*/ | ||
public static ConfigDocument parseString(String s, ConfigParseOptions options) { | ||
return Parseable.newString(s, options).parseConfigDocument(); | ||
} | ||
|
||
/** | ||
* Parses a string (which should be valid HOCON or JSON). Uses the | ||
* default parse options. | ||
* | ||
* @param s string to parse | ||
* @return the parsed configuration | ||
*/ | ||
public static ConfigDocument parseString(String s) { | ||
return parseString(s, ConfigParseOptions.defaults()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/** | ||
* Copyright (C) 2015 Typesafe Inc. <http://typesafe.com> | ||
*/ | ||
package com.typesafe.config; | ||
|
||
/** | ||
* An immutable node that makes up the ConfigDocument AST, and which can be | ||
* used to reproduce part or all of the original text of an input. | ||
* | ||
* <p> | ||
* Because this object is immutable, it is safe to use from multiple threads and | ||
* there's no need for "defensive copies." | ||
* | ||
* <p> | ||
* <em>Do not implement interface {@code ConfigNode}</em>; it should only be | ||
* implemented by the config library. Arbitrary implementations will not work | ||
* because the library internals assume a specific concrete implementation. | ||
* Also, this interface is likely to grow new methods over time, so third-party | ||
* implementations will break. | ||
*/ | ||
public interface ConfigNode { | ||
/** | ||
* The original text of the input which was used to form this particular node. | ||
* @return the original text used to form this node as a String | ||
*/ | ||
public String render(); | ||
} |
29 changes: 29 additions & 0 deletions
29
config/src/main/java/com/typesafe/config/impl/AbstractConfigNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/** | ||
* Copyright (C) 2015 Typesafe Inc. <http://typesafe.com> | ||
*/ | ||
package com.typesafe.config.impl; | ||
|
||
import com.typesafe.config.ConfigNode; | ||
import java.util.Collection; | ||
|
||
abstract class AbstractConfigNode implements ConfigNode { | ||
abstract Collection<Token> tokens(); | ||
final public String render() { | ||
StringBuilder origText = new StringBuilder(); | ||
Iterable<Token> tokens = tokens(); | ||
for (Token t : tokens) { | ||
origText.append(t.tokenText()); | ||
} | ||
return origText.toString(); | ||
} | ||
|
||
@Override | ||
final public boolean equals(Object other) { | ||
return other instanceof AbstractConfigNode && render().equals(((AbstractConfigNode)other).render()); | ||
} | ||
|
||
@Override | ||
final public int hashCode() { | ||
return render().hashCode(); | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
config/src/main/java/com/typesafe/config/impl/AbstractConfigNodeValue.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
/** | ||
* Copyright (C) 2015 Typesafe Inc. <http://typesafe.com> | ||
*/ | ||
package com.typesafe.config.impl; | ||
|
||
// This is required if we want | ||
// to be referencing the AbstractConfigNode class in implementation rather than the | ||
// ConfigNode interface, as we can't cast an AbstractConfigNode to an interface | ||
abstract class AbstractConfigNodeValue extends AbstractConfigNode { | ||
|
||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it can go in a later PR but a natural method to add here would be one that takes a ConfigValue rather than a String (presumably it would just chain over to the string one by doing
value.render()
though)