datacite-mapping 0.2.4 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +27 -11
  3. data/.ruby-version +1 -1
  4. data/CHANGES.md +25 -0
  5. data/Gemfile +2 -0
  6. data/LICENSE.md +1 -1
  7. data/README.md +10 -5
  8. data/Rakefile +5 -3
  9. data/datacite-mapping.gemspec +10 -9
  10. data/examples/reading.rb +1 -1
  11. data/examples/writing.rb +1 -0
  12. data/lib/datacite/mapping/affiliation.rb +44 -0
  13. data/lib/datacite/mapping/alternate_identifier.rb +6 -2
  14. data/lib/datacite/mapping/contributor.rb +35 -7
  15. data/lib/datacite/mapping/contributor_name.rb +42 -0
  16. data/lib/datacite/mapping/creator.rb +43 -9
  17. data/lib/datacite/mapping/creator_name.rb +42 -0
  18. data/lib/datacite/mapping/date.rb +17 -5
  19. data/lib/datacite/mapping/date_value.rb +10 -2
  20. data/lib/datacite/mapping/description.rb +10 -4
  21. data/lib/datacite/mapping/empty_filtering_nodes.rb +3 -0
  22. data/lib/datacite/mapping/funding_reference.rb +31 -10
  23. data/lib/datacite/mapping/geo_location.rb +8 -1
  24. data/lib/datacite/mapping/geo_location_box.rb +17 -10
  25. data/lib/datacite/mapping/geo_location_node.rb +12 -8
  26. data/lib/datacite/mapping/geo_location_point.rb +11 -6
  27. data/lib/datacite/mapping/geo_location_polygon.rb +13 -2
  28. data/lib/datacite/mapping/identifier.rb +18 -14
  29. data/lib/datacite/mapping/module_info.rb +5 -3
  30. data/lib/datacite/mapping/name_identifier.rb +12 -6
  31. data/lib/datacite/mapping/name_type.rb +18 -0
  32. data/lib/datacite/mapping/namespace_extensions.rb +2 -0
  33. data/lib/datacite/mapping/publisher.rb +42 -0
  34. data/lib/datacite/mapping/read_only_nodes.rb +9 -3
  35. data/lib/datacite/mapping/related_identifier.rb +43 -4
  36. data/lib/datacite/mapping/resource.rb +37 -21
  37. data/lib/datacite/mapping/resource_type.rb +7 -1
  38. data/lib/datacite/mapping/rights.rb +35 -6
  39. data/lib/datacite/mapping/subject.rb +7 -4
  40. data/lib/datacite/mapping/title.rb +7 -4
  41. data/lib/datacite/mapping.rb +3 -1
  42. data/spec/.rubocop.yml +3 -0
  43. data/spec/data/datacite4/{datacite-example-Box_dateCollected_DataCollector-v4.0.xml → datacite-example-Box_dateCollected_DataCollector-v4.xml} +9 -11
  44. data/spec/data/datacite4/{datacite-example-GeoLocation-v4.0.xml → datacite-example-GeoLocation-v4.xml} +11 -10
  45. data/spec/data/datacite4/{datacite-example-HasMetadata-v4.0.xml → datacite-example-HasMetadata-v4.xml} +18 -13
  46. data/spec/data/datacite4/{datacite-example-ResearchGroup_Methods-v4.0.xml → datacite-example-ResearchGroup_Methods-v4.xml} +14 -12
  47. data/spec/data/datacite4/{datacite-example-ResourceTypeGeneral_Collection-v4.0.xml → datacite-example-ResourceTypeGeneral_Collection-v4.xml} +9 -9
  48. data/spec/data/datacite4/datacite-example-affiliation-v4.xml +114 -0
  49. data/spec/data/datacite4/{datacite-example-complicated-v4.0.xml → datacite-example-complicated-v4.xml} +14 -11
  50. data/spec/data/datacite4/datacite-example-datapaper-v4.xml +32 -0
  51. data/spec/data/datacite4/{datacite-example-dataset-v4.0.xml → datacite-example-dataset-v4.xml} +20 -14
  52. data/spec/data/datacite4/datacite-example-full-v4.xml +114 -0
  53. data/spec/data/datacite4/{datacite-example-fundingReference-v.4.0.xml → datacite-example-fundingReference-v4.xml} +16 -13
  54. data/spec/data/datacite4/datacite-example-polygon-advanced-v4.xml +141 -0
  55. data/spec/data/datacite4/datacite-example-polygon-v4.xml +161 -0
  56. data/spec/data/datacite4/{datacite-example-relationTypeIsIdenticalTo-v4.0.xml → datacite-example-relationTypeIsIdenticalTo-v4.xml} +17 -17
  57. data/spec/data/datacite4/datacite-example-software-v4.xml +66 -0
  58. data/spec/data/datacite4/{datacite-example-video-v4.0.xml → datacite-example-video-v4.xml} +7 -7
  59. data/spec/data/datacite4/{datacite-example-workflow-v4.0.xml → datacite-example-workflow-v4.xml} +13 -11
  60. data/spec/data/datacite4/metadata.xsd +102 -57
  61. data/spec/rspec_custom_matchers.rb +11 -8
  62. data/spec/spec_helper.rb +2 -0
  63. data/spec/unit/datacite/mapping/alternate_identifier_spec.rb +2 -0
  64. data/spec/unit/datacite/mapping/contributor_spec.rb +9 -1
  65. data/spec/unit/datacite/mapping/creator_spec.rb +11 -3
  66. data/spec/unit/datacite/mapping/date_spec.rb +2 -0
  67. data/spec/unit/datacite/mapping/date_value_spec.rb +2 -0
  68. data/spec/unit/datacite/mapping/description_spec.rb +2 -0
  69. data/spec/unit/datacite/mapping/funding_reference_spec.rb +13 -1
  70. data/spec/unit/datacite/mapping/geo_location_box_spec.rb +2 -0
  71. data/spec/unit/datacite/mapping/geo_location_point_spec.rb +2 -0
  72. data/spec/unit/datacite/mapping/geo_location_polygon_spec.rb +22 -20
  73. data/spec/unit/datacite/mapping/geo_location_spec.rb +24 -22
  74. data/spec/unit/datacite/mapping/identifier_spec.rb +8 -6
  75. data/spec/unit/datacite/mapping/name_identifier_spec.rb +2 -0
  76. data/spec/unit/datacite/mapping/related_identifier_spec.rb +2 -0
  77. data/spec/unit/datacite/mapping/resource_spec.rb +34 -33
  78. data/spec/unit/datacite/mapping/rights_spec.rb +3 -14
  79. data/spec/unit/datacite/mapping/subject_spec.rb +2 -0
  80. data/spec/unit/datacite/mapping/title_spec.rb +2 -0
  81. metadata +74 -60
  82. data/spec/data/datacite4/datacite-example-full-v4.0.xml +0 -71
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: e8d570ed19b36949ccbd477c42b99eb16decca70
4
- data.tar.gz: 3f9608fb7b9520b69bfc5a4f802d36d3cfeba96b
2
+ SHA256:
3
+ metadata.gz: 8775fcefefd2e9b7d31347a04a0495018109f239f1710c45a909c0c6a00f3a7d
4
+ data.tar.gz: 2d2ff543b99b85846be3c8d322f41967038cb836b83e2d8db6dba3ff7bafb4d8
5
5
  SHA512:
