Class: Xmi::NamespaceDetector

Inherits:
Object
  • Object
show all
Defined in:
lib/xmi/namespace_detector.rb

Overview

Detects namespace versions from XMI XML content

This class parses XMI files to extract namespace URIs and detect the specific versions of XMI, UML, and other OMG specifications used.

Constant Summary collapse

VERSION_PATTERN =
/(\d{8})/
NS_PATTERNS =

Namespace URI patterns for OMG specifications

{
  xmi: %r{http://www\.omg\.org/spec/XMI/(\d{8})},
  uml: %r{http://www\.omg\.org/spec/UML/(\d{8})},
  umldi: %r{http://www\.omg\.org/spec/UML/(\d{8})/UMLDI},
  umldc: %r{http://www\.omg\.org/spec/UML/(\d{8})/UMLDC},
}.freeze

Class Method Summary collapse

Class Method Details

.analyze(xml_content) ⇒ Hash

Get a summary of all namespaces and their versions in the XML

Parameters:

  • xml_content (String)

    The XML content to analyze

Returns:

  • (Hash)

    Detailed namespace information



117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/xmi/namespace_detector.rb', line 117

def self.analyze(xml_content)
  versions = detect_versions(xml_content)
  uris = detect_namespace_uris(xml_content)
  raw_namespaces = extract_namespace_uris(xml_content)

  {
    versions: versions,
    uris: uris,
    raw_namespaces: raw_namespaces,
    normalized_needed: normalization_needed?(versions),
  }
end

.build_namespace_uri(type, version) ⇒ String?

Get the full namespace URI for a detected version

Parameters:

  • type (Symbol)

    The namespace type (:xmi, :uml, etc.)

  • version (String)

    The version string (e.g., “20131001”)

Returns:

  • (String, nil)

    The full namespace URI



69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/xmi/namespace_detector.rb', line 69

def self.build_namespace_uri(type, version)
  case type
  when :xmi
    "http://www.omg.org/spec/XMI/#{version}"
  when :uml
    "http://www.omg.org/spec/UML/#{version}"
  when :umldi
    "http://www.omg.org/spec/UML/#{version}/UMLDI"
  when :umldc
    "http://www.omg.org/spec/UML/#{version}/UMLDC"
  end
end

.detect_namespace_uris(xml_content) ⇒ Hash

Get detected namespace URIs for all detected versions

Parameters:

  • xml_content (String)

    The XML content to parse

Returns:

  • (Hash)

    A hash with namespace types as keys and URIs as values



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/xmi/namespace_detector.rb', line 86

def self.detect_namespace_uris(xml_content)
  versions = detect_versions(xml_content)
  {
    xmi: versions[:xmi] ? build_namespace_uri(:xmi, versions[:xmi]) : nil,
    uml: versions[:uml] ? build_namespace_uri(:uml, versions[:uml]) : nil,
    umldi: if versions[:umldi]
             build_namespace_uri(:umldi,
                                 versions[:umldi])
           end,
    umldc: if versions[:umldc]
             build_namespace_uri(:umldc,
                                 versions[:umldc])
           end,
  }
end

.detect_version(namespaces, type) ⇒ String?

Detect version for a specific namespace type

Parameters:

  • namespaces (Hash<String, String>)

    The namespace URIs hash

  • type (Symbol)

    The namespace type (:xmi, :uml, :umldi, :umldc)

Returns:

  • (String, nil)

    The version string (e.g., “20131001”) or nil if not found



52
53
54
55
56
57
58
59
60
61
62
# File 'lib/xmi/namespace_detector.rb', line 52

def self.detect_version(namespaces, type)
  pattern = NS_PATTERNS[type]
  return nil unless pattern

  namespaces.each_value do |uri|
    match = uri.match(pattern)
    return match[1] if match
  end

  nil
end

.detect_versions(xml_content) ⇒ Hash

Detect all namespace versions from XML content

Parameters:

  • xml_content (String)

    The XML content to parse

Returns:

  • (Hash)

    A hash with namespace types as keys and version strings as values Example: { xmi: “20131001”, uml: “20131001”, umldi: nil, umldc: nil }



26
27
28
29
30
31
32
33
34
# File 'lib/xmi/namespace_detector.rb', line 26

def self.detect_versions(xml_content)
  namespaces = extract_namespace_uris(xml_content)
  {
    xmi: detect_version(namespaces, :xmi),
    uml: detect_version(namespaces, :uml),
    umldi: detect_version(namespaces, :umldi),
    umldc: detect_version(namespaces, :umldc),
  }
end

.extract_namespace_uris(xml_content) ⇒ Hash<String, String>

Extract all namespace URIs from XML content

Parameters:

  • xml_content (String)

    The XML content to parse

Returns:

  • (Hash<String, String>)

    A hash mapping prefixes to namespace URIs



40
41
42
43
44
45
# File 'lib/xmi/namespace_detector.rb', line 40

def self.extract_namespace_uris(xml_content)
  doc = Nokogiri::XML(xml_content, &:noent)
  doc.collect_namespaces
rescue Nokogiri::XML::SyntaxError
  {}
end

.normalization_needed?(versions) ⇒ Boolean

Check if namespace normalization is needed

Parameters:

  • versions (Hash)

    The detected versions hash

Returns:

  • (Boolean)

    True if any namespace is not 20131001



134
135
136
# File 'lib/xmi/namespace_detector.rb', line 134

def self.normalization_needed?(versions)
  versions.values.any? { |v| v && v != "20131001" }
end

.uses_version?(xml_content, type, version) ⇒ Boolean

Check if the XML uses a specific namespace version

Parameters:

  • xml_content (String)

    The XML content to check

  • type (Symbol)

    The namespace type

  • version (String)

    The version to check for

Returns:

  • (Boolean)

    True if the XML uses the specified version



108
109
110
111
# File 'lib/xmi/namespace_detector.rb', line 108

def self.uses_version?(xml_content, type, version)
  detected = detect_versions(xml_content)
  detected[type] == version
end