escape_java_properties 0.0.3
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/.gitignore +5 -0
- data/.travis.yml +6 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +106 -0
- data/Rakefile +12 -0
- data/escape_java_properties.gemspec +27 -0
- data/lib/escape_java_properties.rb +46 -0
- data/lib/escape_java_properties/encoding.rb +56 -0
- data/lib/escape_java_properties/encoding/separators.rb +52 -0
- data/lib/escape_java_properties/encoding/special_chars.rb +49 -0
- data/lib/escape_java_properties/encoding/unicode.rb +61 -0
- data/lib/escape_java_properties/generating.rb +1 -0
- data/lib/escape_java_properties/generating/generator.rb +56 -0
- data/lib/escape_java_properties/parsing.rb +2 -0
- data/lib/escape_java_properties/parsing/normalizer.rb +77 -0
- data/lib/escape_java_properties/parsing/parser.rb +64 -0
- data/lib/escape_java_properties/properties.rb +64 -0
- data/lib/escape_java_properties/version.rb +3 -0
- data/spec/escape_java_properties/encoding/separators_spec.rb +19 -0
- data/spec/escape_java_properties/encoding/special_chars_spec.rb +23 -0
- data/spec/escape_java_properties/encoding/unicode_spec.rb +29 -0
- data/spec/escape_java_properties/encoding_spec.rb +72 -0
- data/spec/escape_java_properties/generating/generator_spec.rb +47 -0
- data/spec/escape_java_properties/parsing/normalizer_spec.rb +13 -0
- data/spec/escape_java_properties/parsing/parser_spec.rb +36 -0
- data/spec/escape_java_properties/version_spec.rb +7 -0
- data/spec/escape_java_properties_spec.rb +85 -0
- data/spec/fixtures/test.properties +41 -0
- data/spec/fixtures/test_normalized.properties +14 -0
- data/spec/fixtures/test_out.properties +11 -0
- data/spec/fixtures/test_out_skip_separators.properties +11 -0
- data/spec/fixtures/test_out_skip_special_chars.properties +14 -0
- data/spec/fixtures/test_out_skip_unicode.properties +11 -0
- data/spec/helper.rb +19 -0
- metadata +151 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: cd225b2c845a7d716dc847b8e5b722d12d969477b972bfe8317e768cf64995b0
|
4
|
+
data.tar.gz: 35c294ad227d74d390240d1b50457e4fb4098de2c8a3aade4c7e8b83006c6360
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e92043fffcae2711238c80894d982c37685a3adf9b6410a6c8cdacf7d4cc9c4db4b2883a3da01de8c741ac47819bca90c5dce766662cd626d2700a142a26b9f6
|
7
|
+
data.tar.gz: e88c210c224526b2fe86afabdcfef4f7a19ed61414b27ae8677a445bb6b21c36efae4a23f4384705f8645775d188e9098390a4bbb765c007a6b138bb20ff5564
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Copyright (c) 2014 Jonas Thiel (Applies to code available as https://github.com/jnbt/java-properties 1f2c4b008d69d0eae1084b1adfdea814e2b29899)
|
2
|
+
Copyright (c) 2014 tnarik (Modifications in https://github.com/trace-devops/escape_java_propertie)
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
a copy of this software and associated documentation files (the
|
6
|
+
"Software"), to deal in the Software without restriction, including
|
7
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
[properties_documentation]: http://docs.oracle.com/javase/6/docs/api/java/util/Properties.html#load(java.io.Reader)
|
2
|
+
|
3
|
+
# escape_java_properties
|
4
|
+
|
5
|
+
[](http://rubygems.org/gems/EscapeJavaProperties)
|
6
|
+
|
7
|
+
A ruby library to read and write [Java properties files](http://en.wikipedia.org/wiki/.properties), which format is better described [in the Java documentation][properties_documentation].
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Install via Rubygems or Gemfile
|
12
|
+
|
13
|
+
```zsh
|
14
|
+
$ gem install EscapeJavaProperties
|
15
|
+
```
|
16
|
+
|
17
|
+
## Loading files
|
18
|
+
|
19
|
+
You can load a valid Java properties file from the file system using a path:
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
properties = EscapeJavaProperties.load("path/to/my.properties")
|
23
|
+
properties[:foo] # => "bar"
|
24
|
+
properties['foo'] # => "bar"
|
25
|
+
```
|
26
|
+
|
27
|
+
If have already the content of the properties file at hand than parse the content as:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
properties = EscapeJavaProperties.load("foo=bar")
|
31
|
+
properties[:foo] # => "bar"
|
32
|
+
properties['foo'] # => "bar"
|
33
|
+
```
|
34
|
+
|
35
|
+
## Writing files
|
36
|
+
|
37
|
+
You can write any Hash-like structure (with symbol or string keys) as a properties file:
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
hash = {:foo => "bar", "foobar" => "barfoo"}
|
41
|
+
EscapeJavaProperties.write(hash, "path/to/my.properties")
|
42
|
+
```
|
43
|
+
|
44
|
+
Or if you want to omit the file you can receive the content directly:
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
hash = {:foo => "bar"}
|
48
|
+
EscapeJavaProperties.generate(hash) # => "foo=bar"
|
49
|
+
```
|
50
|
+
|
51
|
+
## Encodings and special chars
|
52
|
+
|
53
|
+
Although ISO 8859-1 is assumed for Java properties files, they normally use UTF-8 encoding. This tool tries to convert them:
|
54
|
+
|
55
|
+
```
|
56
|
+
"ה" <=> "\u05d4"
|
57
|
+
```
|
58
|
+
|
59
|
+
The tool also escaped every '=', ' ' and ':' in the name part of a property line:
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
EscapeJavaProperties.generate({"i : like=strange" => "bar"})
|
63
|
+
# => "i\ \:\ like\=strange=bar"
|
64
|
+
```
|
65
|
+
|
66
|
+
## Multi line and line breaks
|
67
|
+
|
68
|
+
In Java properties files there is distinction between natural lines and logical lines (than may span several lines by escaping the line terminator characters).
|
69
|
+
|
70
|
+
Assume the following input:
|
71
|
+
|
72
|
+
```ini
|
73
|
+
my=This is a multi \
|
74
|
+
line content with only \n one line break
|
75
|
+
```
|
76
|
+
|
77
|
+
The parses would read:
|
78
|
+
|
79
|
+
```ruby
|
80
|
+
{:my => "This is a multi line content which only \n one line break"}
|
81
|
+
```
|
82
|
+
|
83
|
+
In the opposite direction line breaks will be correctly escaped but the generator will never use multi line values.
|
84
|
+
|
85
|
+
## Contributing
|
86
|
+
|
87
|
+
1. [Fork it!](https://github.com/trace-devops/EscapeJavaProperties/fork)
|
88
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
89
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
90
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
91
|
+
5. Create new Pull Request
|
92
|
+
|
93
|
+
## Author
|
94
|
+
|
95
|
+
- Trace DevOps
|
96
|
+
- Stuart Stephen (@mrswadge) : forked at [38b7f7b66b7a8d02c95c320f5921321a5f528b30](https://github.com/mrswadge/proper_properties/commit/38b7f7b66b7a8d02c95c320f5921321a5f528b30)
|
97
|
+
- Tnarik Innael (@tnarik) : forked at [f08b23a1341569f576eb4cf859f59350f58bd1c3](https://github.com/tnarik/proper_properties/commit/f08b23a1341569f576eb4cf859f59350f58bd1c3)
|
98
|
+
- Jonas Thiel (@jonasthiel) : [original project](https://github.com/jnbt/java-properties) upto [1f2c4b008d69d0eae1084b1adfdea814e2b29899](https://github.com/tnarik/proper_properties/commit/1f2c4b008d69d0eae1084b1adfdea814e2b29899)
|
99
|
+
|
100
|
+
## References
|
101
|
+
|
102
|
+
For a proper description about the properties file format have a look at the [Java Plattform documentation][properties_documentation].
|
103
|
+
|
104
|
+
## License
|
105
|
+
|
106
|
+
This gem is released under the MIT License. See the LICENSE.txt file for further details.
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$:.unshift lib unless $:.include?(lib)
|
4
|
+
require 'escape_java_properties/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "escape_java_properties"
|
8
|
+
spec.version = EscapeJavaProperties::VERSION
|
9
|
+
spec.authors = ["trace-devops"]
|
10
|
+
spec.email = ["isysdevops@tracegroup.com"]
|
11
|
+
spec.summary = %q{Loader and writer for Java properties files}
|
12
|
+
spec.description = %q{Library for loading and writing of Java properties files that matches java.util.Properties behaviour}
|
13
|
+
spec.homepage = "https://github.com/trace-devops/escape_java_properties"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.required_ruby_version = '>= 1.9.3'
|
21
|
+
|
22
|
+
# development dependencies
|
23
|
+
spec.add_development_dependency 'rake'
|
24
|
+
spec.add_development_dependency 'coveralls'
|
25
|
+
spec.add_development_dependency 'simplecov'
|
26
|
+
spec.add_development_dependency 'minitest'
|
27
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'escape_java_properties/version'
|
2
|
+
require 'escape_java_properties/properties'
|
3
|
+
require 'escape_java_properties/encoding'
|
4
|
+
require 'escape_java_properties/parsing'
|
5
|
+
require 'escape_java_properties/generating'
|
6
|
+
|
7
|
+
# A module to read and write Escape java properties files
|
8
|
+
module EscapeJavaProperties
|
9
|
+
|
10
|
+
# Parses the content of a escape javaproperties file
|
11
|
+
# @see Parsing::Parser
|
12
|
+
# @param text [String]
|
13
|
+
# @return [Properties]
|
14
|
+
def self.parse(text)
|
15
|
+
Parsing::Parser.parse(text)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Generates the content of a escape java properties file
|
19
|
+
# @see Generating::Generator
|
20
|
+
# @param hash [Hash]
|
21
|
+
# @param options [Hash] options for the generator
|
22
|
+
# @return [String]
|
23
|
+
def self.generate(hash, options = {})
|
24
|
+
Generating::Generator.generate(hash, options)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Loads and parses a escape java properties file
|
28
|
+
# @see Parsing::Parser
|
29
|
+
# @param path [String]
|
30
|
+
# @param encoding [String]
|
31
|
+
# @param allow_invalid_byte_sequence [Boolean]
|
32
|
+
# @return [Properties]
|
33
|
+
def self.load(path, encoding = 'UTF-8', allow_invalid_byte_sequence = true)
|
34
|
+
parse(File.read(path).encode(encoding, 'binary', allow_invalid_byte_sequence ? {invalid: :replace, undef: :replace} : {} ))
|
35
|
+
end
|
36
|
+
|
37
|
+
# Generates a escape java properties file
|
38
|
+
# @see Generating::Generator
|
39
|
+
# @param hash [Hash]
|
40
|
+
# @param path [String]
|
41
|
+
# @param options [Hash] options for the generator
|
42
|
+
def self.write(hash, path, options = {})
|
43
|
+
File.write(path, generate(hash, options))
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'escape_java_properties/encoding/special_chars'
|
2
|
+
require 'escape_java_properties/encoding/separators'
|
3
|
+
require 'escape_java_properties/encoding/unicode'
|
4
|
+
|
5
|
+
module EscapeJavaProperties
|
6
|
+
# Module to encode and decode
|
7
|
+
#
|
8
|
+
# Usage:
|
9
|
+
# encoded = Encoding.encode!("Some text to be encoded")
|
10
|
+
# decoded = Encoding.decode!("Some text to be decoded")
|
11
|
+
#
|
12
|
+
# You can disable separate encoding (and decoding) steps,
|
13
|
+
# by passing in additional flags:
|
14
|
+
#
|
15
|
+
# * SKIP_SEPARATORS: Do not code the separators (space,:,=)
|
16
|
+
# * SKIP_UNICODE: Do not code unicode chars
|
17
|
+
# * SKIP_SPECIAL_CHARS: Do not code newlines, tab stops, ...
|
18
|
+
#
|
19
|
+
module Encoding
|
20
|
+
|
21
|
+
# Flag for skipping separators encodings / decoding
|
22
|
+
# @return [Symbol]
|
23
|
+
SKIP_SEPARATORS=:skip_separators
|
24
|
+
|
25
|
+
# Flag for skipping separators encodings / decoding
|
26
|
+
# @return [Symbol]
|
27
|
+
SKIP_UNICODE=:skip_unicode
|
28
|
+
|
29
|
+
# Flag for skipping separators encodings / decoding
|
30
|
+
# @return [Symbol]
|
31
|
+
SKIP_SPECIAL_CHARS=:skip_special_chars
|
32
|
+
|
33
|
+
# Encode a given text in place
|
34
|
+
# @param text [String]
|
35
|
+
# @param *flags [Array] Optional flags to skip encoding steps
|
36
|
+
# @return [String] The encoded text for chaining
|
37
|
+
def self.encode!(text, *flags)
|
38
|
+
SpecialChars.encode!(text) unless flags.include?(SKIP_SPECIAL_CHARS)
|
39
|
+
Separators.encode!(text) unless flags.include?(SKIP_SEPARATORS)
|
40
|
+
Unicode.encode!(text) unless flags.include?(SKIP_UNICODE)
|
41
|
+
text
|
42
|
+
end
|
43
|
+
|
44
|
+
# Decodes a given text in place
|
45
|
+
# @param text [String]
|
46
|
+
# @param *flags [Array] Optional flags to skip decoding steps
|
47
|
+
# @return [String] The decoded text for chaining
|
48
|
+
def self.decode!(text, *flags)
|
49
|
+
Unicode.decode!(text) unless flags.include?(SKIP_UNICODE)
|
50
|
+
Separators.decode!(text) unless flags.include?(SKIP_SEPARATORS)
|
51
|
+
SpecialChars.decode!(text) unless flags.include?(SKIP_SPECIAL_CHARS)
|
52
|
+
text
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module EscapeJavaProperties
|
2
|
+
module Encoding
|
3
|
+
# Module to escape separators as : or =
|
4
|
+
# @see EscapeJavaProperties::Encoding
|
5
|
+
module Separators
|
6
|
+
|
7
|
+
# Marker for all separators
|
8
|
+
# @return [Regexp]
|
9
|
+
ENCODE_SEPARATOR_MARKER = /[ :=]/
|
10
|
+
|
11
|
+
# Marker for already escaped separators
|
12
|
+
# @return [Regexp]
|
13
|
+
ESCAPING_MARKER = /\\/
|
14
|
+
|
15
|
+
# Char to use for escaping
|
16
|
+
# @return [String]
|
17
|
+
ESCAPE = "\\"
|
18
|
+
|
19
|
+
# Marker for all escaped separators
|
20
|
+
# @return [Regexp]
|
21
|
+
DECODE_SEPARATOR_MARKER = /\\([ :=])/
|
22
|
+
|
23
|
+
# Escapes all not already escaped separators
|
24
|
+
# @param text [text]
|
25
|
+
# @return [String] The escaped text for chaining
|
26
|
+
def self.encode!(text)
|
27
|
+
buffer = StringIO.new
|
28
|
+
last_token = ''
|
29
|
+
text.each_char do |char|
|
30
|
+
if char =~ ENCODE_SEPARATOR_MARKER && last_token !~ ESCAPING_MARKER
|
31
|
+
buffer << ESCAPE
|
32
|
+
end
|
33
|
+
buffer << char
|
34
|
+
last_token = char
|
35
|
+
end
|
36
|
+
text.replace buffer.string
|
37
|
+
text
|
38
|
+
end
|
39
|
+
|
40
|
+
# Removes escapes from escaped separators
|
41
|
+
# @param text [text]
|
42
|
+
# @return [String] The unescaped text for chaining
|
43
|
+
def self.decode!(text)
|
44
|
+
text.gsub!(DECODE_SEPARATOR_MARKER) do
|
45
|
+
$1
|
46
|
+
end
|
47
|
+
text
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module EscapeJavaProperties
|
2
|
+
module Encoding
|
3
|
+
# Module to escape and unescape special chars
|
4
|
+
# @see EscapeJavaProperties::Encoding
|
5
|
+
module SpecialChars
|
6
|
+
|
7
|
+
# Lookup table for escaping special chars
|
8
|
+
# @return [Hash]
|
9
|
+
ESCAPING = {
|
10
|
+
"\t" => '\\t',
|
11
|
+
"\r" => '\\r',
|
12
|
+
"\n" => '\\n',
|
13
|
+
"\f" => '\\f',
|
14
|
+
"\\" => '\\\\'
|
15
|
+
}.freeze
|
16
|
+
|
17
|
+
# Lookup table to remove escaping from special chars
|
18
|
+
# @return [Hash]
|
19
|
+
DESCAPING = ESCAPING.invert.freeze
|
20
|
+
|
21
|
+
# Marks a segment which has is an encoding special char
|
22
|
+
# @return [Regexp]
|
23
|
+
DESCAPING_MARKER = /\\./
|
24
|
+
|
25
|
+
# Encodes the content a text by escaping all special chars
|
26
|
+
# @param text [String]
|
27
|
+
# @return [String] The escaped text for chaining
|
28
|
+
def self.encode!(text)
|
29
|
+
buffer = StringIO.new
|
30
|
+
text.each_char do |char|
|
31
|
+
buffer << ESCAPING.fetch(char, char)
|
32
|
+
end
|
33
|
+
text.replace buffer.string
|
34
|
+
text
|
35
|
+
end
|
36
|
+
|
37
|
+
# Decodes the content a text by removing all escaping from special chars
|
38
|
+
# @param text [String]
|
39
|
+
# @return [String] The unescaped text for chaining
|
40
|
+
def self.decode!(text)
|
41
|
+
text.gsub!(DESCAPING_MARKER) do |match|
|
42
|
+
DESCAPING.fetch(match, match)
|
43
|
+
end
|
44
|
+
text
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module EscapeJavaProperties
|
2
|
+
module Encoding
|
3
|
+
# Module to encode and decode unicode chars
|
4
|
+
# @see EscapeJavaProperties::Encoding
|
5
|
+
module Unicode
|
6
|
+
|
7
|
+
# Marker for encoded unicode chars
|
8
|
+
# @return [Regexp]
|
9
|
+
UNICODE_MARKER = /\\[uU]([0-9a-fA-F]{4,5}|10[0-9a-fA-F]{4})/
|
10
|
+
|
11
|
+
# Escape char for unicode chars
|
12
|
+
# @return [String]
|
13
|
+
UNICODE_ESCAPE = "\\u"
|
14
|
+
|
15
|
+
# Decodes all unicode chars from escape sequences in place
|
16
|
+
# @param text [String]
|
17
|
+
# @return [String] The encoded text for chaining
|
18
|
+
def self.decode!(text)
|
19
|
+
text.gsub!(UNICODE_MARKER) do
|
20
|
+
unicode($1.hex)
|
21
|
+
end
|
22
|
+
text
|
23
|
+
end
|
24
|
+
|
25
|
+
# Decodes all unicode chars into escape sequences in place
|
26
|
+
# @param text [String]
|
27
|
+
# @return [String] The decoded text for chaining
|
28
|
+
def self.encode!(text)
|
29
|
+
buffer = StringIO.new
|
30
|
+
text.each_char do |char|
|
31
|
+
if char.ascii_only?
|
32
|
+
buffer << char
|
33
|
+
else
|
34
|
+
buffer << UNICODE_ESCAPE
|
35
|
+
buffer << hex(char.codepoints.first)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
text.replace buffer.string
|
39
|
+
text
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def self.unicode(code)
|
45
|
+
[code].pack("U")
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.hex(codepoint)
|
49
|
+
hex = codepoint.to_s(16)
|
50
|
+
size = hex.size
|
51
|
+
# padding the hex value for uneven digest
|
52
|
+
if (size % 2) == 1
|
53
|
+
"0#{hex}"
|
54
|
+
else
|
55
|
+
hex
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|