gooddata 0.6.4 → 0.6.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.markdown +4 -0
  3. data/README.md +1 -0
  4. data/lib/gooddata/cli/commands/project_cmd.rb +2 -7
  5. data/lib/gooddata/client.rb +0 -2
  6. data/lib/gooddata/commands/project.rb +10 -0
  7. data/lib/gooddata/core/rest.rb +12 -2
  8. data/lib/gooddata/exceptions/attr_element_not_found.rb +12 -0
  9. data/lib/gooddata/extensions/enumerable.rb +12 -0
  10. data/lib/gooddata/helpers/global_helpers.rb +20 -0
  11. data/lib/gooddata/mixins/author.rb +16 -0
  12. data/lib/gooddata/mixins/content_getter.rb +11 -0
  13. data/lib/gooddata/mixins/content_property_reader.rb +13 -0
  14. data/lib/gooddata/mixins/content_property_writer.rb +13 -0
  15. data/lib/gooddata/mixins/contributor.rb +16 -0
  16. data/lib/gooddata/mixins/data_getter.rb +11 -0
  17. data/lib/gooddata/mixins/data_property_reader.rb +13 -0
  18. data/lib/gooddata/mixins/data_property_writer.rb +13 -0
  19. data/lib/gooddata/mixins/is_attribute.rb +13 -0
  20. data/lib/gooddata/mixins/is_fact.rb +13 -0
  21. data/lib/gooddata/mixins/is_label.rb +15 -0
  22. data/lib/gooddata/mixins/links.rb +11 -0
  23. data/lib/gooddata/mixins/md_finders.rb +36 -0
  24. data/lib/gooddata/mixins/md_id_to_uri.rb +29 -0
  25. data/lib/gooddata/mixins/md_json.rb +11 -0
  26. data/lib/gooddata/mixins/md_object_id.rb +11 -0
  27. data/lib/gooddata/mixins/md_object_indexer.rb +36 -0
  28. data/lib/gooddata/mixins/md_object_query.rb +83 -0
  29. data/lib/gooddata/mixins/md_relations.rb +39 -0
  30. data/lib/gooddata/mixins/meta_getter.rb +11 -0
  31. data/lib/gooddata/mixins/meta_property_reader.rb +13 -0
  32. data/lib/gooddata/mixins/meta_property_writer.rb +13 -0
  33. data/lib/gooddata/mixins/mixins.rb +15 -0
  34. data/lib/gooddata/mixins/not_attribute.rb +13 -0
  35. data/lib/gooddata/mixins/not_exportable.rb +11 -0
  36. data/lib/gooddata/mixins/not_fact.rb +13 -0
  37. data/lib/gooddata/mixins/not_label.rb +15 -0
  38. data/lib/gooddata/mixins/not_metric.rb +13 -0
  39. data/lib/gooddata/mixins/obj_id.rb +11 -0
  40. data/lib/gooddata/mixins/rest_getters.rb +13 -0
  41. data/lib/gooddata/mixins/rest_resource.rb +19 -0
  42. data/lib/gooddata/mixins/root_key_getter.rb +11 -0
  43. data/lib/gooddata/mixins/root_key_setter.rb +11 -0
  44. data/lib/gooddata/mixins/timestamps.rb +15 -0
  45. data/lib/gooddata/models/from_wire.rb +153 -0
  46. data/lib/gooddata/models/metadata.rb +28 -230
  47. data/lib/gooddata/models/metadata/attribute.rb +4 -6
  48. data/lib/gooddata/models/metadata/fact.rb +4 -6
  49. data/lib/gooddata/models/metadata/{display_form.rb → label.rb} +17 -11
  50. data/lib/gooddata/models/metadata/metric.rb +1 -1
  51. data/lib/gooddata/models/metadata/report_definition.rb +2 -2
  52. data/lib/gooddata/models/model.rb +55 -23
  53. data/lib/gooddata/models/models.rb +0 -2
  54. data/lib/gooddata/models/module_constants.rb +0 -2
  55. data/lib/gooddata/models/process.rb +1 -1
  56. data/lib/gooddata/models/project.rb +117 -76
  57. data/lib/gooddata/models/project_blueprint.rb +322 -42
  58. data/lib/gooddata/models/project_creator.rb +5 -4
  59. data/lib/gooddata/models/project_role.rb +20 -55
  60. data/lib/gooddata/models/schema_blueprint.rb +287 -84
  61. data/lib/gooddata/models/schema_builder.rb +0 -4
  62. data/lib/gooddata/models/to_manifest.rb +160 -0
  63. data/lib/gooddata/models/to_wire.rb +150 -0
  64. data/lib/gooddata/version.rb +1 -1
  65. data/spec/data/blueprint_invalid.json +3 -1
  66. data/spec/data/gd_gse_data_blueprint.json +1370 -0
  67. data/spec/data/gd_gse_data_manifest.json +1424 -0
  68. data/spec/data/gd_gse_data_model.json +1772 -0
  69. data/spec/data/manifest_test_project.json +116 -0
  70. data/spec/data/model_view.json +1772 -0
  71. data/spec/data/superfluous_titles_view.json +81 -0
  72. data/spec/data/test_project_model_spec.json +7 -4
  73. data/spec/data/wire_test_project.json +143 -0
  74. data/spec/helpers/crypto_helper.rb +9 -0
  75. data/spec/helpers/project_helper.rb +2 -0
  76. data/spec/integration/command_projects_spec.rb +4 -2
  77. data/spec/integration/full_project_spec.rb +51 -18
  78. data/spec/integration/partial_md_export_import_spec.rb +1 -1
  79. data/spec/spec_helper.rb +2 -1
  80. data/spec/unit/models/attribute_column_spec.rb +7 -7
  81. data/spec/unit/models/domain_spec.rb +2 -2
  82. data/spec/unit/models/from_wire_spec.rb +119 -0
  83. data/spec/unit/models/metadata_spec.rb +4 -2
  84. data/spec/unit/models/project_blueprint_spec.rb +32 -16
  85. data/spec/unit/models/project_role_spec.rb +6 -4
  86. data/spec/unit/models/project_spec.rb +26 -3
  87. data/spec/unit/models/schema_builder_spec.rb +5 -6
  88. data/spec/unit/models/to_manifest_spec.rb +24 -0
  89. data/spec/unit/models/to_wire_spec.rb +63 -0
  90. metadata +53 -29
  91. data/lib/gooddata/models/attributes/anchor.rb +0 -37
  92. data/lib/gooddata/models/attributes/attributes.rb +0 -8
  93. data/lib/gooddata/models/attributes/date_attribute.rb +0 -25
  94. data/lib/gooddata/models/attributes/time_attribute.rb +0 -24
  95. data/lib/gooddata/models/columns/attribute.rb +0 -71
  96. data/lib/gooddata/models/columns/columns.rb +0 -8
  97. data/lib/gooddata/models/columns/date_column.rb +0 -63
  98. data/lib/gooddata/models/columns/fact_model.rb +0 -54
  99. data/lib/gooddata/models/columns/label.rb +0 -55
  100. data/lib/gooddata/models/columns/reference.rb +0 -57
  101. data/lib/gooddata/models/facts/facts.rb +0 -8
  102. data/lib/gooddata/models/facts/time_fact.rb +0 -20
  103. data/lib/gooddata/models/folders/attribute_folder.rb +0 -20
  104. data/lib/gooddata/models/folders/fact_folder.rb +0 -20
  105. data/lib/gooddata/models/folders/folders.rb +0 -8
  106. data/lib/gooddata/models/metadata/column.rb +0 -61
  107. data/lib/gooddata/models/metadata/data_set.rb +0 -32
  108. data/lib/gooddata/models/metadata/date_dimension.rb +0 -26
  109. data/lib/gooddata/models/metadata/schema.rb +0 -227
  110. data/lib/gooddata/models/references/date_reference.rb +0 -44
  111. data/lib/gooddata/models/references/references.rb +0 -8
  112. data/lib/gooddata/models/references/time_reference.rb +0 -13
  113. data/spec/helpers/schema_helper.rb +0 -16
  114. data/spec/unit/models/anchor_spec.rb +0 -32
  115. data/spec/unit/models/tools_spec.rb +0 -95
  116. data/test/test_upload.rb +0 -79
