xbrlware-ruby19 1.1.2.19
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +4 -0
- data/Rakefile +2 -0
- data/lib/xbrlware-ruby19/cgi_patch.rb +58 -0
- data/lib/xbrlware-ruby19/constants.rb +29 -0
- data/lib/xbrlware-ruby19/context.rb +193 -0
- data/lib/xbrlware-ruby19/date_util.rb +45 -0
- data/lib/xbrlware-ruby19/float_patch.rb +26 -0
- data/lib/xbrlware-ruby19/hash_util.rb +175 -0
- data/lib/xbrlware-ruby19/instance.rb +475 -0
- data/lib/xbrlware-ruby19/item.rb +123 -0
- data/lib/xbrlware-ruby19/linkbase/calculation_linkbase.rb +181 -0
- data/lib/xbrlware-ruby19/linkbase/definition_linkbase.rb +226 -0
- data/lib/xbrlware-ruby19/linkbase/label_linkbase.rb +132 -0
- data/lib/xbrlware-ruby19/linkbase/linkbase.rb +193 -0
- data/lib/xbrlware-ruby19/linkbase/presentation_linkbase.rb +204 -0
- data/lib/xbrlware-ruby19/meta_util.rb +50 -0
- data/lib/xbrlware-ruby19/ns_aware.rb +5 -0
- data/lib/xbrlware-ruby19/taxonomies/ifrs_taxonomy_20090401.rb +8278 -0
- data/lib/xbrlware-ruby19/taxonomies/us_gaap_taxonomy_20090131.rb +40365 -0
- data/lib/xbrlware-ruby19/taxonomy.rb +143 -0
- data/lib/xbrlware-ruby19/unit.rb +43 -0
- data/lib/xbrlware-ruby19/util.rb +86 -0
- data/lib/xbrlware-ruby19/version.rb +22 -0
- data/lib/xbrlware-ruby19/xml_parser.rb +142 -0
- data/lib/xbrlware-ruby19.rb +73 -0
- data/xbrlware-ruby19.gemspec +27 -0
- metadata +109 -0
@@ -0,0 +1,193 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#
|
3
|
+
# Author:: xbrlware@bitstat.com
|
4
|
+
#
|
5
|
+
# Copyright:: 2009, 2010 bitstat (http://www.bitstat.com). All Rights Reserved.
|
6
|
+
#
|
7
|
+
# License:: Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
16
|
+
# implied.
|
17
|
+
# See the License for the specific language governing permissions and
|
18
|
+
# limitations under the License.
|
19
|
+
#
|
20
|
+
module Xbrlware
|
21
|
+
module Linkbase
|
22
|
+
|
23
|
+
class Linkbase
|
24
|
+
# Creates a Linkbase.
|
25
|
+
#
|
26
|
+
# linkbase_path::
|
27
|
+
# XBRL Linkbase source. Tries to load and parse linkbase from path.
|
28
|
+
#
|
29
|
+
def initialize(linkbase_path)
|
30
|
+
m=Benchmark.measure do
|
31
|
+
begin
|
32
|
+
@linkbase_content = XmlParser.xml_in(linkbase_path, {'ForceContent' => true})
|
33
|
+
rescue Exception
|
34
|
+
$LOG.warn "File ["+linkbase_path+"] is not well formed. Starting reparsing after removing new lines."
|
35
|
+
@linkbase_content = XmlParser.xml_in(File.open(linkbase_path).read.gsub("\n", ""), {'ForceContent' => true})
|
36
|
+
end
|
37
|
+
end
|
38
|
+
bm("Parsing [" + linkbase_path + "] took", m)
|
39
|
+
|
40
|
+
#Populate role map
|
41
|
+
role_map()
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
def role_map
|
46
|
+
@role_map={}
|
47
|
+
@linkbase_content["roleRef"].each do |role_ref|
|
48
|
+
href = role_ref["xlink:href"]
|
49
|
+
unless href.index("#").nil?
|
50
|
+
@role_map[role_ref["roleURI"]]= href[href.index("#")+1, href.length]
|
51
|
+
else
|
52
|
+
@role_map[role_ref["roleURI"]]=href
|
53
|
+
end
|
54
|
+
end unless @linkbase_content["roleRef"].nil?
|
55
|
+
end
|
56
|
+
|
57
|
+
public
|
58
|
+
|
59
|
+
def inspect
|
60
|
+
self.to_s
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.wireup_relationship(map, parent, child) # :nodoc:
|
64
|
+
|
65
|
+
if child.is_a?(Array)
|
66
|
+
child.each do |c|
|
67
|
+
wireup_relationship(map, parent, c)
|
68
|
+
end
|
69
|
+
return
|
70
|
+
end
|
71
|
+
|
72
|
+
child.parent=parent
|
73
|
+
parent.children.add(child)
|
74
|
+
return unless map.has_key?(child)
|
75
|
+
|
76
|
+
# map contains different instance (that equals to child) as key.
|
77
|
+
# Delete the key, reinsert the proper instance as key
|
78
|
+
children_of_child=map[child]
|
79
|
+
#map.delete(child)
|
80
|
+
map[child]=children_of_child
|
81
|
+
wireup_relationship(map, child, map[child])
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.build_relationship(map) # :nodoc:
|
85
|
+
map.each do |key, value|
|
86
|
+
wireup_relationship(map, key, value)
|
87
|
+
end
|
88
|
+
root_elements=map.keys.select { |key| key.parent.nil?}
|
89
|
+
root_elements.each {|root_element| sort_by_order(root_element)}
|
90
|
+
return root_elements
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.sort_by_order(element) # :nodoc:
|
94
|
+
return if element.children.nil?
|
95
|
+
element.children=element.children.sort_by {|e| (e.respond_to?(:order) && e.order) || "0"}
|
96
|
+
element.children.each do |child|
|
97
|
+
sort_by_order(child)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
class Link
|
102
|
+
|
103
|
+
attr_reader :link_type, :title, :role, :href, :arcs
|
104
|
+
|
105
|
+
def initialize(link_type, title, role, href, arcs=nil)
|
106
|
+
@link_type=link_type
|
107
|
+
@role = role
|
108
|
+
@href = href
|
109
|
+
|
110
|
+
@title=title unless title.nil?
|
111
|
+
@title=role.split("/")[-1] if title.nil?
|
112
|
+
@title=@title.split(/(?=[A-Z])/).join(' ')
|
113
|
+
@title.gsub!(/_/, " ")
|
114
|
+
@title.gsub!(/[ ]+/, " ")
|
115
|
+
|
116
|
+
@arcs = arcs
|
117
|
+
end
|
118
|
+
|
119
|
+
private
|
120
|
+
def print_arc_hierarchy(verbose_flag="q", arcs=@arcs, indent=0)
|
121
|
+
arcs.each do |arc|
|
122
|
+
str=" " * indent + arc.item_name + "("+(arc.label if arc.respond_to?(:label)).to_s+")"
|
123
|
+
if verbose_flag=="v"
|
124
|
+
str +=" label [" +(arc.label if arc.respond_to?(:label)).to_s+"], role ["+arc.role.to_s+"]"
|
125
|
+
end
|
126
|
+
str += " order ["+arc.order.to_s+"]"
|
127
|
+
puts str
|
128
|
+
print_arc_hierarchy(verbose_flag, arc.children, indent+1) if arc.children
|
129
|
+
end unless arcs.nil?
|
130
|
+
end
|
131
|
+
|
132
|
+
public
|
133
|
+
def inspect
|
134
|
+
self.to_s
|
135
|
+
end
|
136
|
+
|
137
|
+
def print(verbose_flag="q")
|
138
|
+
puts " title ["+title+"] role ["+role+"]"
|
139
|
+
print_arc_hierarchy(verbose_flag)
|
140
|
+
return self.to_s
|
141
|
+
end
|
142
|
+
|
143
|
+
class Arc
|
144
|
+
attr_reader :item_id, :item_name, :role, :label, :href, :order, :priority
|
145
|
+
attr_accessor :items, :children, :parent
|
146
|
+
|
147
|
+
def initialize(item_id, href, role=nil, order=nil, priority=nil, label=nil)
|
148
|
+
@item_id=item_id
|
149
|
+
@item_name = @item_id[0, (@item_id.rindex("_")==nil ? @item_id.size: @item_id.rindex("_"))]
|
150
|
+
@href=href
|
151
|
+
@role=role
|
152
|
+
@order=order.to_i
|
153
|
+
@priority=priority.to_i
|
154
|
+
if label.nil?
|
155
|
+
if href.nil?
|
156
|
+
dash_index=item_id.index("_")
|
157
|
+
dash_index=dash_index.nil? ? 0 :(dash_index+1)
|
158
|
+
label=item_id[dash_index, item_id.length]
|
159
|
+
else
|
160
|
+
label=href[href.index("#")+1, href.length] unless href.index("#").nil?
|
161
|
+
label=href if href.index("#").nil?
|
162
|
+
unless label.index("_").nil?
|
163
|
+
dash_index=label.index("_")
|
164
|
+
label=label[dash_index+1, label.length]
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
@label=label
|
169
|
+
@children=Set.new()
|
170
|
+
end
|
171
|
+
|
172
|
+
def has_children?
|
173
|
+
@children.size>0
|
174
|
+
end
|
175
|
+
|
176
|
+
def eql?(o)
|
177
|
+
o.is_a?(Arc) && @item_id == o.item_id
|
178
|
+
end
|
179
|
+
|
180
|
+
def hash
|
181
|
+
@item_id.hash
|
182
|
+
end
|
183
|
+
|
184
|
+
def inspect
|
185
|
+
self.to_s
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
end
|
191
|
+
|
192
|
+
end
|
193
|
+
end
|
@@ -0,0 +1,204 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#
|
3
|
+
# Author:: xbrlware@bitstat.com
|
4
|
+
#
|
5
|
+
# Copyright:: 2009, 2010 bitstat (http://www.bitstat.com). All Rights Reserved.
|
6
|
+
#
|
7
|
+
# License:: Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
16
|
+
# implied.
|
17
|
+
# See the License for the specific language governing permissions and
|
18
|
+
# limitations under the License.
|
19
|
+
#
|
20
|
+
module Xbrlware
|
21
|
+
module Linkbase
|
22
|
+
class PresentationLinkbase < Linkbase
|
23
|
+
|
24
|
+
# Creates a PresentationLinkbase.
|
25
|
+
#
|
26
|
+
# linkbase_path::
|
27
|
+
# XBRL Presentation Linkbase source. Tries to load and parse presentation linkbase from path.
|
28
|
+
#
|
29
|
+
# instance::
|
30
|
+
# Instance object
|
31
|
+
#
|
32
|
+
# def_linkbase::
|
33
|
+
# DefinitionLinkbase object
|
34
|
+
#
|
35
|
+
# label_linkbase::
|
36
|
+
# optional parameter, LabelLinkbase object
|
37
|
+
def initialize(linkbase_path, instance, def_linkbase, label_linkbase=nil)
|
38
|
+
super linkbase_path
|
39
|
+
@instance=instance
|
40
|
+
@def_linkbase=def_linkbase
|
41
|
+
@label_linkbase=label_linkbase
|
42
|
+
@pre_content_optimized=nil
|
43
|
+
end
|
44
|
+
|
45
|
+
def presentation(role=nil)
|
46
|
+
presentations=[]
|
47
|
+
|
48
|
+
if @pre_content_optimized.nil?
|
49
|
+
pre_content=@linkbase_content["presentationLink"]
|
50
|
+
|
51
|
+
@pre_content_optimized = []
|
52
|
+
pre_content.each_with_index do |pre, index|
|
53
|
+
next if pre["loc"].nil? || pre["presentationArc"].nil?
|
54
|
+
pre["loc"].map! do |e|
|
55
|
+
e["xlink:label"]="#{e['xlink:label']}_#{index}"
|
56
|
+
e
|
57
|
+
end
|
58
|
+
|
59
|
+
pre["presentationArc"].map! do |e|
|
60
|
+
e["xlink:from"]="#{e['xlink:from']}_#{index}"
|
61
|
+
e["xlink:to"]="#{e['xlink:to']}_#{index}"
|
62
|
+
e
|
63
|
+
end
|
64
|
+
selected=@pre_content_optimized.select {|pre_existing| pre_existing["xlink:role"]==pre["xlink:role"]}[0]
|
65
|
+
if selected.nil?
|
66
|
+
@pre_content_optimized << pre
|
67
|
+
else
|
68
|
+
pre["loc"].each do |current|
|
69
|
+
matched_loc=nil
|
70
|
+
selected["loc"].each do |existing|
|
71
|
+
if existing["xlink:href"]==current["xlink:href"]
|
72
|
+
matched_loc=current
|
73
|
+
pre["presentationArc"].each do |arc|
|
74
|
+
arc["xlink:from"] = existing["xlink:label"] if current["xlink:label"]==arc["xlink:from"]
|
75
|
+
arc["xlink:to"] = existing["xlink:label"] if current["xlink:label"]==arc["xlink:to"]
|
76
|
+
end
|
77
|
+
break
|
78
|
+
end
|
79
|
+
end
|
80
|
+
selected["loc"] << current if matched_loc.nil?
|
81
|
+
end
|
82
|
+
selected["presentationArc"] += pre["presentationArc"]
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
@pre_content_optimized.each do |pre|
|
88
|
+
next unless pre["xlink:role"]==role unless role.nil?
|
89
|
+
|
90
|
+
if pre["presentationArc"].nil?
|
91
|
+
presentations << Presentation.new(@instance.entity_details, pre["xlink:title"], pre["xlink:role"], @role_map[pre["xlink:role"]])
|
92
|
+
else
|
93
|
+
definition=nil
|
94
|
+
definition=@def_linkbase.definition(pre["xlink:role"]) unless @def_linkbase.nil?
|
95
|
+
|
96
|
+
dimensions=[]
|
97
|
+
dimensions = definition.dimension_domain_map.keys unless definition.nil?
|
98
|
+
|
99
|
+
contexts_and_arcs=arcs(pre, dimensions)
|
100
|
+
presentations << Presentation.new(@instance.entity_details, pre["xlink:title"], pre["xlink:role"], @role_map[pre["xlink:role"]], contexts_and_arcs["contexts"], contexts_and_arcs["arcs"], definition, @instance, dimensions)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
return presentations[0] unless role.nil?
|
104
|
+
presentations
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
def fetch_label(label_name, pref_label)
|
109
|
+
pref_label="http://www.xbrl.org/2003/role/label" if pref_label.nil?
|
110
|
+
label_obj=@label_linkbase.label(label_name, pref_label)
|
111
|
+
label = label_obj.value unless label_obj.nil?
|
112
|
+
return label
|
113
|
+
end
|
114
|
+
|
115
|
+
def arcs(pre, dimensions=[])
|
116
|
+
locators={}
|
117
|
+
pre["loc"].each do |loc|
|
118
|
+
href = loc["xlink:href"]
|
119
|
+
unless href.index("#").nil?
|
120
|
+
locators[loc["xlink:label"]]= href[href.index("#")+1, href.length]
|
121
|
+
else
|
122
|
+
locators[loc["xlink:label"]]=href
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
arc_map={}
|
127
|
+
|
128
|
+
contexts = Set.new()
|
129
|
+
|
130
|
+
pre["presentationArc"].each do |arc|
|
131
|
+
from_label, to_label = nil, nil
|
132
|
+
unless @label_linkbase.nil?
|
133
|
+
to_label = fetch_label(locators[arc["xlink:to"]], arc["preferredLabel"])
|
134
|
+
from_label = fetch_label(locators[arc["xlink:from"]], arc["preferredLabel"])
|
135
|
+
end
|
136
|
+
|
137
|
+
to = Presentation::PresentationArc.new(arc["xlink:to"], locators[arc["xlink:to"]], arc["xlink:arcrole"], arc["order"], arc["priority"], arc["use"], to_label)
|
138
|
+
from = Presentation::PresentationArc.new(arc["xlink:from"], locators[arc["xlink:from"]], role=nil, order=nil, priority=nil, use=nil, label=from_label)
|
139
|
+
|
140
|
+
to_item_name = locators[arc["xlink:to"]].gsub(/.*_/, "")
|
141
|
+
from_item_name = locators[arc["xlink:from"]].gsub(/.*_/, "")
|
142
|
+
|
143
|
+
to_item_map=item_map(@instance.item(to_item_name), dimensions)
|
144
|
+
to.items=to_item_map.values
|
145
|
+
contexts.merge(to_item_map.keys)
|
146
|
+
|
147
|
+
from_item_map=item_map(@instance.item(from_item_name), dimensions)
|
148
|
+
from.items=from_item_map.values
|
149
|
+
contexts.merge(from_item_map.keys)
|
150
|
+
|
151
|
+
if arc_map.has_key?(from)
|
152
|
+
arc_map[from] << to
|
153
|
+
else
|
154
|
+
arc_map[from]=[to]
|
155
|
+
end
|
156
|
+
end
|
157
|
+
return {"contexts" => contexts, "arcs" => Linkbase.build_relationship(arc_map)}
|
158
|
+
end
|
159
|
+
|
160
|
+
|
161
|
+
private
|
162
|
+
def item_map(items, dimensions=[])
|
163
|
+
item_map={}
|
164
|
+
items.each do |item|
|
165
|
+
if dimensions.size>0
|
166
|
+
dims=item.context.dimensions
|
167
|
+
item_map[item.context]=item if (dimensions-dims).size != dimensions.size && (not item.value.nil?)
|
168
|
+
else
|
169
|
+
item_map[item.context]=item unless item.context.has_explicit_dimensions? || item.value.nil?
|
170
|
+
end
|
171
|
+
end unless items.nil?
|
172
|
+
item_map
|
173
|
+
end
|
174
|
+
|
175
|
+
public
|
176
|
+
class Presentation < Linkbase::Link
|
177
|
+
|
178
|
+
attr_reader :contexts, :definition, :instance, :dimensions, :entity_details
|
179
|
+
|
180
|
+
def initialize(entity_details, title, role, href=nil, contexts=nil, arcs=nil, definition=nil, instance=nil, dimensions=[])
|
181
|
+
super("Presentation", title, role, href, arcs)
|
182
|
+
@entity_details=entity_details
|
183
|
+
@contexts=contexts
|
184
|
+
@definition=definition
|
185
|
+
@instance=instance
|
186
|
+
@dimensions=dimensions
|
187
|
+
end
|
188
|
+
|
189
|
+
def has_dimensions?
|
190
|
+
return @dimensions.size>0
|
191
|
+
end
|
192
|
+
|
193
|
+
class PresentationArc < Linkbase::Link::Arc
|
194
|
+
attr_reader :use
|
195
|
+
|
196
|
+
def initialize(item_id, href, role=nil, order=nil, priority=nil, use=nil, label=nil)
|
197
|
+
super item_id, href, role, order, priority, label
|
198
|
+
@use=use
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#
|
3
|
+
# Author:: xbrlware@bitstat.com
|
4
|
+
#
|
5
|
+
# Copyright:: 2009, 2010 bitstat (http://www.bitstat.com). All Rights Reserved.
|
6
|
+
#
|
7
|
+
# License:: Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
16
|
+
# implied.
|
17
|
+
# See the License for the specific language governing permissions and
|
18
|
+
# limitations under the License.
|
19
|
+
#
|
20
|
+
module Xbrlware
|
21
|
+
module MetaUtil # :nodoc:
|
22
|
+
def self.introduce_instance_var(o, i_var_name, i_var_value)
|
23
|
+
o.instance_variable_set("@#{i_var_name}", i_var_value)
|
24
|
+
o.instance_eval %{
|
25
|
+
def #{i_var_name}
|
26
|
+
self.instance_variable_get("@#{i_var_name}")
|
27
|
+
end
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.introduce_instance_writer(o, method_name, i_var_name)
|
32
|
+
o.instance_eval %{
|
33
|
+
def #{method_name}=(value)
|
34
|
+
self.instance_variable_set("@#{i_var_name}", value)
|
35
|
+
end
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.introduce_instance_alias(o, alias_name, actual_name)
|
40
|
+
o.instance_eval %{
|
41
|
+
alias :#{alias_name} :#{actual_name}
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.eval_on_instance(o, method_block)
|
46
|
+
p "#{o.class}"
|
47
|
+
o.instance_eval method_block
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|