class StixSchemaSpy::Schema

Constants

VERSIONS

Attributes

doc[R]
filename[R]
namespace[R]
prefix[R]
stix_version[R]
types[R]

Public Class Methods

all(version = self.latest_version) click to toggle source

Get all schemas

# File lib/stix_schema_spy/models/schema.rb, line 152
def self.all(version = self.latest_version)
  @@schemas[version].values
end
blacklist_enabled=(val) click to toggle source
# File lib/stix_schema_spy/models/schema.rb, line 191
def self.blacklist_enabled=(val)
  @blacklist_enabled = val
end
blacklist_enabled?() click to toggle source
# File lib/stix_schema_spy/models/schema.rb, line 187
def self.blacklist_enabled?
  !!@blacklist_enabled
end
blacklisted?(namespace) click to toggle source

Don't process non STIX or CybOX schemas

# File lib/stix_schema_spy/models/schema.rb, line 183
def self.blacklisted?(namespace)
  blacklist_enabled? && (namespace =~ /(stix)|(cybox)|(data-marking)/).nil?
end
build(schema_location, version = self.latest_version) click to toggle source

Build a new schema, cache it

# File lib/stix_schema_spy/models/schema.rb, line 133
def self.build(schema_location, version = self.latest_version)
  filename = schema_location.split('/').last
  if filename == 'generic.xsd'
    filename = schema_location.split('/')[-2..-1].join('/')
  end
  @@schemas_by_file[version] ||= {}
  @@schemas_by_file[version][filename] ||= self.new(schema_location, version)
end
config() click to toggle source

Return the schemas configuration hash

# File lib/stix_schema_spy/models/schema.rb, line 147
def self.config
  @@config
end
find(prefix_or_ns, version = self.latest_version) click to toggle source

Find a schema by prefix

# File lib/stix_schema_spy/models/schema.rb, line 157
def self.find(prefix_or_ns, version = self.latest_version)
  @@schemas[version] ||= {}
  if @@schemas[version][prefix_or_ns]
    @@schemas[version][prefix_or_ns]
  elsif schema_mapping = self.config['schemas'][prefix_or_ns]
    @@schemas[version][schema_mapping['prefix']]
  end
end
latest_version() click to toggle source
# File lib/stix_schema_spy/models/schema.rb, line 174
def self.latest_version
  "1.2"
end
namespaces() click to toggle source
# File lib/stix_schema_spy/models/schema.rb, line 166
def self.namespaces
  self.all.inject({'xs' => 'http://www.w3.org/2001/XMLSchema', 'xsi' => 'http://www.w3.org/2001/XMLSchema-instance'}) {|coll, schema| coll[schema.prefix] = schema.namespace; coll}
end
new(schema_location, version = self.latest_version) click to toggle source
# File lib/stix_schema_spy/models/schema.rb, line 24
def initialize(schema_location, version = self.latest_version)
  # Open the schema
  @filename = schema_location.split(/[\/\\]/).last
  @doc = Nokogiri::XML(open(schema_location))

  @elements = {}
  @attributes = {}
  @types = {}
  @special_fields = []
  @stix_version = version

  # Find this document's prefix (if any)
  @namespace = doc.root.attributes['targetNamespace'].value
  @prefix = find_prefix(doc)
  @@schemas[version] ||= {}
  @@schemas[version][prefix] = self

  # First, process any schemas that this schema imports (unless they're blacklisted)
  path = schema_location.split('/')[0...-1].join('/')
  doc.xpath('//xs:import', {'xs' => 'http://www.w3.org/2001/XMLSchema'}).each do |import|
    if self.class.config['schemas'][import.attributes['namespace'].value] && lp = Schema.config['schemas'][import.attributes['namespace'].value]['localPath']
      schema_location = "config/schemas/#{lp}"
    else
      schema_location = import.attributes['schemaLocation'].value
      schema_location = "#{path}/#{schema_location}" unless (schema_location =~ /http/)
    end
    self.class.build(schema_location, version) unless self.class.blacklisted?(import.attributes['namespace'].value)
  end

  doc.xpath('//xs:include', {'xs' => 'http://www.w3.org/2001/XMLSchema'}).each do |include_elem|
    schema_location = include_elem.attributes['schemaLocation'].value
    schema_location = "#{path}/#{schema_location}" unless (schema_location =~ /http/)
    @@schemas_by_file[version] ||= {}
    @@schemas_by_file[version][schema_location.split('/').last] = :imported
    process_doc(Nokogiri::XML(open(schema_location)))
  end

  process_doc(@doc)
