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.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +5 -0
  3. data/.travis.yml +6 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +106 -0
  7. data/Rakefile +12 -0
  8. data/escape_java_properties.gemspec +27 -0
  9. data/lib/escape_java_properties.rb +46 -0
  10. data/lib/escape_java_properties/encoding.rb +56 -0
  11. data/lib/escape_java_properties/encoding/separators.rb +52 -0
  12. data/lib/escape_java_properties/encoding/special_chars.rb +49 -0
  13. data/lib/escape_java_properties/encoding/unicode.rb +61 -0
  14. data/lib/escape_java_properties/generating.rb +1 -0
  15. data/lib/escape_java_properties/generating/generator.rb +56 -0
  16. data/lib/escape_java_properties/parsing.rb +2 -0
  17. data/lib/escape_java_properties/parsing/normalizer.rb +77 -0
  18. data/lib/escape_java_properties/parsing/parser.rb +64 -0
  19. data/lib/escape_java_properties/properties.rb +64 -0
  20. data/lib/escape_java_properties/version.rb +3 -0
  21. data/spec/escape_java_properties/encoding/separators_spec.rb +19 -0
  22. data/spec/escape_java_properties/encoding/special_chars_spec.rb +23 -0
  23. data/spec/escape_java_properties/encoding/unicode_spec.rb +29 -0
  24. data/spec/escape_java_properties/encoding_spec.rb +72 -0
  25. data/spec/escape_java_properties/generating/generator_spec.rb +47 -0
  26. data/spec/escape_java_properties/parsing/normalizer_spec.rb +13 -0
  27. data/spec/escape_java_properties/parsing/parser_spec.rb +36 -0
  28. data/spec/escape_java_properties/version_spec.rb +7 -0
  29. data/spec/escape_java_properties_spec.rb +85 -0
  30. data/spec/fixtures/test.properties +41 -0
  31. data/spec/fixtures/test_normalized.properties +14 -0
  32. data/spec/fixtures/test_out.properties +11 -0
  33. data/spec/fixtures/test_out_skip_separators.properties +11 -0
  34. data/spec/fixtures/test_out_skip_special_chars.properties +14 -0
  35. data/spec/fixtures/test_out_skip_unicode.properties +11 -0
  36. data/spec/helper.rb +19 -0
  37. 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
@@ -0,0 +1,5 @@
1
+ .ruby-version
2
+ .ruby-gemset
3
+ Gemfile.lock
4
+ coverage
5
+ pkg
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.0
6
+ - 2.1.1
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in escape_java_properties.gemspec
4
+ gemspec
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
+ [![RubyGems](http://img.shields.io/gem/v/EscapeJavaProperties.svg)](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,12 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ require 'rake/testtask'
4
+
5
+ desc 'Run tests'
6
+ task :default => :test
7
+
8
+ Rake::TestTask.new(:test) do |test|
9
+ test.test_files = FileList['spec/**/*_spec.rb']
10
+ test.libs << 'spec'
11
+ test.verbose = true
12
+ end
@@ -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