Class: DslRuntime
- Inherits:
-
Object
- Object
- DslRuntime
- Includes:
- LifecycleCallbacks, Utils
- Defined in:
- lib/roundtrip_xml/dsl_runtime.rb
Overview
Class which evaluates DSL and read XML files to populate the namespace with classes
Constant Summary
Constants included from Utils
Utils::UNDEFINED_PARAM, Utils::VAR_SUFIX
Class Method Summary collapse
Instance Method Summary collapse
- #add_class(name, clazz) ⇒ Object
- #add_unprocessed_attr(attr_config, clazz) ⇒ Object
- #child_classes(hash, config) ⇒ Object
- #create_cleanroom(root_class, show_undefined_params = false) ⇒ Object
- #deserialize_class(node, config) ⇒ Object
- #evaluate_file(path, root_class, templates = []) ⇒ Object
- #evaluate_raw(dsl, root_class, templates = [], &block) ⇒ Object
- #fetch(class_name) ⇒ Object
- #fetch_cleanroom(root_class) ⇒ Object
- #hash_to_tree(hash, root_name, processed = []) ⇒ Object
-
#initialize ⇒ DslRuntime
constructor
A new instance of DslRuntime.
- #marshal_dump ⇒ Object
- #marshal_load(data) ⇒ Object
- #populate(files) ⇒ Object
- #populate_from_file(file) ⇒ Object
- #populate_raw(raw) ⇒ Object
- #serialize(path) ⇒ Object
- #transform_accessor_opts(opts) ⇒ Object
- #write_dsl(xml, root_class_name, root_method, helpers = nil, &block) ⇒ Object
- #write_dsl_helper(root, root_method, objs) ⇒ Object
Methods included from LifecycleCallbacks
Methods included from Utils
included, #name_to_sym, #new_roxml_class
Constructor Details
#initialize ⇒ DslRuntime
Returns a new instance of DslRuntime.
16 17 18 19 20 |
# File 'lib/roundtrip_xml/dsl_runtime.rb', line 16 def initialize() super @classes = {} @root_classes = Set.new end |
Class Method Details
.load(path) ⇒ Object
202 203 204 205 206 207 |
# File 'lib/roundtrip_xml/dsl_runtime.rb', line 202 def self.load(path) file = File.open path, 'r' obj = Marshal.load file file.close obj end |
Instance Method Details
#add_class(name, clazz) ⇒ Object
77 78 79 |
# File 'lib/roundtrip_xml/dsl_runtime.rb', line 77 def add_class(name, clazz) @classes[name] = clazz end |
#add_unprocessed_attr(attr_config, clazz) ⇒ Object
144 145 146 147 |
# File 'lib/roundtrip_xml/dsl_runtime.rb', line 144 def add_unprocessed_attr(attr_config, clazz) @unprocessed_attrs ||= [] @unprocessed_attrs << AttrJob.new(attr_config, clazz) end |
#child_classes(hash, config) ⇒ Object
187 188 189 190 191 192 193 |
# File 'lib/roundtrip_xml/dsl_runtime.rb', line 187 def child_classes(hash, config) config[:attrs].map do |attr| attr_type = attr[:opts][:as] type = attr_type.class == Array ? attr_type.first : attr_type type if hash.key? type end.compact end |
#create_cleanroom(root_class, show_undefined_params = false) ⇒ Object
103 104 105 |
# File 'lib/roundtrip_xml/dsl_runtime.rb', line 103 def create_cleanroom(root_class, show_undefined_params = false) BaseCleanroom.new(root_class.new, self, show_undefined_params) end |
#deserialize_class(node, config) ⇒ Object
131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/roundtrip_xml/dsl_runtime.rb', line 131 def deserialize_class(node, config) clazz = fetch(node.name) || new_roxml_class(config[:xml_name]) config[:attrs].each do |attr| type_is_parent = node.parentage && (node.parentage << node).any? {|n| n.name == attr[:opts][:as]} if type_is_parent add_unprocessed_attr attr, clazz else clazz.xml_accessor attr[:name], transform_accessor_opts(attr[:opts]) end end clazz end |
#evaluate_file(path, root_class, templates = []) ⇒ Object
81 82 83 84 85 86 |
# File 'lib/roundtrip_xml/dsl_runtime.rb', line 81 def evaluate_file(path, root_class, templates = []) cleanroom = RootCleanroom.new(fetch(root_class).new, self) templates.each { |t| cleanroom.evaluate_file t } cleanroom.evaluate_file path end |
#evaluate_raw(dsl, root_class, templates = [], &block) ⇒ Object
88 89 90 91 92 93 94 95 96 97 |
# File 'lib/roundtrip_xml/dsl_runtime.rb', line 88 def evaluate_raw(dsl, root_class, templates = [], &block) cleanroom = RootCleanroom.new(fetch(root_class).new, self) templates.each { |t| cleanroom.evaluate t } if block_given? cleanroom.evaluate &block else cleanroom.evaluate dsl end end |
#fetch(class_name) ⇒ Object
73 74 75 |
# File 'lib/roundtrip_xml/dsl_runtime.rb', line 73 def fetch(class_name) @classes[class_name] end |
#fetch_cleanroom(root_class) ⇒ Object
99 100 101 |
# File 'lib/roundtrip_xml/dsl_runtime.rb', line 99 def fetch_cleanroom(root_class) BaseCleanroom.new(fetch(root_class).new, self) end |
#hash_to_tree(hash, root_name, processed = []) ⇒ Object
177 178 179 180 181 182 183 184 185 |
# File 'lib/roundtrip_xml/dsl_runtime.rb', line 177 def hash_to_tree(hash, root_name, processed = []) node = Tree::TreeNode.new(root_name, hash[root_name]) processed << root_name children = child_classes(hash, hash[root_name]) children.each do |name| node << hash_to_tree(hash, name, processed) unless processed.include? name end node end |
#marshal_dump ⇒ Object
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/roundtrip_xml/dsl_runtime.rb', line 107 def marshal_dump classes = @classes.inject({}) do |hash, (name, clazz)| hash[name] = {xml_name: clazz.tag_name } hash[name][:attrs] = clazz.roxml_attrs.map do |accessor| type = accessor.sought_type.class == Class ? accessor.sought_type.class_name : accessor.sought_type from = accessor.sought_type == :attr ? "@#{accessor.name}" : accessor.name { name: accessor.accessor, opts: { as: accessor.array? ? [type] : type, from: from } } end hash end { root_classes: @root_classes, classes: classes } end |
#marshal_load(data) ⇒ Object
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
# File 'lib/roundtrip_xml/dsl_runtime.rb', line 161 def marshal_load(data) initialize @root_classes.merge data[:root_classes] trees = @root_classes.map {|clazz| hash_to_tree data[:classes], clazz} trees.each do |tree| tree.postordered_each do |node| @classes[node.name] = deserialize_class(node, node.content) end end @unprocessed_attrs.each do |job| clazz = job.class config = job.config clazz.xml_accessor config[:name], transform_accessor_opts(config[:opts]) end if @unprocessed_attrs end |
#populate(files) ⇒ Object
21 22 23 |
# File 'lib/roundtrip_xml/dsl_runtime.rb', line 21 def populate(files) files.map {|f| populate_from_file f } end |
#populate_from_file(file) ⇒ Object
25 26 27 28 |
# File 'lib/roundtrip_xml/dsl_runtime.rb', line 25 def populate_from_file (file) populate_raw File.read(file) end |
#populate_raw(raw) ⇒ Object
32 33 34 35 36 37 |
# File 'lib/roundtrip_xml/dsl_runtime.rb', line 32 def populate_raw (raw) builder = RoxmlBuilder.new (Nokogiri::XML(raw).root), @classes new_classes = builder.build_classes @root_classes << builder.root_class_name @classes.merge! new_classes end |
#serialize(path) ⇒ Object
196 197 198 199 200 |
# File 'lib/roundtrip_xml/dsl_runtime.rb', line 196 def serialize(path) file = File.new path, 'w' Marshal.dump self, file file.close end |
#transform_accessor_opts(opts) ⇒ Object
149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/roundtrip_xml/dsl_runtime.rb', line 149 def transform_accessor_opts(opts) attr_type = opts[:as] is_array = attr_type.class == Array type = is_array ? attr_type.first : attr_type if is_array opts[:as] = [fetch(type)] else opts[:as] = fetch type end opts end |
#write_dsl(xml, root_class_name, root_method, helpers = nil, &block) ⇒ Object
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/roundtrip_xml/dsl_runtime.rb', line 40 def write_dsl(xml, root_class_name, root_method, helpers = nil, &block) roxml_root = fetch(root_class_name).from_xml xml trigger :after_roxml_created, roxml_root extractor = Extractor.new roxml_root.send(root_method), self, root_class_name, helpers new_objs = extractor.convert_roxml_objs if block_given? partitions = {} new_objs.each do |obj| partition = yield obj partitions[partition] ||= [] partitions[partition] << obj end partitions dsl = partitions.inject({}) do |out, (partition, objs)| out[partition] = write_dsl_helper roxml_root, root_method, objs out end else dsl = write_dsl_helper roxml_root, root_method, new_objs end dsl end |
#write_dsl_helper(root, root_method, objs) ⇒ Object
66 67 68 69 70 71 |
# File 'lib/roundtrip_xml/dsl_runtime.rb', line 66 def write_dsl_helper(root, root_method, objs) root.send("#{root_method}=", objs) builder = SexpDslBuilder.new root, self builder.write_full_dsl root_method end |