Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 6 additions & 13 deletions docs/api/utils/nsparser.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,15 @@

.. module:: stix.utils.nsparser

Classes
-------
Functions
---------

.. autoclass:: NamespaceParser
:show-inheritance:
:members:
.. autofunction:: get_namespaces
.. autofunction:: get_namespace_schemalocation_dict
.. autofunction:: get_xmlns_str
.. autofunction:: get_schemaloc_str

Constants
---------

.. autodata:: XML_NAMESPACES

.. autodata:: STIX_NS_TO_SCHEMALOCATION

.. autodata:: EXT_NS_TO_SCHEMALOCATION

.. autodata:: DEFAULT_STIX_NS_TO_PREFIX

.. autodata:: DEFAULT_EXT_TO_PREFIX
90 changes: 13 additions & 77 deletions stix/base.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.

# builtin
import json
import collections
import itertools
import json
import StringIO

from mixbox import entities
from mixbox import idgen
from mixbox.binding_utils import save_encoding
from mixbox.cache import Cached
from mixbox.datautils import is_sequence

# internal
from . import utils


def _override(*args, **kwargs):
raise NotImplementedError()


class Entity(object):
class Entity(entities.Entity):
"""Base class for all classes in the STIX API."""
_namespace = None
_XSI_TYPE = None
Expand Down Expand Up @@ -145,7 +145,6 @@ def to_xml(self, include_namespaces=True, include_schemalocs=False,
"""

from .utils import nsparser
parser = nsparser.NamespaceParser()

if auto_namespace:
ns_info = nsparser.NamespaceInfo()
Expand Down Expand Up @@ -176,11 +175,11 @@ def to_xml(self, include_namespaces=True, include_schemalocs=False,

namespace_def = ""
if include_namespaces:
xmlns = parser.get_xmlns_str(ns_info.finalized_namespaces)
xmlns = nsparser.get_xmlns_str(ns_info.finalized_namespaces)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think line 182 needs to be updated as well since it still refers to the parser module.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Fixed in a08cb12

namespace_def += ("\n\t" + xmlns)

if include_schemalocs and include_namespaces:
schemaloc = parser.get_schemaloc_str(ns_info.finalized_schemalocs)
schemaloc = nsparser.get_schemaloc_str(ns_info.finalized_schemalocs)
namespace_def += ("\n\t" + schemaloc)

if not pretty:
Expand Down Expand Up @@ -269,75 +268,15 @@ def find(self, id_):
return entity


class EntityList(collections.MutableSequence, Entity):
# TODO: For now, this subclasses mixbox.entities.EntityList and stix.Entity.
# Ultimately we want to remove the latter.
class EntityList(entities.EntityList, Entity):
_binding_class = _override
_binding_var = None
_contained_type = _override
_inner_name = None
_dict_as_list = False

def __init__(self, *args):
super(EntityList, self).__init__()
self._inner = []

if not any(args):
return

for arg in args:
if utils.is_sequence(arg):
self.extend(arg)
else:
self.append(arg)

def __nonzero__(self):
return bool(self._inner)

def __getitem__(self, key):
return self._inner.__getitem__(key)

def __setitem__(self, key, value):
if not self._is_valid(value):
value = self._fix_value(value)
self._inner.__setitem__(key, value)

def __delitem__(self, key):
self._inner.__delitem__(key)

def __len__(self):
return len(self._inner)

def insert(self, idx, value):
if not value:
return
if not self._is_valid(value):
value = self._fix_value(value)
self._inner.insert(idx, value)

def _is_valid(self, value):
"""Check if this is a valid object to add to the list."""
# Subclasses can override this function, but if it becomes common, it's
# probably better to use self._contained_type.istypeof(value)
return isinstance(value, self._contained_type)

def _fix_value(self, value):
"""Attempt to coerce value into the correct type.

Subclasses can override this function.
"""
try:
new_value = self._contained_type(value)
except:
error = "Can't put '{0}' ({1}) into a {2}. Expected a {3} object."
error = error.format(
value, # Input value
type(value), # Type of input value
type(self), # Type of collection
self._contained_type # Expected type of input value
)
raise ValueError(error)

return new_value

# The next four functions can be overridden, but otherwise define the
# default behavior for EntityList subclasses which define the following
# class-level members:
Expand All @@ -357,9 +296,6 @@ def to_obj(self, return_obj=None, ns_info=None):

return return_obj

def to_list(self):
return [h.to_dict() for h in self]

def to_dict(self):
if self._dict_as_list:
return self.to_list()
Expand Down Expand Up @@ -392,7 +328,7 @@ def from_obj(cls, obj, return_obj=None, contained_type=None,
@classmethod
def from_list(cls, list_repr, return_obj=None, contained_type=None):

if not utils.is_sequence(list_repr):
if not is_sequence(list_repr):
return None

if return_obj is None:
Expand Down Expand Up @@ -494,7 +430,7 @@ def from_obj(cls, obj_list, contained_type=None):
if not contained_type:
contained_type = cls._contained_type

if not utils.is_sequence(obj_list):
if not is_sequence(obj_list):
obj_list = [obj_list]

items = (contained_type.from_obj(x) for x in obj_list)
Expand All @@ -506,7 +442,7 @@ def from_list(cls, list_repr, contained_type=None):
if not list_repr:
return None

if isinstance(list_repr, dict) or not utils.is_sequence(list_repr):
if isinstance(list_repr, dict) or not is_sequence(list_repr):
list_repr = [list_repr]

if not contained_type:
Expand Down Expand Up @@ -539,7 +475,7 @@ def _initialize_inner(self, *args):
return

for arg in args:
if utils.is_sequence(arg):
if is_sequence(arg):
self.extend(arg)
else:
self.append(arg)
Expand Down
8 changes: 3 additions & 5 deletions stix/common/information_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@

from __future__ import absolute_import

# external
from mixbox.datautils import is_sequence
#
import cybox.common

# internal
import stix
import stix.utils as utils
import stix.bindings.stix_common as stix_common_binding

# relative
from . import vocabs, VocabString
from .identity import Identity
from .structured_text import StructuredTextList
Expand Down Expand Up @@ -52,7 +50,7 @@ def references(self, value):

if not value:
return
elif utils.is_sequence(value):
elif is_sequence(value):
for v in value:
self.add_reference(v)
else:
Expand Down
12 changes: 7 additions & 5 deletions stix/common/structured_text.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.

import itertools
import contextlib
import collections
import contextlib
import itertools

from mixbox.datautils import is_sequence
from mixbox.exceptions import ignored

import stix
import stix.utils as utils
import stix.bindings.stix_common as stix_common_binding

#: Default ordinality value for StructuredText.
Expand Down Expand Up @@ -199,7 +201,7 @@ def _initialize_inner(self, *args):
return

for arg in args:
if utils.is_sequence(arg):
if is_sequence(arg):
self.update(arg)
else:
self.add(arg)
Expand Down Expand Up @@ -323,7 +325,7 @@ def add(self, value):
value.ordinality = self.next_ordinality

# Remove the existing item if there is one.
with utils.ignored(KeyError):
with ignored(KeyError):
del self[value.ordinality]

self._inner.append(value)
Expand Down
6 changes: 4 additions & 2 deletions stix/core/ttps.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.

from mixbox.datautils import is_sequence

import stix
import stix.utils as utils
from stix.ttp import TTP
from stix.common.kill_chains import KillChains
from stix.bindings import stix_core as core_binding

# deprecation warnings
from stix.utils.deprecated import idref_deprecated


class TTPs(stix.EntityList):
_binding = core_binding
_binding_class = _binding.TTPsType
Expand All @@ -33,7 +35,7 @@ def ttps(self):
def ttps(self, value):
self._inner = []

if utils.is_sequence(value):
if is_sequence(value):
self.extend(value)
else:
self.append(value)
Expand Down
4 changes: 3 additions & 1 deletion stix/exploit_target/vulnerability.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.

from mixbox.datautils import is_sequence

import stix
import stix.utils as utils
import stix.bindings.exploit_target as exploit_target_binding
Expand Down Expand Up @@ -198,7 +200,7 @@ def references(self, value):

if not value:
return
elif utils.is_sequence(value):
elif is_sequence(value):
self._references.extend(x for x in value if x)
else:
self._references.append(value)
Expand Down
Loading