6
- metadata.gz: 1a4d62507b31e9a3c3086ae9a4f2721c7e8539d0e08d49ccff037e85eaca7a2b740d3055791ba81f8df5589e01ca0ab04d90beec3881c979039a58f874a06a4a
7
- data.tar.gz: 56f0d8270aca2b12cca28998fca293490d8cb30ff89f4af1274fbb571bb81bd1a99d50f978cf42b6e1532ec4e573ebdecaf8e5b067978d5bc5dfb1b6b839cfeb
6
+ metadata.gz: 54c5fc88e7ec891b088feff0022dcf89b8cbe8408e1fe6e2de6de76695e5c074397061210378a22c51d1db6653eccd07fe01076fea6807e49d199b8b73c98f90
7
+ data.tar.gz: 419006f6182826184d8a009552aac66aa59355422e679c43c56ce6b6f399fe21507b2c170800ddc5633135f49171cba54734c3f6fe9d70fc3a741d598594afd4
data/.rubocop.yml CHANGED
@@ -1,28 +1,44 @@
1
- # Disable compact style check for example.rb
2
- Style/ClassAndModuleChildren:
3
- Exclude:
4
- - 'example.rb'
5
-
6
1
  # Disable line-length check; it's too easy for the cure to be worse than the disease
7
2
  Metrics/LineLength:
