java_properties 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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 +91 -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.4"
|
4
|
+
s.date = "2008-06-14"
|
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('%02x',( (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,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: java_properties
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 23
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 4
|
10
|
+
version: 0.0.4
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Dwayne Kristjanson
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2008-06-14 00:00:00 +10:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: |-
|
23
|
+
A class that can read and write to Java properties files that behaves
|
24
|
+
otherwise as a standard ruby Enumerable. The keys to this object can
|
25
|
+
be provided as Strings or Symbols, but internally they are Symbols.
|
26
|
+
email: flergl@flergl.net
|
27
|
+
executables:
|
28
|
+
- properties2yaml
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- History.txt
|
33
|
+
- Manifest.txt
|
34
|
+
- README.txt
|
35
|
+
files:
|
36
|
+
- History.txt
|
37
|
+
- Manifest.txt
|
38
|
+
- README.txt
|
39
|
+
- Rakefile
|
40
|
+
- java_properties.gemspec
|
41
|
+
- lib/java_properties.rb
|
42
|
+
- lib/java_properties/delimiters.rb
|
43
|
+
- lib/java_properties/encoding.rb
|
44
|
+
- lib/java_properties/parser.rb
|
45
|
+
- lib/java_properties/properties-files.rb
|
46
|
+
- lib/java_properties/specialchars.rb
|
47
|
+
- lib/java_properties/utf8.rb
|
48
|
+
- lib/java_properties/version.rb
|
49
|
+
- bin/properties2yaml
|
50
|
+
- test/test_data.rb
|
51
|
+
- test/test_helper.rb
|
52
|
+
- test/test_java_properties.rb
|
53
|
+
has_rdoc: true
|
54
|
+
homepage: http://github.com/flergl/java-properties-for-ruby
|
55
|
+
licenses: []
|
56
|
+
|
57
|
+
post_install_message:
|
58
|
+
rdoc_options:
|
59
|
+
- --main
|
60
|
+
- README.txt
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
hash: 3
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
version: "0"
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
hash: 3
|
78
|
+
segments:
|
79
|
+
- 0
|
80
|
+
version: "0"
|
81
|
+
requirements: []
|
82
|
+
|
83
|
+
rubyforge_project:
|
84
|
+
rubygems_version: 1.4.2
|
85
|
+
signing_key:
|
86
|
+
specification_version: 3
|
87
|
+
summary: Simple gem for reading/writing Java properties files from Ruby.
|
88
|
+
test_files:
|
89
|
+
- test/test_data.rb
|
90
|
+
- test/test_helper.rb
|
91
|
+
- test/test_java_properties.rb
|