Ruby Yaml to Enum

From EggeWiki
Revision as of 02:49, 9 October 2009 by Egge (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Generate Java 1.5 enums from a YAML file

<geshi lang="ruby">

  1. !/bin/env ruby
  2. Single value enums are frequently needed and they usually require additional code to lookup or access the enum
  3. 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 </geshi>

Sample Colors.yml

 - red
 - green
 - blue