diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7779003..833b59b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,6 +2,11 @@ # See https://github.com/metanorma/cimas name: release +permissions: + contents: write + packages: write + id-token: write + on: workflow_dispatch: inputs: @@ -16,10 +21,8 @@ on: jobs: release: - uses: metanorma/ci/.github/workflows/rubygems-release.yml@main + uses: relaton/support/.github/workflows/release.yml@main with: next_version: ${{ github.event.inputs.next_version }} secrets: - rubygems-api-key: ${{ secrets.METANORMA_CI_RUBYGEMS_API_KEY }} - pat_token: ${{ secrets.METANORMA_CI_PAT_TOKEN }} - + rubygems-api-key: ${{ secrets.LUTAML_CI_RUBYGEMS_API_KEY }} diff --git a/.rubocop.yml b/.rubocop.yml index 762eebb..7ee1ffb 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,8 +1,19 @@ -AllCops: - TargetRubyVersion: 3.0 +# Auto-generated by Cimas: Do not edit it manually! +# See https://github.com/metanorma/cimas +inherit_from: + - https://raw.githubusercontent.com/riboseinc/oss-guides/main/ci/rubocop.yml + - .rubocop_todo.yml + +inherit_mode: + merge: + - Exclude -Style/StringLiterals: - EnforcedStyle: double_quotes +# local repo-specific modifications +# ... +plugins: + - rubocop-rspec + - rubocop-performance + - rubocop-rake -Style/StringLiteralsInInterpolation: - EnforcedStyle: double_quotes +AllCops: + TargetRubyVersion: 3.0 diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml new file mode 100644 index 0000000..3189721 --- /dev/null +++ b/.rubocop_todo.yml @@ -0,0 +1,241 @@ +# This configuration was generated by +# `rubocop --auto-gen-config` +# on 2026-04-01 07:11:02 UTC using RuboCop version 1.86.0. +# The point is for the user to remove these configuration records +# one by one as the offenses are removed from the code base. +# Note that changes in the inspected code, or installation of new +# versions of RuboCop, may require this file to be generated again. + +# Offense count: 17 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: TreatCommentsAsGroupSeparators, ConsiderPunctuation. +Bundler/OrderedGems: + Exclude: + - 'Gemfile' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: TreatCommentsAsGroupSeparators, ConsiderPunctuation. +Gemspec/OrderedDependencies: + Exclude: + - 'reqif.gemspec' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +Gemspec/RequireMFA: + Exclude: + - 'reqif.gemspec' + +# Offense count: 63 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle, IndentationWidth. +# SupportedStyles: with_first_argument, with_fixed_indentation +Layout/ArgumentAlignment: + Exclude: + - 'lib/reqif.rb' + - 'lib/reqif/datatypes.rb' + - 'lib/reqif/default_value.rb' + - 'lib/reqif/definition.rb' + - 'lib/reqif/doors/readonly_attributes.rb' + - 'lib/reqif/editable_atts.rb' + - 'lib/reqif/reqif_float.rb' + - 'lib/reqif/spec_attributes.rb' + - 'lib/reqif/type.rb' + - 'lib/reqif/values.rb' + +# Offense count: 2 +# This cop supports safe autocorrection (--autocorrect). +Layout/ClosingParenthesisIndentation: + Exclude: + - 'spec/reqif/polarion_export_spec.rb' + - 'spec/spec_helper.rb' + +# Offense count: 22 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AllowForAlignment. +Layout/CommentIndentation: + Exclude: + - 'lib/reqif/doors/module_definition.rb' + - 'lib/reqif/doors/readonly_attributes.rb' + - 'lib/reqif/doors/rif_definition.rb' + - 'lib/reqif/req_if_tool_extension.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +Layout/ElseAlignment: + Exclude: + - 'spec/spec_helper.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: empty_lines, empty_lines_except_namespace, empty_lines_special, no_empty_lines, beginning_only, ending_only +Layout/EmptyLinesAroundClassBody: + Exclude: + - 'lib/reqif/req_if_tool_extension.rb' + +# Offense count: 2 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle, IndentationWidth. +# SupportedStyles: consistent, consistent_relative_to_receiver, special_for_inner_method_call, special_for_inner_method_call_in_parentheses +Layout/FirstArgumentIndentation: + Exclude: + - 'spec/reqif/polarion_export_spec.rb' + - 'spec/spec_helper.rb' + +# Offense count: 4 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: normal, indented_internal_methods +Layout/IndentationConsistency: + Exclude: + - 'lib/reqif/doors/readonly_attributes.rb' + - 'reqif.gemspec' + +# Offense count: 10 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: Width, EnforcedStyleAlignWith, AllowedPatterns. +# SupportedStylesAlignWith: start_of_line, relative_to_receiver +Layout/IndentationWidth: + Exclude: + - 'lib/reqif/doors/readonly_attributes.rb' + - 'spec/spec_helper.rb' + +# Offense count: 78 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings. +# URISchemes: http, https +Layout/LineLength: + Enabled: false + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: symmetrical, new_line, same_line +Layout/MultilineMethodCallBraceLayout: + Exclude: + - 'spec/reqif/polarion_export_spec.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle, IndentationWidth. +# SupportedStyles: aligned, indented +Layout/MultilineOperationIndentation: + Exclude: + - 'spec/reqif_spec.rb' + +# Offense count: 8 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: final_newline, final_blank_line +Layout/TrailingEmptyLines: + Exclude: + - 'lib/reqif/doors/identifier.rb' + - 'lib/reqif/doors/module_definition.rb' + - 'lib/reqif/doors/namespace.rb' + - 'lib/reqif/doors/readonly_attributes.rb' + - 'lib/reqif/doors/rif_definition.rb' + - 'lib/reqif/doors/string_type.rb' + - 'lib/reqif/string_type.rb' + - 'lib/reqif/xhtml/namespace.rb' + +# Offense count: 63 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AllowInHeredoc. +Layout/TrailingWhitespace: + Exclude: + - 'lib/reqif.rb' + - 'lib/reqif/datatypes.rb' + - 'lib/reqif/default_value.rb' + - 'lib/reqif/definition.rb' + - 'lib/reqif/doors/readonly_attributes.rb' + - 'lib/reqif/editable_atts.rb' + - 'lib/reqif/reqif_float.rb' + - 'lib/reqif/spec_attributes.rb' + - 'lib/reqif/type.rb' + - 'lib/reqif/values.rb' + +# Offense count: 1 +# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode. +# AllowedMethods: refine +Metrics/BlockLength: + Max: 90 + +# Offense count: 1 +# Configuration parameters: AllowedMethods, AllowedPatterns, Max. +Metrics/CyclomaticComplexity: + Exclude: + - 'lib/reqif/reqif_float.rb' + +# Offense count: 3 +# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. +Metrics/MethodLength: + Max: 12 + +# Offense count: 1 +# Configuration parameters: IgnoredMetadata. +RSpec/DescribeClass: + Exclude: + - 'spec/reqif/polarion_export_spec.rb' + +# Offense count: 4 +# Configuration parameters: CountAsOne. +RSpec/ExampleLength: + Max: 11 + +# Offense count: 11 +RSpec/MultipleExpectations: + Max: 8 + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: not_to, to_not +RSpec/NotToNot: + Exclude: + - 'spec/reqif/polarion_export_spec.rb' + +# Offense count: 2 +# Configuration parameters: CustomTransform, IgnoreMethods, IgnoreMetadata, InflectorPath, EnforcedInflector. +# SupportedInflectors: default, active_support +RSpec/SpecFilePathFormat: + Exclude: + - 'spec/reqif/data_types_spec.rb' + - 'spec/reqif/tool_extension_spec.rb' + +# Offense count: 2 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: separated, grouped +Style/AccessorGrouping: + Exclude: + - 'lib/reqif/high_precision_date_time.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AllowIfModifier. +Style/IfInsideElse: + Exclude: + - 'spec/spec_helper.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +Style/MultilineIfModifier: + Exclude: + - 'lib/reqif/reqif_float.rb' + +# Offense count: 2 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline. +# SupportedStyles: single_quotes, double_quotes +Style/StringLiterals: + Exclude: + - 'reqif.gemspec' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyleForMultiline. +# SupportedStylesForMultiline: comma, consistent_comma, diff_comma, no_comma +Style/TrailingCommaInArguments: + Exclude: + - 'spec/reqif/req_if_spec.rb' diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..03c4d13 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,73 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Overview + +This is a Ruby gem (`reqif`) that parses and generates ReqIF (Requirements Interchange Format) XML documents. ReqIF is an OMG standard (v1.2) for exchanging requirements between different tools. The gem is part of the `lutaml` family. + +## Commands + +```bash +bundle install # Install dependencies +bundle exec rake # Run specs + rubocop (default) +bundle exec rake spec # Run specs only +bundle exec rake rubocop # Run linter only +bundle exec rspec spec/reqif_spec.rb # Run a single spec file +bundle exec bin/console # Start an IRB console with the gem loaded +``` + +## Architecture + +### Framework: lutaml/model + +All model classes inherit from `Lutaml::Model::Serializable` and use an `xml` DSL block to define XML serialization. The gem uses `Lutaml::Model::XmlAdapter::NokogiriAdapter` for XML parsing/generation. + +### Class-per-file pattern + +Each ReqIF concept is a separate class in `lib/reqif/`. Classes follow a consistent structure: + +```ruby +module Reqif + class Foo < Lutaml::Model::Serializable + attribute :bar, :string + attribute :baz, SomeOtherClass + + xml do + element "FOO" + namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + map_attribute "BAR", to: :bar + map_element "BAZ", to: :baz + end + end +end +``` + +### Key model classes + +- `ReqIf` — Root element, contains `THE-HEADER`, `CORE-CONTENT`, `TOOL-EXTENSIONS` +- `ReqIfContent` — Contains `DATATYPES`, `SPEC-TYPES`, `SPEC-OBJECTS`, `SPEC-RELATIONS`, `SPECIFICATIONS`, `SPEC-RELATION-GROUPS` +- `SpecObject` — A single requirement with attributes (identifier, long_name, desc, etc.) and `VALUES` +- `Specification` — A container/hierarchy that has `CHILDREN` referencing other specs +- `SpecRelation` — A relation between two specs with `SOURCE` and `TARGET` references +- `Values` — Container for `AttributeValue` elements (boolean, date, enumeration, integer, real, string, xhtml) +- `Type` / `SpecObjectType` / `SpecificationType` — Type definitions for spec objects/specifications +- `Datatypes` — Container for datatype definitions (boolean, date, enumeration, integer, real, string, xhtml) + +### Attribute naming conventions + +XML element names use uppercase-kebab-case (e.g., `SPEC-OBJECT`, `LAST-CHANGE`) while Ruby attributes use snake_case (e.g., `spec_object`, `last_change`). The `map_element` and `map_attribute` DSL methods handle the translation. + +### Autoloading + +Zeitwerk is used for autoloading. `lib/reqif.rb` sets up the loader and eager loads all classes. + +### XML round-trip testing + +Round-trip tests in `spec/reqif_spec.rb` parse fixture XML files, regenerate XML via `to_xml`, and compare canonicalization using `xml-c14n`. All fixture files under `spec/fixtures/` (`.xml`, `.reqif`) are automatically included. + +### Style + +- String literals: double quotes enforced by RuboCop +- Ruby version: 3.0+ +- Frozen string literals: required at the top of every file diff --git a/Gemfile b/Gemfile index fbb8f2c..25c379a 100644 --- a/Gemfile +++ b/Gemfile @@ -5,9 +5,12 @@ source "https://rubygems.org" # Specify your gem's dependencies in reqif.gemspec gemspec +gem "canon" +gem "lutaml-model", github: "lutaml/lutaml-model", branch: "main" +gem "nokogiri" gem "rake", "~> 13.0" gem "rspec", "~> 3.0" gem "rubocop", "~> 1.21" -gem "nokogiri" gem "rubocop-performance" -gem "xml-c14n" +gem "rubocop-rake" +gem "rubocop-rspec" diff --git a/lib/reqif.rb b/lib/reqif.rb index ecb43b2..7f33cc0 100644 --- a/lib/reqif.rb +++ b/lib/reqif.rb @@ -2,21 +2,77 @@ require "lutaml/model" -Lutaml::Model::Config.configure do |config| - require "lutaml/model/xml_adapter/nokogiri_adapter" - config.xml_adapter = Lutaml::Model::XmlAdapter::NokogiriAdapter -end - module Reqif class Error < StandardError; end - # Your code goes here... + autoload :AlternativeId, "reqif/alternative_id.rb" + autoload :AttributeDefinitionBoolean, "reqif/attribute_definition_boolean.rb" + autoload :AttributeDefinitionDate, "reqif/attribute_definition_date.rb" + autoload :AttributeDefinitionEnumeration, + "reqif/attribute_definition_enumeration.rb" + autoload :AttributeDefinitionInteger, "reqif/attribute_definition_integer.rb" + autoload :AttributeDefinitionReal, "reqif/attribute_definition_real.rb" + autoload :AttributeDefinitionString, "reqif/attribute_definition_string.rb" + autoload :AttributeDefinitionXhtml, "reqif/attribute_definition_xhtml.rb" + autoload :AttributeValueBoolean, "reqif/attribute_value_boolean.rb" + autoload :AttributeValueDate, "reqif/attribute_value_date.rb" + autoload :AttributeValueEnumeration, "reqif/attribute_value_enumeration.rb" + autoload :AttributeValueInteger, "reqif/attribute_value_integer.rb" + autoload :AttributeValueReal, "reqif/attribute_value_real.rb" + autoload :AttributeValueString, "reqif/attribute_value_string.rb" + autoload :AttributeValueXhtml, "reqif/attribute_value_xhtml.rb" + autoload :Children, "reqif/children.rb" + autoload :CoreContent, "reqif/core_content.rb" + autoload :DatatypeDefinitionBoolean, "reqif/datatype_definition_boolean.rb" + autoload :DatatypeDefinitionDate, "reqif/datatype_definition_date.rb" + autoload :DatatypeDefinitionEnumeration, + "reqif/datatype_definition_enumeration.rb" + autoload :DatatypeDefinitionInteger, "reqif/datatype_definition_integer.rb" + autoload :DatatypeDefinitionReal, "reqif/datatype_definition_real.rb" + autoload :DatatypeDefinitionString, "reqif/datatype_definition_string.rb" + autoload :DatatypeDefinitionXhtml, "reqif/datatype_definition_xhtml.rb" + autoload :Datatypes, "reqif/datatypes.rb" + autoload :DefaultValue, "reqif/default_value.rb" + autoload :Definition, "reqif/definition.rb" + autoload :Doors, "reqif/doors.rb" + autoload :EditableAtts, "reqif/editable_atts.rb" + autoload :EmbeddedValue, "reqif/embedded_value.rb" + autoload :EnumValue, "reqif/enum_value.rb" + autoload :HighPrecisionDateTime, "reqif/high_precision_date_time.rb" + autoload :Namespace, "reqif/namespace.rb" + autoload :Object, "reqif/object.rb" + autoload :Properties, "reqif/properties.rb" + autoload :RelationGroup, "reqif/relation_group.rb" + autoload :RelationGroupType, "reqif/relation_group_type.rb" + autoload :ReqIf, "reqif/req_if.rb" + autoload :ReqIfContent, "reqif/req_if_content.rb" + autoload :ReqIfHeader, "reqif/req_if_header.rb" + autoload :ReqIfToolExtension, "reqif/req_if_tool_extension.rb" + autoload :ReqifFloat, "reqif/reqif_float.rb" + autoload :ReqifInteger, "reqif/reqif_integer.rb" + autoload :Source, "reqif/source.rb" + autoload :SourceSpecification, "reqif/source_specification.rb" + autoload :SpecAttributes, "reqif/spec_attributes.rb" + autoload :SpecHierarchy, "reqif/spec_hierarchy.rb" + autoload :SpecObject, "reqif/spec_object.rb" + autoload :SpecObjectType, "reqif/spec_object_type.rb" + autoload :SpecObjects, "reqif/spec_objects.rb" + autoload :SpecRelation, "reqif/spec_relation.rb" + autoload :SpecRelationGroups, "reqif/spec_relation_groups.rb" + autoload :SpecRelationType, "reqif/spec_relation_type.rb" + autoload :SpecRelations, "reqif/spec_relations.rb" + autoload :SpecTypes, "reqif/spec_types.rb" + autoload :Specification, "reqif/specification.rb" + autoload :SpecificationType, "reqif/specification_type.rb" + autoload :Specifications, "reqif/specifications.rb" + autoload :SpecifiedValues, "reqif/specified_values.rb" + autoload :StringType, "reqif/string_type.rb" + autoload :Target, "reqif/target.rb" + autoload :TargetSpecification, "reqif/target_specification.rb" + autoload :TheHeader, "reqif/the_header.rb" + autoload :ToolExtensions, "reqif/tool_extensions.rb" + autoload :Type, "reqif/type.rb" + autoload :Values, "reqif/values.rb" + autoload :Xhtml, "reqif/xhtml.rb" + autoload :XhtmlContent, "reqif/xhtml_content.rb" end - -require "zeitwerk" - -loader = Zeitwerk::Loader.for_gem -loader.push_dir(__dir__) #, namespace: Reqif) -loader.ignore("#{__dir__}/reqif.rb") -loader.setup -loader.eager_load diff --git a/lib/reqif/alternative_id.rb b/lib/reqif/alternative_id.rb index 50b41c5..50440ea 100644 --- a/lib/reqif/alternative_id.rb +++ b/lib/reqif/alternative_id.rb @@ -5,8 +5,8 @@ class AlternativeId < Lutaml::Model::Serializable attribute :identifier, :string xml do - root "ALTERNATIVE-ID" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "ALTERNATIVE-ID" + namespace Namespace map_attribute "IDENTIFIER", to: :identifier end diff --git a/lib/reqif/attribute_definition_boolean.rb b/lib/reqif/attribute_definition_boolean.rb index 26c5842..be28209 100644 --- a/lib/reqif/attribute_definition_boolean.rb +++ b/lib/reqif/attribute_definition_boolean.rb @@ -12,10 +12,11 @@ class AttributeDefinitionBoolean < Lutaml::Model::Serializable attribute :type, Type xml do - root "ATTRIBUTE-DEFINITION-BOOLEAN" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "ATTRIBUTE-DEFINITION-BOOLEAN" + namespace Namespace + ordered - map_attribute "DESC", to: :desc + map_attribute "DESC", to: :desc, render_empty: true map_attribute "IDENTIFIER", to: :identifier map_attribute "IS-EDITABLE", to: :is_editable map_attribute "LAST-CHANGE", to: :last_change diff --git a/lib/reqif/attribute_definition_date.rb b/lib/reqif/attribute_definition_date.rb index 1b69393..c14c3dc 100644 --- a/lib/reqif/attribute_definition_date.rb +++ b/lib/reqif/attribute_definition_date.rb @@ -12,10 +12,11 @@ class AttributeDefinitionDate < Lutaml::Model::Serializable attribute :type, Type xml do - root "ATTRIBUTE-DEFINITION-DATE" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "ATTRIBUTE-DEFINITION-DATE" + namespace Namespace + ordered - map_attribute "DESC", to: :desc + map_attribute "DESC", to: :desc, render_empty: true map_attribute "IDENTIFIER", to: :identifier map_attribute "IS-EDITABLE", to: :is_editable map_attribute "LAST-CHANGE", to: :last_change diff --git a/lib/reqif/attribute_definition_enumeration.rb b/lib/reqif/attribute_definition_enumeration.rb index 6b8441d..087bf4b 100644 --- a/lib/reqif/attribute_definition_enumeration.rb +++ b/lib/reqif/attribute_definition_enumeration.rb @@ -13,10 +13,11 @@ class AttributeDefinitionEnumeration < Lutaml::Model::Serializable attribute :type, Type xml do - root "ATTRIBUTE-DEFINITION-ENUMERATION" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "ATTRIBUTE-DEFINITION-ENUMERATION" + namespace Namespace + ordered - map_attribute "DESC", to: :desc + map_attribute "DESC", to: :desc, render_empty: true map_attribute "IDENTIFIER", to: :identifier map_attribute "IS-EDITABLE", to: :is_editable map_attribute "LAST-CHANGE", to: :last_change diff --git a/lib/reqif/attribute_definition_integer.rb b/lib/reqif/attribute_definition_integer.rb index 4d48787..5b3daaa 100644 --- a/lib/reqif/attribute_definition_integer.rb +++ b/lib/reqif/attribute_definition_integer.rb @@ -12,10 +12,11 @@ class AttributeDefinitionInteger < Lutaml::Model::Serializable attribute :type, Type xml do - root "ATTRIBUTE-DEFINITION-INTEGER" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "ATTRIBUTE-DEFINITION-INTEGER" + namespace Namespace + ordered - map_attribute "DESC", to: :desc + map_attribute "DESC", to: :desc, render_empty: true map_attribute "IDENTIFIER", to: :identifier map_attribute "IS-EDITABLE", to: :is_editable map_attribute "LAST-CHANGE", to: :last_change diff --git a/lib/reqif/attribute_definition_real.rb b/lib/reqif/attribute_definition_real.rb index 28f3b0d..fb5a932 100644 --- a/lib/reqif/attribute_definition_real.rb +++ b/lib/reqif/attribute_definition_real.rb @@ -12,10 +12,11 @@ class AttributeDefinitionReal < Lutaml::Model::Serializable attribute :type, Type xml do - root "ATTRIBUTE-DEFINITION-REAL" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "ATTRIBUTE-DEFINITION-REAL" + namespace Namespace + ordered - map_attribute "DESC", to: :desc + map_attribute "DESC", to: :desc, render_empty: true map_attribute "IDENTIFIER", to: :identifier map_attribute "IS-EDITABLE", to: :is_editable map_attribute "LAST-CHANGE", to: :last_change diff --git a/lib/reqif/attribute_definition_string.rb b/lib/reqif/attribute_definition_string.rb index 96db4ec..976b918 100644 --- a/lib/reqif/attribute_definition_string.rb +++ b/lib/reqif/attribute_definition_string.rb @@ -12,10 +12,11 @@ class AttributeDefinitionString < Lutaml::Model::Serializable attribute :type, Type xml do - root "ATTRIBUTE-DEFINITION-STRING" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "ATTRIBUTE-DEFINITION-STRING" + namespace Namespace + ordered - map_attribute "DESC", to: :desc + map_attribute "DESC", to: :desc, render_empty: true map_attribute "IDENTIFIER", to: :identifier map_attribute "IS-EDITABLE", to: :is_editable map_attribute "LAST-CHANGE", to: :last_change diff --git a/lib/reqif/attribute_definition_xhtml.rb b/lib/reqif/attribute_definition_xhtml.rb index 2b79a53..47b53fe 100644 --- a/lib/reqif/attribute_definition_xhtml.rb +++ b/lib/reqif/attribute_definition_xhtml.rb @@ -12,10 +12,11 @@ class AttributeDefinitionXhtml < Lutaml::Model::Serializable attribute :type, Type xml do - root "ATTRIBUTE-DEFINITION-XHTML" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "ATTRIBUTE-DEFINITION-XHTML" + namespace Namespace + ordered - map_attribute "DESC", to: :desc + map_attribute "DESC", to: :desc, render_empty: true map_attribute "IDENTIFIER", to: :identifier map_attribute "IS-EDITABLE", to: :is_editable map_attribute "LAST-CHANGE", to: :last_change diff --git a/lib/reqif/attribute_value_boolean.rb b/lib/reqif/attribute_value_boolean.rb index f78bdb5..2ad49c7 100644 --- a/lib/reqif/attribute_value_boolean.rb +++ b/lib/reqif/attribute_value_boolean.rb @@ -6,8 +6,9 @@ class AttributeValueBoolean < Lutaml::Model::Serializable attribute :definition, Definition xml do - root "ATTRIBUTE-VALUE-BOOLEAN" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "ATTRIBUTE-VALUE-BOOLEAN" + namespace Namespace + ordered map_attribute "THE-VALUE", to: :the_value map_element "DEFINITION", to: :definition diff --git a/lib/reqif/attribute_value_date.rb b/lib/reqif/attribute_value_date.rb index dee0f98..312694b 100644 --- a/lib/reqif/attribute_value_date.rb +++ b/lib/reqif/attribute_value_date.rb @@ -2,12 +2,13 @@ module Reqif class AttributeValueDate < Lutaml::Model::Serializable - attribute :the_value, :date_time + attribute :the_value, HighPrecisionDateTime attribute :definition, Definition xml do - root "ATTRIBUTE-VALUE-DATE" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "ATTRIBUTE-VALUE-DATE" + namespace Namespace + ordered map_attribute "THE-VALUE", to: :the_value map_element "DEFINITION", to: :definition diff --git a/lib/reqif/attribute_value_enumeration.rb b/lib/reqif/attribute_value_enumeration.rb index a8ed824..fa7f0cd 100644 --- a/lib/reqif/attribute_value_enumeration.rb +++ b/lib/reqif/attribute_value_enumeration.rb @@ -6,8 +6,9 @@ class AttributeValueEnumeration < Lutaml::Model::Serializable attribute :values, Values xml do - root "ATTRIBUTE-VALUE-ENUMERATION" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "ATTRIBUTE-VALUE-ENUMERATION" + namespace Namespace + ordered map_element "DEFINITION", to: :definition map_element "VALUES", to: :values diff --git a/lib/reqif/attribute_value_integer.rb b/lib/reqif/attribute_value_integer.rb index fb285bf..889e3f4 100644 --- a/lib/reqif/attribute_value_integer.rb +++ b/lib/reqif/attribute_value_integer.rb @@ -2,12 +2,13 @@ module Reqif class AttributeValueInteger < Lutaml::Model::Serializable - attribute :the_value, :integer + attribute :the_value, ReqifInteger attribute :definition, Definition xml do - root "ATTRIBUTE-VALUE-INTEGER" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "ATTRIBUTE-VALUE-INTEGER" + namespace Namespace + ordered map_attribute "THE-VALUE", to: :the_value map_element "DEFINITION", to: :definition diff --git a/lib/reqif/attribute_value_real.rb b/lib/reqif/attribute_value_real.rb index cf52627..8425a04 100644 --- a/lib/reqif/attribute_value_real.rb +++ b/lib/reqif/attribute_value_real.rb @@ -2,12 +2,13 @@ module Reqif class AttributeValueReal < Lutaml::Model::Serializable - attribute :the_value, :float + attribute :the_value, ReqifFloat attribute :definition, Definition xml do - root "ATTRIBUTE-VALUE-REAL" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "ATTRIBUTE-VALUE-REAL" + namespace Namespace + ordered map_attribute "THE-VALUE", to: :the_value map_element "DEFINITION", to: :definition diff --git a/lib/reqif/attribute_value_string.rb b/lib/reqif/attribute_value_string.rb index fe586ac..d45ce8e 100644 --- a/lib/reqif/attribute_value_string.rb +++ b/lib/reqif/attribute_value_string.rb @@ -6,8 +6,9 @@ class AttributeValueString < Lutaml::Model::Serializable attribute :definition, Definition xml do - root "ATTRIBUTE-VALUE-STRING" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "ATTRIBUTE-VALUE-STRING" + namespace Namespace + ordered map_attribute "THE-VALUE", to: :the_value map_element "DEFINITION", to: :definition diff --git a/lib/reqif/attribute_value_xhtml.rb b/lib/reqif/attribute_value_xhtml.rb index 8100179..1572c0f 100644 --- a/lib/reqif/attribute_value_xhtml.rb +++ b/lib/reqif/attribute_value_xhtml.rb @@ -8,8 +8,9 @@ class AttributeValueXhtml < Lutaml::Model::Serializable attribute :definition, Definition xml do - root "ATTRIBUTE-VALUE-XHTML" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "ATTRIBUTE-VALUE-XHTML" + namespace Namespace + ordered map_attribute "IS-SIMPLIFIED", to: :is_simplified map_element "THE-VALUE", to: :the_value diff --git a/lib/reqif/children.rb b/lib/reqif/children.rb index eb442fb..5de4f60 100644 --- a/lib/reqif/children.rb +++ b/lib/reqif/children.rb @@ -5,8 +5,9 @@ class Children < Lutaml::Model::Serializable attribute :spec_hierarchy, SpecHierarchy, collection: true xml do - root "CHILDREN" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "CHILDREN" + namespace Namespace + ordered map_element "SPEC-HIERARCHY", to: :spec_hierarchy end diff --git a/lib/reqif/core_content.rb b/lib/reqif/core_content.rb index 7f2819e..e97ced5 100644 --- a/lib/reqif/core_content.rb +++ b/lib/reqif/core_content.rb @@ -5,8 +5,9 @@ class CoreContent < Lutaml::Model::Serializable attribute :req_if_content, ReqIfContent xml do - root "CORE-CONTENT" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "CORE-CONTENT" + namespace Namespace + ordered map_element "REQ-IF-CONTENT", to: :req_if_content end diff --git a/lib/reqif/datatype_definition_boolean.rb b/lib/reqif/datatype_definition_boolean.rb index 9619696..89b751b 100644 --- a/lib/reqif/datatype_definition_boolean.rb +++ b/lib/reqif/datatype_definition_boolean.rb @@ -9,10 +9,11 @@ class DatatypeDefinitionBoolean < Lutaml::Model::Serializable attribute :alternative_id, AlternativeId xml do - root "DATATYPE-DEFINITION-BOOLEAN" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "DATATYPE-DEFINITION-BOOLEAN" + namespace Namespace + ordered - map_attribute "DESC", to: :desc + map_attribute "DESC", to: :desc, render_empty: true map_attribute "IDENTIFIER", to: :identifier map_attribute "LAST-CHANGE", to: :last_change map_attribute "LONG-NAME", to: :long_name diff --git a/lib/reqif/datatype_definition_date.rb b/lib/reqif/datatype_definition_date.rb index 3688af4..d29775a 100644 --- a/lib/reqif/datatype_definition_date.rb +++ b/lib/reqif/datatype_definition_date.rb @@ -9,10 +9,11 @@ class DatatypeDefinitionDate < Lutaml::Model::Serializable attribute :alternative_id, AlternativeId xml do - root "DATATYPE-DEFINITION-DATE" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "DATATYPE-DEFINITION-DATE" + namespace Namespace + ordered - map_attribute "DESC", to: :desc + map_attribute "DESC", to: :desc, render_empty: true map_attribute "IDENTIFIER", to: :identifier map_attribute "LAST-CHANGE", to: :last_change map_attribute "LONG-NAME", to: :long_name diff --git a/lib/reqif/datatype_definition_enumeration.rb b/lib/reqif/datatype_definition_enumeration.rb index ecb002e..88aaddf 100644 --- a/lib/reqif/datatype_definition_enumeration.rb +++ b/lib/reqif/datatype_definition_enumeration.rb @@ -10,10 +10,11 @@ class DatatypeDefinitionEnumeration < Lutaml::Model::Serializable attribute :specified_values, SpecifiedValues xml do - root "DATATYPE-DEFINITION-ENUMERATION" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "DATATYPE-DEFINITION-ENUMERATION" + namespace Namespace + ordered - map_attribute "DESC", to: :desc + map_attribute "DESC", to: :desc, render_empty: true map_attribute "IDENTIFIER", to: :identifier map_attribute "LAST-CHANGE", to: :last_change map_attribute "LONG-NAME", to: :long_name diff --git a/lib/reqif/datatype_definition_integer.rb b/lib/reqif/datatype_definition_integer.rb index 5ad47b6..4488d50 100644 --- a/lib/reqif/datatype_definition_integer.rb +++ b/lib/reqif/datatype_definition_integer.rb @@ -6,15 +6,16 @@ class DatatypeDefinitionInteger < Lutaml::Model::Serializable attribute :identifier, :string attribute :last_change, HighPrecisionDateTime attribute :long_name, :string - attribute :max, :integer - attribute :min, :integer + attribute :max, ReqifInteger + attribute :min, ReqifInteger attribute :alternative_id, AlternativeId xml do - root "DATATYPE-DEFINITION-INTEGER" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "DATATYPE-DEFINITION-INTEGER" + namespace Namespace + ordered - map_attribute "DESC", to: :desc + map_attribute "DESC", to: :desc, render_empty: true map_attribute "IDENTIFIER", to: :identifier map_attribute "LAST-CHANGE", to: :last_change map_attribute "LONG-NAME", to: :long_name diff --git a/lib/reqif/datatype_definition_real.rb b/lib/reqif/datatype_definition_real.rb index 0a5a6a6..8e3f1cc 100644 --- a/lib/reqif/datatype_definition_real.rb +++ b/lib/reqif/datatype_definition_real.rb @@ -7,16 +7,17 @@ class DatatypeDefinitionReal < Lutaml::Model::Serializable attribute :identifier, :string attribute :last_change, HighPrecisionDateTime attribute :long_name, :string - attribute :max, :float - attribute :min, :float + attribute :max, ReqifFloat + attribute :min, ReqifFloat attribute :alternative_id, AlternativeId xml do - root "DATATYPE-DEFINITION-REAL" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "DATATYPE-DEFINITION-REAL" + namespace Namespace + ordered map_attribute "ACCURACY", to: :accuracy - map_attribute "DESC", to: :desc + map_attribute "DESC", to: :desc, render_empty: true map_attribute "IDENTIFIER", to: :identifier map_attribute "LAST-CHANGE", to: :last_change map_attribute "LONG-NAME", to: :long_name diff --git a/lib/reqif/datatype_definition_string.rb b/lib/reqif/datatype_definition_string.rb index 7ddcefa..9d148a8 100644 --- a/lib/reqif/datatype_definition_string.rb +++ b/lib/reqif/datatype_definition_string.rb @@ -10,10 +10,11 @@ class DatatypeDefinitionString < Lutaml::Model::Serializable attribute :alternative_id, AlternativeId xml do - root "DATATYPE-DEFINITION-STRING" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "DATATYPE-DEFINITION-STRING" + namespace Namespace + ordered - map_attribute "DESC", to: :desc + map_attribute "DESC", to: :desc, render_empty: true map_attribute "IDENTIFIER", to: :identifier map_attribute "LAST-CHANGE", to: :last_change map_attribute "LONG-NAME", to: :long_name diff --git a/lib/reqif/datatype_definition_xhtml.rb b/lib/reqif/datatype_definition_xhtml.rb index 3de612c..3445c36 100644 --- a/lib/reqif/datatype_definition_xhtml.rb +++ b/lib/reqif/datatype_definition_xhtml.rb @@ -9,10 +9,11 @@ class DatatypeDefinitionXhtml < Lutaml::Model::Serializable attribute :alternative_id, AlternativeId xml do - root "DATATYPE-DEFINITION-XHTML" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "DATATYPE-DEFINITION-XHTML" + namespace Namespace + ordered - map_attribute "DESC", to: :desc + map_attribute "DESC", to: :desc, render_empty: true map_attribute "IDENTIFIER", to: :identifier map_attribute "LAST-CHANGE", to: :last_change map_attribute "LONG-NAME", to: :long_name diff --git a/lib/reqif/datatypes.rb b/lib/reqif/datatypes.rb index c5ad431..3c35ff9 100644 --- a/lib/reqif/datatypes.rb +++ b/lib/reqif/datatypes.rb @@ -2,22 +2,33 @@ module Reqif class Datatypes < Lutaml::Model::Serializable - attribute :datatype_definition_boolean, DatatypeDefinitionBoolean, collection: true - attribute :datatype_definition_date, DatatypeDefinitionDate, collection: true - attribute :datatype_definition_enumeration, DatatypeDefinitionEnumeration, collection: true - attribute :datatype_definition_integer, DatatypeDefinitionInteger, collection: true - attribute :datatype_definition_real, DatatypeDefinitionReal, collection: true - attribute :datatype_definition_string, DatatypeDefinitionString, collection: true - attribute :datatype_definition_xhtml, DatatypeDefinitionXhtml, collection: true + attribute :datatype_definition_boolean, DatatypeDefinitionBoolean, + collection: true + attribute :datatype_definition_date, DatatypeDefinitionDate, + collection: true + attribute :datatype_definition_enumeration, DatatypeDefinitionEnumeration, + collection: true + attribute :datatype_definition_integer, DatatypeDefinitionInteger, + collection: true + attribute :datatype_definition_real, DatatypeDefinitionReal, + collection: true + attribute :datatype_definition_string, DatatypeDefinitionString, + collection: true + attribute :datatype_definition_xhtml, DatatypeDefinitionXhtml, + collection: true xml do - root "DATATYPES", ordered: true - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "DATATYPES" + namespace Namespace + ordered - map_element "DATATYPE-DEFINITION-BOOLEAN", to: :datatype_definition_boolean + map_element "DATATYPE-DEFINITION-BOOLEAN", + to: :datatype_definition_boolean map_element "DATATYPE-DEFINITION-DATE", to: :datatype_definition_date - map_element "DATATYPE-DEFINITION-ENUMERATION", to: :datatype_definition_enumeration - map_element "DATATYPE-DEFINITION-INTEGER", to: :datatype_definition_integer + map_element "DATATYPE-DEFINITION-ENUMERATION", + to: :datatype_definition_enumeration + map_element "DATATYPE-DEFINITION-INTEGER", + to: :datatype_definition_integer map_element "DATATYPE-DEFINITION-REAL", to: :datatype_definition_real map_element "DATATYPE-DEFINITION-STRING", to: :datatype_definition_string map_element "DATATYPE-DEFINITION-XHTML", to: :datatype_definition_xhtml diff --git a/lib/reqif/default_value.rb b/lib/reqif/default_value.rb index c15f35a..0092c0f 100644 --- a/lib/reqif/default_value.rb +++ b/lib/reqif/default_value.rb @@ -11,13 +11,14 @@ class DefaultValue < Lutaml::Model::Serializable attribute :attribute_value_xhtml, AttributeValueXhtml xml do - root "DEFAULT-VALUE" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "DEFAULT-VALUE" + namespace Namespace # TODO: Only one of these values can be active at the same time map_element "ATTRIBUTE-VALUE-BOOLEAN", to: :attribute_value_boolean map_element "ATTRIBUTE-VALUE-DATE", to: :attribute_value_date - map_element "ATTRIBUTE-VALUE-ENUMERATION", to: :attribute_value_enumeration + map_element "ATTRIBUTE-VALUE-ENUMERATION", + to: :attribute_value_enumeration map_element "ATTRIBUTE-VALUE-INTEGER", to: :attribute_value_integer map_element "ATTRIBUTE-VALUE-REAL", to: :attribute_value_real map_element "ATTRIBUTE-VALUE-STRING", to: :attribute_value_string diff --git a/lib/reqif/definition.rb b/lib/reqif/definition.rb index 1c65d9c..b836552 100644 --- a/lib/reqif/definition.rb +++ b/lib/reqif/definition.rb @@ -2,26 +2,34 @@ module Reqif class Definition < Lutaml::Model::Serializable - attribute :attribute_definition_boolean_ref, :string - attribute :attribute_definition_date_ref, :string - attribute :attribute_definition_enumeration_ref, :string - attribute :attribute_definition_integer_ref, :string - attribute :attribute_definition_real_ref, :string - attribute :attribute_definition_string_ref, :string - attribute :attribute_definition_xhtml_ref, :string + attribute :attribute_definition_boolean_ref, ::Reqif::StringType + attribute :attribute_definition_date_ref, ::Reqif::StringType + attribute :attribute_definition_enumeration_ref, ::Reqif::StringType + attribute :attribute_definition_integer_ref, ::Reqif::StringType + attribute :attribute_definition_real_ref, ::Reqif::StringType + attribute :attribute_definition_string_ref, ::Reqif::StringType + attribute :attribute_definition_xhtml_ref, ::Reqif::StringType xml do - root "DEFINITION" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "DEFINITION" + namespace Namespace + ordered # TODO: Only one of these values can be active at the same time - map_element "ATTRIBUTE-DEFINITION-BOOLEAN-REF", to: :attribute_definition_boolean_ref - map_element "ATTRIBUTE-DEFINITION-DATE-REF", to: :attribute_definition_date_ref - map_element "ATTRIBUTE-DEFINITION-ENUMERATION-REF", to: :attribute_definition_enumeration_ref - map_element "ATTRIBUTE-DEFINITION-INTEGER-REF", to: :attribute_definition_integer_ref - map_element "ATTRIBUTE-DEFINITION-REAL-REF", to: :attribute_definition_real_ref - map_element "ATTRIBUTE-DEFINITION-STRING-REF", to: :attribute_definition_string_ref - map_element "ATTRIBUTE-DEFINITION-XHTML-REF", to: :attribute_definition_xhtml_ref + map_element "ATTRIBUTE-DEFINITION-BOOLEAN-REF", + to: :attribute_definition_boolean_ref + map_element "ATTRIBUTE-DEFINITION-DATE-REF", + to: :attribute_definition_date_ref + map_element "ATTRIBUTE-DEFINITION-ENUMERATION-REF", + to: :attribute_definition_enumeration_ref + map_element "ATTRIBUTE-DEFINITION-INTEGER-REF", + to: :attribute_definition_integer_ref + map_element "ATTRIBUTE-DEFINITION-REAL-REF", + to: :attribute_definition_real_ref + map_element "ATTRIBUTE-DEFINITION-STRING-REF", + to: :attribute_definition_string_ref + map_element "ATTRIBUTE-DEFINITION-XHTML-REF", + to: :attribute_definition_xhtml_ref end end end diff --git a/lib/reqif/doors.rb b/lib/reqif/doors.rb new file mode 100644 index 0000000..a1382ba --- /dev/null +++ b/lib/reqif/doors.rb @@ -0,0 +1,12 @@ +require "lutaml/model" + +module Reqif + module Doors + autoload :Namespace, "#{__dir__}/doors/namespace.rb" + autoload :Identifier, "#{__dir__}/doors/identifier.rb" + autoload :ModuleDefinition, "#{__dir__}/doors/module_definition.rb" + autoload :RifDefinition, "#{__dir__}/doors/rif_definition.rb" + autoload :ReadonlyAttributes, "#{__dir__}/doors/readonly_attributes.rb" + autoload :StringType, "#{__dir__}/doors/string_type.rb" + end +end diff --git a/lib/reqif/doors/identifier.rb b/lib/reqif/doors/identifier.rb new file mode 100644 index 0000000..2506358 --- /dev/null +++ b/lib/reqif/doors/identifier.rb @@ -0,0 +1,15 @@ +require "lutaml/model" + +module Reqif + module Doors + class Identifier < Lutaml::Model::Serializable + attribute :content, :string + + xml do + element "IDENTIFIER" + namespace Namespace + map_content to: :content + end + end + end +end diff --git a/lib/reqif/doors/module_definition.rb b/lib/reqif/doors/module_definition.rb new file mode 100644 index 0000000..faaf7e7 --- /dev/null +++ b/lib/reqif/doors/module_definition.rb @@ -0,0 +1,23 @@ +require "lutaml/model" + +module Reqif + module Doors + class ModuleDefinition < Lutaml::Model::Serializable + # + # DDC_FULL_MODULE + # _3166b6de-d4b9-4334-a13f-a55792546604 + # + + attribute :ddc_mode, :string + attribute :specification_ref, ::Reqif::Doors::StringType + + xml do + element "MODULE-DEFINITION" + namespace Namespace + + map_element "DDC-MODE", to: :ddc_mode + map_element "SPECIFICATION-REF", to: :specification_ref + end + end + end +end diff --git a/lib/reqif/doors/namespace.rb b/lib/reqif/doors/namespace.rb new file mode 100644 index 0000000..25e746d --- /dev/null +++ b/lib/reqif/doors/namespace.rb @@ -0,0 +1,10 @@ +require "lutaml/model" + +module Reqif + module Doors + class Namespace < Lutaml::Xml::Namespace + uri "http://www.ibm.com/rdm/doors/REQIF/xmlns/1.0" + prefix_default "doors" + end + end +end diff --git a/lib/reqif/doors/readonly_attributes.rb b/lib/reqif/doors/readonly_attributes.rb new file mode 100644 index 0000000..a6479c9 --- /dev/null +++ b/lib/reqif/doors/readonly_attributes.rb @@ -0,0 +1,48 @@ +require "lutaml/model" + +module Reqif + module Doors + class ReadonlyAttributes < Lutaml::Model::Serializable + # + # rmf-0d13686b-83c4-487b-9bcc-2f11a673c97a + # rmf-b5ff951b-70fc-440f-b775-cda530e97083 + # rmf-0c2fc6c9-50e9-43ae-970b-c04ab506d834 + + attribute :attribute_definition_boolean_ref, ::Reqif::Doors::StringType, + collection: true + attribute :attribute_definition_date_ref, ::Reqif::Doors::StringType, + collection: true + attribute :attribute_definition_enumeration_ref, + ::Reqif::Doors::StringType, collection: true + attribute :attribute_definition_integer_ref, ::Reqif::Doors::StringType, + collection: true + attribute :attribute_definition_real_ref, ::Reqif::Doors::StringType, + collection: true + attribute :attribute_definition_string_ref, ::Reqif::Doors::StringType, + collection: true + attribute :attribute_definition_xhtml_ref, ::Reqif::Doors::StringType, + collection: true + + xml do + element "READONLY-ATTRIBUTES" + namespace ::Reqif::Doors::Namespace + ordered + + map_element "ATTRIBUTE-DEFINITION-BOOLEAN-REF", + to: :attribute_definition_boolean_ref + map_element "ATTRIBUTE-DEFINITION-DATE-REF", + to: :attribute_definition_date_ref + map_element "ATTRIBUTE-DEFINITION-ENUMERATION-REF", + to: :attribute_definition_enumeration_ref + map_element "ATTRIBUTE-DEFINITION-INTEGER-REF", + to: :attribute_definition_integer_ref + map_element "ATTRIBUTE-DEFINITION-REAL-REF", + to: :attribute_definition_real_ref + map_element "ATTRIBUTE-DEFINITION-STRING-REF", + to: :attribute_definition_string_ref + map_element "ATTRIBUTE-DEFINITION-XHTML-REF", + to: :attribute_definition_xhtml_ref + end + end + end +end diff --git a/lib/reqif/doors/rif_definition.rb b/lib/reqif/doors/rif_definition.rb new file mode 100644 index 0000000..ea6527c --- /dev/null +++ b/lib/reqif/doors/rif_definition.rb @@ -0,0 +1,26 @@ +require "lutaml/model" + +module Reqif + module Doors + class RifDefinition < Lutaml::Model::Serializable + # + # _ae71eb64-2aa6-4780-9212-bda594614a7f + # + # DDC_FULL_MODULE + # _3166b6de-d4b9-4334-a13f-a55792546604 + # + # + + attribute :identifier, ::Reqif::Doors::Identifier + attribute :module_definition, ::Reqif::Doors::ModuleDefinition + + xml do + element "DOORS-RIF-DEFINITION" + namespace ::Reqif::Doors::Namespace + + map_element "IDENTIFIER", to: :identifier + map_element "MODULE-DEFINITION", to: :module_definition + end + end + end +end diff --git a/lib/reqif/doors/string_type.rb b/lib/reqif/doors/string_type.rb new file mode 100644 index 0000000..4b144a8 --- /dev/null +++ b/lib/reqif/doors/string_type.rb @@ -0,0 +1,12 @@ +module Reqif + module Doors + # String type that uses the ReqIF namespace, not Doors namespace. + # This is because elements like ATTRIBUTE-DEFINITION-*-REF inside + # Doors elements like READONLY-ATTRIBUTES still belong to the ReqIF namespace. + class StringType < Lutaml::Model::Type::String + xml do + namespace ::Reqif::Namespace + end + end + end +end diff --git a/lib/reqif/editable_atts.rb b/lib/reqif/editable_atts.rb index de3faf5..04024c1 100644 --- a/lib/reqif/editable_atts.rb +++ b/lib/reqif/editable_atts.rb @@ -2,25 +2,33 @@ module Reqif class EditableAtts < Lutaml::Model::Serializable - attribute :attribute_definition_boolean_ref, :string, collection: true - attribute :attribute_definition_date_ref, :string, collection: true - attribute :attribute_definition_enumeration_ref, :string, collection: true - attribute :attribute_definition_integer_ref, :string, collection: true - attribute :attribute_definition_real_ref, :string, collection: true - attribute :attribute_definition_string_ref, :string, collection: true - attribute :attribute_definition_xhtml_ref, :string, collection: true + attribute :attribute_definition_boolean_ref, StringType, collection: true + attribute :attribute_definition_date_ref, StringType, collection: true + attribute :attribute_definition_enumeration_ref, StringType, + collection: true + attribute :attribute_definition_integer_ref, StringType, collection: true + attribute :attribute_definition_real_ref, StringType, collection: true + attribute :attribute_definition_string_ref, StringType, collection: true + attribute :attribute_definition_xhtml_ref, StringType, collection: true xml do - root "EDITABLE-ATTS" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "EDITABLE-ATTS" + namespace Namespace - map_element "ATTRIBUTE-DEFINITION-BOOLEAN-REF", to: :attribute_definition_boolean_ref - map_element "ATTRIBUTE-DEFINITION-DATE-REF", to: :attribute_definition_date_ref - map_element "ATTRIBUTE-DEFINITION-ENUMERATION-REF", to: :attribute_definition_enumeration_ref - map_element "ATTRIBUTE-DEFINITION-INTEGER-REF", to: :attribute_definition_integer_ref - map_element "ATTRIBUTE-DEFINITION-REAL-REF", to: :attribute_definition_real_ref - map_element "ATTRIBUTE-DEFINITION-STRING-REF", to: :attribute_definition_string_ref - map_element "ATTRIBUTE-DEFINITION-XHTML-REF", to: :attribute_definition_xhtml_ref + map_element "ATTRIBUTE-DEFINITION-BOOLEAN-REF", + to: :attribute_definition_boolean_ref + map_element "ATTRIBUTE-DEFINITION-DATE-REF", + to: :attribute_definition_date_ref + map_element "ATTRIBUTE-DEFINITION-ENUMERATION-REF", + to: :attribute_definition_enumeration_ref + map_element "ATTRIBUTE-DEFINITION-INTEGER-REF", + to: :attribute_definition_integer_ref + map_element "ATTRIBUTE-DEFINITION-REAL-REF", + to: :attribute_definition_real_ref + map_element "ATTRIBUTE-DEFINITION-STRING-REF", + to: :attribute_definition_string_ref + map_element "ATTRIBUTE-DEFINITION-XHTML-REF", + to: :attribute_definition_xhtml_ref end end end diff --git a/lib/reqif/embedded_value.rb b/lib/reqif/embedded_value.rb index 95bf450..44303d5 100644 --- a/lib/reqif/embedded_value.rb +++ b/lib/reqif/embedded_value.rb @@ -6,11 +6,12 @@ class EmbeddedValue < Lutaml::Model::Serializable attribute :other_content, :string xml do - root "EMBEDDED-VALUE" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "EMBEDDED-VALUE" + namespace Namespace + ordered map_attribute "KEY", to: :key - map_attribute "OTHER-CONTENT", to: :other_content + map_attribute "OTHER-CONTENT", to: :other_content, render_empty: true end end end diff --git a/lib/reqif/enum_value.rb b/lib/reqif/enum_value.rb index af1cd38..a23e88c 100644 --- a/lib/reqif/enum_value.rb +++ b/lib/reqif/enum_value.rb @@ -10,10 +10,10 @@ class EnumValue < Lutaml::Model::Serializable attribute :properties, Properties xml do - root "ENUM-VALUE" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "ENUM-VALUE" + namespace Namespace - map_attribute "DESC", to: :desc + map_attribute "DESC", to: :desc, render_empty: true map_attribute "IDENTIFIER", to: :identifier map_attribute "LAST-CHANGE", to: :last_change map_attribute "LONG-NAME", to: :long_name diff --git a/lib/reqif/high_precision_date_time.rb b/lib/reqif/high_precision_date_time.rb index cec11b6..eafe13f 100644 --- a/lib/reqif/high_precision_date_time.rb +++ b/lib/reqif/high_precision_date_time.rb @@ -1,16 +1,52 @@ +# frozen_string_literal: true + require "lutaml/model/type/date_time" module Reqif + # High precision DateTime type that preserves fractional seconds precision class HighPrecisionDateTime < Lutaml::Model::Type::DateTime + attr_accessor :precision, :has_explicit_timezone + + def initialize(value = nil) + super + @precision = 0 + end # The format looks like this `2012-04-07T01:51:37.112+02:00` + # or this `2021-07-01T01:12:06.749Z` def self.from_xml(xml_string) - ::DateTime.parse(xml_string) + new(::DateTime.parse(xml_string)).tap do |date_time| + date_time.precision = extract_precision(xml_string) + date_time.has_explicit_timezone = xml_string.match?(/[Zz]|[+-]\d{2}:\d{2}$/) + end + end + + # Extract the precision of the milliseconds from the XML string + def self.extract_precision(xml_string) + if xml_string.include?(".") + milliseconds_part = xml_string.split(".").last.split(/Z|\+|-/).first + milliseconds_part.length + else + 0 + end end - # The %L adds milliseconds to the time def to_xml - value.strftime("%Y-%m-%dT%H:%M:%S.%L99999%:z") + base = "%Y-%m-%dT%H:%M:%S" + pattern = precision.positive? ? "#{base}.%#{precision}N" : base + if has_explicit_timezone + value.offset.zero? ? value.strftime("#{pattern}Z") : value.strftime("#{pattern}%:z") + else + value.strftime(pattern) + end + end + + def iso8601(precision = nil) + if precision.nil? || precision.zero? + value.iso8601 + else + value.strftime("%Y-%m-%dT%H:%M:%S.%#{precision}N%z") + end end end end diff --git a/lib/reqif/namespace.rb b/lib/reqif/namespace.rb new file mode 100644 index 0000000..a254862 --- /dev/null +++ b/lib/reqif/namespace.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +require "lutaml/xml/namespace" + +module Reqif + # Namespace class for ReqIF XML elements. + # Supports alias URIs for backwards compatibility with different ReqIF versions. + # ReqIF 1.1 uses http://www.omg.org/spec/ReqIF/20110401/reqif.xsd + # Some older tools (e.g., Eclipse RMF) used http://www.omg.org/spec/ReqIF/20101201 + class Namespace < Lutaml::Xml::Namespace + uri "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + uri_aliases "http://www.omg.org/spec/ReqIF/20101201" + element_form_default :qualified + attribute_form_default :qualified + end +end diff --git a/lib/reqif/object.rb b/lib/reqif/object.rb index 5ca7fc0..7dec4cb 100644 --- a/lib/reqif/object.rb +++ b/lib/reqif/object.rb @@ -2,11 +2,11 @@ module Reqif class Object < Lutaml::Model::Serializable - attribute :spec_object_ref, :string + attribute :spec_object_ref, StringType xml do - root "OBJECT" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "OBJECT" + namespace Namespace map_element "SPEC-OBJECT-REF", to: :spec_object_ref end diff --git a/lib/reqif/properties.rb b/lib/reqif/properties.rb index ab7491f..bb1cc1e 100644 --- a/lib/reqif/properties.rb +++ b/lib/reqif/properties.rb @@ -5,8 +5,8 @@ class Properties < Lutaml::Model::Serializable attribute :embedded_value, EmbeddedValue xml do - root "PROPERTIES" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "PROPERTIES" + namespace Namespace map_element "EMBEDDED-VALUE", to: :embedded_value end diff --git a/lib/reqif/relation_group.rb b/lib/reqif/relation_group.rb index 27cf6be..ec1d1c9 100644 --- a/lib/reqif/relation_group.rb +++ b/lib/reqif/relation_group.rb @@ -13,10 +13,11 @@ class RelationGroup < Lutaml::Model::Serializable attribute :type, Type xml do - root "RELATION-GROUP" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "RELATION-GROUP" + namespace Namespace + ordered - map_attribute "DESC", to: :desc + map_attribute "DESC", to: :desc, render_empty: true map_attribute "IDENTIFIER", to: :identifier map_attribute "LAST-CHANGE", to: :last_change map_attribute "LONG-NAME", to: :long_name diff --git a/lib/reqif/relation_group_type.rb b/lib/reqif/relation_group_type.rb index 11bebdf..f08949e 100644 --- a/lib/reqif/relation_group_type.rb +++ b/lib/reqif/relation_group_type.rb @@ -10,10 +10,11 @@ class RelationGroupType < Lutaml::Model::Serializable attribute :spec_attributes, SpecAttributes xml do - root "RELATION-GROUP-TYPE" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "RELATION-GROUP-TYPE" + namespace Namespace + ordered - map_attribute "DESC", to: :desc + map_attribute "DESC", to: :desc, render_empty: true map_attribute "IDENTIFIER", to: :identifier map_attribute "LAST-CHANGE", to: :last_change map_attribute "LONG-NAME", to: :long_name diff --git a/lib/reqif/req_if.rb b/lib/reqif/req_if.rb index c4766e1..94dbffc 100644 --- a/lib/reqif/req_if.rb +++ b/lib/reqif/req_if.rb @@ -1,17 +1,20 @@ require "lutaml/model" +require "hyperlang" module Reqif class ReqIf < Lutaml::Model::Serializable attribute :the_header, TheHeader attribute :core_content, CoreContent attribute :tool_extensions, ToolExtensions - attribute :lang, :string + attribute :lang, Lutaml::Xml::W3c::XmlLangType xml do - root "REQ-IF" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "REQ-IF" + namespace Namespace + namespace_scope [Xhtml::Namespace] + ordered - map_attribute "lang", to: :lang, namespace: "http://www.w3.org/XML/1998/namespace", prefix: "xml" + map_attribute "lang", to: :lang map_element "THE-HEADER", to: :the_header map_element "CORE-CONTENT", to: :core_content map_element "TOOL-EXTENSIONS", to: :tool_extensions diff --git a/lib/reqif/req_if_content.rb b/lib/reqif/req_if_content.rb index 397cf3f..194f1ed 100644 --- a/lib/reqif/req_if_content.rb +++ b/lib/reqif/req_if_content.rb @@ -10,8 +10,9 @@ class ReqIfContent < Lutaml::Model::Serializable attribute :spec_relation_groups, SpecRelationGroups xml do - root "REQ-IF-CONTENT" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "REQ-IF-CONTENT" + namespace Namespace + ordered map_element "DATATYPES", to: :datatypes map_element "SPEC-TYPES", to: :spec_types diff --git a/lib/reqif/req_if_header.rb b/lib/reqif/req_if_header.rb index 7c1c7f9..9f541bd 100644 --- a/lib/reqif/req_if_header.rb +++ b/lib/reqif/req_if_header.rb @@ -2,7 +2,7 @@ module Reqif class ReqIfHeader < Lutaml::Model::Serializable attribute :identifier, :string attribute :comment, :string - attribute :creation_time, :date_time + attribute :creation_time, HighPrecisionDateTime attribute :repository_id, :string attribute :req_if_tool_id, :string attribute :req_if_version, :string @@ -10,8 +10,9 @@ class ReqIfHeader < Lutaml::Model::Serializable attribute :title, :string xml do - root "REQ-IF-HEADER", ordered: true - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "REQ-IF-HEADER" + namespace Namespace + ordered map_attribute "IDENTIFIER", to: :identifier map_element "COMMENT", to: :comment diff --git a/lib/reqif/req_if_tool_extension.rb b/lib/reqif/req_if_tool_extension.rb index a19d1d7..7b98daa 100644 --- a/lib/reqif/req_if_tool_extension.rb +++ b/lib/reqif/req_if_tool_extension.rb @@ -2,9 +2,55 @@ module Reqif class ReqIfToolExtension < Lutaml::Model::Serializable + # + # _ae71eb64-2aa6-4780-9212-bda594614a7f + # + # DDC_FULL_MODULE + # _3166b6de-d4b9-4334-a13f-a55792546604 + # + # + + # + # rmf-0d13686b-83c4-487b-9bcc-2f11a673c97a + + # rmf-48ed4896-28e9-492a-a45a-ca3716a64632 + + # rmf-b5ff951b-70fc-440f-b775-cda530e97083 + + # rmf-81da08a0-6257-488b-b373-04d59395c81a + + # rmf-0c2fc6c9-50e9-43ae-970b-c04ab506d834 + + # rmf-f0d39171-054d-43e9-aec3-810b47c32334 + + # rmf-34c59c32-81d4-43ef-99be-a445358cd4bd + + # rmf-d683201b-4545-4afc-beee-401855fa2ded + + # rmf-baad7651-7ec7-4694-8913-68daa9927781 + + # rmf-ee42329b-d592-44fb-91d2-469a9a9b9dce + + # rmf-47a379f0-441b-4df1-bbd8-a4281b890c26 + + # rmf-5c6c023c-8ace-4f68-807b-80190ba90552 + + # rmf-6b83e957-ff2c-4de6-8bf8-4d2549d0d7bc + + # rmf-a8329820-0ccd-4ebf-8701-a2fd599dc463 + + # rmf-012fb471-e36e-4785-91e6-fdb754ad3613 + # + + attribute :doors_rif_definition, ::Reqif::Doors::RifDefinition + attribute :readonly_attributes, ::Reqif::Doors::ReadonlyAttributes + xml do - root "REQ-IF-TOOL-EXTENSION" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "REQ-IF-TOOL-EXTENSION" + namespace Namespace + + map_element "DOORS-RIF-DEFINITION", to: :doors_rif_definition + map_element "READONLY-ATTRIBUTES", to: :readonly_attributes end end end diff --git a/lib/reqif/reqif_float.rb b/lib/reqif/reqif_float.rb new file mode 100644 index 0000000..4c029f7 --- /dev/null +++ b/lib/reqif/reqif_float.rb @@ -0,0 +1,97 @@ +# frozen_string_literal: true + +require "bigdecimal" +require "lutaml/model/type/float" + +module Reqif + # Custom Float type that handles ReqIF float serialization. + # Preserves decimal notation for simple values and uses scientific + # notation only when necessary (very large/small numbers). + class ReqifFloat < Lutaml::Model::Type::Float + # Format a float value for ReqIF. + # Uses decimal notation for values that can be represented cleanly, + # otherwise uses scientific notation with uppercase E. + # + # @param f [Float] The float value + # @return [String] ReqIF formatted string + def self.reqif_format(float_value) + # Try to represent as a clean decimal first + decimal_str = format_float_as_decimal(float_value) + return decimal_str if decimal_str + + # Fall back to scientific notation + format_scientific(float_value) + end + + # Format as decimal if it can be done cleanly + def self.format_float_as_decimal(float_value) + # Use a reasonable precision to avoid floating point artifacts + # Check if the value can be represented cleanly in decimal + decimal_str = format("%.10g", float_value) + + # Skip if it's in scientific notation (contains 'e' or 'E') + return nil if decimal_str.include?("e") || decimal_str.include?("E") + + # Verify round-trip: parse back and check if we get the same value + parsed = BigDecimal(decimal_str).to_f + return decimal_str if parsed == float_value + + # Try with higher precision + decimal_str = format("%.15g", float_value) + return nil if decimal_str.include?("e") || decimal_str.include?("E") + + parsed = BigDecimal(decimal_str).to_f + return decimal_str if parsed == float_value + + nil # Couldn't represent cleanly + end + + # Format in scientific notation + def self.format_scientific(float_value) + formatted = format("%.15e", float_value).upcase + mantissa, exp = formatted.split("E") + + # Strip trailing zeros from mantissa + mantissa = mantissa.sub(/\.?0+$/, "") + mantissa = "0" if mantissa.empty? + # Remove decimal point if it becomes trailing (e.g. "1.") + mantissa = mantissa.chomp(".") + + # Handle exponent sign and strip leading zeros + sign = exp.start_with?("-") ? "-" : "" + digits = exp.sub(/^[+-]/, "").sub(/\A0+/, "") + digits = "0" if digits.empty? + + "#{mantissa}E#{sign}#{digits}" + end + + def self.cast(value, options = {}) + return nil if value.nil? + + unless options.equal?(EMPTY_OPTIONS) + Lutaml::Model::Services::Type::Validator::Number.validate!(value, + options) + end + + case value + when String then BigDecimal(value).to_f + when Float then value + when BigDecimal then value.to_f + else Float(value.to_s) + end + end + + def self.to_xml(value) + return nil if value.nil? + + result = cast(value) + return nil if result.nil? + + reqif_format(result) + end + + def to_xml + self.class.to_xml(value) + end + end +end diff --git a/lib/reqif/reqif_integer.rb b/lib/reqif/reqif_integer.rb new file mode 100644 index 0000000..ad3ec51 --- /dev/null +++ b/lib/reqif/reqif_integer.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +require "bigdecimal" +require "lutaml/model/type/decimal" + +module Reqif + # Custom Integer type using BigDecimal internally to support + # arbitrary precision integers beyond Ruby's native 64-bit range. + # Serializes without a decimal point for ReqIF compatibility. + class ReqifInteger < Lutaml::Model::Type::Decimal + def self.cast(value, options = {}) + return nil if value.nil? + + result = super + return nil if result.nil? + + result + end + + # Serialize to XML as a plain integer (no decimal point, no fractional part). + # Uses BigDecimal#to_i to strip any fractional part, ensuring output + # matches ReqIF's integer format. + def self.to_xml(value) + return nil if value.nil? + + result = cast(value) + return nil if result.nil? + + result.to_i.to_s + end + + def to_xml + self.class.to_xml(value) + end + end +end diff --git a/lib/reqif/source.rb b/lib/reqif/source.rb index 4f79157..8123872 100644 --- a/lib/reqif/source.rb +++ b/lib/reqif/source.rb @@ -2,11 +2,11 @@ module Reqif class Source < Lutaml::Model::Serializable - attribute :spec_object_ref, :string + attribute :spec_object_ref, StringType xml do - root "SOURCE" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "SOURCE" + namespace Namespace map_element "SPEC-OBJECT-REF", to: :spec_object_ref end diff --git a/lib/reqif/source_specification.rb b/lib/reqif/source_specification.rb index 6510dfa..74c324b 100644 --- a/lib/reqif/source_specification.rb +++ b/lib/reqif/source_specification.rb @@ -2,11 +2,11 @@ module Reqif class SourceSpecification < Lutaml::Model::Serializable - attribute :specification_ref, :string + attribute :specification_ref, StringType xml do - root "SOURCE-SPECIFICATION" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "SOURCE-SPECIFICATION" + namespace Namespace map_element "SPECIFICATION-REF", to: :specification_ref end diff --git a/lib/reqif/spec_attributes.rb b/lib/reqif/spec_attributes.rb index a52081c..518b0fd 100644 --- a/lib/reqif/spec_attributes.rb +++ b/lib/reqif/spec_attributes.rb @@ -2,24 +2,36 @@ module Reqif class SpecAttributes < Lutaml::Model::Serializable - attribute :attribute_definition_boolean, AttributeDefinitionBoolean, collection: true - attribute :attribute_definition_date, AttributeDefinitionDate, collection: true - attribute :attribute_definition_enumeration, AttributeDefinitionEnumeration, collection: true - attribute :attribute_definition_integer, AttributeDefinitionInteger, collection: true - attribute :attribute_definition_real, AttributeDefinitionReal, collection: true - attribute :attribute_definition_string, AttributeDefinitionString, collection: true - attribute :attribute_definition_xhtml, AttributeDefinitionXhtml, collection: true + attribute :attribute_definition_boolean, AttributeDefinitionBoolean, + collection: true + attribute :attribute_definition_date, AttributeDefinitionDate, + collection: true + attribute :attribute_definition_enumeration, + AttributeDefinitionEnumeration, collection: true + attribute :attribute_definition_integer, AttributeDefinitionInteger, + collection: true + attribute :attribute_definition_real, AttributeDefinitionReal, + collection: true + attribute :attribute_definition_string, AttributeDefinitionString, + collection: true + attribute :attribute_definition_xhtml, AttributeDefinitionXhtml, + collection: true xml do - root "SPEC-ATTRIBUTES" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "SPEC-ATTRIBUTES" + namespace Namespace + ordered - map_element "ATTRIBUTE-DEFINITION-BOOLEAN", to: :attribute_definition_boolean + map_element "ATTRIBUTE-DEFINITION-BOOLEAN", + to: :attribute_definition_boolean map_element "ATTRIBUTE-DEFINITION-DATE", to: :attribute_definition_date - map_element "ATTRIBUTE-DEFINITION-ENUMERATION", to: :attribute_definition_enumeration - map_element "ATTRIBUTE-DEFINITION-INTEGER", to: :attribute_definition_integer + map_element "ATTRIBUTE-DEFINITION-ENUMERATION", + to: :attribute_definition_enumeration + map_element "ATTRIBUTE-DEFINITION-INTEGER", + to: :attribute_definition_integer map_element "ATTRIBUTE-DEFINITION-REAL", to: :attribute_definition_real - map_element "ATTRIBUTE-DEFINITION-STRING", to: :attribute_definition_string + map_element "ATTRIBUTE-DEFINITION-STRING", + to: :attribute_definition_string map_element "ATTRIBUTE-DEFINITION-XHTML", to: :attribute_definition_xhtml end end diff --git a/lib/reqif/spec_hierarchy.rb b/lib/reqif/spec_hierarchy.rb index b6a2a77..0b89d70 100644 --- a/lib/reqif/spec_hierarchy.rb +++ b/lib/reqif/spec_hierarchy.rb @@ -14,10 +14,11 @@ class SpecHierarchy < Lutaml::Model::Serializable attribute :object, Object xml do - root "SPEC-HIERARCHY" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "SPEC-HIERARCHY" + namespace Namespace + ordered - map_attribute "DESC", to: :desc + map_attribute "DESC", to: :desc, render_empty: true map_attribute "IDENTIFIER", to: :identifier map_attribute "IS-EDITABLE", to: :is_editable map_attribute "IS-TABLE-INTERNAL", to: :is_table_internal diff --git a/lib/reqif/spec_object.rb b/lib/reqif/spec_object.rb index f2d34c1..b73797f 100644 --- a/lib/reqif/spec_object.rb +++ b/lib/reqif/spec_object.rb @@ -11,10 +11,11 @@ class SpecObject < Lutaml::Model::Serializable attribute :type, Type xml do - root "SPEC-OBJECT" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "SPEC-OBJECT" + namespace Namespace + ordered - map_attribute "DESC", to: :desc + map_attribute "DESC", to: :desc, render_empty: true map_attribute "IDENTIFIER", to: :identifier map_attribute "LAST-CHANGE", to: :last_change map_attribute "LONG-NAME", to: :long_name diff --git a/lib/reqif/spec_object_type.rb b/lib/reqif/spec_object_type.rb index e98d415..6287de6 100644 --- a/lib/reqif/spec_object_type.rb +++ b/lib/reqif/spec_object_type.rb @@ -10,10 +10,11 @@ class SpecObjectType < Lutaml::Model::Serializable attribute :spec_attributes, SpecAttributes xml do - root "SPEC-OBJECT-TYPE" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "SPEC-OBJECT-TYPE" + namespace Namespace + ordered - map_attribute "DESC", to: :desc + map_attribute "DESC", to: :desc, render_empty: true map_attribute "IDENTIFIER", to: :identifier map_attribute "LAST-CHANGE", to: :last_change map_attribute "LONG-NAME", to: :long_name diff --git a/lib/reqif/spec_objects.rb b/lib/reqif/spec_objects.rb index bca98f4..e20def4 100644 --- a/lib/reqif/spec_objects.rb +++ b/lib/reqif/spec_objects.rb @@ -5,8 +5,9 @@ class SpecObjects < Lutaml::Model::Serializable attribute :spec_object, SpecObject, collection: true xml do - root "SPEC-OBJECTS" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "SPEC-OBJECTS" + namespace Namespace + ordered map_element "SPEC-OBJECT", to: :spec_object end diff --git a/lib/reqif/spec_relation.rb b/lib/reqif/spec_relation.rb index ff3f63c..b9bc7cd 100644 --- a/lib/reqif/spec_relation.rb +++ b/lib/reqif/spec_relation.rb @@ -13,10 +13,11 @@ class SpecRelation < Lutaml::Model::Serializable attribute :type, Type xml do - root "SPEC-RELATION" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "SPEC-RELATION" + namespace Namespace + ordered - map_attribute "DESC", to: :desc + map_attribute "DESC", to: :desc, render_empty: true map_attribute "IDENTIFIER", to: :identifier map_attribute "LAST-CHANGE", to: :last_change map_attribute "LONG-NAME", to: :long_name diff --git a/lib/reqif/spec_relation_groups.rb b/lib/reqif/spec_relation_groups.rb index 9ef213e..2e84851 100644 --- a/lib/reqif/spec_relation_groups.rb +++ b/lib/reqif/spec_relation_groups.rb @@ -5,8 +5,8 @@ class SpecRelationGroups < Lutaml::Model::Serializable attribute :relation_group, RelationGroup, collection: true xml do - root "SPEC-RELATION-GROUPS" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "SPEC-RELATION-GROUPS" + namespace Namespace map_element "RELATION-GROUP", to: :relation_group end diff --git a/lib/reqif/spec_relation_type.rb b/lib/reqif/spec_relation_type.rb index 3c0e28b..ff7ac12 100644 --- a/lib/reqif/spec_relation_type.rb +++ b/lib/reqif/spec_relation_type.rb @@ -10,10 +10,11 @@ class SpecRelationType < Lutaml::Model::Serializable attribute :spec_attributes, SpecAttributes xml do - root "SPEC-RELATION-TYPE" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "SPEC-RELATION-TYPE" + namespace Namespace + ordered - map_attribute "DESC", to: :desc + map_attribute "DESC", to: :desc, render_empty: true map_attribute "IDENTIFIER", to: :identifier map_attribute "LAST-CHANGE", to: :last_change map_attribute "LONG-NAME", to: :long_name diff --git a/lib/reqif/spec_relations.rb b/lib/reqif/spec_relations.rb index b9a79cd..3a4ef39 100644 --- a/lib/reqif/spec_relations.rb +++ b/lib/reqif/spec_relations.rb @@ -3,11 +3,11 @@ module Reqif class SpecRelations < Lutaml::Model::Serializable attribute :spec_relation, SpecRelation, collection: true - attribute :spec_relation_ref, :string, collection: true + attribute :spec_relation_ref, StringType, collection: true xml do - root "SPEC-RELATIONS" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "SPEC-RELATIONS" + namespace Namespace # TODO: Only one of these values can be active at the same time map_element "SPEC-RELATION", to: :spec_relation diff --git a/lib/reqif/spec_types.rb b/lib/reqif/spec_types.rb index 3e707ea..e1b1ce4 100644 --- a/lib/reqif/spec_types.rb +++ b/lib/reqif/spec_types.rb @@ -8,8 +8,9 @@ class SpecTypes < Lutaml::Model::Serializable attribute :specification_type, SpecificationType, collection: true xml do - root "SPEC-TYPES" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "SPEC-TYPES" + namespace Namespace + ordered map_element "RELATION-GROUP-TYPE", to: :relation_group_type map_element "SPEC-OBJECT-TYPE", to: :spec_object_type diff --git a/lib/reqif/specification.rb b/lib/reqif/specification.rb index ad20dff..59b8a4d 100644 --- a/lib/reqif/specification.rb +++ b/lib/reqif/specification.rb @@ -12,10 +12,11 @@ class Specification < Lutaml::Model::Serializable attribute :type, Type xml do - root "SPECIFICATION" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "SPECIFICATION" + namespace Namespace + ordered - map_attribute "DESC", to: :desc + map_attribute "DESC", to: :desc, render_empty: true map_attribute "IDENTIFIER", to: :identifier map_attribute "LAST-CHANGE", to: :last_change map_attribute "LONG-NAME", to: :long_name diff --git a/lib/reqif/specification_type.rb b/lib/reqif/specification_type.rb index b8ca86b..30ccbe0 100644 --- a/lib/reqif/specification_type.rb +++ b/lib/reqif/specification_type.rb @@ -10,10 +10,11 @@ class SpecificationType < Lutaml::Model::Serializable attribute :spec_attributes, SpecAttributes xml do - root "SPECIFICATION-TYPE" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "SPECIFICATION-TYPE" + namespace Namespace + ordered - map_attribute "DESC", to: :desc + map_attribute "DESC", to: :desc, render_empty: true map_attribute "IDENTIFIER", to: :identifier map_attribute "LAST-CHANGE", to: :last_change map_attribute "LONG-NAME", to: :long_name diff --git a/lib/reqif/specifications.rb b/lib/reqif/specifications.rb index 94b2cb5..073d23e 100644 --- a/lib/reqif/specifications.rb +++ b/lib/reqif/specifications.rb @@ -5,8 +5,9 @@ class Specifications < Lutaml::Model::Serializable attribute :specification, Specification, collection: true xml do - root "SPECIFICATIONS" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "SPECIFICATIONS" + namespace Namespace + ordered map_element "SPECIFICATION", to: :specification end diff --git a/lib/reqif/specified_values.rb b/lib/reqif/specified_values.rb index 4aa71ed..0c020d3 100644 --- a/lib/reqif/specified_values.rb +++ b/lib/reqif/specified_values.rb @@ -5,8 +5,8 @@ class SpecifiedValues < Lutaml::Model::Serializable attribute :enum_value, EnumValue, collection: true xml do - root "SPECIFIED-VALUES" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "SPECIFIED-VALUES" + namespace Namespace map_element "ENUM-VALUE", to: :enum_value end diff --git a/lib/reqif/string_type.rb b/lib/reqif/string_type.rb new file mode 100644 index 0000000..0f7ded6 --- /dev/null +++ b/lib/reqif/string_type.rb @@ -0,0 +1,7 @@ +module Reqif + class StringType < Lutaml::Model::Type::String + xml do + namespace Namespace + end + end +end diff --git a/lib/reqif/target.rb b/lib/reqif/target.rb index dde65bc..476c050 100644 --- a/lib/reqif/target.rb +++ b/lib/reqif/target.rb @@ -2,11 +2,11 @@ module Reqif class Target < Lutaml::Model::Serializable - attribute :spec_object_ref, :string + attribute :spec_object_ref, StringType xml do - root "TARGET" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "TARGET" + namespace Namespace map_element "SPEC-OBJECT-REF", to: :spec_object_ref end diff --git a/lib/reqif/target_specification.rb b/lib/reqif/target_specification.rb index d5a89c1..6fa3b14 100644 --- a/lib/reqif/target_specification.rb +++ b/lib/reqif/target_specification.rb @@ -2,11 +2,11 @@ module Reqif class TargetSpecification < Lutaml::Model::Serializable - attribute :specification_ref, :string + attribute :specification_ref, StringType xml do - root "TARGET-SPECIFICATION" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "TARGET-SPECIFICATION" + namespace Namespace map_element "SPECIFICATION-REF", to: :specification_ref end diff --git a/lib/reqif/the_header.rb b/lib/reqif/the_header.rb index 36ee9cb..40c746d 100644 --- a/lib/reqif/the_header.rb +++ b/lib/reqif/the_header.rb @@ -5,8 +5,9 @@ class TheHeader < Lutaml::Model::Serializable attribute :req_if_header, ReqIfHeader xml do - root "THE-HEADER" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "THE-HEADER" + namespace Namespace + ordered map_element "REQ-IF-HEADER", to: :req_if_header end diff --git a/lib/reqif/tool_extensions.rb b/lib/reqif/tool_extensions.rb index 1e0f6e9..12c9a3e 100644 --- a/lib/reqif/tool_extensions.rb +++ b/lib/reqif/tool_extensions.rb @@ -5,8 +5,8 @@ class ToolExtensions < Lutaml::Model::Serializable attribute :req_if_tool_extension, ReqIfToolExtension, collection: true xml do - root "TOOL-EXTENSIONS" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "TOOL-EXTENSIONS" + namespace Namespace map_element "REQ-IF-TOOL-EXTENSION", to: :req_if_tool_extension end diff --git a/lib/reqif/type.rb b/lib/reqif/type.rb index ba658ca..5f42e0d 100644 --- a/lib/reqif/type.rb +++ b/lib/reqif/type.rb @@ -2,32 +2,40 @@ module Reqif class Type < Lutaml::Model::Serializable - attribute :datatype_definition_boolean_ref, :string - attribute :specification_type_ref, :string - attribute :relation_group_type_ref, :string - attribute :datatype_definition_date_ref, :string - attribute :datatype_definition_enumeration_ref, :string - attribute :datatype_definition_integer_ref, :string - attribute :datatype_definition_real_ref, :string - attribute :datatype_definition_string_ref, :string - attribute :datatype_definition_xhtml_ref, :string - attribute :spec_object_type_ref, :string - attribute :spec_relation_type_ref, :string + attribute :datatype_definition_boolean_ref, StringType + attribute :specification_type_ref, StringType + attribute :relation_group_type_ref, StringType + attribute :datatype_definition_date_ref, StringType + attribute :datatype_definition_enumeration_ref, StringType + attribute :datatype_definition_integer_ref, StringType + attribute :datatype_definition_real_ref, StringType + attribute :datatype_definition_string_ref, StringType + attribute :datatype_definition_xhtml_ref, StringType + attribute :spec_object_type_ref, StringType + attribute :spec_relation_type_ref, StringType xml do - root "TYPE" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "TYPE" + namespace Namespace + ordered # TODO: Only one of these values can be active at the same time - map_element "DATATYPE-DEFINITION-BOOLEAN-REF", to: :datatype_definition_boolean_ref + map_element "DATATYPE-DEFINITION-BOOLEAN-REF", + to: :datatype_definition_boolean_ref map_element "SPECIFICATION-TYPE-REF", to: :specification_type_ref map_element "RELATION-GROUP-TYPE-REF", to: :relation_group_type_ref - map_element "DATATYPE-DEFINITION-DATE-REF", to: :datatype_definition_date_ref - map_element "DATATYPE-DEFINITION-ENUMERATION-REF", to: :datatype_definition_enumeration_ref - map_element "DATATYPE-DEFINITION-INTEGER-REF", to: :datatype_definition_integer_ref - map_element "DATATYPE-DEFINITION-REAL-REF", to: :datatype_definition_real_ref - map_element "DATATYPE-DEFINITION-STRING-REF", to: :datatype_definition_string_ref - map_element "DATATYPE-DEFINITION-XHTML-REF", to: :datatype_definition_xhtml_ref + map_element "DATATYPE-DEFINITION-DATE-REF", + to: :datatype_definition_date_ref + map_element "DATATYPE-DEFINITION-ENUMERATION-REF", + to: :datatype_definition_enumeration_ref + map_element "DATATYPE-DEFINITION-INTEGER-REF", + to: :datatype_definition_integer_ref + map_element "DATATYPE-DEFINITION-REAL-REF", + to: :datatype_definition_real_ref + map_element "DATATYPE-DEFINITION-STRING-REF", + to: :datatype_definition_string_ref + map_element "DATATYPE-DEFINITION-XHTML-REF", + to: :datatype_definition_xhtml_ref map_element "SPEC-OBJECT-TYPE-REF", to: :spec_object_type_ref map_element "SPEC-RELATION-TYPE-REF", to: :spec_relation_type_ref end diff --git a/lib/reqif/values.rb b/lib/reqif/values.rb index 6dd92f3..ac8ca3e 100644 --- a/lib/reqif/values.rb +++ b/lib/reqif/values.rb @@ -4,21 +4,24 @@ module Reqif class Values < Lutaml::Model::Serializable attribute :attribute_value_boolean, AttributeValueBoolean, collection: true attribute :attribute_value_date, AttributeValueDate, collection: true - attribute :attribute_value_enumeration, AttributeValueEnumeration, collection: true + attribute :attribute_value_enumeration, AttributeValueEnumeration, + collection: true attribute :attribute_value_integer, AttributeValueInteger, collection: true attribute :attribute_value_real, AttributeValueReal, collection: true attribute :attribute_value_string, AttributeValueString, collection: true attribute :attribute_value_xhtml, AttributeValueXhtml, collection: true - attribute :enum_value_ref, :string, collection: true + attribute :enum_value_ref, StringType, collection: true # TODO: if ENUM-VALUE-REF is present, all others cannot be present. xml do - root "VALUES" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "VALUES" + namespace Namespace + ordered map_element "ATTRIBUTE-VALUE-BOOLEAN", to: :attribute_value_boolean map_element "ATTRIBUTE-VALUE-DATE", to: :attribute_value_date - map_element "ATTRIBUTE-VALUE-ENUMERATION", to: :attribute_value_enumeration + map_element "ATTRIBUTE-VALUE-ENUMERATION", + to: :attribute_value_enumeration map_element "ATTRIBUTE-VALUE-INTEGER", to: :attribute_value_integer map_element "ATTRIBUTE-VALUE-REAL", to: :attribute_value_real map_element "ATTRIBUTE-VALUE-STRING", to: :attribute_value_string diff --git a/lib/reqif/xhtml.rb b/lib/reqif/xhtml.rb new file mode 100644 index 0000000..14dbdd2 --- /dev/null +++ b/lib/reqif/xhtml.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +require "lutaml/model" + +module Reqif + module Xhtml + autoload :Namespace, "#{__dir__}/xhtml/namespace.rb" + autoload :Div, "#{__dir__}/xhtml/div.rb" + autoload :Span, "#{__dir__}/xhtml/span.rb" + autoload :P, "#{__dir__}/xhtml/p.rb" + end +end diff --git a/lib/reqif/xhtml/div.rb b/lib/reqif/xhtml/div.rb new file mode 100644 index 0000000..92b8885 --- /dev/null +++ b/lib/reqif/xhtml/div.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require "lutaml/model" + +module Reqif + module Xhtml + class Div < Lutaml::Model::Serializable + attribute :content, :string + + xml do + element "div" + namespace Namespace + + map_content to: :content + end + end + end +end diff --git a/lib/reqif/xhtml/namespace.rb b/lib/reqif/xhtml/namespace.rb new file mode 100644 index 0000000..557c302 --- /dev/null +++ b/lib/reqif/xhtml/namespace.rb @@ -0,0 +1,10 @@ +require "lutaml/model" + +module Reqif + module Xhtml + class Namespace < Lutaml::Xml::Namespace + uri "http://www.w3.org/1999/xhtml" + prefix_default "xhtml" + end + end +end diff --git a/lib/reqif/xhtml/p.rb b/lib/reqif/xhtml/p.rb new file mode 100644 index 0000000..b6e2659 --- /dev/null +++ b/lib/reqif/xhtml/p.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require "lutaml/model" + +module Reqif + module Xhtml + class P < Lutaml::Model::Serializable + attribute :content, :string + + xml do + element "p" + namespace Namespace + + map_content to: :content + end + end + end +end diff --git a/lib/reqif/xhtml/span.rb b/lib/reqif/xhtml/span.rb new file mode 100644 index 0000000..606bacf --- /dev/null +++ b/lib/reqif/xhtml/span.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require "lutaml/model" + +module Reqif + module Xhtml + class Span < Lutaml::Model::Serializable + attribute :content, :string + + xml do + element "span" + namespace Namespace + + map_content to: :content + end + end + end +end diff --git a/lib/reqif/xhtml_content.rb b/lib/reqif/xhtml_content.rb index 1f7cae9..efdc5a1 100644 --- a/lib/reqif/xhtml_content.rb +++ b/lib/reqif/xhtml_content.rb @@ -1,10 +1,190 @@ +# frozen_string_literal: true + require "lutaml/model" module Reqif class XhtmlContent < Lutaml::Model::Serializable + # All XHTML block and inline elements that can appear in XHTML-CONTENT + attribute :div, Hyperlang::Xhtml::Div, collection: true + attribute :p, Hyperlang::Xhtml::P, collection: true + attribute :span, Hyperlang::Xhtml::Span, collection: true + attribute :br, Hyperlang::Xhtml::Br, collection: true + attribute :strong, Hyperlang::Xhtml::Strong, collection: true + attribute :em, Hyperlang::Xhtml::Em, collection: true + attribute :ul, Hyperlang::Xhtml::Ul, collection: true + attribute :ol, Hyperlang::Xhtml::Ol, collection: true + attribute :li, Hyperlang::Xhtml::Li, collection: true + attribute :a, Hyperlang::Xhtml::A, collection: true + attribute :h1, Hyperlang::Xhtml::H1, collection: true + attribute :h2, Hyperlang::Xhtml::H2, collection: true + attribute :h3, Hyperlang::Xhtml::H3, collection: true + attribute :h4, Hyperlang::Xhtml::H4, collection: true + attribute :h5, Hyperlang::Xhtml::H5, collection: true + attribute :h6, Hyperlang::Xhtml::H6, collection: true + attribute :img, Hyperlang::Xhtml::Img, collection: true + attribute :blockquote, Hyperlang::Xhtml::Blockquote, collection: true + attribute :pre, Hyperlang::Xhtml::Pre, collection: true + attribute :code, Hyperlang::Xhtml::Code, collection: true + attribute :dl, Hyperlang::Xhtml::Dl, collection: true + attribute :dt, Hyperlang::Xhtml::Dt, collection: true + attribute :dd, Hyperlang::Xhtml::Dd, collection: true + attribute :table, Hyperlang::Xhtml::Table, collection: true + attribute :tr, Hyperlang::Xhtml::Tr, collection: true + attribute :th, Hyperlang::Xhtml::Th, collection: true + attribute :td, Hyperlang::Xhtml::Td, collection: true + attribute :thead, Hyperlang::Xhtml::Thead, collection: true + attribute :tbody, Hyperlang::Xhtml::Tbody, collection: true + attribute :tfoot, Hyperlang::Xhtml::Tfoot, collection: true + attribute :caption, Hyperlang::Xhtml::Caption, collection: true + attribute :form, Hyperlang::Xhtml::Form, collection: true + attribute :input, Hyperlang::Xhtml::Input, collection: true + attribute :select, Hyperlang::Xhtml::Select, collection: true + attribute :option, Hyperlang::Xhtml::Option, collection: true + attribute :textarea, Hyperlang::Xhtml::Textarea, collection: true + attribute :button, Hyperlang::Xhtml::Button, collection: true + attribute :label, Hyperlang::Xhtml::Label, collection: true + attribute :fieldset, Hyperlang::Xhtml::Fieldset, collection: true + attribute :legend, Hyperlang::Xhtml::Legend, collection: true + attribute :hr, Hyperlang::Xhtml::Hr, collection: true + attribute :address, Hyperlang::Xhtml::Address, collection: true + attribute :b, Hyperlang::Xhtml::B, collection: true + attribute :i, Hyperlang::Xhtml::I, collection: true + attribute :u, Hyperlang::Xhtml::U, collection: true + attribute :s, Hyperlang::Xhtml::S, collection: true + attribute :strike, Hyperlang::Xhtml::Strike, collection: true + attribute :big, Hyperlang::Xhtml::Big, collection: true + attribute :small, Hyperlang::Xhtml::Small, collection: true + attribute :sub, Hyperlang::Xhtml::Sub, collection: true + attribute :sup, Hyperlang::Xhtml::Sup, collection: true + attribute :tt, Hyperlang::Xhtml::Tt, collection: true + attribute :abbr, Hyperlang::Xhtml::Abbr, collection: true + attribute :acronym, Hyperlang::Xhtml::Acronym, collection: true + attribute :cite, Hyperlang::Xhtml::Cite, collection: true + attribute :code, Hyperlang::Xhtml::Code, collection: true + attribute :dfn, Hyperlang::Xhtml::Dfn, collection: true + attribute :kbd, Hyperlang::Xhtml::Kbd, collection: true + attribute :samp, Hyperlang::Xhtml::Samp, collection: true + attribute :var, Hyperlang::Xhtml::Var, collection: true + attribute :q, Hyperlang::Xhtml::Q, collection: true + attribute :del, Hyperlang::Xhtml::Del, collection: true + attribute :ins, Hyperlang::Xhtml::Ins, collection: true + attribute :noscript, Hyperlang::Xhtml::Noscript, collection: true + attribute :script, Hyperlang::Xhtml::Script, collection: true + attribute :map, Hyperlang::Xhtml::Map, collection: true + attribute :area, Hyperlang::Xhtml::Area, collection: true + attribute :object, Hyperlang::Xhtml::Object, collection: true + attribute :param, Hyperlang::Xhtml::Param, collection: true + attribute :col, Hyperlang::Xhtml::Col, collection: true + attribute :colgroup, Hyperlang::Xhtml::Colgroup, collection: true + attribute :ruby, Hyperlang::Xhtml::Ruby, collection: true + attribute :rb, Hyperlang::Xhtml::Rb, collection: true + attribute :rt, Hyperlang::Xhtml::Rt, collection: true + attribute :rp, Hyperlang::Xhtml::Rp, collection: true + attribute :rbc, Hyperlang::Xhtml::Rbc, collection: true + attribute :rtc, Hyperlang::Xhtml::Rtc, collection: true + attribute :content, :string + xml do - root "XHTML-CONTENT" - namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" + element "XHTML-CONTENT" + namespace Namespace + mixed_content + map_content to: :content + + # Block and structural elements + map_element "div", to: :div + map_element "p", to: :p + map_element "h1", to: :h1 + map_element "h2", to: :h2 + map_element "h3", to: :h3 + map_element "h4", to: :h4 + map_element "h5", to: :h5 + map_element "h6", to: :h6 + map_element "blockquote", to: :blockquote + map_element "pre", to: :pre + map_element "hr", to: :hr + map_element "address", to: :address + + # Lists + map_element "ul", to: :ul + map_element "ol", to: :ol + map_element "li", to: :li + map_element "dl", to: :dl + map_element "dt", to: :dt + map_element "dd", to: :dd + + # Tables + map_element "table", to: :table + map_element "caption", to: :caption + map_element "thead", to: :thead + map_element "tbody", to: :tbody + map_element "tfoot", to: :tfoot + map_element "tr", to: :tr + map_element "th", to: :th + map_element "td", to: :td + map_element "col", to: :col + map_element "colgroup", to: :colgroup + + # Inline text elements + map_element "span", to: :span + map_element "br", to: :br + map_element "strong", to: :strong + map_element "em", to: :em + map_element "a", to: :a + map_element "img", to: :img + map_element "code", to: :code + map_element "q", to: :q + map_element "b", to: :b + map_element "i", to: :i + map_element "u", to: :u + map_element "s", to: :s + map_element "strike", to: :strike + map_element "big", to: :big + map_element "small", to: :small + map_element "sub", to: :sub + map_element "sup", to: :sup + map_element "tt", to: :tt + map_element "abbr", to: :abbr + map_element "acronym", to: :acronym + map_element "cite", to: :cite + map_element "dfn", to: :dfn + map_element "kbd", to: :kbd + map_element "samp", to: :samp + map_element "var", to: :var + + # Forms + map_element "form", to: :form + map_element "input", to: :input + map_element "select", to: :select + map_element "option", to: :option + map_element "textarea", to: :textarea + map_element "button", to: :button + map_element "label", to: :label + map_element "fieldset", to: :fieldset + map_element "legend", to: :legend + + # Edit elements + map_element "del", to: :del + map_element "ins", to: :ins + + # Scripting + map_element "noscript", to: :noscript + map_element "script", to: :script + + # Image map + map_element "map", to: :map + map_element "area", to: :area + + # Object + map_element "object", to: :object + map_element "param", to: :param + + # Ruby + map_element "ruby", to: :ruby + map_element "rb", to: :rb + map_element "rt", to: :rt + map_element "rp", to: :rp + map_element "rbc", to: :rbc + map_element "rtc", to: :rtc end end end diff --git a/reqif.gemspec b/reqif.gemspec index caff890..07ba0c6 100644 --- a/reqif.gemspec +++ b/reqif.gemspec @@ -16,6 +16,7 @@ Gem::Specification.new do |spec| spec.metadata["homepage_uri"] = spec.homepage spec.metadata["source_code_uri"] = spec.homepage spec.metadata["changelog_uri"] = "https://github.com/lutaml/reqif/releases" + spec.metadata["rubygems_mfa_required"] = "true" # Specify which files should be added to the gem when it is released. # The `git ls-files -z` loads the files in the RubyGem @@ -31,6 +32,6 @@ Gem::Specification.new do |spec| spec.required_ruby_version = ">= 3.0.0" - spec.add_dependency "lutaml-model" - spec.add_dependency "zeitwerk", "~> 2.6.18" + spec.add_dependency "hyperlang", "~> 0.1.1" + spec.add_dependency "lutaml-model", "~> 0.8.0" end diff --git a/spec/reqif/polarion_export_spec.rb b/spec/reqif/polarion_export_spec.rb index 2035274..284e8c8 100644 --- a/spec/reqif/polarion_export_spec.rb +++ b/spec/reqif/polarion_export_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + RSpec.describe "Polarion Export" do let(:xml_file) { File.read("spec/fixtures/polarion_export.xml") } let(:reqif) { Reqif::ReqIf.from_xml(xml_file) } @@ -5,11 +7,16 @@ it "parses Polarion export correctly" do expect(reqif.the_header.req_if_header.req_if_tool_id).to eq("Polarion") - enum_type = reqif.core_content.req_if_content.datatypes.datatype_definition_enumeration.find { |d| d.long_name == "Status" } - expect(enum_type).to_not be_nil - expect(enum_type.specified_values.map(&:long_name)).to contain_exactly("Draft", "Approved") + enum_type = reqif.core_content.req_if_content.datatypes.datatype_definition_enumeration.find do |d| + d.long_name == "Status" + end + expect(enum_type).not_to be_nil + expect(enum_type.specified_values.enum_value.map(&:long_name)).to contain_exactly( + "Draft", "Approved" + ) - spec_object = reqif.req_if_content.spec_objects.spec_object.first - expect(spec_object.values.first.the_value).to include("The system shall be able to handle concurrent users.") + spec_object = reqif.core_content.req_if_content.spec_objects.spec_object.first + xhtml_val = spec_object.values.attribute_value_xhtml.first + expect(xhtml_val.the_value).to be_a(Reqif::XhtmlContent) end end diff --git a/spec/reqif/req_if_header_spec.rb b/spec/reqif/req_if_header_spec.rb index 021a2e9..2afe4ab 100644 --- a/spec/reqif/req_if_header_spec.rb +++ b/spec/reqif/req_if_header_spec.rb @@ -1,10 +1,11 @@ +# frozen_string_literal: true + RSpec.describe Reqif::ReqIfHeader do let(:header_xml) do <<~XML - + Example ReqIF file 2023-10-26T12:00:00Z - _1234567890 reqif-tool 1.0 source-tool @@ -18,8 +19,8 @@ describe "attributes" do it "parses all header attributes" do expect(header.comment).to eq("Example ReqIF file") - expect(header.creation_time).to be_a(DateTime) - expect(header.creation_time.utc.iso8601).to eq("2023-10-26T12:00:00Z") + expect(header.creation_time).to be_a(Reqif::HighPrecisionDateTime) + expect(header.creation_time.iso8601).to eq("2023-10-26T12:00:00+00:00") expect(header.identifier).to eq("_1234567890") expect(header.req_if_tool_id).to eq("reqif-tool") expect(header.req_if_version).to eq("1.0") diff --git a/spec/reqif/req_if_spec.rb b/spec/reqif/req_if_spec.rb index fa62cd0..cdb6688 100644 --- a/spec/reqif/req_if_spec.rb +++ b/spec/reqif/req_if_spec.rb @@ -1,19 +1,22 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Reqif::ReqIf do - let(:xml_string) { File.read("spec/fixtures/strictdoc_01_minimal_reqif_sample.reqif") } + let(:xml_string) { File.read("spec/fixtures/eclipse_rmf_sample.reqif") } let(:parsed) { described_class.from_xml(xml_string) } describe ".from_xml" do it "parses ReqIF XML correctly" do expect(parsed).to be_a(described_class) - expect(parsed.the_header).to be_a(Reqif::ReqIfHeader) - expect(parsed.req_if_content).to be_a(Reqif::ReqIfContent) + expect(parsed.the_header.req_if_header).to be_a(Reqif::ReqIfHeader) + expect(parsed.core_content.req_if_content).to be_a(Reqif::ReqIfContent) end it "maintains XML namespaces" do generated = parsed.to_xml - expect(generated).to include('xmlns="http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"') + # Eclipse RMF fixtures use 20101201 namespace which should be preserved + expect(generated).to include('xmlns="http://www.omg.org/spec/ReqIF/20101201"') end end @@ -34,7 +37,7 @@ # puts "------" # puts generated - expect(generated).to be_analogous_with(xml_string) + expect(generated).to be_xml_equivalent_to(xml_string) end end end diff --git a/spec/reqif/spec_objects_spec.rb b/spec/reqif/spec_objects_spec.rb index 38dc4c8..103a4bf 100644 --- a/spec/reqif/spec_objects_spec.rb +++ b/spec/reqif/spec_objects_spec.rb @@ -1,13 +1,18 @@ +# frozen_string_literal: true + RSpec.describe Reqif::SpecObject do let(:spec_object_xml) do <<~XML - - st1 + + + st1 + - - ad1 - System shall provide login functionality - + + + ad1 + + XML @@ -19,12 +24,11 @@ it "parses basic attributes" do expect(spec_object.identifier).to eq("so1") expect(spec_object.long_name).to eq("Login Requirement") - expect(spec_object.type_ref).to eq("st1") + expect(spec_object.type.spec_object_type_ref).to eq("st1") end it "parses values" do - value = spec_object.values.first - expect(value.definition_ref).to eq("ad1") + value = spec_object.values.attribute_value_string.first expect(value.the_value).to eq("System shall provide login functionality") end end diff --git a/spec/reqif/spec_relations_spec.rb b/spec/reqif/spec_relations_spec.rb index 8d6d03a..d64b8ac 100644 --- a/spec/reqif/spec_relations_spec.rb +++ b/spec/reqif/spec_relations_spec.rb @@ -1,11 +1,19 @@ +# frozen_string_literal: true + RSpec.describe Reqif::SpecRelations do let(:spec_relations_xml) do <<~XML - + - so1 - so2 - rt1 + + so1 + + + so2 + + + rt1 + XML @@ -17,9 +25,9 @@ it "parses relation attributes" do relation = spec_relations.spec_relation.first expect(relation.identifier).to eq("rel1") - expect(relation.source_ref).to eq("so1") - expect(relation.target_ref).to eq("so2") - expect(relation.type_ref).to eq("rt1") + expect(relation.source.spec_object_ref).to eq("so1") + expect(relation.target.spec_object_ref).to eq("so2") + expect(relation.type.spec_relation_type_ref).to eq("rt1") end end end diff --git a/spec/reqif/spec_types_spec.rb b/spec/reqif/spec_types_spec.rb index d44ca1f..d77c8ee 100644 --- a/spec/reqif/spec_types_spec.rb +++ b/spec/reqif/spec_types_spec.rb @@ -1,15 +1,20 @@ +# frozen_string_literal: true + RSpec.describe Reqif::SpecTypes do let(:spec_types_xml) do <<~XML - + - + - dt1 - No description provided - false + + dt1 + + + + - + XML @@ -25,12 +30,11 @@ end it "parses attribute definitions" do - attr_def = spec_types.spec_object_type.first.attribute_definitions.first + attr_def = spec_types.spec_object_type.first.spec_attributes.attribute_definition_string.first expect(attr_def.identifier).to eq("ad1") expect(attr_def.long_name).to eq("Description") - expect(attr_def.type_ref).to eq("dt1") - expect(attr_def.default_value).to eq("No description provided") - expect(attr_def.multi_valued).to be false + expect(attr_def.type.datatype_definition_string_ref).to eq("dt1") + expect(attr_def.default_value.attribute_value_string.the_value).to eq("No description provided") end end end diff --git a/spec/reqif/specifications_spec.rb b/spec/reqif/specifications_spec.rb index 476d656..7b764fe 100644 --- a/spec/reqif/specifications_spec.rb +++ b/spec/reqif/specifications_spec.rb @@ -1,11 +1,15 @@ +# frozen_string_literal: true + RSpec.describe Reqif::Specifications do let(:specifications_xml) do <<~XML - + - so1 + + so1 + @@ -23,9 +27,9 @@ end it "parses spec hierarchy" do - hierarchy = specifications.specification.first.children.first + hierarchy = specifications.specification.first.children.spec_hierarchy.first expect(hierarchy.identifier).to eq("sh1") - expect(hierarchy.object_ref).to eq("so1") + expect(hierarchy.object.spec_object_ref).to eq("so1") end end end diff --git a/spec/reqif/tool_extension_spec.rb b/spec/reqif/tool_extension_spec.rb index 5872530..020297f 100644 --- a/spec/reqif/tool_extension_spec.rb +++ b/spec/reqif/tool_extension_spec.rb @@ -1,21 +1,27 @@ -RSpec.describe Reqif::ReqIfToolExtension do - let(:tool_extension_xml) do +# frozen_string_literal: true + +RSpec.describe Reqif::ToolExtensions do + let(:tool_extensions_xml) do <<~XML - - - custom-tool - Custom data + + + + _test-id + + DDC_FULL_MODULE + + XML end - let(:tool_extension) { described_class.from_xml(tool_extension_xml) } + let(:tool_extensions) { described_class.from_xml(tool_extensions_xml) } describe "tool extensions" do it "parses tool extension data" do - expect(tool_extension.extensions).to be_a(Array) - expect(tool_extension.extensions.first).to include("TOOL-ID" => "custom-tool") + ext = tool_extensions.req_if_tool_extension.first + expect(ext.doors_rif_definition.identifier.content).to eq("_test-id") end end end diff --git a/spec/reqif_spec.rb b/spec/reqif_spec.rb index 42d3bd7..637e977 100644 --- a/spec/reqif_spec.rb +++ b/spec/reqif_spec.rb @@ -9,7 +9,7 @@ describe "XML round-trip conversion" do xml_files = Dir[fixtures_dir.join("**", "*.xml")] + - Dir[fixtures_dir.join("**", "*.reqif")] + Dir[fixtures_dir.join("**", "*.reqif")] # def check_parsed_content(parsed, reparsed) # %i[ @@ -48,19 +48,7 @@ encoding: "utf-8", ) - # cleaned_xml_string = xml_string - cleaned_xml_string = xml_string - .gsub(/^<\?xml.*\n/, "") - # cleaned_xml_string = xml_string - # .gsub(/^<\?xml-model.*\n/, "") - # .gsub(/^<\?xml-stylesheet.*\n/, "") - - # puts "original---------" - # puts cleaned_xml_string - # puts "------" - # puts generated - - expect(generated).to be_analogous_with(cleaned_xml_string) + expect(generated).to be_xml_equivalent_to(xml_string) end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index d4c204e..981a50a 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -2,7 +2,56 @@ require "reqif" require "nokogiri" -require "xml-c14n" +require "canon/rspec_matchers" + +# Configure Canon to ignore XML comments (lutaml-model doesn't preserve them) +# and structural whitespace (input/output formatting may differ) +Canon::Config.configure do |config| + config.xml.match.options = { + comments: :ignore, + structural_whitespace: :ignore, + attribute_order: :ignore, + } +end + +# Monkey-patch FormatPreservationRule to handle namespaces without prefix_default. +# When a namespace URI is declared with a prefix in the input (e.g., xmlns:reqif="..."), +# the preserved_input_format becomes :prefix. But if the Namespace class doesn't +# define prefix_default, we fall back to :default format to avoid an error. +module Lutaml + module Xml + module Decisions + module Rules + class FormatPreservationRule + alias_method :original_decide, :decide + def decide(context) + input_format = context.preserved_input_format + + if input_format == :default + Decision.default( + namespace_class: context.namespace_class, + reason: "Priority 1: Input used default format - preserve it", + ) + elsif context.namespace_class.prefix_default.nil? + # input_format is :prefix but prefix_default might be nil + # Fall back to default format to avoid ArgumentError + Decision.default( + namespace_class: context.namespace_class, + reason: "Priority 1: No prefix_default - use default format", + ) + else + Decision.prefix( + prefix: context.namespace_class.prefix_default, + namespace_class: context.namespace_class, + reason: "Priority 1: Input used prefix format - preserve it", + ) + end + end + end + end + end + end +end RSpec.configure do |config| # Enable flags like --only-failures and --next-failure @@ -16,13 +65,6 @@ end end -require "lutaml/model" -require "lutaml/model/xml_adapter/nokogiri_adapter" -require "lutaml/model/json_adapter/standard_json_adapter" -require "lutaml/model/yaml_adapter/standard_yaml_adapter" - Lutaml::Model::Config.configure do |config| - config.xml_adapter = Lutaml::Model::XmlAdapter::NokogiriAdapter - config.json_adapter = Lutaml::Model::JsonAdapter::StandardJsonAdapter - config.yaml_adapter = Lutaml::Model::YamlAdapter::StandardYamlAdapter + config.xml_adapter_type = :nokogiri end