module XML::Mapping::ClassMethods
The instance methods of this module are automatically added as class methods to a class that includes XML::Mapping.
Public Instance Methods
Add getter and setter methods for a new attribute named name (must be a symbol or a string) to this class, taking care not to replace existing getters/setters. This is a convenience method intended to be called from Node class initializers.
# File lib/xml/mapping/base.rb, line 308 def add_accessor(name) # existing methods search. Search for symbols and strings # to be compatible with Ruby 1.8 and 1.9. methods = self.instance_methods if methods[0].kind_of? Symbol getter = :"#{name}" setter = :"#{name}=" else getter = "#{name}" setter = "#{name}=" end unless methods.include?(getter) self.module_eval <<-EOS attr_reader :#{name} EOS end unless methods.include?(setter) self.module_eval <<-EOS attr_writer :#{name} EOS end end
enumeration of all nodes in effect when marshalling/unmarshalling this class, that is, nodes defined for this class as well as for its superclasses. The nodes are returned in the order of their definition, starting with the topmost superclass that has nodes defined. keyword arguments are the same as for xml_mapping_nodes.
# File lib/xml/mapping/base.rb, line 394 def all_xml_mapping_nodes(options={:mapping=>nil,:create=>true}) # TODO: we could return a dynamic Enumerable here, or cache # the array... result = [] if superclass and superclass.respond_to?(:all_xml_mapping_nodes) result += superclass.all_xml_mapping_nodes options end result += xml_mapping_nodes options end
return the current default mapping (:_default initially, or the value set with the latest call to #use_mapping)
# File lib/xml/mapping/base.rb, line 300 def default_mapping @default_mapping end
The default root element name for this class. Equals the class name, with all parent module names stripped, and with capital letters converted to lowercase and preceded by a dash; e.g. “Foo::Bar::MySampleClass” becomes “my-sample-class”.
# File lib/xml/mapping/base.rb, line 435 def default_root_element_name self.name.split('::')[-1].gsub(/^(.)/){$1.downcase}.gsub(/(.)([A-Z])/){$1+"-"+$2.downcase} end
Create a new instance of this class from the XML contained in the file named filename. Calls #load_from_xml internally.
# File lib/xml/mapping/base.rb, line 333 def load_from_file(filename, options={:mapping=>:_default}) xml = REXML::Document.new(File.new(filename)) load_from_xml xml.root, :mapping=>options[:mapping] end
Create a new instance of this class from the XML contained in xml (a REXML::Element).
Allocates a new object, then calls fill_from_xml(xml) on it.
# File lib/xml/mapping/base.rb, line 343 def load_from_xml(xml, options={:mapping=>:_default}) raise(MappingError, "undefined mapping: #{options[:mapping].inspect}") unless xml_mapping_nodes_hash.has_key?(options[:mapping]) # create the new object. It is recommended that the class # have a no-argument initializer, so try new first. If that # doesn't work, try allocate, which bypasses the initializer. begin obj = self.new #TODO: this will normally invoke our base XML::Mapping#initialize, which calls # obj.initialize_xml_mapping, which is called below again (with the correct :mapping parameter). # obj.initialize_xml_mapping calls obj_initializing on all nodes. # So obj_initializing may be called on the nodes twice for this initialization. # Maybe document this for node writers? rescue ArgumentError # TODO: this may hide real errors. # how to statically check whether # self self.new accepts an empty # argument list? obj = self.allocate end obj.initialize_xml_mapping :mapping=>options[:mapping] obj.fill_from_xml xml, :mapping=>options[:mapping] obj end
the formatter to be used for output formatting when writing xml to character streams (Files/IOs). Combined getter/setter. Defaults to simple (compact/no-whitespace) formatting, may be overridden on a per-call base via options
# File lib/xml/mapping/base.rb, line 443 def mapping_output_formatter(formatter=nil) # TODO make it per-mapping if formatter @mapping_output_formatter = formatter end @mapping_output_formatter ||= REXML::Formatters::Default.new end
The “root element name” of this class (combined getter/setter method).
The root element name is the name of the root element of the XML tree returned by <this class>.#save_to_xml (or, more specifically, <this class>.#pre_save). By default, this method returns the default_root_element_name; you may call this method with an argument to set the root element name to something other than the default. The option argument :mapping specifies the mapping the root element is/will be defined in, it defaults to the current default mapping (:_default initially, or the value set with the latest call to #use_mapping)
# File lib/xml/mapping/base.rb, line 418 def root_element_name(name=nil, options={:mapping=>@default_mapping}) if Hash===name # ugly... options=name; name=nil end @root_element_names ||= {} if name Classes_by_rootelt_names.remove_class root_element_name, options[:mapping], self @root_element_names[options[:mapping]] = name Classes_by_rootelt_names.create_classes_for(name, options[:mapping]) << self end @root_element_names[options[:mapping]] || default_root_element_name end
Make mapping the mapping to be used by default in future node declarations in this class. The default can be overwritten on a per-node basis by passing a :mapping option parameter to the node factory method
The initial default mapping in a mapping class is :_default
# File lib/xml/mapping/base.rb, line 291 def use_mapping mapping @default_mapping = mapping xml_mapping_nodes_hash[mapping] ||= [] # create empty mapping node list if # there wasn't one before so future calls # to load/save_xml etc. w/ this mapping don't raise end
array of all nodes defined in this class, in the order of their definition. Option :create specifies whether or not an empty array should be created and returned if there was none before (if not, an exception is raised). :mapping specifies the mapping the returned nodes must have been defined in; nil means return all nodes regardless of their mapping
# File lib/xml/mapping/base.rb, line 374 def xml_mapping_nodes(options={:mapping=>nil,:create=>true}) unless options[:mapping] return xml_mapping_nodes_hash.values.inject([]){|a1,a2|a1+a2} end options[:create] = true if options[:create].nil? if options[:create] xml_mapping_nodes_hash[options[:mapping]] ||= [] else xml_mapping_nodes_hash[options[:mapping]] || raise(MappingError, "undefined mapping: #{options[:mapping].inspect}") end end