java-properties 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +20 -0
- data/README.md +88 -0
- data/Rakefile +12 -0
- data/java-properties.gemspec +23 -0
- data/lib/java-properties.rb +43 -0
- data/lib/java-properties/encoding.rb +44 -0
- data/lib/java-properties/encoding/separators.rb +51 -0
- data/lib/java-properties/encoding/special_chars.rb +47 -0
- data/lib/java-properties/encoding/unicode.rb +60 -0
- data/lib/java-properties/generating.rb +1 -0
- data/lib/java-properties/generating/generator.rb +34 -0
- data/lib/java-properties/parsing.rb +2 -0
- data/lib/java-properties/parsing/normalizer.rb +74 -0
- data/lib/java-properties/parsing/parser.rb +64 -0
- data/lib/java-properties/properties.rb +6 -0
- data/lib/java-properties/version.rb +7 -0
- data/spec/fixtures/test.properties +33 -0
- data/spec/fixtures/test_normalized.properties +11 -0
- data/spec/fixtures/test_out.properties +11 -0
- metadata +67 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 574e7ba19cb13bc15df2a6adbe13d7980568d441
|
4
|
+
data.tar.gz: 91a7367ff442648a2761b29c0d74ea7cc5457f0e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2f7def4045006710af040db297a36b065c24e82d727101cf2a48917362e7a5822757534d957c9a453821a3abd394187f8562c54e608897756b190e33f33a092d
|
7
|
+
data.tar.gz: 1d4808985ac4a0b5c3a5e631b484a1c5d03f9feeca981e01cc296d1c44fcbeed7e4f73dd0892909bbc3f4c65b44f3f7331fd77cdd82cd52b9ce181c2a62608a7
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2014 Jonas Thiel
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
# JavaProperties
|
2
|
+
|
3
|
+
[](https://travis-ci.org/jnbt/jnbt/java-properties)
|
4
|
+
[](https://codeclimate.com/github/jnbt/java-properties)
|
5
|
+
[](https://coveralls.io/r/jnbt/java-properties)
|
6
|
+
[](http://rubygems.org/gems/java-properties)
|
7
|
+
|
8
|
+
A ruby library to read and write [Java properties files](http://en.wikipedia.org/wiki/.properties).
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
Install via Rubygems
|
13
|
+
|
14
|
+
gem install java-properties
|
15
|
+
|
16
|
+
... or add to your Gemfile
|
17
|
+
|
18
|
+
gem "java-properties"
|
19
|
+
|
20
|
+
## Loading files
|
21
|
+
|
22
|
+
You can load a valid Java properties file from the file system using a path:
|
23
|
+
|
24
|
+
properties = JavaProperties.load("path/to/my.properties")
|
25
|
+
properties[:foo] # => "bar"
|
26
|
+
|
27
|
+
If have already the content of the properties file at hand than parse the content as:
|
28
|
+
|
29
|
+
properties = JavaProperties.load("foo=bar")
|
30
|
+
properties[:foo] # => "bar"
|
31
|
+
|
32
|
+
## Writing files
|
33
|
+
|
34
|
+
You can write any Hash-like structure as a properties file:
|
35
|
+
|
36
|
+
hash = {:foo => "bar"}
|
37
|
+
JavaProperties.write(hash, "path/to/my.properties")
|
38
|
+
|
39
|
+
Or if you want to omit the file you can receive the content directly:
|
40
|
+
|
41
|
+
hash = {:foo => "bar"}
|
42
|
+
JavaProperties.generate(hash) # => "foo=bar"
|
43
|
+
|
44
|
+
## Encodings and special chars
|
45
|
+
|
46
|
+
As Java properties files normally hold UTF-8 chars in their escaped representation this tool tries to convert them:
|
47
|
+
|
48
|
+
"ה" <=> "\u05d4"
|
49
|
+
|
50
|
+
The tool also escaped every '=', ' ' and ':' in the name part of a property line:
|
51
|
+
|
52
|
+
JavaProperties.generate({"i : like=strange" => "bar"})
|
53
|
+
# => "i\ \:\ like\=strange=bar"
|
54
|
+
|
55
|
+
## Multi line and line breaks
|
56
|
+
|
57
|
+
In Java properties files a string can be multi line but line breaks have to be escaped.
|
58
|
+
|
59
|
+
Assume the following input:
|
60
|
+
|
61
|
+
my=This is a multi \
|
62
|
+
line content with only \n one line break
|
63
|
+
|
64
|
+
The parses would read:
|
65
|
+
|
66
|
+
{:my => "This is a multi line content which only \n one line break"}
|
67
|
+
|
68
|
+
In the opposite direction line breaks will be correctly escaped but the generator will never use multi line values.
|
69
|
+
|
70
|
+
## Contributing
|
71
|
+
|
72
|
+
1. [Fork it!](https://github.com/jnbt/java-properties/fork)
|
73
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
74
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
75
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
76
|
+
5. Create new Pull Request
|
77
|
+
|
78
|
+
## Author
|
79
|
+
|
80
|
+
Jonas Thiel (@jonasthiel)
|
81
|
+
|
82
|
+
## References
|
83
|
+
|
84
|
+
For more information about the properties file format have a look at the [Java Plattform documenation](http://docs.oracle.com/javase/6/docs/api/java/util/Properties.html).
|
85
|
+
|
86
|
+
## License
|
87
|
+
|
88
|
+
This gem is released under the MIT License. See the LICENSE file for further details.
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# coding: utf-8
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'java-properties/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = "java-properties"
|
9
|
+
spec.version = JavaProperties::VERSION.dup
|
10
|
+
spec.authors = ["Jonas Thiel"]
|
11
|
+
spec.email = ["jonas@thiel.io"]
|
12
|
+
spec.summary = %q{Loader and writer for *.properties files}
|
13
|
+
spec.description = %q{Tool for loading and writing Java properties files}
|
14
|
+
spec.homepage = "https://github.com/jnbt/java-properties"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = %w(LICENSE README.md Rakefile java-properties.gemspec)
|
18
|
+
spec.files += Dir.glob("lib/**/*.rb")
|
19
|
+
spec.test_files = Dir.glob("spec/**/*.rb")
|
20
|
+
spec.test_files = Dir.glob("spec/fixtures/**/*.properties")
|
21
|
+
|
22
|
+
spec.required_rubygems_version = '>= 1.3.5'
|
23
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
require 'java-properties/version'
|
3
|
+
require 'java-properties/properties'
|
4
|
+
require 'java-properties/encoding'
|
5
|
+
require 'java-properties/parsing'
|
6
|
+
require 'java-properties/generating'
|
7
|
+
|
8
|
+
# A module to read and write Java properties files
|
9
|
+
module JavaProperties
|
10
|
+
|
11
|
+
# Parses the content of a Java properties file
|
12
|
+
# @see Parsing::Parser
|
13
|
+
# @param text [String]
|
14
|
+
# @return [Properties]
|
15
|
+
def self.parse(text)
|
16
|
+
Parsing::Parser.parse(text)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Generates the content of a Java properties file
|
20
|
+
# @see Generating::Generator
|
21
|
+
# @param hash [Hash]
|
22
|
+
# @return [String]
|
23
|
+
def self.generate(hash)
|
24
|
+
Generating::Generator.generate(hash)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Loads and parses a Java properties file
|
28
|
+
# @see Parsing::Parser
|
29
|
+
# @param path [String]
|
30
|
+
# @return [Properties]
|
31
|
+
def self.load(path)
|
32
|
+
parse(File.read(path))
|
33
|
+
end
|
34
|
+
|
35
|
+
# Generates a Java properties file
|
36
|
+
# @see Generating::Generator
|
37
|
+
# @param hash [Hash]
|
38
|
+
# @param path [String]
|
39
|
+
def self.write(hash, path)
|
40
|
+
File.write(path, generate(hash))
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'java-properties/encoding/special_chars'
|
2
|
+
require 'java-properties/encoding/separators'
|
3
|
+
require 'java-properties/encoding/unicode'
|
4
|
+
|
5
|
+
module JavaProperties
|
6
|
+
# Module to encode and decode
|
7
|
+
module Encoding
|
8
|
+
|
9
|
+
# Flag for skipping separators encodings / decoding
|
10
|
+
# @return [Symbol]
|
11
|
+
SKIP_SEPARATORS=:skip_separators
|
12
|
+
|
13
|
+
# Flag for skipping separators encodings / decoding
|
14
|
+
# @return [Symbol]
|
15
|
+
SKIP_UNICODE=:skip_unicode
|
16
|
+
|
17
|
+
# Flag for skipping separators encodings / decoding
|
18
|
+
# @return [Symbol]
|
19
|
+
SKIP_SPECIAL_CHARS=:skip_special_chars
|
20
|
+
|
21
|
+
# Encode a given text in place
|
22
|
+
# @param text [String]
|
23
|
+
# @param flags [Symbol] Optional flags to skip encoding steps
|
24
|
+
# @return [String]
|
25
|
+
def self.encode!(text, *flags)
|
26
|
+
SpecialChars.encode!(text) unless flags.include?(SKIP_SPECIAL_CHARS)
|
27
|
+
Separators.encode!(text) unless flags.include?(SKIP_SEPARATORS)
|
28
|
+
Unicode.encode!(text) unless flags.include?(SKIP_UNICODE)
|
29
|
+
text
|
30
|
+
end
|
31
|
+
|
32
|
+
# Decodes a given text in place
|
33
|
+
# @param text [String]
|
34
|
+
# @param flags [Symbol] Optional flags to skip decoding steps
|
35
|
+
# @return [String]
|
36
|
+
def self.decode!(text, *flags)
|
37
|
+
Unicode.decode!(text) unless flags.include?(SKIP_UNICODE)
|
38
|
+
Separators.decode!(text) unless flags.include?(SKIP_SEPARATORS)
|
39
|
+
SpecialChars.decode!(text) unless flags.include?(SKIP_SPECIAL_CHARS)
|
40
|
+
text
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module JavaProperties
|
2
|
+
module Encoding
|
3
|
+
# Module to escape separators as : or =
|
4
|
+
module Separators
|
5
|
+
|
6
|
+
# Marker for all separators
|
7
|
+
# @return [Regexp]
|
8
|
+
ENCODE_SEPARATOR_MARKER = /[ :=]/
|
9
|
+
|
10
|
+
# Marker for already escaped separators
|
11
|
+
# @return [Regexp]
|
12
|
+
ESCAPING_MARKER = /\\/
|
13
|
+
|
14
|
+
# Char to use for escaping
|
15
|
+
# @return [String]
|
16
|
+
ESCAPE = "\\"
|
17
|
+
|
18
|
+
# Marker for all escaped separators
|
19
|
+
# @return [Regexp]
|
20
|
+
DECODE_SEPARATOR_MARKER = /\\([ :=])/
|
21
|
+
|
22
|
+
# Escapes all not already escaped separators
|
23
|
+
# @param text [text]
|
24
|
+
# @return [String]
|
25
|
+
def self.encode!(text)
|
26
|
+
buffer = StringIO.new
|
27
|
+
last_token = ''
|
28
|
+
text.each_char do |char|
|
29
|
+
if char =~ ENCODE_SEPARATOR_MARKER && last_token !~ ESCAPING_MARKER
|
30
|
+
buffer << ESCAPE
|
31
|
+
end
|
32
|
+
buffer << char
|
33
|
+
last_token = char
|
34
|
+
end
|
35
|
+
text.replace buffer.string
|
36
|
+
text
|
37
|
+
end
|
38
|
+
|
39
|
+
# Removes escapes from escaped separators
|
40
|
+
# @param text [text]
|
41
|
+
# @return [String]
|
42
|
+
def self.decode!(text)
|
43
|
+
text.gsub!(DECODE_SEPARATOR_MARKER) do
|
44
|
+
$1
|
45
|
+
end
|
46
|
+
text
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module JavaProperties
|
2
|
+
module Encoding
|
3
|
+
# Module to escape and unescape special chars
|
4
|
+
module SpecialChars
|
5
|
+
|
6
|
+
# Lookup table for escaping special chars
|
7
|
+
# @return [Hash]
|
8
|
+
ESCAPING = {
|
9
|
+
"\t" => '\\t',
|
10
|
+
"\r" => '\\r',
|
11
|
+
"\n" => '\\n',
|
12
|
+
"\f" => '\\f'
|
13
|
+
}.freeze
|
14
|
+
|
15
|
+
# Lookup table to remove escaping from special chars
|
16
|
+
# @return [Hash]
|
17
|
+
DESCAPING = ESCAPING.invert.freeze
|
18
|
+
|
19
|
+
# Marks a segment which has is an encoding special char
|
20
|
+
# @return [Regexp]
|
21
|
+
DESCAPING_MARKER = /\\./
|
22
|
+
|
23
|
+
# Encodes the content a text by escaping all special chars
|
24
|
+
# @param text [String]
|
25
|
+
# @return [String]
|
26
|
+
def self.encode!(text)
|
27
|
+
buffer = StringIO.new
|
28
|
+
text.each_char do |char|
|
29
|
+
buffer << ESCAPING.fetch(char, char)
|
30
|
+
end
|
31
|
+
text.replace buffer.string
|
32
|
+
text
|
33
|
+
end
|
34
|
+
|
35
|
+
# Decodes the content a text by removing all escaping from special chars
|
36
|
+
# @param text [String]
|
37
|
+
# @return [String]
|
38
|
+
def self.decode!(text)
|
39
|
+
text.gsub!(DESCAPING_MARKER) do |match|
|
40
|
+
DESCAPING.fetch(match, match)
|
41
|
+
end
|
42
|
+
text
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module JavaProperties
|
2
|
+
module Encoding
|
3
|
+
# Module to encode and decode unicode chars
|
4
|
+
module Unicode
|
5
|
+
|
6
|
+
# Marker for encoded unicode chars
|
7
|
+
# @return [Regexp]
|
8
|
+
UNICODE_MARKER = /\\[uU]([0-9a-fA-F]{4,5}|10[0-9a-fA-F]{4})/
|
9
|
+
|
10
|
+
# Escape char for unicode chars
|
11
|
+
# @return [String]
|
12
|
+
UNICODE_ESCAPE = "\\u"
|
13
|
+
|
14
|
+
# Decodes all unicode chars from escape sequences in place
|
15
|
+
# @param text [String]
|
16
|
+
# @return [String]
|
17
|
+
def self.decode!(text)
|
18
|
+
text.gsub!(UNICODE_MARKER) do
|
19
|
+
unicode($1.hex)
|
20
|
+
end
|
21
|
+
text
|
22
|
+
end
|
23
|
+
|
24
|
+
# Decodes all unicode chars into escape sequences in place
|
25
|
+
# @param text [String]
|
26
|
+
# @return [String]
|
27
|
+
def self.encode!(text)
|
28
|
+
buffer = StringIO.new
|
29
|
+
text.each_char do |char|
|
30
|
+
if char.ascii_only?
|
31
|
+
buffer << char
|
32
|
+
else
|
33
|
+
buffer << UNICODE_ESCAPE
|
34
|
+
buffer << hex(char.codepoints.first)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
text.replace buffer.string
|
38
|
+
text
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def self.unicode(code)
|
44
|
+
[code].pack("U")
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.hex(codepoint)
|
48
|
+
hex = codepoint.to_s(16)
|
49
|
+
size = hex.size
|
50
|
+
# padding the hex value for uneven digest
|
51
|
+
if (size % 2) == 1
|
52
|
+
"0#{hex}"
|
53
|
+
else
|
54
|
+
hex
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'java-properties/generating/generator'
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module JavaProperties
|
2
|
+
module Generating
|
3
|
+
# This module allows generating the content of a properties file
|
4
|
+
# base on a {Properties} object (or any other hash like structure)
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# Generator.generate({:item => "something ה"}) => "item=something \u05d4"
|
8
|
+
#
|
9
|
+
module Generator
|
10
|
+
# Character used for key-value separation
|
11
|
+
# @return [String]
|
12
|
+
KEY_VALUE_SEPARATOR = '='
|
13
|
+
|
14
|
+
# Generates a properties file content based on a hash
|
15
|
+
# @param properties [Properties] or simple hash
|
16
|
+
# @return [String]
|
17
|
+
def self.generate(properties)
|
18
|
+
lines = []
|
19
|
+
properties.each do |key, value|
|
20
|
+
lines << build_line(key, value)
|
21
|
+
end
|
22
|
+
lines.join("\n")
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def self.build_line(key, value = '')
|
28
|
+
Encoding.encode!(key.to_s.dup) +
|
29
|
+
KEY_VALUE_SEPARATOR +
|
30
|
+
Encoding.encode!(value.to_s.dup, Encoding::SKIP_SEPARATORS)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module JavaProperties
|
2
|
+
module Parsing
|
3
|
+
# Module to normalize the content of a properties file
|
4
|
+
#
|
5
|
+
# @example Normalizes:
|
6
|
+
# # Comment 1
|
7
|
+
# ! Comment 2
|
8
|
+
# item0
|
9
|
+
# item1 = item1
|
10
|
+
# item2 : item2
|
11
|
+
# item3=line 1 \
|
12
|
+
# line 2
|
13
|
+
#
|
14
|
+
# @example Into:
|
15
|
+
#
|
16
|
+
# item0
|
17
|
+
# item1=item1
|
18
|
+
# item2=item2
|
19
|
+
# item3=line 1 line 2
|
20
|
+
#
|
21
|
+
module Normalizer
|
22
|
+
|
23
|
+
# Describes a single normalization rule by replacing content
|
24
|
+
class Rule
|
25
|
+
# Initializes a new rules base on a matching regexp
|
26
|
+
# and a replacement as substitution
|
27
|
+
# @param matcher [Regexp]
|
28
|
+
# @param replacement [String]
|
29
|
+
def initialize(matcher, replacement = '')
|
30
|
+
@matcher = matcher
|
31
|
+
@replacement = replacement
|
32
|
+
end
|
33
|
+
|
34
|
+
# Apply the substitution to the text in place
|
35
|
+
# @param text [string]
|
36
|
+
# @return [String]
|
37
|
+
def apply!(text)
|
38
|
+
text.gsub!(@matcher, @replacement)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Collection of ordered rules
|
43
|
+
RULES = []
|
44
|
+
|
45
|
+
# Removes comments
|
46
|
+
RULES << Rule.new(/^\s*[!\#].*$/)
|
47
|
+
|
48
|
+
# Removes leading whitepsace
|
49
|
+
RULES << Rule.new(/^\s+/)
|
50
|
+
|
51
|
+
# Removes tailing whitepsace
|
52
|
+
RULES << Rule.new(/\s+$/)
|
53
|
+
|
54
|
+
# Strings ending with \ are concatenated
|
55
|
+
RULES << Rule.new(/\\\s*$[\n\r]+/)
|
56
|
+
|
57
|
+
# Remove whitespace around delimiters and replace with =
|
58
|
+
RULES << Rule.new(/^((?:(?:\\[=: \t])|[^=: \t])+)[ \t]*[=: \t][ \t]*/, '\1=')
|
59
|
+
|
60
|
+
RULES.freeze
|
61
|
+
|
62
|
+
# Normalizes the content of a properties file content by applying the RULES
|
63
|
+
# @param text [String]
|
64
|
+
# @return [String]
|
65
|
+
def self.normalize!(text)
|
66
|
+
RULES.each do |rule|
|
67
|
+
rule.apply!(text)
|
68
|
+
end
|
69
|
+
text
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
module JavaProperties
|
3
|
+
module Parsing
|
4
|
+
# This module allows parsing of a properties file content string
|
5
|
+
# into a {Properties} object
|
6
|
+
#
|
7
|
+
# @example
|
8
|
+
# Parser.parse("item=something \u05d4") => {:item => "something ה"}
|
9
|
+
#
|
10
|
+
module Parser
|
11
|
+
|
12
|
+
# Symbol which separates key from value after normalization
|
13
|
+
# @return [String]
|
14
|
+
KEY_VALUE_MARKER = '='
|
15
|
+
|
16
|
+
# Symbol which escapes a KEY_VALUE_MARKER in the key name
|
17
|
+
# @return [String]
|
18
|
+
KEY_ESCAPE = '\\'
|
19
|
+
|
20
|
+
# Marker for a line which only consists of an key w/o value
|
21
|
+
# @return [Regexp]
|
22
|
+
KEY_ONLY_MARKER = /^(\S+)$/
|
23
|
+
|
24
|
+
# Parses a string into a {Properties} object
|
25
|
+
# @param text [String]
|
26
|
+
# @return [Properties]
|
27
|
+
def self.parse(text)
|
28
|
+
properties = Properties.new
|
29
|
+
Normalizer.normalize!(text)
|
30
|
+
text.each_line do |line|
|
31
|
+
key, value = extract_key_and_value(line.chomp)
|
32
|
+
append_to_properties(properties, key, value)
|
33
|
+
end
|
34
|
+
properties
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def self.extract_key_and_value(line)
|
40
|
+
# A line must be handled char by char to handled escaped '=' chars in the key name
|
41
|
+
key = StringIO.new
|
42
|
+
value = StringIO.new
|
43
|
+
key_complete = false
|
44
|
+
last_token = ''
|
45
|
+
line.each_char do |char|
|
46
|
+
if !key_complete && char == KEY_VALUE_MARKER && last_token != KEY_ESCAPE
|
47
|
+
key_complete = true
|
48
|
+
else
|
49
|
+
(key_complete ? value : key) << char
|
50
|
+
end
|
51
|
+
last_token = char
|
52
|
+
end
|
53
|
+
[key.string, value.string]
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.append_to_properties(properties, key, value)
|
57
|
+
unless key.nil? && value.nil?
|
58
|
+
properties[Encoding.decode!(key).to_sym] = Encoding.decode!(value, Encoding::SKIP_SEPARATORS)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# Comment 1
|
2
|
+
! Comment 2
|
3
|
+
item0
|
4
|
+
item1 = item1
|
5
|
+
item2 : item2
|
6
|
+
item3 item3
|
7
|
+
|
8
|
+
#Comment 3
|
9
|
+
! Comment 4
|
10
|
+
|
11
|
+
it\ em4=item4
|
12
|
+
it\=em5:item5
|
13
|
+
item6 item6
|
14
|
+
|
15
|
+
!Comment 4
|
16
|
+
# Comment 5
|
17
|
+
|
18
|
+
item7 = line 1 \
|
19
|
+
line 2 \
|
20
|
+
line 3
|
21
|
+
|
22
|
+
item8 : line 1 \
|
23
|
+
line 2 \
|
24
|
+
line 3
|
25
|
+
|
26
|
+
item9 line 1 \
|
27
|
+
line 2 \
|
28
|
+
line 3
|
29
|
+
|
30
|
+
item10=test\n\ttest\u0050 \
|
31
|
+
test\n\ttest \
|
32
|
+
test\n\ttest = test
|
33
|
+
|
metadata
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: java-properties
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jonas Thiel
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-02-13 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Tool for loading and writing Java properties files
|
14
|
+
email:
|
15
|
+
- jonas@thiel.io
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- LICENSE
|
21
|
+
- README.md
|
22
|
+
- Rakefile
|
23
|
+
- java-properties.gemspec
|
24
|
+
- lib/java-properties/encoding/separators.rb
|
25
|
+
- lib/java-properties/encoding/special_chars.rb
|
26
|
+
- lib/java-properties/encoding/unicode.rb
|
27
|
+
- lib/java-properties/encoding.rb
|
28
|
+
- lib/java-properties/generating/generator.rb
|
29
|
+
- lib/java-properties/generating.rb
|
30
|
+
- lib/java-properties/parsing/normalizer.rb
|
31
|
+
- lib/java-properties/parsing/parser.rb
|
32
|
+
- lib/java-properties/parsing.rb
|
33
|
+
- lib/java-properties/properties.rb
|
34
|
+
- lib/java-properties/version.rb
|
35
|
+
- lib/java-properties.rb
|
36
|
+
- spec/fixtures/test.properties
|
37
|
+
- spec/fixtures/test_normalized.properties
|
38
|
+
- spec/fixtures/test_out.properties
|
39
|
+
homepage: https://github.com/jnbt/java-properties
|
40
|
+
licenses:
|
41
|
+
- MIT
|
42
|
+
metadata: {}
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options: []
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - '>='
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - '>='
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 1.3.5
|
57
|
+
requirements: []
|
58
|
+
rubyforge_project:
|
59
|
+
rubygems_version: 2.1.11
|
60
|
+
signing_key:
|
61
|
+
specification_version: 4
|
62
|
+
summary: Loader and writer for *.properties files
|
63
|
+
test_files:
|
64
|
+
- spec/fixtures/test.properties
|
65
|
+
- spec/fixtures/test_normalized.properties
|
66
|
+
- spec/fixtures/test_out.properties
|
67
|
+
has_rdoc:
|