Class: StixSchemaSpy::Schema
- Inherits:
-
Object
- Object
- StixSchemaSpy::Schema
- Includes:
- HasChildren, Util::SchemaNaming
- Defined in:
- lib/stix_schema_spy/models/schema.rb
Constant Summary collapse
- VERSIONS =
['1.2', '1.1.1', '1.1', '1.0.1', '1.0']
- @@schemas =
{}
- @@schemas_by_file =
{}
- @@config =
JSON.parse(File.read(File.join(File.dirname(File.(__FILE__)), '..', '..', '..', 'config', 'mappings.json')))
Constants included from Util::SchemaNaming
Util::SchemaNaming::EXTENSION_TYPE, Util::SchemaNaming::PROJECT_NAMES
Instance Attribute Summary collapse
-
#doc ⇒ Object
readonly
Returns the value of attribute doc.
-
#filename ⇒ Object
readonly
Returns the value of attribute filename.
-
#namespace ⇒ Object
readonly
Returns the value of attribute namespace.
-
#prefix ⇒ Object
readonly
Returns the value of attribute prefix.
-
#stix_version ⇒ Object
readonly
Returns the value of attribute stix_version.
-
#types ⇒ Object
readonly
Returns the value of attribute types.
Class Method Summary collapse
-
.all(version = self.latest_version) ⇒ Object
Get all schemas.
- .blacklist_enabled=(val) ⇒ Object
- .blacklist_enabled? ⇒ Boolean
-
.blacklisted?(namespace) ⇒ Boolean
Don’t process non STIX or CybOX schemas.
-
.build(schema_location, version = self.latest_version) ⇒ Object
Build a new schema, cache it.
-
.config ⇒ Object
Return the schemas configuration hash.
-
.find(prefix_or_ns, version = self.latest_version) ⇒ Object
Find a schema by prefix.
- .latest_version ⇒ Object
- .namespaces ⇒ Object
- .preload!(version = self.latest_version, schema_location = nil) ⇒ Object
- .schema_dir(version = self.latest_version) ⇒ Object
- .schema_root ⇒ Object
- .schema_root=(value) ⇒ Object
- .schemas_by_file ⇒ Object
Instance Method Summary collapse
- #blacklisted? ⇒ Boolean
- #complex_types ⇒ Object
-
#config ⇒ Object
Get the configuration entry for this schema.
-
#doc_path ⇒ Object
Returns the path to the documentation, just by looking it up in the config.
-
#find_prefix(doc) ⇒ Object
Find the namespace prefix by searching through the namespaces for the TNS.
-
#find_type(name) ⇒ Object
Find a type in this schema by name.
-
#initialize(schema_location, version = self.latest_version) ⇒ Schema
constructor
A new instance of Schema.
-
#is_cybox_object? ⇒ Boolean
Returns whether the schema is a CybOX object.
- #latest_version ⇒ Object
-
#load! ⇒ Object
More compatibility with type.
-
#parent_type ⇒ Object
Again, just for compatibility with Type.
- #preload! ⇒ Object
- #process_doc(doc) ⇒ Object
-
#schema ⇒ Object
This makes the has_children module work a little easier (doesn’t have to know the difference) between schemas and types.
- #simple_types ⇒ Object
-
#version ⇒ Object
Find the version of this schema by looking at the version attribute.
Methods included from Util::SchemaNaming
#project, #schema_location, #title, #type, #xpath_name
Methods included from HasChildren
#attributes, #elements, #fields, #find_attribute, #find_element, #own_fields
Constructor Details
#initialize(schema_location, version = self.latest_version) ⇒ Schema
Returns a new instance of Schema.
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# 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 |
Instance Attribute Details
#doc ⇒ Object (readonly)
Returns the value of attribute doc.
17 18 19 |
# File 'lib/stix_schema_spy/models/schema.rb', line 17 def doc @doc end |
#filename ⇒ Object (readonly)
Returns the value of attribute filename.
17 18 19 |
# File 'lib/stix_schema_spy/models/schema.rb', line 17 def filename @filename end |
#namespace ⇒ Object (readonly)
Returns the value of attribute namespace.
17 18 19 |
# File 'lib/stix_schema_spy/models/schema.rb', line 17 def namespace @namespace end |
#prefix ⇒ Object (readonly)
Returns the value of attribute prefix.
17 18 19 |
# File 'lib/stix_schema_spy/models/schema.rb', line 17 def prefix @prefix end |
#stix_version ⇒ Object (readonly)
Returns the value of attribute stix_version.
17 18 19 |
# File 'lib/stix_schema_spy/models/schema.rb', line 17 def stix_version @stix_version end |
#types ⇒ Object (readonly)
Returns the value of attribute types.
17 18 19 |
# File 'lib/stix_schema_spy/models/schema.rb', line 17 def types @types end |
Class Method Details
.all(version = self.latest_version) ⇒ Object
Get all schemas
152 153 154 |
# File 'lib/stix_schema_spy/models/schema.rb', line 152 def self.all(version = self.latest_version) @@schemas[version].values end |
.blacklist_enabled=(val) ⇒ Object
191 192 193 |
# File 'lib/stix_schema_spy/models/schema.rb', line 191 def self.blacklist_enabled=(val) @blacklist_enabled = val end |
.blacklist_enabled? ⇒ Boolean
187 188 189 |
# File 'lib/stix_schema_spy/models/schema.rb', line 187 def self.blacklist_enabled? !!@blacklist_enabled end |
.blacklisted?(namespace) ⇒ Boolean
Don’t process non STIX or CybOX schemas
183 184 185 |
# 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) ⇒ Object
Build a new schema, cache it
133 134 135 136 137 138 139 140 |
# 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 ⇒ Object
Return the schemas configuration hash
147 148 149 |
# File 'lib/stix_schema_spy/models/schema.rb', line 147 def self.config @@config end |
.find(prefix_or_ns, version = self.latest_version) ⇒ Object
Find a schema by prefix
157 158 159 160 161 162 163 164 |
# 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 ⇒ Object
174 175 176 |
# File 'lib/stix_schema_spy/models/schema.rb', line 174 def self.latest_version "1.2" end |
.namespaces ⇒ Object
166 167 168 |
# 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 |
.preload!(version = self.latest_version, schema_location = nil) ⇒ Object
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# 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) ⇒ Object
170 171 172 |
# File 'lib/stix_schema_spy/models/schema.rb', line 170 def self.schema_dir(version = self.latest_version) File.join(File.dirname(File.(__FILE__)), '..', '..', '..', 'config', version, 'stix') end |
.schema_root ⇒ Object
220 221 222 |
# File 'lib/stix_schema_spy/models/schema.rb', line 220 def self.schema_root @schema_root end |
.schema_root=(value) ⇒ Object
224 225 226 |
# File 'lib/stix_schema_spy/models/schema.rb', line 224 def self.schema_root=(value) @schema_root = value end |
.schemas_by_file ⇒ Object
142 143 144 |
# File 'lib/stix_schema_spy/models/schema.rb', line 142 def self.schemas_by_file @@schemas_by_file end |
Instance Method Details
#blacklisted? ⇒ Boolean
228 229 230 |
# File 'lib/stix_schema_spy/models/schema.rb', line 228 def blacklisted? self.class.blacklisted?(self.namespace) end |
#complex_types ⇒ Object
124 125 126 |
# File 'lib/stix_schema_spy/models/schema.rb', line 124 def complex_types @types.values.select {|t| t.kind_of?(ComplexType)} end |
#config ⇒ Object
Get the configuration entry for this schema
71 72 73 |
# File 'lib/stix_schema_spy/models/schema.rb', line 71 def config @@config['schemas'][namespace] || {} end |
#doc_path ⇒ Object
Returns the path to the documentation, just by looking it up in the config
115 116 117 |
# File 'lib/stix_schema_spy/models/schema.rb', line 115 def doc_path config['docs'] end |
#find_prefix(doc) ⇒ Object
Find the namespace prefix by searching through the namespaces for the TNS
97 98 99 100 101 102 103 104 105 106 107 |
# 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) ⇒ Object
Find a type in this schema by name
110 111 112 |
# File 'lib/stix_schema_spy/models/schema.rb', line 110 def find_type(name) @types[name] end |
#is_cybox_object? ⇒ Boolean
Returns whether the schema is a CybOX object
120 121 122 |
# File 'lib/stix_schema_spy/models/schema.rb', line 120 def is_cybox_object? namespace =~ /objects#/ end |
#latest_version ⇒ Object
178 179 180 |
# File 'lib/stix_schema_spy/models/schema.rb', line 178 def latest_version self.class.latest_version end |
#load! ⇒ Object
More compatibility with type
87 88 89 |
# File 'lib/stix_schema_spy/models/schema.rb', line 87 def load! # Schemas are automatically loaded, so do nothing end |
#parent_type ⇒ Object
Again, just for compatibility with Type
82 83 84 |
# File 'lib/stix_schema_spy/models/schema.rb', line 82 def parent_type false end |
#preload! ⇒ Object
195 196 197 198 199 200 201 |
# 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) ⇒ Object
64 65 66 67 68 |
# 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 ⇒ Object
This makes the has_children module work a little easier (doesn’t have to know the difference) between schemas and types.
77 78 79 |
# File 'lib/stix_schema_spy/models/schema.rb', line 77 def schema self end |
#simple_types ⇒ Object
128 129 130 |
# File 'lib/stix_schema_spy/models/schema.rb', line 128 def simple_types @types.values.select {|t| t.kind_of?(SimpleType)} end |
#version ⇒ Object
Find the version of this schema by looking at the version attribute
92 93 94 |
# File 'lib/stix_schema_spy/models/schema.rb', line 92 def version doc.root.attributes['version'].value || "Unknown" end |