@@ -0,0 +1,83 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Mixin
5
+ module MdObjectQuery
6
+ # Method intended to get all objects of that type in a specified project
7
+ #
8
+ # @param options [Hash] the options hash
9
+ # @option options [Boolean] :full if passed true the subclass can decide to pull in full objects. This is desirable from the usability POV but unfortunately has negative impact on performance so it is not the default
10
+ # @return [Array<GoodData::MdObject> | Array<Hash>] Return the appropriate metadata objects or their representation
11
+ def all(options = {})
12
+ fail NotImplementedError, 'Method should be implemented in subclass. Currently there is no way hoe to get all metadata objects on API.'
13
+ end
14
+
15
+ # Method intended to be called by individual classes in their all
16
+ # implementations. It abstracts the way interacting with query resources.
17
+ # It either returns the array of hashes from query. If asked it also
18
+ # goes and brings the full objects. Due to performance reasons
19
+ # :full => false is the default. This will most likely change
20
+ #
21
+ # @param query_obj_type [String] string used in URI to distinguish different query resources for different objects
22
+ # @param klass [Class] A class used for instantiating the returned data
23
+ # @param options [Hash] the options hash
24
+ # @option options [Boolean] :full if passed true the subclass can decide to pull in full objects. This is desirable from the usability POV but unfortunately has negative impact on performance so it is not the default
25
+ # @return [Array<GoodData::MdObject> | Array<Hash>] Return the appropriate metadata objects or their representation
26
+ def query(query_obj_type, klass, options = {})
27
+ fail(NoProjectError, 'Connect to a project before searching for an object') unless GoodData.project
28
+ query_result = GoodData.get(GoodData.project.md['query'] + "/#{query_obj_type}/")['query']['entries']
29
+ options[:full] ? query_result.map { |item| klass[item['link']] } : query_result
30
+ end
31
+
32
+ def dependency(uri, key = nil)
33
+ result = GoodData.get(uri)['entries']
34
+ if key.nil?
35
+ result
36
+ elsif key.respond_to?(:category)
37
+ result.select { |item| item['category'] == key.category }
38
+ else
39
+ result.select { |item| item['category'] == key }
40
+ end
41
+ end
42
+
43
+ # Checks for dependency
44
+ def dependency?(type, uri, target_uri)
45
+ uri = uri.respond_to?(:uri) ? uri.uri : uri
46
+ objs = case type
47
+ when :usedby
48
+ usedby(uri)
49
+ when :using
50
+ using(uri)
51
+ end
52
+
53
+ target_uri = target_uri.respond_to?(:uri) ? target_uri.uri : target_uri
54
+ objs.any? do |obj|
55
+ obj['link'] == target_uri
56
+ end
57
+ end
58
+
59
+ # Returns which objects uses this MD resource
60
+ def usedby(uri, key = nil, project = GoodData.project)
61
+ dependency("#{project.md['usedby2']}/#{obj_id(uri)}", key)
62
+ end
63
+
64
+ alias_method :used_by, :usedby
65
+
66
+ # Returns which objects this MD resource uses
67
+ def using(uri, key = nil)
68
+ dependency("#{GoodData.project.md['using2']}/#{obj_id(uri)}", key)
69
+ end
70
+
71
+ def usedby?(uri, target_uri)
72
+ dependency?(:usedby, uri, target_uri)
73
+ end
74
+
75
+ alias_method :used_by?, :usedby?
76
+
77
+ # Checks if obj is using this MD resource
78
+ def using?(uri, target_uri)
79
+ dependency?(:using, uri, target_uri)
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,39 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Mixin
5
+ module MdRelations
6
+ def dependency(uri, key = nil)
7
+ GoodData::MdObject.dependency(uri, key)
8
+ end
9
+
10
+ # Checks for dependency
11
+ def dependency?(type, obj)
12
+ GoodData::MdObject.dependency?(type, self, obj)
13
+ end
14
+
15
+ # Returns which objects uses this MD resource
16
+ def usedby(key = nil, project = GoodData.project)
17
+ dependency("#{project.md['usedby2']}/#{obj_id}", key)
18
+ end
19
+
20
+ alias_method :used_by, :usedby
21
+
22
+ # Returns which objects this MD resource uses
23
+ def using(key = nil)
24
+ dependency("#{GoodData.project.md['using2']}/#{obj_id}", key)
25
+ end
26
+
27
+ def usedby?(obj)
28
+ GoodData::MdObject.used_by?(self, obj)
29
+ end
30
+
31
+ alias_method :used_by?, :usedby?
32
+
33
+ # Checks if obj is using this MD resource
34
+ def using?(obj)
35
+ dependency?(:using, obj)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Mixin
5
+ module MetaGetter
6
+ def meta
7
+ data && data['meta']
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Mixin
5
+ module MetaPropertyReader
6
+ def metadata_property_reader(*props)
7
+ props.each do |prop|
8
+ define_method prop, proc { meta[prop.to_s] }
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Mixin
5
+ module MetaPropertyWriter
6
+ def metadata_property_writer(*props)
7
+ props.each do |prop|
8
+ define_method "#{prop}=", proc { |val| meta[prop.to_s] = val }
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'pathname'
4
+
5
+ base = Pathname(__FILE__).dirname.expand_path
6
+ Dir.glob(base + '*.rb').each do |file|
7
+ blacklist = [
8
+ File.join(base, 'rest_getters.rb'),
9
+ File.join(base, 'rest_resource.rb')
10
+ ]
11
+
12
+ require file unless blacklist.include? file
13
+ end
14
+ require_relative 'rest_getters'
15
+ require_relative 'rest_resource'
@@ -0,0 +1,13 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Mixin
5
+ module NotAttribute
6
+ # Returns true if the object is a fact false otherwise
7
+ # @return [Boolean]
8
+ def attribute?
9
+ false
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Mixin
5
+ module NotExportable
6
+ def exportable?
7
+ false
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Mixin
5
+ module NotFact
6
+ # Returns true if the object is a fact false otherwise
7
+ # @return [Boolean]
8
+ def fact?
9
+ false
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Mixin
5
+ module NotLabel
6
+ # Returns true if the object is a fact label otherwise
7
+ # @return [Boolean]
8
+ def label?
9
+ false
10
+ end
11
+
12
+ alias_method :display_form?, :label?
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Mixin
5
+ module NotMetric
6
+ # Returns true if the object is a metric false otherwise
7
+ # @return [Boolean]
8
+ def metric?
9
+ false
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Mixin
5
+ module ObjId
6
+ def obj_id
7
+ uri.split('/').last
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: UTF-8
2
+
3
+ require_relative 'data_getter'
4
+ require_relative 'meta_getter'
5
+
6
+ module GoodData
7
+ module Mixin
8
+ module RestGetters
9
+ include GoodData::Mixin::MetaGetter
10
+ include GoodData::Mixin::DataGetter
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: UTF-8
2
+
3
+ require_relative 'root_key_setter'
4
+ require_relative 'data_property_reader'
5
+ require_relative 'data_property_writer'
6
+ require_relative 'meta_property_reader'
7
+ require_relative 'meta_property_reader'
8
+
9
+ module GoodData
10
+ module Mixin
11
+ module RestResource
12
+ include GoodData::Mixin::RootKeySetter
13
+ include GoodData::Mixin::DataPropertyReader
14
+ include GoodData::Mixin::DataPropertyWriter
15
+ include GoodData::Mixin::MetaPropertyReader
16
+ include GoodData::Mixin::MetaPropertyWriter
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Mixin
5
+ module RootKeyGetter
6
+ def root_key
7
+ raw_data.keys.first
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Mixin
5
+ module RootKeySetter
6
+ def root_key(a_key)
7
+ define_method :root_key, proc { a_key.to_s }
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Mixin
5
+ module Timestamps
6
+ def updated
7
+ Time.parse(meta['updated'])
8
+ end
9
+
10
+ def created
11
+ Time.parse(meta['created'])
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,153 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Model
5
+ module FromWire
6
+ # Converts dataset from wire format into an internal blueprint representation
7
+ #
8
+ # @param stuff [Hash] Whatever comes from wire
9
+ # @return [Hash] Manifest for a particular reference
10
+ def self.dataset_from_wire(stuff)
11
+ Hash.new.tap do |d|
12
+ d[:type] = :dataset
13
+ d[:title] = stuff['dataset']['title'] if stuff['dataset']['title'] != stuff['dataset']['identifier'].split('.').last.titleize
14
+ d[:name] = stuff['dataset']['identifier'].split('.').last
15
+ d[:columns] = (parse_anchor(stuff) + parse_attributes(stuff) + parse_facts(stuff) + parse_references(stuff))
16
+ end
17
+ end
18
+
19
+ # Entry method for converting information about project mode from wire
20
+ # format into an internal blueprint representation
21
+ #
22
+ # @param stuff [Hash] Whatever comes from wire
23
+ # @return [GoodData::Model::ProjectBlueprint] Manifest for a particular reference
24
+ def self.from_wire(stuff)
25
+ model = stuff['projectModelView']['model']['projectModel']
26
+ datasets = model['datasets'] || []
27
+ dims = model['dateDimensions'] || []
28
+ ProjectBlueprint.new(
29
+ datasets: datasets.map { |ds| dataset_from_wire(ds) },
30
+ date_dimensions: dims.map { |dd| parse_date_dimensions(dd) }
31
+ )
32
+ end
33
+
34
+ # Converts anchor from wire format into an internal blueprint representation
35
+ #
36
+ # @param stuff [Hash] Whatever comes from wire
37
+ # @return [Hash] Manifest for a particular reference
38
+ def self.parse_anchor(stuff)
39
+ attribute = stuff['dataset']['anchor']['attribute']
40
+ if !attribute.key?('labels')
41
+ []
42
+ else
43
+ labels = attribute['labels'] || []
44
+ default_label = attribute['defaultLabel']
45
+ primary_label_name = attribute['identifier'].split('.').last
46
+ dataset_name = attribute['identifier'].split('.')[1]
47
+ primary_label_identifier = GoodData::Model.identifier_for({ name: dataset_name }, type: :primary_label, name: primary_label_name)
48
+ primary_labels, regular_labels = labels.partition { |x| x['label']['identifier'] == primary_label_identifier }
49
+ dl = primary_labels.map do |label|
50
+ parse_label(attribute, label, 'anchor', default_label)
51
+ end
52
+ rl = regular_labels.map do |label|
53
+ parse_label(attribute, label, 'label', default_label)
54
+ end
55
+ dl + rl
56
+ end
57
+ end
58
+
59
+ # Converts attrbutes from wire format into an internal blueprint representation
60
+ #
61
+ # @param stuff [Hash] Whatever comes from wire
62
+ # @return [Hash] Manifest for a particular reference
63
+ def self.parse_attributes(stuff)
64
+ dataset = stuff['dataset']
65
+ attributes = dataset['attributes'] || []
66
+ attributes.mapcat do |a|
67
+ attribute = a['attribute']
68
+ labels = attribute['labels'] || []
69
+ default_label = attribute['defaultLabel']
70
+ primary_label_name = attribute['identifier'].split('.').last
71
+ dataset_name = attribute['identifier'].split('.')[1]
72
+ primary_label_identifier = GoodData::Model.identifier_for({ name: dataset_name }, type: :primary_label, name: primary_label_name)
73
+ primary_labels, regular_labels = labels.partition { |x| x['label']['identifier'] == primary_label_identifier }
74
+ dl = primary_labels.map do |label|
75
+ parse_label(attribute, label, 'attribute', default_label)
76
+ end
77
+ rl = regular_labels.map do |label|
78
+ parse_label(attribute, label, 'label', default_label)
79
+ end
80
+ dl + rl
81
+ end
82
+ end
83
+
84
+ # Converts date dimensions from wire format into an internal blueprint representation
85
+ #
86
+ # @param stuff [Hash] Whatever comes from wire
87
+ # @return [Hash] Manifest for a particular reference
88
+ def self.parse_date_dimensions(stuff)
89
+ Hash.new.tap do |d|
90
+ d[:type] = :date_dimension
91
+ # d[:urn] = :date_dimension
92
+ d[:name] = stuff['dateDimension']['name']
93
+ d[:title] = stuff['dateDimension']['title'] if stuff['dateDimension']['title'] != stuff['dateDimension']['title'].titleize
94
+ end
95
+ end
96
+
97
+ # Converts facts from wire format into an internal blueprint representation
98
+ #
99
+ # @param stuff [Hash] Whatever comes from wire
100
+ # @return [Hash] Manifest for a particular reference
101
+ def self.parse_facts(stuff)
102
+ facts = stuff['dataset']['facts'] || []
103
+ facts.map do |fact|
104
+ Hash.new.tap do |f|
105
+ f[:type] = fact['fact']['identifier'] =~ /^dt\./ ? :date_fact : :fact
106
+ f[:name] = fact['fact']['identifier'].split('.').last
107
+ f[:title] = fact['fact']['title'] if fact['fact']['title'] != fact['fact']['identifier'].split('.').last.titleize
108
+ f[:gd_data_type] = fact['fact']['dataType'] if fact['fact'].key?('dataType')
109
+ end
110
+ end
111
+ end
112
+
113
+ # Converts label from wire format into an internal blueprint representation
114
+ #
115
+ # @param stuff [Hash] Whatever comes from wire
116
+ # @return [Hash] Manifest for a particular reference
117
+ def self.parse_label(attribute, label, type, default_label = nil)
118
+ Hash.new.tap do |l|
119
+ l[:type] = type
120
+ l[:reference] = attribute['identifier'].split('.').last if type == 'label'
121
+ l[:name] = label['label']['identifier'].split('.').last
122
+ l[:title] = label['label']['title'] if label['label']['title'] != label['label']['identifier'].split('.').last.titleize
123
+ l[:gd_data_type] = label['label']['dataType'] if label['label'].key?('dataType')
124
+ l[:gd_type] = label['label']['type'] if label['label'].key?('type')
125
+ l[:default_label] = true if default_label == label['label']['identifier']
126
+ end
127
+ end
128
+
129
+ # Converts label from wire format into an internal blueprint representation
130
+ #
131
+ # @param stuff [Hash] Whatever comes from wire
132
+ # @return [Hash] Manifest for a particular reference
133
+ def self.parse_references(stuff)
134
+ references = stuff['dataset']['references'] || []
135
+ references.map do |ref|
136
+ if ref =~ /^dataset\./
137
+ {
138
+ :type => :reference,
139
+ :name => ref.gsub('dataset.', ''),
140
+ :dataset => ref.gsub('dataset.', '')
141
+ }
142
+ else
143
+ {
144
+ :type => :date,
145
+ :name => ref.gsub('dataset.', ''),
146
+ :dataset => ref.gsub('dataset.', '')
147
+ }
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end
153
+ end