# # Copyright (C) 2013 Christian Meier # # Permission is hereby granted, free of charge, to any person obtaining a copy of # this software and associated documentation files (the "Software"), to deal in # the Software without restriction, including without limitation the rights to # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of # the Software, and to permit persons to whom the Software is furnished to do so, # subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # module Maven module Model class Tag def self.prepend_tags(*tags) _tags(true, *tags) end def self.tags(*tags) _tags(false, *tags) end def self._tags(prepend, *tags) if tags.size == 0 @tags else #self.send :attr_accessor, *tags tags.each do |tag| eval <<-EOF def #{tag.to_s}(val = nil) @#{tag.to_s} = val if val @#{tag.to_s} end def #{tag.to_s}=(val) @#{tag.to_s} = val end EOF end if self.superclass.respond_to?:tags @tags ||= (self.superclass.tags || []).dup else @tags ||= [] end unless @tags.include? tags[0] if prepend @tags.replace([tags, @tags].flatten) else @tags.replace([@tags, tags].flatten) end end @tags end end def _name self.class.to_s.downcase.sub(/.*::/, '') end def initialize(args = {}) warn "deprecated #{args.inspect}" if args.size > 0 args.each do |k,v| send("#{k}=".to_sym, v) end end def comment(c) @comment = c if c @comment end def to_xml(buf = "", indent = "") buf << "#{indent}<#{_name}>\n" buf << "#{indent}\n" if @comment self.class.tags.each do |var| val = instance_variable_get("@#{var}".to_sym) var = var.to_s.gsub(/_(.)/) { $1.upcase } case val when Array val.flatten! if val.size > 0 buf << "#{indent} <#{var}>\n" val.each do |v| if v.is_a? Tag v.to_xml(buf, indent + " ") else buf << "#{indent} <#{var.to_s.sub(/s$/, '')}>#{v}\n" end end buf << "#{indent} \n" end when Hash if val.size > 0 buf << "#{indent} <#{var}>\n" val.keys.sort{ |n,m| n.to_s <=> m.to_s }.each do |k| v = val[k] if v.is_a? Tag v.to_xml(buf, indent + " ") else buf << "#{indent} <#{k}>#{v}\n" end end buf << "#{indent} \n" end when Tag val.to_xml(buf, indent + " ") else #when String buf << "#{indent} <#{var}>#{val}\n" if val end end buf << "#{indent}\n" buf end end class NamedArray < Array attr_reader :name def initialize(name, &block) @name = name.to_s if block block.call(self) end self end end class ResourceArray < Array def initialize( name = 'resources', child = Resource, &block ) @_child = child #super( name, &block ) if block block.call self end self end alias :do_add :<< def add( &block ) r = @_child.new block.call( r ) do_add r r end alias :<< :add end class ModelHash < Hash def initialize(clazz) @clazz = clazz end def keys @keys ||= [] end def get(key, &block) key = key.to_sym if key result = self[key] if result.nil? keys << key result = (self[key] = @clazz.new(key)) end if block block.call(result) end result end alias :new :get alias :add :get def default_model @default_model ||= begin model = @clazz.new self[nil] = model model end end def method_missing(method, *args, &block) default_model.send(method, *args, &block) end end class NamedHash < Hash def keys @keys ||= [] end def new_instance( clazz, args ) if args.size == 1 && args[0].is_a?(clazz) args[0] else clazz.new(*args) end end def do_get( clazz, args, method, block = nil) value = new_instance( clazz, args ) key = value.send method keys << key unless keys.member? key self[ key ] = value if block block.call( value ) end value end def get; end end class DeveloperHash < NamedHash def get( *args, &block ) do_get( Developer, args, :id, block ) end alias :new :get alias :add :get end class LicenseHash < NamedHash def get( *args, &block ) do_get( License, args, :name, block ) end alias :new :get alias :add :get end class PluginHash < Hash def adjust_key(name) name = name.to_s if (name =~ /\:/).nil? if [:jruby, :gem, :rspec, :rake, :minitest, :rails3, :gemify, :cucumber, :runit, :bundler].member? name.to_sym "de.saumya.mojo:#{name}-maven-plugin" else "maven-#{name}-plugin" end else name end end def key?(k) super( adjust_key(k).to_sym ) end def keys @keys ||= [] end def get(*args, &block) case args.size when 3 name = "#{args[0]}:#{args[1]}" version = args[2] when 2 name = args[0].to_s version = args[1] when 1 name = args[0].to_s else raise "need name" end name = adjust_key(name) group_id = name =~ /\:/ ? name.sub(/:.+$/, '') : nil artifact_id = name.sub(/^.+:/, '') k = "#{group_id}:#{artifact_id}".to_sym result = self[k] if result.nil? keys << k result = (self[k] = Plugin.new(group_id, artifact_id, version)) end result.version = version if version if block block.call(result) end result end alias :new :get alias :add :get end class ListItems < Tag def initialize(name = nil) @name = name end def add(item) @items ||= Array.new @items << item end alias :<< :add def to_xml(buf = "", indent = "") buf << "#{indent}<#{@name}>\n" if @name buf << "#{indent}\n" if @comment @items.each do |i| i.to_xml(buf, indent) end buf << "#{indent}\n" if @name end end class HashTag < Tag def initialize(name, args = {}) @name = name @props = args end def [](key) @props ||= {} @props[key] end def []=(key, value) @props ||= {} @props[key] = value end def to_xml(buf = "", indent = "") buf << "#{indent}<#{@name}>\n" buf << "#{indent}\n" if @comment map_to_xml(buf, indent, @props) buf << "#{indent}\n" end def map_to_xml(buf, indent, map) # sort the hash over the keys map.collect { |k,v| [k.to_s, v]}.sort.each do |k,v| case v when Hash buf << "#{indent} <#{k}>\n" map_to_xml(buf, indent + " ", v) buf << "#{indent} \n" when NamedArray buf << "#{indent} <#{k}>\n" v.each do|i| buf << "#{indent} <#{v.name}>\n" case i when Hash map_to_xml(buf, indent + " ", i) end buf << "#{indent} \n" end buf << "#{indent} \n" when Array buf << "#{indent} <#{k}>\n" singular = k.to_s.sub(/s$/, '') v.each do |i| case i when Hash buf << "#{indent} <#{singular}>\n" map_to_xml(buf, indent + " ", i) buf << "#{indent} \n" else buf << "#{indent} <#{singular}>#{i}\n" end end buf << "#{indent} \n" when /\n$/ buf << "#{indent} <#{k}>#{v}" buf << "#{indent} \n" else buf << "#{indent} <#{k}>#{v}\n" end end end end end end