8
3
  Enabled: False
9
4
 
5
+ # Disable parameter-length check; this is determined by the number of XML attributes defined in the DataCite schema
6
+ Metrics/ParameterLists:
7
+ Enabled: False
8
+
10
9
  # Disable problematic module documentation check (see https://github.com/bbatsov/rubocop/issues/947)
11
10
  Style/Documentation:
12
11
  Enabled: false
13
12
 
14
- # Allow one line around class body (Style/EmptyLines will still disallow two or more)
15
- Style/EmptyLinesAroundClassBody:
13
+ # Allow one line around class body (Layout/EmptyLines will still disallow two or more)
14
+ Layout/EmptyLinesAroundClassBody:
16
15
  Enabled: false
17
16
 
18
- # Allow one line around module body (Style/EmptyLines will still disallow two or more)
19
- Style/EmptyLinesAroundModuleBody:
17
+ # Allow one line around module body (Layout/EmptyLines will still disallow two or more)
18
+ Layout/EmptyLinesAroundModuleBody:
20
19
  Enabled: false
21
20
 
22
- # Allow one line around block body (Style/EmptyLines will still disallow two or more)
23
- Style/EmptyLinesAroundBlockBody:
21
+ # Allow one line around block body (Layout/EmptyLines will still disallow two or more)
22
+ Layout/EmptyLinesAroundBlockBody:
24
23
  Enabled: false
25
24
 
26
25
  # Allow leading underscores for 'internal' accessors
27
26
  Lint/UnderscorePrefixedVariableName:
28
27
  Enabled: false
28
+
29
+ # Seriously?
30
+ Style/CommentedKeyword:
31
+ Enabled: false
32
+
33
+ # Use DateTime to preserve compatibility
34
+ Style/DateTime:
35
+ Enabled: false
36
+
37
+ # Disable some checks in sample code
38
+ Style/ClassAndModuleChildren:
39
+ Exclude:
40
+ - 'examples/*'
41
+
42
+ Style/MixinUsage:
43
+ Exclude:
44
+ - 'examples/*'
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.2.3
1
+ 2.6.6
data/CHANGES.md CHANGED
@@ -1,3 +1,28 @@
1
+ ## 0.4.0 (12 November 2019
2
+
3
+ - Datacite 4.3 support:
4
+ - Added the new elements and attributes introduced in DataCite 4.1, 4.2, and 4.3.
5
+ - Updated sample DataCite XML documents to include the new examples introduced in DataCite 4.3.
6
+ - Reading from XML still supports any version of the DataCite schema from 3.0 through 4.3.
7
+ - Object mapping for some items was updated to use full objects instead of simple Strings
8
+ when the DataCite schema introduced more complicated structure. E.g., because ContributorName
9
+ can now include a nameType and an xml:lang, the simple "name" String in the Contributor object was
10
+ replaced with a ContributorName object, accessed through Contributor.contributor_name, while
11
+ Contributor.name is now a convenience method that allows access to the value as a String.
12
+ - These updates to the gem are fully backwards compatible with respect to the input/output XML, but some changes in the object
13
+ model were required to support the more complex XML. So ruby code that worked with version 0.3.0 will require minor updates to use
14
+ this version.
15
+
16
+ ## 0.3.0 (2 January 2018)
17
+
18
+ - Update to Ruby 2.4.1
19
+ - Update to RuboCop 0.52
20
+
21
+ ## 0.2.5 (10 January 2017)
22
+
23
+ - Update to Ruby 2.2.5
24
+ - Treat blank or empty award number as nil when constructing a `FundingReference`.
25
+
1
26
  ## 0.2.4 (8 November 2016)
2
27
 
