1# Copyright (c) 2018, The MITRE Corporation. All rights reserved.
2# See LICENSE.txt for complete terms.
3
4import sys
5
6from mixbox.binding_utils import *
7
8from maec.bindings import maec_package as maec_package_schema
9
10class ContainerType(GeneratedsSuper):
11    """The ContainerType encompasses all forms of MAEC data. Currently,
12    this entails a list of Packages.The required id attribute
13    specifies a unique ID for this Container. The ID must follow the
14    pattern defined in the ContainerIDPattern simple type.The
15    required schema_version attribute specifies the version of the
16    MAEC Container Schema that the document has been written in and
17    that should be used for validation.The timestamp attribute
18    specifies the date/time that the Container was generated."""
19    subclass = None
20    superclass = None
21    def __init__(self, timestamp=None, id=None, schema_version=None, Packages=None):
22        self.timestamp = _cast(None, timestamp)
23        self.id = _cast(None, id)
24        self.schema_version = schema_version
25        self.Packages = Packages
26    def factory(*args_, **kwargs_):
27        if ContainerType.subclass:
28            return ContainerType.subclass(*args_, **kwargs_)
29        else:
30            return ContainerType(*args_, **kwargs_)
31    factory = staticmethod(factory)
32    def get_Packages(self): return self.Packages
33    def set_Packages(self, Packages): self.Packages = Packages
34    def get_timestamp(self): return self.timestamp
35    def set_timestamp(self, timestamp): self.timestamp = timestamp
36    def get_id(self): return self.id
37    def set_id(self, id): self.id = id
38    def get_schema_version(self): return self.schema_version
39    def set_schema_version(self, schema_version): self.schema_version = schema_version
40    def hasContent_(self):
41        if (
42            self.Packages is not None
43            ):
44            return True
45        else:
46            return False
47    def export(self, write, level, namespace_='maecContainer:', name_='MAEC_Container', namespacedef_='', pretty_print=True):
48        if pretty_print:
49            eol_ = '\n'
50        else:
51            eol_ = ''
52        showIndent(write, level, pretty_print)
53        write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', ))
54        already_processed = set()
55        self.exportAttributes(write, level, already_processed, namespace_, name_='MAEC_Container')
56        if self.hasContent_():
57            write('>%s' % (eol_, ))
58            self.exportChildren(write, level + 1, namespace_, name_, pretty_print=pretty_print)
59            showIndent(write, level, pretty_print)
60            write('</%s%s>%s' % (namespace_, name_, eol_))
61        else:
62            write('/>%s' % (eol_, ))
63    def exportAttributes(self, write, level, already_processed, namespace_='maecContainer:', name_='MAEC_Container'):
64        if self.timestamp is not None and 'timestamp' not in already_processed:
65            already_processed.add('timestamp')
66            write(' timestamp="%s"' % self.gds_format_datetime(self.timestamp, input_name='timestamp'))
67        if self.id is not None and 'id' not in already_processed:
68            already_processed.add('id')
69            write(' id=%s' % (quote_attrib(self.id), ))
70        if self.schema_version is not None and 'schema_version' not in already_processed:
71            already_processed.add('schema_version')
72            write(' schema_version="%s"' % self.schema_version)
73    def exportChildren(self, write, level, namespace_='maecContainer:', name_='MAEC_Container', fromsubclass_=False, pretty_print=True):
74        if pretty_print:
75            eol_ = '\n'
76        else:
77            eol_ = ''
78        if self.Packages is not None:
79            self.Packages.export(write, level, 'maecContainer:', name_='Packages', pretty_print=pretty_print)
80    def build(self, node):
81        self.__sourcenode__ = node
82        already_processed = set()
83        self.buildAttributes(node, node.attrib, already_processed)
84        for child in node:
85            nodeName_ = Tag_pattern_.match(child.tag).groups()[-1]
86            self.buildChildren(child, node, nodeName_)
87    def buildAttributes(self, node, attrs, already_processed):
88        value = find_attr_value_('timestamp', node)
89        if value is not None and 'timestamp' not in already_processed:
90            already_processed.add('timestamp')
91            try:
92                self.timestamp = value
93            except ValueError as exp:
94                raise ValueError('Bad date-time attribute (timestamp): %s' % exp)
95        value = find_attr_value_('id', node)
96        if value is not None and 'id' not in already_processed:
97            already_processed.add('id')
98            self.id = value
99        value = find_attr_value_('schema_version', node)
100        if value is not None and 'schema_version' not in already_processed:
101            already_processed.add('schema_version')
102            self.schema_version = value
103    def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
104        if nodeName_ == 'Packages':
105            obj_ = PackageListType.factory()
106            obj_.build(child_)
107            self.set_Packages(obj_)
108# end class ContainerType
109
110class PackageListType(GeneratedsSuper):
111    """The PackageListType captures a list of Packages."""
112    subclass = None
113    superclass = None
114    def __init__(self, Package=None):
115        if Package is None:
116            self.Package = []
117        else:
118            self.Package = Package
119    def factory(*args_, **kwargs_):
120        if PackageListType.subclass:
121            return PackageListType.subclass(*args_, **kwargs_)
122        else:
123            return PackageListType(*args_, **kwargs_)
124    factory = staticmethod(factory)
125    def get_Package(self): return self.Package
126    def set_Package(self, Package): self.Package = Package
127    def add_Package(self, value): self.Package.append(value)
128    def insert_Package(self, index, value): self.Package[index] = value
129    def hasContent_(self):
130        if (
131            self.Package
132            ):
133            return True
134        else:
135            return False
136    def export(self, write, level, namespace_='maecContainer:', name_='PackageListType', namespacedef_='', pretty_print=True):
137        if pretty_print:
138            eol_ = '\n'
139        else:
140            eol_ = ''
141        showIndent(write, level, pretty_print)
142        write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', ))
143        already_processed = set()
144        self.exportAttributes(write, level, already_processed, namespace_, name_='PackageListType')
145        if self.hasContent_():
146            write('>%s' % (eol_, ))
147            self.exportChildren(write, level + 1, namespace_, name_, pretty_print=pretty_print)
148            showIndent(write, level, pretty_print)
149            write('</%s%s>%s' % (namespace_, name_, eol_))
150        else:
151            write('/>%s' % (eol_, ))
152    def exportAttributes(self, write, level, already_processed, namespace_='maecContainer:', name_='PackageListType'):
153        pass
154    def exportChildren(self, write, level, namespace_='maecContainer:', name_='PackageListType', fromsubclass_=False, pretty_print=True):
155        if pretty_print:
156            eol_ = '\n'
157        else:
158            eol_ = ''
159        for Package_ in self.Package:
160            Package_.export(write, level, 'maecContainer:', name_='Package', pretty_print=pretty_print)
161    def build(self, node):
162        self.__sourcenode__ = node
163        already_processed = set()
164        self.buildAttributes(node, node.attrib, already_processed)
165        for child in node:
166            nodeName_ = Tag_pattern_.match(child.tag).groups()[-1]
167            self.buildChildren(child, node, nodeName_)
168    def buildAttributes(self, node, attrs, already_processed):
169        pass
170    def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
171        if nodeName_ == 'Package':
172            obj_ = maec_package_schema.PackageType.factory()
173            obj_.build(child_)
174            self.Package.append(obj_)
175# end class PackageListType
176
177USAGE_TEXT = """
178Usage: python <Parser>.py [ -s ] <in_xml_file>
179"""
180
181def usage():
182    print(USAGE_TEXT)
183    sys.exit(1)
184
185def get_root_tag(node):
186    tag = Tag_pattern_.match(node.tag).groups()[-1]
187    rootClass = GDSClassesMapping.get(tag)
188    if rootClass is None:
189        rootClass = globals().get(tag)
190    return tag, rootClass
191
192def parse(inFileName):
193    doc = parsexml_(inFileName)
194    rootNode = doc.getroot()
195    rootTag, rootClass = get_root_tag(rootNode)
196    rootObj = rootClass.factory()
197    rootObj.build(rootNode)
198    # Enable Python to collect the space used by the DOM.
199    doc = None
200    #sys.stdout.write('<?xml version="1.0" ?>\n')
201    #rootObj.export(sys.stdout, 0, name_=rootTag,
202    #    namespacedef_='',
203    #    pretty_print=True)
204    return rootObj
205
206def parseEtree(inFileName):
207    doc = parsexml_(inFileName)
208    rootNode = doc.getroot()
209    rootTag, rootClass = get_root_tag(rootNode)
210    rootObj = rootClass.factory()
211    rootObj.build(rootNode)
212    # Enable Python to collect the space used by the DOM.
213    doc = None
214    rootElement = rootObj.to_etree(None, name_=rootTag)
215    content = etree_.tostring(rootElement, pretty_print=True,
216        xml_declaration=True, encoding="utf-8")
217    sys.stdout.write(content)
218    sys.stdout.write('\n')
219    return rootObj, rootElement
220
221def parseString(inString):
222    from mixbox.vendor.six import StringIO
223    doc = parsexml_(StringIO(inString))
224    rootNode = doc.getroot()
225    rootTag, rootClass = get_root_tag(rootNode)
226    rootObj = rootClass.factory()
227    rootObj.build(rootNode)
228    # Enable Python to collect the space used by the DOM.
229    doc = None
230    #sys.stdout.write('<?xml version="1.0" ?>\n')
231    #rootObj.export(sys.stdout, 0, name_="MAEC_Container",
232    #    namespacedef_='')
233    return rootObj
234
235def parseLiteral(inFileName):
236    doc = parsexml_(inFileName)
237    rootNode = doc.getroot()
238    rootTag, rootClass = get_root_tag(rootNode)
239    rootObj = rootClass.factory()
240    rootObj.build(rootNode)
241    # Enable Python to collect the space used by the DOM.
242    doc = None
243    sys.stdout.write('#from maec_container_temp import *\n\n')
244    sys.stdout.write('from datetime import datetime as datetime_\n\n')
245    sys.stdout.write('import maec_container_temp as model_\n\n')
246    sys.stdout.write('rootObj = model_.rootTag(\n')
247    rootObj.exportLiteral(sys.stdout, 0, name_=rootTag)
248    sys.stdout.write(')\n')
249    return rootObj
250
251def main():
252    args = sys.argv[1:]
253    if len(args) == 1:
254        parse(args[0])
255    else:
256        usage()
257
258if __name__ == '__main__':
259    #import pdb; pdb.set_trace()
260    main()
261
262__all__ = [
263    "ContainerType",
264    "PackageListType"
265    ]
266
267GDSClassesMapping = {
268    "ContainerType": ContainerType,
269    "PackageListType": PackageListType
270}
271