peterseverin-java_properties 0.0.5
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.
- data/History.txt +4 -0
- data/Manifest.txt +24 -0
- data/README.txt +36 -0
- data/Rakefile +4 -0
- data/bin/properties2yaml +71 -0
- data/java_properties.gemspec +23 -0
- data/lib/java_properties.rb +100 -0
- data/lib/java_properties/delimiters.rb +40 -0
- data/lib/java_properties/encoding.rb +38 -0
- data/lib/java_properties/parser.rb +52 -0
- data/lib/java_properties/properties-files.rb +70 -0
- data/lib/java_properties/specialchars.rb +56 -0
- data/lib/java_properties/utf8.rb +119 -0
- data/lib/java_properties/version.rb +9 -0
- data/test/test_data.rb +209 -0
- data/test/test_helper.rb +32 -0
- data/test/test_java_properties.rb +105 -0
- metadata +75 -0
data/History.txt
ADDED
data/Manifest.txt
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
History.txt
|
2
|
+
License.txt
|
3
|
+
Manifest.txt
|
4
|
+
README.txt
|
5
|
+
Rakefile
|
6
|
+
config/hoe.rb
|
7
|
+
config/requirements.rb
|
8
|
+
lib/java_properties.rb
|
9
|
+
lib/java_properties/version.rb
|
10
|
+
log/debug.log
|
11
|
+
script/destroy
|
12
|
+
script/generate
|
13
|
+
script/txt2html
|
14
|
+
setup.rb
|
15
|
+
tasks/deployment.rake
|
16
|
+
tasks/environment.rake
|
17
|
+
tasks/website.rake
|
18
|
+
test/test_helper.rb
|
19
|
+
test/test_java_properties.rb
|
20
|
+
website/index.html
|
21
|
+
website/index.txt
|
22
|
+
website/javascripts/rounded_corners_lite.inc.js
|
23
|
+
website/stylesheets/screen.css
|
24
|
+
website/template.rhtml
|
data/README.txt
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
= Java Properties Files in Ruby
|
2
|
+
|
3
|
+
I don't know if there's a real need for this, and if there is the jruby
|
4
|
+
people probably have it covered a lot better than I do. These classes
|
5
|
+
were mainly whipped up as an exercise in creating a ruby gem.
|
6
|
+
|
7
|
+
= JavaProperties::Properties
|
8
|
+
|
9
|
+
A class that can read and write to Java properties files that behaves
|
10
|
+
otherwise as a standard ruby Enumerable. The keys to this object can
|
11
|
+
be provided as Strings or Symbols, but internally they are Symbols.
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'java_properties'
|
15
|
+
|
16
|
+
# Create a new object from a file
|
17
|
+
props = JavaProperties::Properties.new("/path/to/file.properties")
|
18
|
+
|
19
|
+
# Merge in another file
|
20
|
+
props.load("/path/to/other/file.properties")
|
21
|
+
|
22
|
+
# Behaves as an Enumerable
|
23
|
+
props.each{ |key,value| puts "#{key} = #{value}" }
|
24
|
+
|
25
|
+
= properties2yaml
|
26
|
+
|
27
|
+
An executable script to convert an existing properties file to a YAML
|
28
|
+
file. There is no script to go the other way because not all YAML
|
29
|
+
files can be saved into a properties file. (That and I was feeling lazy.)
|
30
|
+
|
31
|
+
Usage: properties2yaml [options] [INPUT] [OUTPUT]
|
32
|
+
|
33
|
+
Options are:
|
34
|
+
|
35
|
+
-s, --stdin Read input from standard input instead of an input file
|
36
|
+
-h, --help Show this help message.
|
data/Rakefile
ADDED
data/bin/properties2yaml
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Created on 2008-6-12.
|
4
|
+
# Copyright (c) 2008. All rights reserved.
|
5
|
+
|
6
|
+
# NOTE: Adding gem lib dir to includes path
|
7
|
+
# This probably isn't the right way to do this, but until I know how
|
8
|
+
# this works.
|
9
|
+
$:.unshift "#{File.dirname(__FILE__)}/../lib/"
|
10
|
+
|
11
|
+
begin
|
12
|
+
require 'rubygems'
|
13
|
+
rescue LoadError
|
14
|
+
# no rubygems to load, so we fail silently
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'optparse'
|
18
|
+
require 'java_properties'
|
19
|
+
require 'yaml'
|
20
|
+
|
21
|
+
OPTIONS = {
|
22
|
+
:stdin => false
|
23
|
+
}
|
24
|
+
MANDATORY_OPTIONS = %w( )
|
25
|
+
|
26
|
+
parser = OptionParser.new do |opts|
|
27
|
+
opts.banner = <<BANNER
|
28
|
+
Converts a Java properties file to YAML.
|
29
|
+
|
30
|
+
Usage: #{File.basename($0)} [options] [INPUT] [OUTPUT]
|
31
|
+
|
32
|
+
Options are:
|
33
|
+
BANNER
|
34
|
+
opts.separator ""
|
35
|
+
opts.on("-s", "--stdin",
|
36
|
+
"Read input from standard input instead of an input file") { |OPTIONS[:path]| }
|
37
|
+
opts.on("-h", "--help",
|
38
|
+
"Show this help message.") { puts opts; exit }
|
39
|
+
opts.parse!(ARGV)
|
40
|
+
|
41
|
+
if MANDATORY_OPTIONS && MANDATORY_OPTIONS.find { |option| OPTIONS[option.to_sym].nil? }
|
42
|
+
puts opts; exit
|
43
|
+
end
|
44
|
+
if ARGV.empty? && !OPTIONS[:stdin]
|
45
|
+
puts opts; exit
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
infile = $stdin
|
50
|
+
outfile = $stdout
|
51
|
+
|
52
|
+
stdin = OPTIONS[:stdin] ? $stdin : false
|
53
|
+
|
54
|
+
begin
|
55
|
+
infilepath = ARGV.shift unless(ARGV.empty? || stdin)
|
56
|
+
infile = File.open(infilepath,'r') if infilepath
|
57
|
+
outfilepath = ARGV.shift unless(ARGV.empty?)
|
58
|
+
outfile = File.open(outfilepath,'w') if outfilepath
|
59
|
+
rescue
|
60
|
+
$stderr.puts "Error opening input properties file '#{infilepath}' for reading." unless infile.is_a? File
|
61
|
+
$stderr.puts "Error opening output YAML file '#{outfilepath}' for writing." if infile.is_a? File
|
62
|
+
exit 1
|
63
|
+
end
|
64
|
+
|
65
|
+
props = {}
|
66
|
+
JavaProperties::Parser.parse( infile.read ).each do |key,value|
|
67
|
+
# Convert all of the keys in the properties file to strings
|
68
|
+
# so that they don't output as symbols in the to_yaml results
|
69
|
+
props[key.to_s] = value
|
70
|
+
end
|
71
|
+
outfile.puts props.to_yaml
|
@@ -0,0 +1,23 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "java_properties"
|
3
|
+
s.version = "0.0.5"
|
4
|
+
s.date = "2009-08-04"
|
5
|
+
s.summary = "Simple gem for reading/writing Java properties files from Ruby."
|
6
|
+
s.email = "flergl@flergl.net"
|
7
|
+
s.homepage = "http://github.com/flergl/java-properties-for-ruby"
|
8
|
+
s.description = "A class that can read and write to Java properties files that behaves
|
9
|
+
otherwise as a standard ruby Enumerable. The keys to this object can
|
10
|
+
be provided as Strings or Symbols, but internally they are Symbols."
|
11
|
+
s.has_rdoc = true
|
12
|
+
s.authors = ["Dwayne Kristjanson"]
|
13
|
+
s.files = ["History.txt", "Manifest.txt", "README.txt", "Rakefile","java_properties.gemspec",
|
14
|
+
"lib/java_properties.rb","lib/java_properties/delimiters.rb",
|
15
|
+
"lib/java_properties/encoding.rb","lib/java_properties/parser.rb",
|
16
|
+
"lib/java_properties/properties-files.rb","lib/java_properties/specialchars.rb",
|
17
|
+
"lib/java_properties/utf8.rb","lib/java_properties/version.rb","bin/properties2yaml",
|
18
|
+
"test/test_data.rb","test/test_helper.rb","test/test_java_properties.rb"]
|
19
|
+
s.test_files = ["test/test_data.rb","test/test_helper.rb","test/test_java_properties.rb"]
|
20
|
+
s.rdoc_options = ["--main", "README.txt"]
|
21
|
+
s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.txt"]
|
22
|
+
s.executables = ["properties2yaml"]
|
23
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__)
|
2
|
+
|
3
|
+
require 'java_properties/encoding'
|
4
|
+
require 'java_properties/properties-files'
|
5
|
+
require 'java_properties/parser'
|
6
|
+
|
7
|
+
# The JavaProperties::Properties class provides a wrapper around
|
8
|
+
# a Hash of key/value pairs that provides the ability to load
|
9
|
+
# from and save to Java properties files.
|
10
|
+
|
11
|
+
module JavaProperties
|
12
|
+
|
13
|
+
# A class that can read and write to Java properties files that behaves
|
14
|
+
# otherwise as a standard ruby Enumerable. The keys to this object can
|
15
|
+
# be provided as Strings or Symbols, but internally they are Symbols.
|
16
|
+
#
|
17
|
+
# require 'rubygems'
|
18
|
+
# require 'java_properties'
|
19
|
+
#
|
20
|
+
# # Create a new object from a file
|
21
|
+
# props = JavaProperties::Properties.new("/path/to/file.properties")
|
22
|
+
#
|
23
|
+
# # Merge in another file
|
24
|
+
# props.load("/path/to/other/file.properties")
|
25
|
+
#
|
26
|
+
# # Behaves as an Enumerable
|
27
|
+
# props.each{ |key,value| puts "#{key} = #{value}" }
|
28
|
+
|
29
|
+
class Properties
|
30
|
+
|
31
|
+
include Enumerable
|
32
|
+
|
33
|
+
# Creates a new Properties object based on the contents
|
34
|
+
# of a Java properties file.
|
35
|
+
|
36
|
+
def self.load file
|
37
|
+
Properties.new file
|
38
|
+
end
|
39
|
+
|
40
|
+
# Merges the contents of a Java properties file with
|
41
|
+
# the properties already contained in this object.
|
42
|
+
|
43
|
+
def load file
|
44
|
+
@props.merge! Parser.parse( PropFile.read( file ) )
|
45
|
+
end
|
46
|
+
|
47
|
+
def initialize file
|
48
|
+
@props = {}
|
49
|
+
load(file)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Stores the current properties into a properties file.
|
53
|
+
# Optionally, a header comment can be provided.
|
54
|
+
|
55
|
+
def store file, header = nil
|
56
|
+
PropFile.write(file, self, header)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Appends the current properties to the end of another
|
60
|
+
# properties file. Optionally, a seperator comment
|
61
|
+
# can be provided.
|
62
|
+
|
63
|
+
def append file, seperator = nil
|
64
|
+
PropFile.append(file, self, seperator)
|
65
|
+
end
|
66
|
+
|
67
|
+
def[](key)
|
68
|
+
@props[key.to_sym]
|
69
|
+
end
|
70
|
+
|
71
|
+
def[]=(key,value)
|
72
|
+
@props[key.to_sym] = value
|
73
|
+
end
|
74
|
+
|
75
|
+
def each &block
|
76
|
+
@props.each &block
|
77
|
+
end
|
78
|
+
|
79
|
+
def keys
|
80
|
+
@props.keys
|
81
|
+
end
|
82
|
+
|
83
|
+
# Converts the properties contained in this object into a
|
84
|
+
# string that can be saved directly as a Java properties
|
85
|
+
# file.
|
86
|
+
|
87
|
+
def to_s
|
88
|
+
string = ""
|
89
|
+
# Sort to make testing easier -> output will consistent
|
90
|
+
@props.sort_by do |key,val|
|
91
|
+
key.to_s
|
92
|
+
end.each do |key,val|
|
93
|
+
string << Encoding.encode(key.to_s) << "=" << Encoding.encode(val) << "\n"
|
94
|
+
end
|
95
|
+
string
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module JavaProperties
|
2
|
+
|
3
|
+
module Encoding
|
4
|
+
|
5
|
+
# Modules for encoding and decoding delimiters characters
|
6
|
+
# for Java properties files when those delimiters are
|
7
|
+
# found in the property keys.
|
8
|
+
|
9
|
+
module Delimiters
|
10
|
+
|
11
|
+
# Encodes any delimiter characters found in the
|
12
|
+
# property keys by prepending a \
|
13
|
+
|
14
|
+
def self.encode string
|
15
|
+
s = ''
|
16
|
+
prev = ''
|
17
|
+
chars = string.split( // )
|
18
|
+
while(chars.size > 0) do
|
19
|
+
char = chars.shift
|
20
|
+
if char =~ /[ :=]/ && prev !~ /\\/ then
|
21
|
+
s << "\\" << char
|
22
|
+
else
|
23
|
+
s << char
|
24
|
+
end
|
25
|
+
prev = char
|
26
|
+
end
|
27
|
+
s
|
28
|
+
end
|
29
|
+
|
30
|
+
# No decoding is necessary, but this method has
|
31
|
+
# been provided for consistency with other
|
32
|
+
# encoding modules.
|
33
|
+
|
34
|
+
def self.decode string
|
35
|
+
string
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "java_properties/utf8"
|
2
|
+
require "java_properties/specialchars"
|
3
|
+
require "java_properties/delimiters"
|
4
|
+
|
5
|
+
module JavaProperties
|
6
|
+
|
7
|
+
# Classes for encoding and decoding strings for Java properties files.
|
8
|
+
|
9
|
+
module Encoding
|
10
|
+
|
11
|
+
# Encodes a string by escaping special characters (\n, \t, etc.),
|
12
|
+
# delimiters ( =, :) and UTF-8 characters.
|
13
|
+
|
14
|
+
def self.encode string
|
15
|
+
# Replace special chars with proper \n escaped characters
|
16
|
+
string = SpecialChars.encode(string)
|
17
|
+
|
18
|
+
# Replace unescaped delimiters with proper \n escaped characters
|
19
|
+
string = Delimiters.encode(string)
|
20
|
+
|
21
|
+
# Replace UTF-8 bytes with \uXXXX encoding
|
22
|
+
string = Utf8.encode(string)
|
23
|
+
|
24
|
+
string
|
25
|
+
end
|
26
|
+
|
27
|
+
# Decodes a string by unescaping UTF-8 and special characters
|
28
|
+
|
29
|
+
def self.decode string
|
30
|
+
# Replace \uXXXX escaped chars with proper UTF-8 bytes
|
31
|
+
string = Utf8.decode(string)
|
32
|
+
|
33
|
+
# Replace \n escaped chars with proper characters
|
34
|
+
string = SpecialChars.decode(string)
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require "java_properties/encoding"
|
2
|
+
|
3
|
+
module JavaProperties
|
4
|
+
|
5
|
+
# Module for parsing Java properties text into a Hash.
|
6
|
+
#
|
7
|
+
# props_hash = JavaProperties::Parser.parse( string_of_propfile_contents )
|
8
|
+
|
9
|
+
module Parser
|
10
|
+
|
11
|
+
# Parses a string containing the contents of a Java properties
|
12
|
+
# file into a hash of key/value pairs. The keys are converted
|
13
|
+
# into symbols.
|
14
|
+
|
15
|
+
def self.parse text
|
16
|
+
props = {}
|
17
|
+
text = self.normalize(text)
|
18
|
+
text.split(/[\n\r]+/).each do |line|
|
19
|
+
if line =~ /^([^=]*)=(.*)$/ then
|
20
|
+
key,value = $1,$2
|
21
|
+
elsif line =~ /\S/ then
|
22
|
+
key,value = line, ''
|
23
|
+
else
|
24
|
+
key,value = nil,nil
|
25
|
+
end
|
26
|
+
props[Encoding.decode(key).to_sym] = Encoding.decode(value) unless key.nil? && value.nil?
|
27
|
+
end
|
28
|
+
props
|
29
|
+
end
|
30
|
+
|
31
|
+
# Normalizes the contents of a Java properties file so
|
32
|
+
# that comments are removed, leading spaces are trimmed off,
|
33
|
+
# multiline entries are consolidated and all delimiters
|
34
|
+
# are consistent.
|
35
|
+
|
36
|
+
def self.normalize text
|
37
|
+
# Remove comment lines
|
38
|
+
text.gsub!( /^\s*[!\#].*$/, '' )
|
39
|
+
# Remove all leading spaces
|
40
|
+
text.gsub!( /^\s+/, '' )
|
41
|
+
# Remove all trailing spaces
|
42
|
+
text.gsub!( /\s+$/, '' )
|
43
|
+
# Concatenate strings ending with \
|
44
|
+
text.gsub!( /\\\s*$[\n\r]+/, '' )
|
45
|
+
# Remove spaces next to delimiters and replace all with =
|
46
|
+
text.gsub!( /^((?:(?:\\[=: \t])|[^=: \t])+)[ \t]*[=: \t][ \t]*/, '\1=' )
|
47
|
+
|
48
|
+
text
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'java_properties/encoding'
|
2
|
+
|
3
|
+
# Modules for reading and writing Java properties files.
|
4
|
+
|
5
|
+
module JavaProperties
|
6
|
+
|
7
|
+
# PropFile allows reading and writing properties files
|
8
|
+
#
|
9
|
+
# props = JavaProperties::PropFile.read( file )
|
10
|
+
#
|
11
|
+
# JavaProperties::PropFile.write( file, props, "Optional header comment" )
|
12
|
+
#
|
13
|
+
# JavaProperties::PropFile.append( file, props, "Optional seperator comment" )
|
14
|
+
#
|
15
|
+
|
16
|
+
module PropFile
|
17
|
+
|
18
|
+
# Reads in a Java properties file and returns the
|
19
|
+
# contents as a string for parsing.
|
20
|
+
|
21
|
+
def self.read file
|
22
|
+
file = open(file)
|
23
|
+
text = ''
|
24
|
+
while(line = file.gets) do
|
25
|
+
text += line
|
26
|
+
end
|
27
|
+
text
|
28
|
+
end
|
29
|
+
|
30
|
+
# Writes out a Hash of key/value pairs to a properities
|
31
|
+
# file. Optionally a header comment can be provided.
|
32
|
+
|
33
|
+
def self.write file, props, header = nil
|
34
|
+
unless header.nil? then
|
35
|
+
File.open(file,'w') { |f| f.write "# " + header +"\n" }
|
36
|
+
File.open(file,'a') { |f| f.write self.stringify(props) }
|
37
|
+
else
|
38
|
+
File.open(file,'w') { |f| f.write self.stringify(props) }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Appends a Hash of key/value paris to the end of an existing
|
43
|
+
# properties file. Optionally a seperator comment can be
|
44
|
+
# provided.
|
45
|
+
|
46
|
+
def self.append file, props, seperator = nil
|
47
|
+
unless seperator.nil? then
|
48
|
+
File.open(file,'a') { |f| f.write "\n# " + seperator }
|
49
|
+
end
|
50
|
+
File.open(file,'a') { |f| f.write "\n" + self.stringify(props) }
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
# Converts a Hash of key/value pairs into a String that can
|
56
|
+
# be directly saved into a Java properties file.
|
57
|
+
|
58
|
+
def self.stringify props
|
59
|
+
string = ""
|
60
|
+
# Sort to make testing easier -> output will consistent
|
61
|
+
props.sort_by do |key,val|
|
62
|
+
key.to_s
|
63
|
+
end.each do |key,val|
|
64
|
+
string << Encoding.encode(key.to_s) << "=" << Encoding.encode(val) << "\n"
|
65
|
+
end
|
66
|
+
string
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module JavaProperties
|
2
|
+
|
3
|
+
module Encoding
|
4
|
+
|
5
|
+
# Modules for encoding and decoding special characters for
|
6
|
+
# Java properties files.
|
7
|
+
|
8
|
+
module SpecialChars
|
9
|
+
|
10
|
+
# Encodes all special characters by replacing them with
|
11
|
+
# the proper \X escaped value.
|
12
|
+
|
13
|
+
def self.encode string
|
14
|
+
# Replace special chars with proper \n escaped characters
|
15
|
+
string.gsub!( /([\t\n\r\f])/ ) do |c|
|
16
|
+
char = $1
|
17
|
+
case char
|
18
|
+
when "\t"
|
19
|
+
'\\t'
|
20
|
+
when "\n"
|
21
|
+
'\\n'
|
22
|
+
when "\r"
|
23
|
+
'\\r'
|
24
|
+
when "\f"
|
25
|
+
'\\f'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
string
|
29
|
+
end
|
30
|
+
|
31
|
+
# Decodes any \X characters read in from a properties file.
|
32
|
+
|
33
|
+
def self.decode string
|
34
|
+
# Replace \n escaped chars with proper characters
|
35
|
+
string.gsub!( /\\(.)/ ) do |c|
|
36
|
+
char = $1 if c =~ /\\(.)/
|
37
|
+
case char
|
38
|
+
when 't'
|
39
|
+
"\t"
|
40
|
+
when 'n'
|
41
|
+
"\n"
|
42
|
+
when 'r'
|
43
|
+
"\r"
|
44
|
+
when 'f'
|
45
|
+
"\f"
|
46
|
+
else
|
47
|
+
char
|
48
|
+
end
|
49
|
+
end
|
50
|
+
string
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
module JavaProperties
|
2
|
+
|
3
|
+
module Encoding
|
4
|
+
|
5
|
+
# Modules for encoding and decoding UTF-8 characters into ASCII
|
6
|
+
# for Java properties files.
|
7
|
+
#
|
8
|
+
# # Decode a string with UTF-8 encoded as \uXXXX (e.g. \u0050 = 'P')
|
9
|
+
# decoded_string = JavaProperties::Encoding::Utf8.decode( encoded_string )
|
10
|
+
#
|
11
|
+
# # Encode a string so that unicode characters are escaped as \uXXXX
|
12
|
+
# encoded_string = JavaProperties::Encoding::Utf8.encode( decoded_string )
|
13
|
+
#
|
14
|
+
# # Get the bytes that represent a given UTF-9 code point
|
15
|
+
# utf8_char_as_string = JavaProperties::Encoding::Utf8.utf8( code_point )
|
16
|
+
|
17
|
+
module Utf8
|
18
|
+
|
19
|
+
# Replaces \uXXXX escaped chars with proper UTF-8 bytes
|
20
|
+
|
21
|
+
def self.decode(string)
|
22
|
+
string.gsub!( /\\[uU]([0-9a-fA-f]{1,6})/) do |c|
|
23
|
+
Encoding::Utf8.utf8($1.hex)
|
24
|
+
end
|
25
|
+
string
|
26
|
+
end
|
27
|
+
|
28
|
+
# Gets the UTF-8 encoding of a given unicode code point (provided as an Fixnum)
|
29
|
+
|
30
|
+
def self.utf8(ud)
|
31
|
+
s = ""
|
32
|
+
if ud < 128 then
|
33
|
+
# UTF-8 is 1 byte long, the value of ud.
|
34
|
+
s << ud
|
35
|
+
elsif ud >= 128 && ud <= 2047 then
|
36
|
+
# UTF-8 is 2 bytes long.
|
37
|
+
s << (192 + (ud.div 64))
|
38
|
+
s << (128 + (ud % 64))
|
39
|
+
elsif ud >= 2048 && ud <= 65535 then
|
40
|
+
# UTF-8 is 3 bytes long.
|
41
|
+
s << (224 + (ud.div 4096))
|
42
|
+
s << (128 + ((ud.div 64) % 64))
|
43
|
+
s << (128 + (ud % 64))
|
44
|
+
elsif ud >= 65536 && ud <=2097151 then
|
45
|
+
# UTF-8 is 4 bytes long.
|
46
|
+
s << (240 + (ud.div 262144))
|
47
|
+
s << (128 + ((ud.div 4096) % 64))
|
48
|
+
s << (128 + ((ud.div 64) % 64))
|
49
|
+
s << (128 + (ud % 64))
|
50
|
+
elsif ud >= 2097152 && ud <= 7108863 then
|
51
|
+
# UTF-8 is 5 bytes long.
|
52
|
+
s << (248 + (ud.div 16777216))
|
53
|
+
s << (128 + ((ud.div 262144) % 64))
|
54
|
+
s << (128 + ((ud.div 4096) % 64))
|
55
|
+
s << (128 + ((ud.div 64) % 64))
|
56
|
+
s << (128 + (ud % 64))
|
57
|
+
elsif ud >= 67108864 && ud <= 2147483647
|
58
|
+
# then UTF-8 is 6 bytes long.
|
59
|
+
s << (252 + (ud.div 1073741824))
|
60
|
+
s << (128 + ((ud.div 16777216) % 64))
|
61
|
+
s << (128 + ((ud.div 262144) % 64))
|
62
|
+
s << (128 + ((ud.div 4096) % 64))
|
63
|
+
s << (128 + ((ud.div 64) % 64))
|
64
|
+
s << (128 + (ud % 64))
|
65
|
+
end
|
66
|
+
s
|
67
|
+
end
|
68
|
+
|
69
|
+
# Encodes all UTF-8 characters in the provided string using \uXXXX
|
70
|
+
# format.
|
71
|
+
|
72
|
+
def self.encode(string)
|
73
|
+
s = ""
|
74
|
+
chars = string.split( // )
|
75
|
+
while(chars.size > 0) do
|
76
|
+
z = chars.shift[0].to_i
|
77
|
+
if z >= 0 && z <= 127 then
|
78
|
+
# 1 byte -- essentially ascii
|
79
|
+
s << z
|
80
|
+
elsif z >= 192 && z <= 223 then
|
81
|
+
# 2 bytes
|
82
|
+
y = chars.shift[0].to_i
|
83
|
+
s << "\\u#{sprintf('%04x',( (z-192)*64 + (y-128) ))}"
|
84
|
+
elsif z >= 224 && z <= 239 then
|
85
|
+
# 3 bytes
|
86
|
+
y = chars.shift[0].to_i
|
87
|
+
x = chars.shift[0].to_i
|
88
|
+
s << "\\u#{sprintf('%04x',( (z-224)*4096 + (y-128)*64 + (x-128) ))}"
|
89
|
+
elsif z >= 240 && z <= 247 then
|
90
|
+
# 4 bytes
|
91
|
+
y = chars.shift[0].to_i
|
92
|
+
x = chars.shift[0].to_i
|
93
|
+
w = chars.shift[0].to_i
|
94
|
+
s << "\\u#{sprintf('%06x',( (z-240)*262144 + (y-128)*4096 + (x-128)*64 + (w-128) ))}"
|
95
|
+
elsif z >= 248 && z <= 251 then
|
96
|
+
# 5 bytes
|
97
|
+
y = chars.shift[0].to_i
|
98
|
+
x = chars.shift[0].to_i
|
99
|
+
w = chars.shift[0].to_i
|
100
|
+
v = chars.shift[0].to_i
|
101
|
+
s << "\\u#{sprintf('%08x',( (z-248)*16777216 + (y-128)*262144 + (x-128)*4096 + (w-128)*64 + (v-128) ))}"
|
102
|
+
elsif z >= 252 && z <= 253 then
|
103
|
+
# 6 bytes
|
104
|
+
y = chars.shift[0].to_i
|
105
|
+
x = chars.shift[0].to_i
|
106
|
+
w = chars.shift[0].to_i
|
107
|
+
v = chars.shift[0].to_i
|
108
|
+
u = chars.shift[0].to_i
|
109
|
+
s << "\\u#{sprintf('%010x',( (z-252)*1073741824 + (y-128)*16777216 + (x-128)*262144 + (w-128)*4096 + (v-128)*64 + (u-128) ))}"
|
110
|
+
else
|
111
|
+
s << z
|
112
|
+
end
|
113
|
+
end
|
114
|
+
s
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
end
|
data/test/test_data.rb
ADDED
@@ -0,0 +1,209 @@
|
|
1
|
+
class TestJavaPropertiesData
|
2
|
+
|
3
|
+
def self.file1
|
4
|
+
File.dirname(__FILE__) + '/test_files/test1.properties'
|
5
|
+
end
|
6
|
+
def self.file2
|
7
|
+
File.dirname(__FILE__) + '/test_files/test2.properties'
|
8
|
+
end
|
9
|
+
def self.file3
|
10
|
+
File.dirname(__FILE__) + '/test_files/test3.properties'
|
11
|
+
end
|
12
|
+
def self.file4
|
13
|
+
File.dirname(__FILE__) + '/test_files/test4.properties'
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.properties_contents1
|
17
|
+
<<-EOF;
|
18
|
+
# Comment 1
|
19
|
+
! Comment 2
|
20
|
+
item0
|
21
|
+
item1 = item1
|
22
|
+
item2 : item2
|
23
|
+
item3 item3
|
24
|
+
|
25
|
+
#Comment 3
|
26
|
+
! Comment 4
|
27
|
+
|
28
|
+
item4=item4
|
29
|
+
item5:item5
|
30
|
+
item6 item6
|
31
|
+
|
32
|
+
!Comment 4
|
33
|
+
# Comment 5
|
34
|
+
|
35
|
+
item7 = line 1 \\
|
36
|
+
line 2 \\
|
37
|
+
line 3
|
38
|
+
|
39
|
+
item8 : line 1 \\
|
40
|
+
line 2 \\
|
41
|
+
line 3
|
42
|
+
|
43
|
+
item9 line 1 \\
|
44
|
+
line 2 \\
|
45
|
+
line 3
|
46
|
+
|
47
|
+
item10 test\\n\\ttest\\u0050 \\
|
48
|
+
test\\n\\ttest \\
|
49
|
+
test\\n\\ttest \\= test
|
50
|
+
|
51
|
+
EOF
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.properties_contents2
|
55
|
+
<<-EOF;
|
56
|
+
# Comment 1
|
57
|
+
! Comment 2
|
58
|
+
|
59
|
+
item1 = item1 again
|
60
|
+
item11 : item11
|
61
|
+
item12 : contains \\uAC00 unicode
|
62
|
+
item100=
|
63
|
+
spaces\\ x : spaces x
|
64
|
+
|
65
|
+
EOF
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.properties_contents3
|
69
|
+
<<-EOF;
|
70
|
+
# with header
|
71
|
+
item100=
|
72
|
+
item2=item2
|
73
|
+
item8=line\\ 1\\ line\\ 2\\ line\\ 3
|
74
|
+
item3=item3
|
75
|
+
item9=line\\ 1\\ line\\ 2\\ line\\ 3
|
76
|
+
item4=item4
|
77
|
+
item1=item1\\ again
|
78
|
+
item10=test\\n\\ttestP\\ test\\n\\ttest\\ test\\n\\ttest\\ \\=\\ test
|
79
|
+
item5=item5
|
80
|
+
item11=item11
|
81
|
+
item6=item6
|
82
|
+
item12=contains \\uac00 unicode
|
83
|
+
spaces\\ x=spaces\\ x
|
84
|
+
item0=
|
85
|
+
item7=line\\ 1\\ line\\ 2\\ line\\ 3
|
86
|
+
EOF
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.properties_contents4
|
90
|
+
<<-EOF;
|
91
|
+
# This is a test
|
92
|
+
#
|
93
|
+
# with a comment
|
94
|
+
item100=
|
95
|
+
item2=item2
|
96
|
+
item8=line\\ 1\\ line\\ 2\\ line\\ 3
|
97
|
+
item3=item3
|
98
|
+
item9=line\\ 1\\ line\\ 2\\ line\\ 3
|
99
|
+
item4=item4
|
100
|
+
item1=item1\\ again
|
101
|
+
item10=test\\n\\ttestP\\ test\\n\\ttest\\ test\\n\\ttest\\ \\=\\ test
|
102
|
+
item5=item5
|
103
|
+
item11=item11
|
104
|
+
item6=item6
|
105
|
+
item12=contains \\uac00 unicode
|
106
|
+
spaces\\ x=spaces\\ x
|
107
|
+
item0=
|
108
|
+
item7=line\\ 1\\ line\\ 2\\ line\\ 3
|
109
|
+
EOF
|
110
|
+
end
|
111
|
+
|
112
|
+
def self.content1
|
113
|
+
<<-EOF;
|
114
|
+
item0=
|
115
|
+
item1=item1
|
116
|
+
item10=test\\n\\ttestP\\ test\\n\\ttest\\ test\\n\\ttest\\ \\=\\ test
|
117
|
+
item2=item2
|
118
|
+
item3=item3
|
119
|
+
item4=item4
|
120
|
+
item5=item5
|
121
|
+
item6=item6
|
122
|
+
item7=line\\ 1\\ line\\ 2\\ line\\ 3
|
123
|
+
item8=line\\ 1\\ line\\ 2\\ line\\ 3
|
124
|
+
item9=line\\ 1\\ line\\ 2\\ line\\ 3
|
125
|
+
EOF
|
126
|
+
end
|
127
|
+
|
128
|
+
def self.content2
|
129
|
+
<<-EOF;
|
130
|
+
item0=
|
131
|
+
item1=item1\\ again
|
132
|
+
item10=test\\n\\ttestP\\ test\\n\\ttest\\ test\\n\\ttest\\ \\=\\ test
|
133
|
+
item100=
|
134
|
+
item11=item11
|
135
|
+
item12=contains\\ \\uac00\\ unicode
|
136
|
+
item2=item2
|
137
|
+
item3=item3
|
138
|
+
item4=item4
|
139
|
+
item5=item5
|
140
|
+
item6=item6
|
141
|
+
item7=line\\ 1\\ line\\ 2\\ line\\ 3
|
142
|
+
item8=line\\ 1\\ line\\ 2\\ line\\ 3
|
143
|
+
item9=line\\ 1\\ line\\ 2\\ line\\ 3
|
144
|
+
spaces\\ x=spaces\\ x
|
145
|
+
EOF
|
146
|
+
end
|
147
|
+
|
148
|
+
def self.content3
|
149
|
+
<<-EOF;
|
150
|
+
# with header
|
151
|
+
item0=
|
152
|
+
item1=item1\\ again
|
153
|
+
item10=test\\n\\ttestP\\ test\\n\\ttest\\ test\\n\\ttest\\ \\=\\ test
|
154
|
+
item100=
|
155
|
+
item11=item11
|
156
|
+
item12=contains\\ \\uac00\\ unicode
|
157
|
+
item2=item2
|
158
|
+
item3=item3
|
159
|
+
item4=item4
|
160
|
+
item5=item5
|
161
|
+
item6=item6
|
162
|
+
item7=line\\ 1\\ line\\ 2\\ line\\ 3
|
163
|
+
item8=line\\ 1\\ line\\ 2\\ line\\ 3
|
164
|
+
item9=line\\ 1\\ line\\ 2\\ line\\ 3
|
165
|
+
spaces\\ x=spaces\\ x
|
166
|
+
EOF
|
167
|
+
end
|
168
|
+
|
169
|
+
def self.content4
|
170
|
+
<<-EOF;
|
171
|
+
# This is a test
|
172
|
+
#
|
173
|
+
# with a comment
|
174
|
+
item100=
|
175
|
+
item2=item2
|
176
|
+
item8=line\\ 1\\ line\\ 2\\ line\\ 3
|
177
|
+
item3=item3
|
178
|
+
item9=line\\ 1\\ line\\ 2\\ line\\ 3
|
179
|
+
item4=item4
|
180
|
+
item1=item1\\ again
|
181
|
+
item10=test\\n\\ttestP\\ test\\n\\ttest\\ test\\n\\ttest\\ \\=\\ test
|
182
|
+
item5=item5
|
183
|
+
item11=item11
|
184
|
+
item6=item6
|
185
|
+
item12=contains \\uac00 unicode
|
186
|
+
spaces\\ x=spaces\\ x
|
187
|
+
item0=
|
188
|
+
item7=line\\ 1\\ line\\ 2\\ line\\ 3
|
189
|
+
|
190
|
+
# with spacer
|
191
|
+
item0=
|
192
|
+
item1=item1\\ again
|
193
|
+
item10=test\\n\\ttestP\\ test\\n\\ttest\\ test\\n\\ttest\\ \\=\\ test
|
194
|
+
item100=
|
195
|
+
item11=item11
|
196
|
+
item12=contains\\ \\uac00\\ unicode
|
197
|
+
item2=item2
|
198
|
+
item3=item3
|
199
|
+
item4=item4
|
200
|
+
item5=item5
|
201
|
+
item6=item6
|
202
|
+
item7=line\\ 1\\ line\\ 2\\ line\\ 3
|
203
|
+
item8=line\\ 1\\ line\\ 2\\ line\\ 3
|
204
|
+
item9=line\\ 1\\ line\\ 2\\ line\\ 3
|
205
|
+
spaces\\ x=spaces\\ x
|
206
|
+
EOF
|
207
|
+
end
|
208
|
+
|
209
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.dirname(__FILE__) + '/../lib/java_properties'
|
3
|
+
require File.dirname(__FILE__) + '/test_data.rb'
|
4
|
+
|
5
|
+
def create_test_files
|
6
|
+
remove_test_files
|
7
|
+
File.open(TestJavaPropertiesData.file1,'w') { |f| f.write TestJavaPropertiesData.properties_contents1 }
|
8
|
+
File.open(TestJavaPropertiesData.file2,'w') { |f| f.write TestJavaPropertiesData.properties_contents2 }
|
9
|
+
#File.open(TestJavaPropertiesData.file3,'w') { |f| f.write TestJavaPropertiesData.properties_contents3 }
|
10
|
+
File.open(TestJavaPropertiesData.file4,'w') { |f| f.write TestJavaPropertiesData.properties_contents4 }
|
11
|
+
end
|
12
|
+
|
13
|
+
def remove_test_files
|
14
|
+
File.delete(TestJavaPropertiesData.file1) if File.exist?(TestJavaPropertiesData.file1)
|
15
|
+
File.delete(TestJavaPropertiesData.file2) if File.exist?(TestJavaPropertiesData.file2)
|
16
|
+
File.delete(TestJavaPropertiesData.file3) if File.exist?(TestJavaPropertiesData.file3)
|
17
|
+
File.delete(TestJavaPropertiesData.file4) if File.exist?(TestJavaPropertiesData.file4)
|
18
|
+
end
|
19
|
+
|
20
|
+
def get_file_as_string file_name
|
21
|
+
if File.exist?(file_name) then
|
22
|
+
file_contents = ''
|
23
|
+
File.open(file_name,'r') do |f|
|
24
|
+
while(line = f.gets) do
|
25
|
+
file_contents += line
|
26
|
+
end
|
27
|
+
end
|
28
|
+
file_contents
|
29
|
+
else
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
|
3
|
+
class TestJavaProperties < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
create_test_files
|
7
|
+
end
|
8
|
+
|
9
|
+
def teardown
|
10
|
+
remove_test_files
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_truth
|
14
|
+
assert true
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_can_load_from_file
|
18
|
+
props = JavaProperties::Properties.load(TestJavaPropertiesData.file1)
|
19
|
+
assert_equal TestJavaPropertiesData.content1, props.to_s
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_can_merge_properties_from_two_files
|
23
|
+
props = JavaProperties::Properties.load(TestJavaPropertiesData.file1)
|
24
|
+
props.load(TestJavaPropertiesData.file2)
|
25
|
+
assert_equal TestJavaPropertiesData.content2, props.to_s
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_can_access_property_by_symbol
|
29
|
+
props = JavaProperties::Properties.load(TestJavaPropertiesData.file1)
|
30
|
+
assert_equal 'item1', props[:item1]
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_can_access_property_by_string
|
34
|
+
props = JavaProperties::Properties.load(TestJavaPropertiesData.file1)
|
35
|
+
assert_equal 'item1', props['item1']
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_can_access_property_key_with_whitespace
|
39
|
+
props = JavaProperties::Properties.load(TestJavaPropertiesData.file2)
|
40
|
+
assert_equal 'spaces x', props['spaces x']
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_can_store_properties_in_file
|
44
|
+
props = JavaProperties::Properties.load(TestJavaPropertiesData.file1)
|
45
|
+
props.load(TestJavaPropertiesData.file2)
|
46
|
+
props.store(TestJavaPropertiesData.file3, 'with header')
|
47
|
+
assert( File.exist?(TestJavaPropertiesData.file3) )
|
48
|
+
assert_equal TestJavaPropertiesData.content3, get_file_as_string(TestJavaPropertiesData.file3)
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_append_properties_to_file
|
52
|
+
props = JavaProperties::Properties.load(TestJavaPropertiesData.file1)
|
53
|
+
props.load(TestJavaPropertiesData.file2)
|
54
|
+
props.append(TestJavaPropertiesData.file4,'with spacer')
|
55
|
+
assert( File.exist?(TestJavaPropertiesData.file4) )
|
56
|
+
assert_equal TestJavaPropertiesData.content4, get_file_as_string(TestJavaPropertiesData.file4)
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_ignores_hash_comments
|
60
|
+
props = JavaProperties::Properties.load(TestJavaPropertiesData.file2)
|
61
|
+
assert_no_match( /Comment 1/, props.to_s)
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_ignores_bang_comments
|
65
|
+
props = JavaProperties::Properties.load(TestJavaPropertiesData.file2)
|
66
|
+
assert_no_match( /Comment 2/, props.to_s)
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_sets_key_and_value_seperated_by_equal
|
70
|
+
props = JavaProperties::Properties.load(TestJavaPropertiesData.file1)
|
71
|
+
assert_equal 'item1', props[:item1]
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_sets_key_and_value_seperated_by_colon
|
75
|
+
props = JavaProperties::Properties.load(TestJavaPropertiesData.file1)
|
76
|
+
assert_equal 'item2', props[:item2]
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_sets_key_and_value_seperated_by_whitespace
|
80
|
+
props = JavaProperties::Properties.load(TestJavaPropertiesData.file1)
|
81
|
+
assert_equal 'item3', props[:item3]
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_sets_multiline_values
|
85
|
+
props = JavaProperties::Properties.load(TestJavaPropertiesData.file1)
|
86
|
+
assert_equal 'line 1 line 2 line 3', props[:item7]
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_sets_encoded_unicode
|
90
|
+
props = JavaProperties::Properties.load(TestJavaPropertiesData.file2)
|
91
|
+
assert_equal "contains \352\260\200 unicode", props[:item12]
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_sets_backslash_escaped_chars
|
95
|
+
props = JavaProperties::Properties.load(TestJavaPropertiesData.file1)
|
96
|
+
assert_equal "test\n\ttestP test\n\ttest test\n\ttest = test", props[:item10]
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_ignores_leading_whitespace
|
100
|
+
props = JavaProperties::Properties.load(TestJavaPropertiesData.file1)
|
101
|
+
assert_equal props[:item7], props[:item8]
|
102
|
+
assert_equal props[:item7], props[:item9]
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
metadata
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: peterseverin-java_properties
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.5
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Dwayne Kristjanson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-08-04 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: A class that can read and write to Java properties files that behaves otherwise as a standard ruby Enumerable. The keys to this object can be provided as Strings or Symbols, but internally they are Symbols.
|
17
|
+
email: flergl@flergl.net
|
18
|
+
executables:
|
19
|
+
- properties2yaml
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- History.txt
|
24
|
+
- Manifest.txt
|
25
|
+
- README.txt
|
26
|
+
files:
|
27
|
+
- History.txt
|
28
|
+
- Manifest.txt
|
29
|
+
- README.txt
|
30
|
+
- Rakefile
|
31
|
+
- java_properties.gemspec
|
32
|
+
- lib/java_properties.rb
|
33
|
+
- lib/java_properties/delimiters.rb
|
34
|
+
- lib/java_properties/encoding.rb
|
35
|
+
- lib/java_properties/parser.rb
|
36
|
+
- lib/java_properties/properties-files.rb
|
37
|
+
- lib/java_properties/specialchars.rb
|
38
|
+
- lib/java_properties/utf8.rb
|
39
|
+
- lib/java_properties/version.rb
|
40
|
+
- bin/properties2yaml
|
41
|
+
- test/test_data.rb
|
42
|
+
- test/test_helper.rb
|
43
|
+
- test/test_java_properties.rb
|
44
|
+
has_rdoc: true
|
45
|
+
homepage: http://github.com/flergl/java-properties-for-ruby
|
46
|
+
licenses:
|
47
|
+
post_install_message:
|
48
|
+
rdoc_options:
|
49
|
+
- --main
|
50
|
+
- README.txt
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
version:
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: "0"
|
64
|
+
version:
|
65
|
+
requirements: []
|
66
|
+
|
67
|
+
rubyforge_project:
|
68
|
+
rubygems_version: 1.3.5
|
69
|
+
signing_key:
|
70
|
+
specification_version: 2
|
71
|
+
summary: Simple gem for reading/writing Java properties files from Ruby.
|
72
|
+
test_files:
|
73
|
+
- test/test_data.rb
|
74
|
+
- test/test_helper.rb
|
75
|
+
- test/test_java_properties.rb
|