Ruby Yaml to Enum

From EggeWiki

Jump to: navigation, search

Generate Java 1.5 enums from a YAML file

#!/bin/env ruby
#
# Single value enums are frequently needed and they usually require additional code to lookup or access the enum
# based on a value.  This Ruby script generates a .java enum based on a YAML input file
#
require 'yaml'
require 'erb'
 
def java_name(s)
    s.upcase.gsub('/', '_')
end
 
template = ERB.new <<-EOF
package <%= @package %>;
 
public enum <%= @enum %> {
    EMPTY(""),<% @enums.each do |i| %>
    <%= java_name(i) %>("<%= i %>")<%= (i == @enums[-1]) ? ';' : ',' %><% end %>
 
    private final String value;
 
    <%= @enum %>(String value) {
        this.value = value;
    }
 
    @Override
    public String toString() {
        return value;
    }
 
    public static <%= @enum %> getValue(String value) {
        for (<%= @enum %> e : values()) {
            if (e.value.equals(value)) {
                return e;
            }
        }
        return EMPTY;
    }
 
}
 
EOF
 
if ARGV.size == 0 then
    srcDir = 'C:\\dev\\src\\java\\com'
    destDir = 'C:\\dev\\generated-src\\java\\com'
else
    srcDir = ARGV[0]
    destDir = ARGV[1]
end
 
class Fields
    attr_accessor :enums, :name, :package, :enum
    def initialize(file)
        @name = /(com.*)/.match( file.gsub('\\', '.').gsub('/', '.') )[1].gsub(/\.yml$/, '.java')
        @package = @name.split('.')[0..-3].join('.')
        @enum = @name.split('.')[-2]
    end
    # Support templating of member data.
    def get_binding
        binding
    end
end
 
if !File.directory?(destDir) then
    Dir.mkdir(destDir)
end
 
Dir.entries(srcDir).select{|f| File.file?(File.join(srcDir, f)) && File.extname(f) == ".yml" }.each do |f|
 
    file = File.join(srcDir, f)
 
    data = Fields.new(file)
    File.open( file, "r" ) do |yf|
        data.enums = YAML::load( yf )
        output = template.result(data.get_binding)
        destFile = File.join(destDir, data.enum + '.java')
        if !File.exists?(destFile) || File.read(destFile) != output then
            File.open(destFile, 'a+') do |dest|
                dest.write output
                dest.truncate(dest.pos)
            end
            puts "Updated #{destFile}"
        else
            puts "#{destFile} is up to date"
        end
    end
end

Sample Colors.yml

 - red
 - green
 - blue
Personal tools
Travelling Salesman

Get the app!