end
preload!(version = self.latest_version, schema_location = nil) click to toggle source
# File lib/stix_schema_spy/models/schema.rb, line 203
def self.preload!(version = self.latest_version, schema_location = nil)
  @preloaded ||= {}
  return if @preloaded[version]
  @preloaded[version] = true
  schema_location ||= schema_dir(version)
  Dir.glob("#{schema_location}/cybox/*.xsd").each {|f| self.build(f, version)}
  Dir.glob("#{schema_location}/cybox/objects/*.xsd").each {|f| self.build(f, version)}
  Dir.glob("#{schema_location}/cybox/extensions/*.xsd").each {|f| self.build(f, version)}
  Dir.glob("#{schema_location}/*.xsd").each {|f| self.build(f, version)}
  Dir.glob("#{schema_location}/extensions/**/*.xsd").each {|f| self.build(f, version)}
  @uber_schema = Dir.chdir(schema_location) {
    Nokogiri::XML::Schema.new(File.read('uber_schema.xsd')) if File.exists?('uber_schema.xsd')
  }
  Schema.all(version).each(&:preload!)
  return true
end
schema_dir(version = self.latest_version) click to toggle source
# File lib/stix_schema_spy/models/schema.rb, line 170
def self.schema_dir(version = self.latest_version)
  File.join(File.dirname(File.expand_path(__FILE__)), '..', '..', '..', 'config', version, 'stix')
end
schema_root() click to toggle source
# File lib/stix_schema_spy/models/schema.rb, line 220
def self.schema_root
  @schema_root
end
schema_root=(value) click to toggle source
# File lib/stix_schema_spy/models/schema.rb, line 224
def self.schema_root=(value)
  @schema_root = value
end
schemas_by_file() click to toggle source
# File lib/stix_schema_spy/models/schema.rb, line 142
def self.schemas_by_file
  @@schemas_by_file
end

Public Instance Methods

blacklisted?() click to toggle source
# File lib/stix_schema_spy/models/schema.rb, line 228
def blacklisted?
  self.class.blacklisted?(self.namespace)
end
complex_types() click to toggle source
# File lib/stix_schema_spy/models/schema.rb, line 124
def complex_types
  @types.values.select {|t| t.kind_of?(ComplexType)}
end
config() click to toggle source

Get the configuration entry for this schema

# File lib/stix_schema_spy/models/schema.rb, line 71
def config
  @@config['schemas'][namespace] || {}
end
doc_path() click to toggle source

Returns the path to the documentation, just by looking it up in the config

# File lib/stix_schema_spy/models/schema.rb, line 115
def doc_path
  config['docs']
end
find_prefix(doc) click to toggle source

Find the namespace prefix by searching through the namespaces for the TNS

# File lib/stix_schema_spy/models/schema.rb, line 97
def find_prefix(doc)
  return config['prefix'] if config && config['prefix']

  # Loop through the attributes until we see one with the same value
  ns_prefix_attribute = doc.namespaces.find do |prefix, ns|
    ns.to_s == namespace.to_s && prefix != 'xmlns'
  end

  # If the attribute was found, return it, otherwise return nil
  ns_prefix_attribute ? ns_prefix_attribute[0].split(':').last : "Unknown"
end
find_type(name) click to toggle source

Find a type in this schema by name

# File lib/stix_schema_spy/models/schema.rb, line 110
def find_type(name)
  @types[name]
end
is_cybox_object?() click to toggle source

Returns whether the schema is a CybOX object

# File lib/stix_schema_spy/models/schema.rb, line 120
def is_cybox_object?
  namespace =~ /objects#/
end
latest_version() click to toggle source
# File lib/stix_schema_spy/models/schema.rb, line 178
def latest_version
  self.class.latest_version
end
load!() click to toggle source

More compatibility with type

# File lib/stix_schema_spy/models/schema.rb, line 87
def load!
  # Schemas are automatically loaded, so do nothing
end
parent_type() click to toggle source

Again, just for compatibility with Type

# File lib/stix_schema_spy/models/schema.rb, line 82
def parent_type
  false
end
preload!() click to toggle source
# File lib/stix_schema_spy/models/schema.rb, line 195
def preload!
  100.times do
    schema.elements.map(&:type)
    schema.attributes.map(&:type)
    schema.complex_types.each {|t| t.elements.each(&:type)}
  end
end
process_doc(doc) click to toggle source
# File lib/stix_schema_spy/models/schema.rb, line 64
def process_doc(doc)
  doc.xpath('/xs:schema/*', {'xs' => 'http://www.w3.org/2001/XMLSchema'}).each do |field|
    process_field(field)
  end
end
schema() click to toggle source

This makes the has_children module work a little easier (doesn't have to know the difference) between schemas and types.

# File lib/stix_schema_spy/models/schema.rb, line 77
def schema
  self
end
simple_types() click to toggle source
# File lib/stix_schema_spy/models/schema.rb, line 128
def simple_types
  @types.values.select {|t| t.kind_of?(SimpleType)}
end
version() click to toggle source

Find the version of this schema by looking at the version attribute

# File lib/stix_schema_spy/models/schema.rb, line 92
def version
  doc.root.attributes['version'].value || "Unknown"
end