3
28
  - Fix issue where writing a resource in Datacite 3 would cause the Datacite 3 namespace
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  gemspec
data/LICENSE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2016 The Regents of the University of California
3
+ Copyright (c) 2018 The Regents of the University of California
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining
6
6
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -10,9 +10,14 @@ based on [xml-mapping](http://multi-io.github.io/xml-mapping/) and
10
10
  [xml-mapping_extensions](https://github.com/dmolesUC3/xml-mapping_extensions).
11
11
  Full API documentation on [RubyDoc.info](http://www.rubydoc.info/github/CDLUC3/datacite-mapping/master/frames).
12
12
 
13
- Supports [Datacite 4.0](https://schema.labs.datacite.org/meta/kernel-4.0/); backward-compatible with
13
+ Supports [Datacite 4.3](https://schema.labs.datacite.org/meta/kernel-4.3/); backward-compatible with
14
14
  [Datacite 3.1](https://schema.labs.datacite.org/meta/kernel-3/).
15
15
 
16
+ Note that although this gem maintains compatibility with multiple
17
+ versions of DataCite XML, changes to DataCite XML sometimes force
18
+ changes to the internal object model of the gem. So different versions
19
+ of this gem may require minor updates to how a part of the model is accessed.
20
+
16
21
  ## Usage
17
22
 
18
23
  The core of the Datacite::Mapping library is the `Resource` class, corresponding to the root `<resource/>` element
@@ -37,17 +42,17 @@ Example:
37
42
  require 'datacite/mapping'
38
43
  include Datacite::Mapping
39
44
 
40
- resource = Resource.load_from_file('datacite-example-full-v4.0.xml')
45
+ resource = Resource.load_from_file('datacite-example-full-v4.3.xml')
41
46
  # => #<Datacite::Mapping::Resource:0x007f97689e87a0 …
42
47
 
43
48
  abstract = resource.descriptions.find { |d| d.type = DescriptionType::ABSTRACT }
44
49
  # => #<Datacite::Mapping::Description:0x007f976aafa330 …
45
50
  abstract.value
46
- # => "XML example of all DataCite Metadata Schema v4.0 properties."
51
+ # => "XML example of all DataCite Metadata Schema v4.3 properties."
47
52
  ```
48
53
 
49
- Note that Datacite::Mapping uses the `TypesafeEnum` gem to represent controlled vocabularies such
50
- as [ResourceTypeGeneral](http://www.rubydoc.info/github/CDLUC3/datacite-mapping/master/Datacite/Mapping/ResourceTypeGeneral)
54
+ Note that Datacite::Mapping uses the [TypesafeEnum](https://github.com/dmolesUC3/typesafe_enum) gem to represent controlled
55
+ vocabularies such as [ResourceTypeGeneral](http://www.rubydoc.info/github/CDLUC3/datacite-mapping/master/Datacite/Mapping/ResourceTypeGeneral)
51
56
  and [DescriptionType](http://www.rubydoc.info/github/CDLUC3/datacite-mapping/master/Datacite/Mapping/DescriptionType).
52
57
 
53
58
  ### Writing
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # ------------------------------------------------------------
2
4
  # RSpec
3
5
 
@@ -8,7 +10,7 @@ namespace :spec do
8
10
 
9
11
  desc 'Run all unit tests'
10
12
  RSpec::Core::RakeTask.new(:unit) do |task|
11
- task.rspec_opts = %w(--color --format documentation --order default)
13
+ task.rspec_opts = %w[--color --format documentation --order default]
12
14
  task.pattern = 'unit/**/*_spec.rb'
13
15
  end
14
16
 
@@ -38,7 +40,7 @@ RuboCop::RakeTask.new
38
40
 
39
41
  desc 'List TODOs (from spec/todo.rb)'
40
42
  RSpec::Core::RakeTask.new(:todo) do |task|
41
- task.rspec_opts = %w(--color --format documentation --order default)
43
+ task.rspec_opts = %w[--color --format documentation --order default]
42
44
  task.pattern = 'todo.rb'
43
45
  end
44
46
 
@@ -46,4 +48,4 @@ end
46
48
  # Defaults
47
49
 
48
50
  desc 'Run unit tests, check test coverage, run acceptance tests, check code style'
49
- task default: [:coverage, :rubocop]
51
+ task default: %i[coverage rubocop]
@@ -1,5 +1,6 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
5
 
5
6
  require 'uri'
@@ -15,7 +16,7 @@ Gem::Specification.new do |spec|
15
16
  spec.license = 'MIT'
16
17
 
17
18
  origin = `git config --get remote.origin.url`.chomp
18
- origin_uri = origin.start_with?('http') ? URI(origin) : URI(origin.sub('git@github.com:', 'https://github.com/'))
19
+ origin_uri = origin.start_with?('http') ? URI(origin) : URI(origin.gsub(%r{git@([^:]+)(.com|.org)[^\/]+}, 'http://\1\2'))
19
20
  spec.homepage = URI::HTTP.build(host: origin_uri.host, path: origin_uri.path.chomp('.git')).to_s
20
21
 
21
22
  spec.files = `git ls-files -z`.split("\x0")
@@ -27,14 +28,14 @@ Gem::Specification.new do |spec|
27
28
  spec.add_dependency 'typesafe_enum', '~> 0.1', '>= 0.1.7'
28
29
  spec.add_dependency 'xml-mapping_extensions', '~> 0.4', '>= 0.4.7'
29
30
 
30
- spec.add_development_dependency 'bundler', '~> 1.7'
31
+ spec.add_development_dependency 'bundler', '>= 2.2.33'
31
32
  spec.add_development_dependency 'equivalent-xml', '~> 0.6.0'
32
- spec.add_development_dependency 'rake', '~> 10.4'
33
+ spec.add_development_dependency 'github-markup', '~> 1.4'
34
+ spec.add_development_dependency 'rake', '>= 12.3.3'
35
+ spec.add_development_dependency 'redcarpet', '~> 3.3'
33
36
  spec.add_development_dependency 'rspec', '~> 3.2'
37
+ spec.add_development_dependency 'rubocop', '~> 0.52'
34
38
  spec.add_development_dependency 'simplecov', '~> 0.9.2'
35
39
  spec.add_development_dependency 'simplecov-console', '~> 0.2.0'
36
- spec.add_development_dependency 'rubocop', '~> 0.32.1'
37
- spec.add_development_dependency 'redcarpet', '~> 3.3'
38
- spec.add_development_dependency 'github-markup', '~> 1.4'
39
- spec.add_development_dependency 'yard', '~> 0.8'
40
+ spec.add_development_dependency 'yard', '~> 0.9'
40
41
  end
data/examples/reading.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- # coding: UTF-8
2
+ # frozen_string_literal: true
3
3
 
4
4
  require 'datacite/mapping'
5
5
  include Datacite::Mapping
data/examples/writing.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'datacite/mapping'
4
5
  include Datacite::Mapping
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'xml/mapping'
4
+ require 'datacite/mapping/read_only_nodes'
5
+
6
+ module Datacite
7
+ module Mapping
8
+ class Affiliation
9
+ include XML::Mapping
10
+
11
+ def initialize(identifier: nil, identifier_scheme: nil, scheme_uri: nil, value:)
12
+ self.identifier = identifier
13
+ self.identifier_scheme = identifier_scheme
14
+ self.scheme_uri = scheme_uri
15
+ self.value = value
16
+ end
17
+
18
+ def value=(value)
19
+ new_value = value&.strip
20
+ raise ArgumentError, 'Value cannot be empty or nil' unless new_value && !new_value.empty?
21
+
22
+ @value = new_value.strip
23
+ end
24
+
25
+ # @!attribute [rw] identifier
26
+ # @return [String, nil] The affiliation identifier. Optional.
27
+ text_node :identifier, '@affiliationIdentifier', default_value: nil
28
+
29
+ # @!attribute [rw] identifier_scheme
30
+ # @return [String, nil] The scheme for the affiliation identifier. Optional.
31
+ text_node :identifier_scheme, '@affiliationIdentifierScheme', default_value: nil
32
+
33
+ # @!attribute [rw] scheme_uri
34
+ # @return [URI, nil] the URI of the identifier scheme. Optional.
35
+ uri_node :scheme_uri, '@schemeURI', default_value: nil
36
+
37
+ # @!attribute [rw] value
38
+ # @return [String] the name itself.
39
+ text_node :value, 'text()'
40
+
41
+ fallback_mapping :datacite_3, :_default
42
+ end
43
+ end
44
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'xml/mapping_extensions'
2
4
 
3
5
  module Datacite
@@ -19,14 +21,16 @@ module Datacite
19
21
  # Sets the type. Cannot be nil.
20
22
  # @param val [String] the identifier type
21
23
  def type=(val)
22
- fail ArgumentError, 'No identifier type provided' unless val
24
+ raise ArgumentError, 'No identifier type provided' unless val
25
+
23
26
  @type = val
24
27
  end
25
28
 
26
29
  # Sets the value. Cannot be nil.
27
30
  # @param val [String] the value
28
31
  def value=(val)
29
- fail ArgumentError, 'No identifier value provided' unless val
32
+ raise ArgumentError, 'No identifier value provided' unless val
33
+
30
34
  @value = val
31
35
  end
32
36
 
@@ -1,5 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'xml/mapping_extensions'
2
4
  require 'datacite/mapping/name_identifier'
5
+ require 'datacite/mapping/contributor_name'
3
6
 
4
7
  module Datacite
5
8
  module Mapping
@@ -91,20 +94,45 @@ module Datacite
91
94
  self.type = type
92
95
  end
93
96
 
97
+ # name can be entered as a string or a ContributorName object, but it will be stored
98
+ # internally as a ContributorName object
94
99
  def name=(value)
95
- new_value = value && value.strip
96
- fail ArgumentError, 'Name cannot be empty or nil' unless new_value && !new_value.empty?
97
- @name = new_value
100
+ raise ArgumentError, 'Name cannot be empty or nil' unless value
101
+
102
+ @contributor_name = if value.is_a?(ContributorName)
103
+ value
104
+ else
105
+ ContributorName.new(value: value)
106
+ end
107
+ end
108
+
109
+ def contributor_name=(value)
110
+ raise ArgumentError, 'ContributorName cannot be empty or nil' unless value
111
+
112
+ @contributor_name = value
113
+ end
114
+
115
+ def name
116
+ @contributor_name&.value
98
117
  end
99
118
 
100
119
  def type=(value)
101
- fail ArgumentError, 'Type cannot be nil' unless value
120
+ raise ArgumentError, 'Type cannot be nil' unless value
121
+
102
122
  @type = value
103
123
  end
104
124
 
105
125
  # @!attribute [rw] name
106
- # @return [String] the personal name of the contributor, in the format `Family, Given`. Cannot be empty or nil
107
- text_node :name, 'contributorName'
126
+ # @return [String] The personal name of the creator, in the format `Family, Given`. Cannot be empty or nil.
127
+ object_node :contributor_name, 'contributorName', class: ContributorName
128
+
129
+ # @!attribute [rw] given_name
130
+ # @return [String, nil] The given name of the creator. Optional.
131
+ text_node :given_name, 'givenName', default_value: nil
132
+
133
+ # @!attribute [rw] family_name
134
+ # @return [String, nil] The family name of the creator. Optional.
135
+ text_node :family_name, 'familyName', default_value: nil
108
136
 
109
137
  # @!attribute [rw] identifier
110
138
  # @return [NameIdentifier, nil] an identifier for the contributor. Optional.
@@ -112,7 +140,7 @@ module Datacite
112
140
 
113
141
  # @!attribute [rw] affiliations
114
142
  # @return [Array<String>] the contributor's affiliations. Defaults to an empty list.
115
- array_node :affiliations, 'affiliation', class: String, default_value: []
143
+ array_node :affiliations, 'affiliation', class: Affiliation, default_value: []
116
144
 
117
145
  # @!attribute [rw] type
118
146
  # @return [ContributorType] the contributor type. Cannot be nil.
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'xml/mapping'
4
+ require 'datacite/mapping/read_only_nodes'
5
+ require 'datacite/mapping/name_identifier'
6
+ require 'datacite/mapping/name_type'
7
+
8
+ module Datacite
9
+ module Mapping
10
+ class ContributorName
11
+ include XML::Mapping
12
+ def initialize(type: nil, language: nil, value:)
13
+ self.type = type
14
+ self.language = language
15
+ self.value = value
16
+ end
17
+
18
+ def language=(value)
19
+ @language = value&.strip
20
+ end
21
+
22
+ def value=(value)
23
+ new_value = value&.strip
24
+ raise ArgumentError, 'Value cannot be empty or nil' unless new_value && !new_value.empty?
25
+
26
+ @value = new_value.strip
27
+ end
28
+
29
+ # @!attribute [rw] type
30
+ # @return [NameType, nil] the name type. Optional.
31
+ typesafe_enum_node :type, '@nameType', class: NameType, default_value: nil
32
+
33
+ # @!attribute [rw] language
34
+ # @return [String, nil] an IETF BCP 47, ISO 639-1 language code identifying the language.
35
+ text_node :language, '@xml:lang', default_value: nil
36
+
37
+ # @!attribute [rw] value
38
+ # @return [String] the name itself.
39
+ text_node :value, 'text()'
40
+ end
41
+ end
42
+ end
@@ -1,9 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'xml/mapping'
2
4
  require 'datacite/mapping/read_only_nodes'
3
5
  require 'datacite/mapping/name_identifier'
6
+ require 'datacite/mapping/creator_name'
7
+ require 'datacite/mapping/affiliation'
4
8
 
5
9
  module Datacite
6
10
  module Mapping
11
+
7
12
  # The main researchers involved working on the data, or the authors of the publication in priority order.
8
13
  class Creator
9
14
  include XML::Mapping
@@ -13,7 +18,7 @@ module Datacite
13
18
  # @param given_name [String, nil] The given name of the creator. Optional.
14
19
  # @param given_name [String, nil] The family name of the creator. Optional.
15
20
  # @param identifier [NameIdentifier, nil] An identifier for the creator. Optional.
16
- # @param affiliations [Array<String>, nil] The creator's affiliations. Defaults to an empty list.
21
+ # @param affiliations [Array<Affiliation>, nil] The creator's affiliations. Defaults to an empty list.
17
22
  def initialize(name:, given_name: nil, family_name: nil, identifier: nil, affiliations: [])
18
23
  self.name = name
19
24
  self.given_name = given_name
@@ -22,29 +27,58 @@ module Datacite
22
27
  self.affiliations = affiliations
23
28
  end
24
29
 
30
+ # name can be entered as a string or a CreatorName object, but it will be stored
31
+ # internally as a CreatorName object
25
32
  def name=(value)
26
- new_value = value && value.strip
27
- fail ArgumentError, 'Name cannot be empty or nil' unless new_value && !new_value.empty?
28
- @name = new_value
33
+ raise ArgumentError, 'Name cannot be empty or nil' unless value
34
+
35
+ @creator_name = if value.is_a?(CreatorName)
36
+ value
37
+ else
38
+ CreatorName.new(value: value)
39
+ end
40
+ end
41
+
42
+ def creator_name=(value)
43
+ raise ArgumentError, 'CreatorName cannot be empty or nil' unless value
44
+
45
+ @creator_name = value
46
+ end
47
+
48
+ def name
49
+ @creator_name&.value
29
50
  end
30
51
 
31
52
  def given_name=(value)
32
- new_value = value && value.strip
53
+ new_value = value&.strip
33
54
  @given_name = new_value
34
55
  end
35
56
 
36
57
  def family_name=(value)
37
- new_value = value && value.strip
58
+ new_value = value&.strip
38
59
  @family_name = new_value
39
60
  end
40
61
 
62
+ # Affiliations can be entered as an array of Strings or an array of Affiliation objects,
63
+ # but will be stored internally as an array of Affiliation objects
41
64
  def affiliations=(value)
42
- @affiliations = value || []
65
+ @affiliations = []
66
+ value&.each do |affil|
67
+ @affiliations << if affil.is_a?(Affiliation)
68
+ affil
69
+ else
70
+ Affiliation.new(value: affil)
71
+ end
72
+ end
73
+ end
74
+
75
+ def affiliation_names
76
+ @affiliations.map { |affil| affil&.value }
43
77
  end
44
78
 
45
79
  # @!attribute [rw] name
46
80
  # @return [String] The personal name of the creator, in the format `Family, Given`. Cannot be empty or nil.
47
- text_node :name, 'creatorName'
81
+ object_node :creator_name, 'creatorName', class: CreatorName
48
82
 
49
83
  # @!attribute [rw] given_name
50
84
  # @return [String, nil] The given name of the creator. Optional.
@@ -60,7 +94,7 @@ module Datacite
60
94
 
61
95
  # @!attribute [rw] affiliations
62
96
  # @return [Array<String>, nil] The creator's affiliations. Defaults to an empty list.
63
- array_node :affiliations, 'affiliation', class: String, default_value: []
97
+ array_node :affiliations, 'affiliation', class: Affiliation, default_value: []
64
98
 
65
99
  use_mapping :datacite_3
66
100
 
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'xml/mapping'
4
+ require 'datacite/mapping/read_only_nodes'
5
+ require 'datacite/mapping/name_identifier'
6
+ require 'datacite/mapping/name_type'
7
+
8
+ module Datacite
9
+ module Mapping
10
+ class CreatorName
11
+ include XML::Mapping
12
+ def initialize(type: nil, language: nil, value:)
13
+ self.type = type
14
+ self.language = language
15
+ self.value = value
16
+ end
17
+
18
+ def language=(value)
19
+ @language = value&.strip
20
+ end
21
+
22
+ def value=(value)
23
+ new_value = value&.strip
24
+ raise ArgumentError, 'Value cannot be empty or nil' unless new_value && !new_value.empty?
25
+
26
+ @value = new_value.strip
27
+ end
28
+
29
+ # @!attribute [rw] type
30
+ # @return [NameType, nil] the name type. Optional.
31
+ typesafe_enum_node :type, '@nameType', class: NameType, default_value: nil
32
+
33
+ # @!attribute [rw] language
34
+ # @return [String] an IETF BCP 47, ISO 639-1 language code identifying the language.
35
+ text_node :language, '@xml:lang', default_value: nil
36
+
37
+ # @!attribute [rw] value
38
+ # @return [String] the name itself.
39
+ text_node :value, 'text()'
40
+ end
41
+ end
42
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'xml/mapping_extensions'
2
4
 
3
5
  require 'datacite/mapping/date_value'
@@ -25,6 +27,9 @@ module Datacite
25
27
  # @!parse ISSUED = Issued
26
28
  new :ISSUED, 'Issued'
27
29
 
30
+ # @!parse OTHER = Other
31
+ new :OTHER, 'Other'
32
+
28
33
  # @!parse SUBMITTED = Submitted
29
34
  new :SUBMITTED, 'Submitted'
30
35
 
@@ -34,6 +39,9 @@ module Datacite
34
39
  # @!parse VALID = Valid
35
40
  new :VALID, 'Valid'
36
41
 
42
+ # @!parse WITHDRAWN = Withdrawn
43
+ new :WITHDRAWN, 'Withdrawn'
44
+
37
45
  end
38
46
 
39
47
  # Represents a DataCite `<date/>` field, which can be a year, date (year-month-day or just year-month),
@@ -67,7 +75,8 @@ module Datacite
67
75
  end
68
76
 
69
77
  def type=(val)
70
- fail ArgumentError, 'Date type cannot be nil' unless val
78
+ raise ArgumentError, 'Date type cannot be nil' unless val
79
+
71
80
  @type = val
72
81
  end
73
82
 
@@ -80,14 +89,15 @@ module Datacite
80
89
  @range_start, @range_end = parts.map(&:strip).map { |part| DateValue.new(part) unless part == '' }
81
90
  # puts "#{val} -> [#{range_start}, #{range_end}]"
82
91
  else
83
- fail ArgumentError, "Unable to parse date value #{val}"
92
+ raise ArgumentError, "Unable to parse date value #{val}"
84
93
  end
85
94
  @value = date_value ? date_value.to_s : "#{range_start}/#{range_end}"
86
95
  end
87
96
 
88
97
  def <=>(other)
89
98
  return nil unless other.class == self.class
90
- [:date_value, :range_start, :range_end, :type].each do |v|
99
+
100
+ %i[date_value range_start range_end type].each do |v|
91
101
  order = send(v) <=> other.send(v)
92
102
  return order if order.nonzero?
93
103
  end
@@ -102,12 +112,14 @@ module Datacite
102
112
  @value
103
113
  end
104
114
 
105
- private
106
-
107
115
  # @!attribute [rw] type
108
116
  # @return [DateType] the type of date. Cannot be nil.
109
117
  typesafe_enum_node :type, '@dateType', class: DateType
110
118
 
119
+ # @!attribute [rw] date_information
120
+ # @return [String] information to clarify a date
121
+ text_node :date_information, '@dateInformation', default_value: nil
122
+
111
123
  # @!method value
112
124
  # @return [String] The value as a string. May be any [W3C DateTime format](http://www.w3.org/TR/NOTE-datetime).
113
125
  text_node :value, 'text()'