lib/libeagle/base.rb
module LibEagle
class AttributeRequired < StandardError; end
class AttributeValueInvalid < StandardError; end
class Base
def self.iname(name)
name.gsub(/^class$/, "clazz")
end
#
# Getter of LibEagle objects
def self.lib_eagle_objects
@lib_eagle_objects ||= Hash.new
@lib_eagle_objects[:attributes] ||= {}
@lib_eagle_objects[:objects] ||= {}
@lib_eagle_objects[:empty_element] ||= false
@lib_eagle_objects[:root_element] ||= false
@lib_eagle_objects[:text_content] ||= false
@lib_eagle_objects[:element_name] ||= false
@lib_eagle_objects
end
def self.empty_element
lib_eagle_objects[:empty_element] = true
end
def self.root_element
lib_eagle_objects[:root_element] = true
end
def self.text_content
lib_eagle_objects[:text_content] = true
# Define Setter and getter
attr_accessor :content
end
def self.change_element_name(element_name)
lib_eagle_objects[:element_name] = true
define_method "element_name".to_sym do
instance_variable_set("@element_name", element_name) unless instance_variable_defined?("@element_name")
instance_variable_get("@element_name")
end
end
def self.attribute(attribute_name, params = {})
attribute_name = attribute_name.to_s
variable_name = "@attribute_#{attribute_name}"
# Initialize place inside LibEagle objects
lib_eagle_objects[:attributes][attribute_name] ||= {}
lib_eagle_objects[:attributes][attribute_name][:required] = true if params[:required]
lib_eagle_objects[:attributes][attribute_name][:type] = params[:type] if params[:type]
lib_eagle_objects[:attributes][attribute_name][:valid_values] = params[:valid_values] if params[:valid_values]
# If default value is set return default value
if params[:default]
define_method "attribute_#{attribute_name}".to_sym do
instance_variable_set(variable_name, params[:default]) unless instance_variable_defined?(variable_name)
instance_variable_get(variable_name)
end
else
define_method "attribute_#{attribute_name}".to_sym do
instance_variable_get(variable_name)
end
end
# Attribute setter
define_method "attribute_#{attribute_name}=".to_sym do |value|
if is_valid?(attribute_name,value)
instance_variable_set(variable_name,value)
end
end
end
def self.object(object_name, params = {})
object_name = object_name.to_s
variable_name = "@object_#{object_name}"
# Initialize place inside LibEagle objects
lib_eagle_objects[:objects][object_name] ||= {}
lib_eagle_objects[:objects][object_name][:class] = params[:class] if params[:class]
lib_eagle_objects[:objects][object_name][:class] = object_name.capitalize unless params[:class]
# Object getter
define_method "object_#{object_name}".to_sym do
instance_variable_get(variable_name)
end
# Object setter
define_method "object_#{object_name}=".to_sym do |value|
instance_variable_set(variable_name,value)
end
end
def self.newFile(file)
xml = LibEagle::XML::Loader.new.loadFile(file)
self.new_with_xml(xml)
end
def self.newXML(block_xml)
xml = LibEagle::XML::Loader.new.loadBlock(block_xml)
self.new_with_xml(xml)
end
def self.new_with_xml(xml)
@base_class = self.new
if @lib_eagle_objects[:text_content]
@base_class.instance_variable_set("@content", xml.content)
end
if @lib_eagle_objects[:attributes].size > 0
@lib_eagle_objects[:attributes].each_pair do |attribute_name, params|
@base_class.instance_variable_set("@attribute_#{attribute_name}",xml[attribute_name]) if xml[attribute_name]
end
end
if @lib_eagle_objects[:objects].size > 0
@lib_eagle_objects[:objects].each_pair do |object_name, params|
if xml.xpath(object_name).size > 1
objects = []
xml.xpath(object_name).each do |xml_node|
objects << LibEagle::const_get(params[:class]).new_with_xml(xml_node)
end
@base_class.instance_variable_set("@object_#{object_name}",objects)
elsif xml.xpath(object_name).size == 1
xml_node = xml.xpath(object_name).first
object = LibEagle::const_get(params[:class]).new_with_xml(xml_node)
@base_class.instance_variable_set("@object_#{object_name}",object)
end
end
end
return @base_class
end
def is_valid?(attribute,value)
params = self.class.lib_eagle_objects[:attributes][attribute]
if params[:required]
unless value
raise AttributeRequired.new("#{self.class.name}: #{attribute} is required")
return false
end
end
if params[:type] && value
unless params[:type] =~ value
raise AttributeValueInvalid.new("`#{attribute}` value: \"#{value}\" isn't in valid range (#{params[:type]})")
return false
end
end
return true
end
def valid?
self.class.lib_eagle_objects[:attributes].each_pair do |attribute, params|
value = self.instance_variable_get("@attribute_#{attribute}")
if params[:required]
unless value
raise AttributeRequired.new("#{self.class.name}: #{attribute} is required")
return false
end
end
if params[:type] && value
unless params[:type] =~ value
raise AttributeValueInvalid.new("`#{attribute}` value: \"#{value}\" isn't in valid range (#{params[:type]})")
return false
end
end
return true
end
end
def saveXML
if valid?
LibEagle::XML::Saver.new(self.class.lib_eagle_objects,self).parse
end
end
end
end