Beispiel #1
0
    def swagger_type(t):
        if t.WhichOneof('type') == 'set':
            return {'type': 'array', 'items': swagger_type(t.set)}

        # TODO: Probably should use datamodel.typeref
        if t.WhichOneof('type') == 'type_ref':
            # TODO: What is the impact of removing this?
            #assert len(t.type_ref.ref.path) == 1
            model = t.type_ref.ref.path[0]
            if model in module.apps:
                used_models.add(model)
                return {'$ref': '#/definitions/' + model}

        type_ = datamodel.typeref(t, module)[2]
        if type_ is None:
            return None

        which_type = type_.WhichOneof('type')

        if which_type == 'primitive':
            return TYPE_MAP[type_.primitive]
        elif which_type == 'enum':
            return {'type': 'number', 'format': 'integer'}
        elif which_type in ['tuple', 'relation']:
            deftype = '.'.join(t.type_ref.ref.path)
            used_definitions.add(deftype)
            return {'$ref': '#/definitions/' + deftype}
        else:
            # return {'type': 'sysl:' + type_.WhichOneof('type')}
            raise RuntimeError('Unexpected field type for Swagger '
                               'export: ' + which_type)
Beispiel #2
0
    def swagger_type(t):
        if t.WhichOneof('type') == 'set':
            return {'type': 'array', 'items': swagger_type(t.set)}

        # TODO: Probably should use datamodel.typeref
        if t.WhichOneof('type') == 'type_ref':
            # TODO: What is the impact of removing this?
            #assert len(t.type_ref.ref.path) == 1
            model = t.type_ref.ref.path[0]
            if model in module.apps:
                used_models.add(model)
                return {'$ref': '#/definitions/' + model}

        type_ = datamodel.typeref(t, module)[2]
        if type_ is None:
            return None

        which_type = type_.WhichOneof('type')

        if which_type == 'primitive':
            return TYPE_MAP[type_.primitive]
        elif which_type == 'enum':
            return {'type': 'number', 'format': 'integer'}
        elif which_type in ['tuple', 'relation']:
            deftype = '.'.join(t.type_ref.ref.path)
            used_definitions.add(deftype)
            return {'$ref': '#/definitions/' + deftype}
        else:
            # return {'type': 'sysl:' + type_.WhichOneof('type')}
            raise RuntimeError(
                'Unexpected field type for Swagger '
                'export: ' + which_type)
Beispiel #3
0
def export_model_js(module, appname, outpath, indent):
    '''The Model as JSON'''
    app = module.apps.get(appname)
    assert app, appname

    model = {}
    model['_version'] = '0.1'
    model['model'] = '_'.join(app.name.part)
    tables = model['types'] = {}

    for (tname, t) in app.types.iteritems():
        titem = tables[tname] = {}
        tmeta = titem['_'] = {}
        if t.HasField('relation'):
            tmeta['rel'] = True

        pkey = datamodel.primary_key_params(t, module)
        pkey_fields = {f for (_, f, _) in pkey}
        param_defs = [(typ, f) for (typ, _, f) in pkey]
        pk_param = ', '.join(f for (_, _, f) in pkey)

        fkeys = {
            java.name(fname): type_info
            for (fname, _, type_info) in datamodel.foreign_keys(t, module)
        }

        for (fname, f) in datamodel.sorted_fields(t):
            jfname = java.name(fname)
            (java_type, type_info, ftype) = datamodel.typeref(f, module)

            which_f = f.WhichOneof('type')
            if which_f == 'primitive':
                ftname = ftype.primitive
            elif fname in fkeys:
                fk_type_info = fkeys[fname]
                ftname = (fk_type_info.parent_path +
                          ('.' + fk_type_info.field
                           if fk_type_info.field != jfname else '='))

            if fname in pkey_fields:
                jfname += '*'
            elif 'required' in syslx.patterns(f.attrs):
                jfname += '!'

            fitem = titem[jfname] = [ftname]

            if len(fitem) == 1:
                fitem = titem[jfname] = fitem[0]

    out = cStringIO.StringIO()
    js_dump(appname, model, indent, out)
    open(outpath, 'w').write(out.getvalue())
Beispiel #4
0
 def build_element(attr_fname, attr_f, is_set, is_attr):
     jfname = java.name(attr_fname)
     method = java.CamelCase(jfname)
     type_ = datamodel.typeref(attr_f, context.module)[2]
     which_type = type_.WhichOneof('type')
     if which_type == 'primitive':
         xsdtype = XSD_TYPE_MAP[type_.primitive]
     elif which_type == 'enum':
         xsdtype = 'xs:int'
     elif which_type == 'tuple':
         offset = -1
         if is_set:
             offset = -2
         xsdtype = datamodel.typeref(attr_f,
                                     context.module)[0].split('.')[offset]
     else:
         raise RuntimeError('Unexpected field type for XSD '
                            'export: ' + which_type)
     if is_attr:
         xs('attribute/', name=jfname, type=xsdtype, use='optional')
     else:
         xs('element/', name=jfname, type=xsdtype, minOccurs=0)
Beispiel #5
0
 def build_element(attr_fname, attr_f, is_set, is_attr):
     jfname = java.name(attr_fname)
     method = java.CamelCase(jfname)
     type_ = datamodel.typeref(attr_f, context.module)[2]
     which_type = type_.WhichOneof('type')
     if which_type == 'primitive':
         xsdtype = XSD_TYPE_MAP[type_.primitive]
     elif which_type == 'enum':
         xsdtype = 'xs:int'
     elif which_type == 'tuple':
         offset = -1
         if is_set:
             offset = -2
         xsdtype = datamodel.typeref(attr_f, context.module)[
             0].split('.')[offset]
     else:
         raise RuntimeError(
             'Unexpected field type for XSD '
             'export: ' + which_type)
     if is_attr:
         xs('attribute/', name=jfname, type=xsdtype, use='optional')
     else:
         xs('element/', name=jfname, type=xsdtype, minOccurs=0)
Beispiel #6
0
def export_model_js(module, appname, outpath, indent):
    '''The Model as JSON'''
    app = module.apps.get(appname)
    assert app, appname

    model = {}
    model['_version'] = '0.1'
    model['model'] = '_'.join(app.name.part)
    tables = model['types'] = {}

    for (tname, t) in app.types.iteritems():
        titem = tables[tname] = {}
        tmeta = titem['_'] = {}
        if t.HasField('relation'):
            tmeta['rel'] = True

        pkey = datamodel.primary_key_params(t, module)
        pkey_fields = {f for (_, f, _) in pkey}
        param_defs = [(typ, f) for (typ, _, f) in pkey]
        pk_param = ', '.join(f for (_, _, f) in pkey)

        fkeys = {java.name(fname): type_info
                 for (fname, _, type_info) in datamodel.foreign_keys(t, module)}

        for (fname, f) in datamodel.sorted_fields(t):
            jfname = java.name(fname)
            (java_type, type_info, ftype) = datamodel.typeref(f, module)

            which_f = f.WhichOneof('type')
            if which_f == 'primitive':
                ftname = ftype.primitive
            elif fname in fkeys:
                fk_type_info = fkeys[fname]
                ftname = (
                    fk_type_info.parent_path +
                    ('.' + fk_type_info.field if fk_type_info.field != jfname else '='))

            if fname in pkey_fields:
                jfname += '*'
            elif 'required' in syslx.patterns(f.attrs):
                jfname += '!'

            fitem = titem[jfname] = [ftname]

            if len(fitem) == 1:
                fitem = titem[jfname] = fitem[0]

    out = cStringIO.StringIO()
    js_dump(appname, model, indent, out)
    open(outpath, 'w').write(out.getvalue())
Beispiel #7
0
def export_facade_class(context):
    model_name = syslx.fmt_app_name(context.wrapped_model.name)
    modelpkg = syslx.View(context.wrapped_model.attrs)['package'].s

    w = writer.Writer('java')

    java.Package(w, context.package)
    java.StandardImports(w)
    java.Import(w, modelpkg + '.' + model_name)

    w()
    with java.Class(w,
                    context.appname,
                    context.write_file,
                    package=context.package):
        with java.Ctor(w, '\npublic', context.appname,
                       [(model_name, 'model')]):
            w('this.model = model;')
            for (tname, _, _) in syslx.wrapped_facade_types(context):
                w('this.{}Facade = new {}Facade();',
                  java.safe(tname[:1].lower() + tname[1:]), tname)

        with java.Method(w, '\npublic', model_name, 'getModel'):
            w('return model;')

        java.SeparatorComment(w)

        for (tname, ft, t) in syslx.wrapped_facade_types(context):
            if t.HasField('relation'):
                pkey = datamodel.primary_key_params(t, context.module)
                pkey_fields = {f for (_, f, _) in pkey}
                param_defs = [(typ, jfname) for (typ, fname, jfname) in pkey
                              if 'autoinc' not in syslx.patterns(
                                  t.relation.attr_defs[fname].attrs)]
                params = ''.join(', ' + f for (_, f) in param_defs)
                param = ', '.join(f for (_, f) in param_defs)

                fkeys = {
                    java.name(fname): type_info
                    for (fname, _, type_info
                         ) in datamodel.foreign_keys(t, context.module)
                }

                inner_type = ('HashMap<Key, {}>'
                              if pkey else 'HashSet<{}>').format(tname)

                required = []
                for fname in sorted(ft.relation.attr_defs.keys()):
                    f = t.relation.attr_defs.get(fname)
                    if ('required' in syslx.patterns(f.attrs)
                            or 'required' in syslx.patterns(
                                ft.relation.attr_defs.get(fname).attrs)):
                        jfname = java.name(fname)
                        method = java.CamelCase(jfname)
                        (java_type, type_info,
                         _) = datamodel.typeref(f, context.module)
                        if java_type == 'Object':
                            datamodel.typeref(f, context.module)
                        required.append((fname, java_type))

                with java.Method(w, '\npublic', tname + 'Facade',
                                 'get' + tname):
                    w('return {}Facade;',
                      java.safe(tname[:1].lower() + tname[1:]))

                w()
                with java.Class(w, tname + 'Facade', context.write_file):
                    with java.Method(w, 'public',
                                     '{}.{}.Table'.format(modelpkg,
                                                          tname), 'table'):
                        w('return model.get{}Table();', tname, param)

                    w()
                    if param_defs or required:
                        with java.Method(w, 'public', 'Builder0', 'build'):
                            w('return new Builder0();')

                        keytypes = {f: kt for (kt, f) in param_defs}
                        keys = sorted(keytypes)
                        keyindices = {k: i for (i, k) in enumerate(keys)}

                        if len(keys) > 3:
                            # 4 perms yields 16 builders with 32 setters.
                            logging.error('OUCH! Too many primary key fields')
                            raise Exception('Too many primary key fields')
                        for perm in range(2**len(keys)):
                            bname = 'Builder' + str(perm)
                            w()
                            with java.Class(w, bname, context.write_file):
                                done = [
                                    k for (i, k) in enumerate(keys)
                                    if 2**i & perm
                                ]
                                remaining = [k for k in keys if k not in done]

                                with java.Ctor(w, '', bname, [(keytypes[k], k)
                                                              for k in done]):
                                    for k in done:
                                        w('this.{0} = {0};', k)
                                    if required and not remaining:
                                        w(
                                            'this._pending = {};',
                                            hex(2**len(required) -
                                                1).rstrip('L'))

                                for fname in remaining:
                                    f = t.relation.attr_defs[fname]
                                    jfname = java.name(fname)
                                    method = java.CamelCase(jfname)
                                    (java_type, type_info,
                                     _) = datamodel.typeref(f, context.module)
                                    next_bname = 'Builder{}'.format(
                                        perm | 2**keyindices[fname])
                                    w()

                                    if jfname in fkeys:
                                        fk_type = fkeys[jfname].parent_path
                                        fk_field = fkeys[jfname].field
                                        if f.type_ref.ref.path[-1:] == [fname]:
                                            method_suffix = fk_type
                                        else:
                                            method_suffix = method + 'From'
                                        with java.Method(
                                                w, 'public', next_bname,
                                                'with' + method_suffix,
                                            [(modelpkg + '.' + fk_type,
                                              'entity')]):
                                            w(
                                                '{} {} = entity == null ? null : entity.get{}();',
                                                java_type, jfname,
                                                java.CamelCase(fk_field))
                                            w(
                                                'return new {}({});',
                                                next_bname,
                                                ', '.join(k for k in keys
                                                          if k == fname
                                                          or k in done))
                                    else:
                                        with java.Method(
                                                w, 'public', next_bname,
                                                'with' + java.CamelCase(fname),
                                            [(keytypes[fname], fname)]):
                                            w(
                                                'return new {}({});',
                                                next_bname,
                                                ', '.join(k for k in keys
                                                          if k == fname
                                                          or k in done))

                                if not remaining:
                                    for (i, (r, rtype)) in enumerate(required):
                                        method = java.CamelCase(r)
                                        w()

                                        # TODO: jfname set in a previous loop??
                                        if jfname in fkeys:
                                            fk_type = fkeys[jfname].parent_path
                                            fk_field = fkeys[jfname].field
                                            if f.type_ref.ref.path[-1:] == [
                                                    fname
                                            ]:
                                                method = fk_type
                                            else:
                                                method += 'From'
                                            with java.Method(
                                                    w, 'public', bname,
                                                    'with' + method,
                                                [(modelpkg + '.' + fk_type,
                                                  java.mixedCase(fk_type))]):
                                                with java.If(
                                                        w,
                                                        '(_pending & {}) == 0',
                                                        hex(2**i)):
                                                    # TODO: More specific
                                                    # exception
                                                    w('throw new RuntimeException();'
                                                      )
                                                w('this.{0} = {0};',
                                                  java.mixedCase(fk_type))
                                                w('_pending &= ~{};',
                                                  hex(2**i))
                                                w('return this;')
                                        else:
                                            with java.Method(
                                                    w, 'public', bname,
                                                    'with' + method,
                                                [(rtype, r)]):
                                                with java.If(
                                                        w,
                                                        '(_pending & {}) == 0',
                                                        hex(2**i)):
                                                    # TODO: More specific
                                                    # exception
                                                    w('throw new RuntimeException();'
                                                      )
                                                w('this.{0} = {0};', r)
                                                w('_pending &= ~{};',
                                                  hex(2**i))
                                                w('return this;')

                                    with java.Method(w, '\npublic',
                                                     modelpkg + '.' + tname,
                                                     'insert'):
                                        if required:
                                            with java.If(w, '_pending != 0'):
                                                # TODO: More specific exception
                                                w('throw new RuntimeException();'
                                                  )
                                            w(
                                                u'{} result = table()._PRIVATE_insert({});',
                                                modelpkg + '.' + tname, param)
                                            for (r, rtype) in required:
                                                if jfname in fkeys:
                                                    fk_field = fkeys[
                                                        jfname].field
                                                    w('result.set{}({});',
                                                      fk_type,
                                                      java.mixedCase(fk_type))
                                                else:
                                                    w('result.set{}({});',
                                                      java.CamelCase(r), r)
                                            w('return result;')
                                        else:
                                            w(
                                                u'return table()._PRIVATE_insert({});',
                                                param)

                                if done:
                                    w()
                                    w('// primary key')
                                    for d in done:
                                        w('private final {} {};', keytypes[d],
                                          d)

                                if required and not remaining:
                                    w()
                                    w('// required fields')
                                    for (r, rtype) in required:
                                        if jfname in fkeys:
                                            fk_type = fkeys[jfname].parent_path
                                            fk_field = fkeys[jfname].field
                                            w('private {} {};',
                                              modelpkg + '.' + fk_type,
                                              java.mixedCase(fk_type))
                                        else:
                                            w('private {} {};', rtype, r)
                                    w()
                                    w('private int _pending;')
                    else:
                        with java.Method(w, 'public', modelpkg + '.' + tname,
                                         'insert'):
                            w('{} result = table()._PRIVATE_insert();',
                              modelpkg + '.' + tname)
                            w('return result;')

                java.SeparatorComment(w)

        for (tname, _, t) in syslx.wrapped_facade_types(context):
            if t.HasField('relation'):
                w('private final {}Facade {}Facade;', tname,
                  java.safe(tname[:1].lower() + tname[1:]))

        w()
        w('private final {}.{} model;', modelpkg, model_name)
        w()
Beispiel #8
0
def serializer(context):
    (app, module, package, model_class, write_file, _, _) = context

    facade = bool(context.wrapped_model)

    w = writer.Writer('java')

    java.Package(w, package)

    java.StandardImports(w)

    java.Import(w, 'java.text.ParseException')
    w.head()
    java.Import(w, 'javax.xml.stream.XMLStreamException')
    java.Import(w, 'javax.xml.stream.XMLStreamWriter')
    w.head()
    java.Import(w, 'org.joda.time.format.DateTimeFormatter')
    java.Import(w, 'org.joda.time.format.ISODateTimeFormat')

    if facade:
        model_name = syslx.fmt_app_name(context.wrapped_model.name)
        modelpkg = syslx.View(context.wrapped_model.attrs)['package'].s
        w.head()
        java.Import(w, modelpkg + '.*')
    else:
        modelpkg = package

    with java.Class(w, '\n{}XmlSerializer'.format(model_class), write_file,
                    package=package):
        with java.Method(w, '\npublic', 'void', 'serialize',
                         [(model_class, 'facade' if facade else 'model'),
                          ('XMLStreamWriter', 'xsw')],
                         throws=['XMLStreamException']):
            if facade:
                w('{} model = facade.getModel();', model_name)

            w('xsw.writeStartElement("{}");', model_class)
            for (tname, ft, t) in syslx.sorted_types(context):
                if t.WhichOneof('type') == 'relation':
                    w('serialize(model.get{0}Table(), xsw, "{0}");', tname)
            w('xsw.writeEndElement();')

        for (tname, ft, t) in syslx.sorted_types(context):
            java.SeparatorComment(w)

            if t.WhichOneof('type') in ['relation', 'tuple']:
                with java.Method(w, '\npublic', 'void', 'serialize',
                                 [(modelpkg + '.' + tname + '.View', 'view'),
                                  ('XMLStreamWriter', 'xsw'),
                                  ('String', 'tag')],
                                 throws=['XMLStreamException']):
                    with java.If(w, 'view == null || view.isEmpty()'):
                        w('return;')
                    if t.WhichOneof('type') == 'relation':
                        w('xsw.writeStartElement("{}List");', tname)
                    order = [o.s for o in syslx.View(
                        t.attrs)['xml_order'].a.elt]
                    if order:
                        order_logic = []
                        for o in order:
                            order_logic.append(
                                '            i = io.sysl.ExprHelper.doCompare'
                                '(a.get{0}(), b.get{0}());\n'
                                '            if (i != 0) return i;\n'.format(java.CamelCase(o)))
                        order_by = (
                            '.orderBy(\n'
                            '    new java.util.Comparator<{0}> () {{\n'
                            '        @Override\n'
                            '        public int compare({0} a, {0} b) {{\n'
                            '            int i;\n'
                            '{1}'
                            '            return 0;\n'
                            '        }}\n'
                            '    }})\n').format(tname, ''.join(order_logic))
                    else:
                        order_by = ''

                    with java.For(w, '{} item : view{}',
                                  modelpkg + '.' + tname, order_by):
                        w('serialize(item, xsw, tag);', tname)
                    if t.WhichOneof('type') == 'relation':
                        w('xsw.writeEndElement();')

                with java.Method(w, '\npublic', 'void', 'serialize',
                                 [(modelpkg + '.' + tname, 'entity'),
                                  ('XMLStreamWriter', 'xsw')],
                                 throws=['XMLStreamException']):
                    w('serialize(entity, xsw, "{}");', tname)

                with java.Method(w, '\npublic', 'void', 'serialize',
                                 [(modelpkg + '.' + tname, 'entity'),
                                  ('XMLStreamWriter', 'xsw'),
                                  ('String', 'tag')],
                                 throws=['XMLStreamException']):
                    with java.If(w, 'entity == null'):
                        w('return;')
                    w('xsw.writeStartElement(tag);', tname)
                    for wantAttrs in [True, False]:
                        for (fname, f) in datamodel.sorted_fields(t):
                            jfname = java.name(fname)
                            method = java.CamelCase(jfname)
                            tref = datamodel.typeref(f, module)
                            type_ = tref[2]
                            if not type_:
                                continue
                            extra = ''
                            which_type = type_.WhichOneof('type')
                            if which_type == 'primitive':
                                extra = XML_GEN_MAP[type_.primitive]
                                if type_.primitive == type_.DECIMAL:
                                    for c in type_.constraint:
                                        if c.scale:
                                            access = 'round(entity.get{}(), {})'.format(
                                                method, c.scale)
                                            break
                                    else:
                                        access = 'round(entity.get{}(), 0)'.format(
                                            method)
                                else:
                                    access = 'entity.get{}()'.format(method)
                            elif which_type == 'enum':
                                access = 'entity.get{}().getValue()'.format(method)
                            elif which_type == 'tuple':
                                access = 'entity.get{}()'.format(method)
                            else:
                                raise RuntimeError(
                                    'Unexpected field type for XML export: ' + which_type)
                            if wantAttrs == (
                                    'xml_attribute' in syslx.patterns(f.attrs)):
                                if wantAttrs:
                                    w('serializeAttr("{}", {}{}, xsw);',
                                      jfname, access, extra)
                                else:
                                    # TODO: Why is 'index' bad? (NB: This was a debug hook, but the author forgot why.)
                                    assert jfname != 'index'
                                    w('serializeField("{}", {}{}, xsw);',
                                      jfname, access, extra)
                    w('xsw.writeEndElement();')

                with java.Method(w, '\npublic', 'void', 'serializeField',
                                 [('String', 'fieldname'),
                                  (modelpkg + '.' + tname + '.View', 'view'),
                                  ('XMLStreamWriter', 'xsw')],
                                 throws=['XMLStreamException']):
                    with java.If(w, 'view != null && !view.isEmpty()'):
                        w('serialize(view, xsw, fieldname);')

                with java.Method(w, '\npublic', 'void', 'serializeField',
                                 [('String', 'fieldname'), (modelpkg + '.' + tname, 'entity'),
                                  ('XMLStreamWriter', 'xsw')],
                                 throws=['XMLStreamException']):
                    with java.If(w, 'entity != null'):
                        w('serialize(entity, xsw, fieldname);')

        def serialize(t, access, extra_args=None):
            with java.Method(w, '\nprivate', 'void', 'serialize',
                             ([(t, 'value')] + (extra_args or []) +
                              [('XMLStreamWriter', 'xsw')]),
                             throws=['XMLStreamException']):
                w('xsw.writeCharacters({});', access)

        serialize('String', 'value')
        serialize('Boolean', 'value.toString()')
        serialize('Integer', 'value.toString()')
        serialize('Double', 'value.toString()')
        serialize('BigDecimal', 'value.toString()')
        serialize('UUID', 'value.toString()')
        serialize('DateTime', 'fmt.print(value)',
                  [('DateTimeFormatter', 'fmt')])
        serialize('LocalDate', 'iso8601Date.print(value)')

        def serializeField(t, access, extra_args=None):
            with java.Method(w, '\nprivate', 'void', 'serializeField',
                             ([('String', 'fieldname'), (t, 'value')] + (extra_args or []) +
                              [('XMLStreamWriter', 'xsw')]),
                             throws=['XMLStreamException']):
                with java.If(w, 'value != null'):
                    w('xsw.writeStartElement(fieldname);')
                    w('serialize(value{}, xsw);',
                      ''.join(', ' + arg for (_, arg) in extra_args or []))
                    w('xsw.writeEndElement();')

            with java.Method(w, '\nprivate', 'void', 'serializeAttr',
                             ([('String', 'fieldname'), (t, 'value')] + (extra_args or []) +
                              [('XMLStreamWriter', 'xsw')]),
                             throws=['XMLStreamException']):
                with java.If(w, 'value != null'):
                    w('xsw.writeAttribute(fieldname, {});', access)

        serializeField('String', 'value')
        serializeField('Boolean', 'value.toString()')
        serializeField('Integer', 'value.toString()')
        serializeField('Double', 'value.toString()')
        serializeField('BigDecimal', 'value.toString()')
        serializeField('UUID', 'value.toString()')
        serializeField('DateTime', 'fmt.print(value)',
                       [('DateTimeFormatter', 'fmt')])
        serializeField('LocalDate', 'iso8601Date.print(value)')

        with java.Method(w, '\nprivate final', 'BigDecimal', 'round',
                         [('BigDecimal', 'd'), ('int', 'scale')]):
            w('return d == null ? d : '
              'd.setScale(scale, java.math.RoundingMode.HALF_UP);')

        w('\nprivate final DateTimeFormatter iso8601Date = '
          'ISODateTimeFormat.date();')
        w('private final DateTimeFormatter iso8601DateTime = '
          'ISODateTimeFormat.dateTime();')
Beispiel #9
0
def serializer(context):
    (app, module, package, model_class, write_file, _, _) = context

    facade = bool(context.wrapped_model)

    w = writer.Writer('java')

    java.Package(w, package)

    java.StandardImports(w)

    java.Import(w, 'java.io.IOException')
    w.head()
    java.Import(w, 'java.text.ParseException')
    w.head()
    java.Import(w, 'com.fasterxml.jackson.core.JsonGenerator')
    java.Import(w, 'com.fasterxml.jackson.databind.JsonSerializer')
    java.Import(w, 'com.fasterxml.jackson.databind.SerializerProvider')
    w.head()
    java.Import(w, 'org.joda.time.format.DateTimeFormatter')
    java.Import(w, 'org.joda.time.format.ISODateTimeFormat')

    if facade:
        model_name = syslx.fmt_app_name(context.wrapped_model.name)
        modelpkg = syslx.View(context.wrapped_model.attrs)['package'].s
        w.head()
        java.Import(w, modelpkg + '.*')

    w()
    with java.Class(w, model_class + 'JsonSerializer', write_file,
                    package=package, extends='JsonSerializer<' + model_class + '>'):
        w()
        with java.Method(w, 'public', 'void', 'serialize',
                         [(model_class, 'facade' if facade else 'model'),
                          ('JsonGenerator', 'g'),
                          ('SerializerProvider', 'provider')],
                         throws=['IOException'],
                         override=True):
            if facade:
                w('{} model = facade.getModel();', model_name)

            w(u'g.writeStartObject();')
            for (tname, t) in sorted(app.types.iteritems()):
                if t.WhichOneof('type') == 'relation':
                    w(u'serialize{0}View(g, model.get{0}Table());', tname)
            w(u'g.writeEndObject();')

        for (tname, t) in sorted(app.types.iteritems()):
            if not t.WhichOneof('type') in ['relation', 'tuple']:
                continue
            java.SeparatorComment(w)
            if t.WhichOneof('type') == 'relation':
                w()
                with java.Method(w, 'public', 'void', 'serialize' + tname + 'View',
                                 [('JsonGenerator', 'g'),
                                  (tname + '.View', 'view')],
                                 throws=['IOException']):
                    with java.If(w, 'view.isEmpty()'):
                        w('return;')
                    w('g.writeArrayFieldStart("{}");', tname)
                    with java.For(w, '{} item : view', tname):
                        w('g.writeStartObject();')
                        for (fname, f) in datamodel.sorted_fields(t):
                            jfname = java.name(fname)
                            method = java.CamelCase(jfname)
                            type_ = datamodel.typeref(f, module)[2]
                            extra = '{}'
                            which_type = type_.WhichOneof('type')
                            if which_type == 'primitive':
                                (jsontype,
                                 extra) = JSON_GEN_MAP[type_.primitive]
                                if type_.primitive == type_.DECIMAL:
                                    for c in type_.constraint:
                                        if c.scale:
                                            access = (
                                                '{0} == null ? null : item.{0}.setScale({1}, '
                                                'java.math.RoundingMode.HALF_UP)').format(
                                                jfname, c.scale)
                                            break
                                else:
                                    access = jfname
                            elif which_type == 'enum':
                                jsontype = 'Number'
                                access = jfname + '.getValue()'
                            elif which_type == 'tuple':
                                access = jfname
                            else:
                                raise RuntimeError(
                                    'Unexpected field type for JSON export: ' + which_type)
                            w(u'writeField(g, "{}", {});',
                              jfname, extra.format('item.' + access))
                        w(u'g.writeEndObject();')
                    w(u'g.writeEndArray();')
            else:
                # fieldname, entity
                with java.Method(w, 'public', 'void', 'serialize',
                                 [('JsonGenerator', 'g'),
                                  ('String', 'fieldname'),
                                  (tname, 'entity')],
                                 throws=['IOException']):
                    with java.If(w, 'entity == null'):
                        w(u'return;')
                    w(u'g.writeFieldName(fieldname);')
                    w(u'serialize(g, entity);')

                # entity
                with java.Method(w, 'public', 'void', 'serialize',
                                 [('JsonGenerator', 'g'),
                                  (tname, 'entity')],
                                 throws=['IOException']):
                    w(u'g.writeStartObject();')
                    for (fname, f) in datamodel.sorted_fields(t):
                        jfname = java.name(fname)
                        method = java.CamelCase(jfname)
                        type_ = datamodel.typeref(f, module)[2]
                        which_type = ''
                        if type_ is None:
                            if f.WhichOneof('type') == 'set' and f.set.HasField('primitive'):
                                which_type = 'tuple'
                        else:
                            which_type = type_.WhichOneof('type')
                        extra = '{}'
                        if which_type == 'primitive':
                            access = 'entity.get{}()'.format(method)
                            (jsontype, extra) = JSON_GEN_MAP[type_.primitive]
                            if type_.primitive == type_.DECIMAL:
                                for c in type_.constraint:
                                    if c.scale:
                                        access = (
                                            'entity.{} == null ? null : entity.get{}().setScale({}, '
                                            'java.math.RoundingMode.HALF_UP)').format(
                                            jfname, method, c.scale)
                                        break
                            w(u'writeField(g, "{}", {});', jfname, access)
                        elif which_type == 'enum':
                            access = 'entity.{} == null ? null : entity.get{}().getValue()'.format(jfname, method)
                            w(u'writeField(g, "{}", {});', jfname, access)
                        elif which_type == 'tuple':
                            w(u'serialize(g, "{}", entity.get{}());'.format(
                                fname, method))
                        else:
                            raise RuntimeError(
                                'Unexpected field type for JSON export: ' + which_type)
                    # end for
                    w(u'g.writeEndObject();')
                w()

                # view, fieldname
                with java.Method(w, 'public', 'void', 'serialize',
                                 [('JsonGenerator', 'g'), ('String', 'fieldname'),
                                  (tname + '.View', 'view')],
                                 throws=['IOException']):
                    with java.If(w, 'view == null || view.isEmpty()'):
                        w(u'return;')
                    w(u'g.writeArrayFieldStart(fieldname);')
                    with java.For(w, '{} item : view', tname):
                        w(u'serialize(g, item);')
                    w(u'g.writeEndArray();')

        for t in ['Boolean', 'String']:
            w()
            with java.Method(w, 'private', 'void', 'writeField',
                             [('JsonGenerator', 'g'),
                              ('String', 'fieldname'), (t, 'value')],
                             throws=['IOException']):
                with java.If(w, 'value != null'):
                    w('g.write{}Field(fieldname, value);', t)

        # TODO(sahejsingh): implement for ['Boolean', 'Integer', 'Double', 'BigDecimal', 'DateTime', 'LocalDate', 'UUID']
        w()
        with java.Method(w, 'private', 'void', 'serialize',
                         [('JsonGenerator', 'g'),
                          ('String', 'fieldname'), ('HashSet<String>', 'value')],
                         throws=['IOException']):
            with java.If(w, 'value == null || value.isEmpty()'):
                w(u'return;')
            w(u'g.writeArrayFieldStart(fieldname);')
            with java.For(w, 'String item : value', t):
                w(u'g.writeString(item);')
            w(u'g.writeEndArray();')

        w()
        with java.Method(w, 'private', 'void', 'writeField',
                         [('JsonGenerator', 'g'), ('String',
                                                   'fieldname'), ('Integer', 'value')],
                         throws=['IOException']):
            with java.If(w, 'value != null'):
                w('g.writeNumberField(fieldname, value.intValue());')

        w()
        with java.Method(w, 'private', 'void', 'writeField',
                         [('JsonGenerator', 'g'), ('String',
                                                   'fieldname'), ('Double', 'value')],
                         throws=['IOException']):
            with java.If(w, 'value != null'):
                w('g.writeNumberField(fieldname, value.doubleValue());')

        w()
        with java.Method(w, 'private', 'void', 'writeField',
                         [('JsonGenerator', 'g'),
                          ('String', 'fieldname'),
                          ('BigDecimal', 'value')],
                         throws=['IOException']):
            with java.If(w, 'value != null'):
                w('g.writeNumberField(fieldname, value);')

        w()
        with java.Method(w, 'private', 'void', 'writeField',
                         [('JsonGenerator', 'g'),
                          ('String', 'fieldname'),
                          ('DateTime', 'value')],
                         throws=['IOException']):
            with java.If(w, 'value != null'):
                w('g.writeStringField(fieldname, iso8601DateTime.print(value));')

        w()
        with java.Method(w, 'private', 'void', 'writeField',
                         [('JsonGenerator', 'g'),
                          ('String', 'fieldname'),
                          ('LocalDate', 'value')],
                         throws=['IOException']):
            with java.If(w, 'value != null'):
                w('g.writeStringField(fieldname, iso8601Date.print(value));')

        w()
        with java.Method(w, 'private', 'void', 'writeField',
                         [('JsonGenerator', 'g'), ('String',
                                                   'fieldname'), ('UUID', 'value')],
                         throws=['IOException']):
            with java.If(w, 'value != null'):
                w('g.writeStringField(fieldname, value.toString());')

        w('\nprivate final DateTimeFormatter iso8601Date = '
          'ISODateTimeFormat.date();')
        w('private final DateTimeFormatter iso8601DateTime = '
          'ISODateTimeFormat.dateTime();')
Beispiel #10
0
def deserializer(context):
    (app, module, package, model_class, write_file, _, _) = context

    facade = bool(context.wrapped_model)

    w = writer.Writer('java')

    java.Package(w, package)

    java.StandardImports(w)

    java.Import(w, 'java.io.IOException')
    w.head()
    java.Import(w, 'java.text.ParseException')
    w.head()
    java.Import(w, 'com.fasterxml.jackson.core.JsonParseException')
    java.Import(w, 'com.fasterxml.jackson.core.JsonParser')
    java.Import(w, 'com.fasterxml.jackson.core.JsonToken')
    java.Import(w, 'com.fasterxml.jackson.databind.JsonDeserializer')
    java.Import(w, 'com.fasterxml.jackson.databind.DeserializationContext')
    w.head()
    java.Import(w, 'org.joda.time.format.DateTimeFormatter')
    java.Import(w, 'org.joda.time.format.ISODateTimeFormat')

    if facade:
        model_name = syslx.fmt_app_name(context.wrapped_model.name)
        modelpkg = syslx.View(context.wrapped_model.attrs)['package'].s
        w.head()
        java.Import(w, modelpkg + '.*')
    else:
        model_name = model_class

    has_tables = any(
        t.HasField('relation')
        for (tname, t) in sorted(app.types.iteritems()))

    w()
    with java.Class(w, model_class + 'JsonDeserializer', write_file,
                    package=package,
                    extends='JsonDeserializer<' + model_class + '>'):
        w()
        with java.Method(w, 'public', model_class, 'deserialize',
                            [('JsonParser', 'p'),
                             ('DeserializationContext', 'provider')],
                            throws=['IOException', 'JsonParseException'], override=True):
            w('{0} model = new {0}();', model_name)
            if facade:
                w('{0} facade = new {0}(model);', model_class)
            w()
            w('eatToken(p, JsonToken.START_OBJECT);')
            with java.While(w, 'p.getCurrentToken() != JsonToken.END_OBJECT'):
                with java.Switch(w, 'eatName(p)'):
                    for (tname, t) in sorted(app.types.iteritems()):
                        if t.HasField('relation'):
                            w(('case "{0}": deserialize{0}Table(p, '
                                'model.get{0}Table()); break;'),
                                tname)
                    w('default: skipJson(p);')
            w('expectToken(p, JsonToken.END_OBJECT);')
            w()
            if facade:
                w('return facade;')
            else:
                w('return model;')

        for (tname, t) in sorted(app.types.iteritems()):
            if t.HasField('tuple'):
                # HashSet<User defined type>
                with java.Method(w, 'private', tname + '.View', 'deserialize' + tname + 'View',
                                    [('JsonParser', 'p')],
                                    throws=['IOException', 'JsonParseException']):
                    w()
                    w('{0}.Set view = new {0}.Set();', tname)
                    w('eatToken(p, JsonToken.START_ARRAY);')
                    with java.While(w, 'p.getCurrentToken() != JsonToken.END_ARRAY'):
                        w('{0} entity = {0}._PRIVATE_new();', tname)
                        w('deserialize(p, entity);')
                        w('view.add(entity);')
                    w('p.nextToken();')
                    w('return view;')

                with java.Method(w, 'public', tname, 'deserialize',
                                    [('JsonParser', 'p'), (tname, 'entity')],
                                    throws=['IOException', 'JsonParseException'], override=False):
                    w()
                    w('eatToken(p, JsonToken.START_OBJECT);')
                    with java.If(w, 'entity == null'):
                        w('entity = {0}._PRIVATE_new();', tname)
                    with java.While(w, 'p.getCurrentToken() != JsonToken.END_OBJECT'):
                        with java.Switch(w, 'eatName(p)'):
                            for (fname, f) in datamodel.sorted_fields(t):
                                jfname = java.name(fname)
                                (typename, _, type_) = datamodel.typeref(
                                    f, module)
                                extra = '{}'
                                set_with_primitive = False

                                if type_ is None:
                                    if f.WhichOneof('type') == 'set' and f.set.HasField('primitive'):
                                        which_type = 'tuple'
                                        set_with_primitive = True
                                        type_ = f.set
                                else:
                                    which_type = type_.WhichOneof('type')

                                if which_type == 'primitive':
                                    jsontype = JSON_PARSE_MAP[type_.primitive]
                                    if isinstance(jsontype, tuple):
                                        (jsontype, extra) = jsontype
                                elif which_type == 'enum':
                                    jsontype = 'IntValue'
                                    extra = typename + '.from({})'
                                elif which_type == 'tuple':
                                    if set_with_primitive:
                                        extra = 'deserializeArray(p)'
                                    elif f.WhichOneof('type') == 'set':
                                        extra = 'deserialize{}View(p)'.format(
                                            f.set.type_ref.ref.path[-1])
                                    elif f.WhichOneof('type') == 'type_ref':
                                        extra = 'deserialize(p, entity.get{}())'.format(
                                            java.CamelCase(jfname))
                                    jsontype = ''
                                else:
                                    raise RuntimeError(
                                        'Unexpected field type for JSON export: ' + which_type)
                                private = ''
                                if type_.primitive in [
                                        sysl_pb2.Type.DATE, sysl_pb2.Type.DATETIME]:
                                    with java.Case(w, '"{}"', jfname):
                                        w(('entity.{}set{}('
                                            'p.getCurrentToken() == JsonToken.VALUE_NULL'
                                            ' ? null : {}); p.nextToken(); break;'),
                                            private,
                                            java.CamelCase(jfname),
                                            extra.format('p.get{}()'.format(jsontype)))
                                else:
                                    w(('case "{}": entity.{}set{}(p.getCurrentToken() == '
                                        'JsonToken.VALUE_NULL ? null : {}); {} break;'),
                                        jfname,
                                        private,
                                        java.CamelCase(jfname),
                                        extra.format(
                                            'p.get{}()'.format(jsontype)),
                                        '' if which_type == 'tuple' else 'p.nextToken();')

                            w('default: skipJson(p);')
                    w('p.nextToken();')
                    w('return entity;')

            if not t.HasField('relation'):
                continue

            pkey = datamodel.primary_key_params(t, context.module)
            pkey_fields = {f for (_, f, _) in pkey}
            fkeys = {
                java.name(fname): type_info
                for (fname, _, type_info) in datamodel.foreign_keys(t, context.module)}

            private_setters = pkey_fields | set(fkeys.iterkeys())

            w()
            with java.Method(w, 'private', 'void', 'deserialize' + tname + 'Table',
                             [('JsonParser', 'p'), (tname + '.Table', 'table')],
                             throws=['IOException', 'JsonParseException']):
                w('eatToken(p, JsonToken.START_ARRAY);')
                with java.While(w, 'p.getCurrentToken() != JsonToken.END_ARRAY'):
                    w('eatToken(p, JsonToken.START_OBJECT);')
                    w('{0} entity = {0}._PRIVATE_new(table.model());', tname)
                    with java.While(w, 'p.getCurrentToken() != JsonToken.END_OBJECT'):
                        with java.Switch(w, u'eatName(p)'):
                            for (fname, f) in datamodel.sorted_fields(t):
                                jfname = java.name(fname)
                                (typename, _, type_) = datamodel.typeref(f, module)
                                extra = '{}'
                                which_type = type_.WhichOneof('type')
                                if which_type == 'primitive':
                                    jsontype = JSON_PARSE_MAP[type_.primitive]
                                    if isinstance(jsontype, tuple):
                                        (jsontype, extra) = jsontype
                                elif which_type == 'enum':
                                    jsontype = 'IntValue'
                                    extra = typename + '.from({})'
                                else:
                                    raise RuntimeError(
                                        'Unexpected field type for JSON export: ' + which_type)
                                private = '_PRIVATE_' if jfname in private_setters else ''
                                if type_.primitive in [
                                        sysl_pb2.Type.DATE, sysl_pb2.Type.DATETIME]:
                                    with java.Case(w, '"{}"', jfname):
                                        w(('entity.{}set{}('
                                           'p.getCurrentToken() == JsonToken.VALUE_NULL'
                                           ' ? null : {}); break;'),
                                          private,
                                          java.CamelCase(jfname),
                                          extra.format('p.get{}()'.format(jsontype)))
                                else:
                                    w(('case "{}": entity.{}set{}(p.getCurrentToken() == '
                                       'JsonToken.VALUE_NULL ? null : {}); break;'),
                                      jfname,
                                      private,
                                      java.CamelCase(jfname),
                                      extra.format('p.get{}()'.format(jsontype)))
                            with java.Default(w):
                                w('skipJson(p);')
                                w('continue;')
                        w('p.nextToken();')
                    w('p.nextToken();')
                    w()
                    w('table.insert(entity);')
                w('p.nextToken();')

        # HashSet<Primitive Type>
        with java.Method(w, 'private', 'HashSet<String>', 'deserializeArray',
                            [('JsonParser', 'p')],
                            throws=['IOException', 'JsonParseException']):
            w()
            w('HashSet<String> view = new HashSet<String>();')
            w('eatToken(p, JsonToken.START_ARRAY);')
            with java.While(w, 'p.getCurrentToken() != JsonToken.END_ARRAY'):
                w('expectToken(p, JsonToken.VALUE_STRING);')
                w('view.add(p.getText());')
                w('p.nextToken();')
            w('p.nextToken();')
            w('return view;')

        with java.Method(w, '\nprivate', 'void', 'eatToken',
                         [('JsonParser', 'p'), ('JsonToken', 'token')],
                         throws=['IOException']):
            w(u'expectToken(p, token);')
            w(u'p.nextToken();')

        with java.Method(w, '\nprivate', 'void', 'expectToken',
                         [('JsonParser', 'p'), ('JsonToken', 'token')]):
            with java.If(w, 'p.getCurrentToken() != token'):
                w(('System.err.printf("<<Unexpected token: %s (expecting %s)>>\\n", '
                   'tokenName(p.getCurrentToken()), tokenName(token));'))
                w('throw new {}Exception();', model_name)

        with java.Method(w, '\nprivate', 'String', 'eatName', [('JsonParser', 'p')],
                         throws=['IOException']):
            w('expectToken(p, JsonToken.FIELD_NAME);')
            w('String name = p.getCurrentName();')
            w('p.nextToken();')
            w('return name;')

        with java.Method(w, '\nprivate', 'String', 'tokenName',
                         [('JsonToken', 'token')]):
            with java.If(w, 'token == null'):
                w('return "null";')
            with java.Switch(w, 'token'):
                for tok in (
                    'END_ARRAY END_OBJECT FIELD_NAME NOT_AVAILABLE START_ARRAY '
                    'START_OBJECT VALUE_EMBEDDED_OBJECT VALUE_FALSE VALUE_NULL '
                    'VALUE_NUMBER_FLOAT VALUE_NUMBER_INT VALUE_STRING VALUE_TRUE'
                ).split():
                    w('case {0}: return "{0}";', tok)
            w('return "";')

        # TODO: refactor into base class
        # TODO: replace recursion with depth counter
        with java.Method(w, '\nprivate', 'void', 'skipJson', [('JsonParser', 'p')],
                         throws=['IOException']):
            w('JsonToken tok = p.getCurrentToken();')
            w('p.nextToken();')
            with java.Switch(w, 'tok'):
                for tok in (
                    'END_ARRAY END_OBJECT FIELD_NAME NOT_AVAILABLE '
                    'VALUE_EMBEDDED_OBJECT VALUE_FALSE VALUE_NULL '
                        'VALUE_NUMBER_FLOAT VALUE_NUMBER_INT VALUE_STRING VALUE_TRUE').split():
                    w('case {}: break;', tok)
                with java.Case(w, 'START_ARRAY'):
                    with java.While(w, 'p.getCurrentToken() != JsonToken.END_ARRAY'):
                        w('skipJson(p);')
                    w('p.nextToken();')
                    w('break;')
                with java.Case(w, 'START_OBJECT'):
                    with java.While(w, 'p.getCurrentToken() != JsonToken.END_OBJECT'):
                        w('p.nextToken();')
                        w('skipJson(p);')
                    w('p.nextToken();')
                    w('break;')

        # TODO: Is permissive dateTimeParser OK for date types?
        w('\nprivate final DateTimeFormatter iso8601DateTime = '
          'ISODateTimeFormat.dateTimeParser();')

        w()
Beispiel #11
0
def serializer(context):
    (app, module, package, model_class, write_file, _, _) = context

    facade = bool(context.wrapped_model)

    w = writer.Writer('java')

    java.Package(w, package)

    java.StandardImports(w)

    java.Import(w, 'java.io.IOException')
    w.head()
    java.Import(w, 'java.text.ParseException')
    w.head()
    java.Import(w, 'com.fasterxml.jackson.core.JsonGenerator')
    java.Import(w, 'com.fasterxml.jackson.databind.JsonSerializer')
    java.Import(w, 'com.fasterxml.jackson.databind.SerializerProvider')
    w.head()
    java.Import(w, 'org.joda.time.format.DateTimeFormatter')
    java.Import(w, 'org.joda.time.format.ISODateTimeFormat')

    if facade:
        model_name = syslx.fmt_app_name(context.wrapped_model.name)
        modelpkg = syslx.View(context.wrapped_model.attrs)['package'].s
        w.head()
        java.Import(w, modelpkg + '.*')

    w()
    with java.Class(w,
                    model_class + 'JsonSerializer',
                    write_file,
                    package=package,
                    extends='JsonSerializer<' + model_class + '>'):
        w()
        with java.Method(w,
                         'public',
                         'void',
                         'serialize',
                         [(model_class, 'facade' if facade else 'model'),
                          ('JsonGenerator', 'g'),
                          ('SerializerProvider', 'provider')],
                         throws=['IOException'],
                         override=True):
            if facade:
                w('{} model = facade.getModel();', model_name)

            w(u'g.writeStartObject();')
            for (tname, t) in sorted(app.types.iteritems()):
                if t.WhichOneof('type') == 'relation':
                    w(u'serialize{0}View(g, model.get{0}Table());', tname)
            w(u'g.writeEndObject();')

        for (tname, t) in sorted(app.types.iteritems()):
            if not t.WhichOneof('type') in ['relation', 'tuple']:
                continue
            java.SeparatorComment(w)
            if t.WhichOneof('type') == 'relation':
                w()
                with java.Method(w,
                                 'public',
                                 'void',
                                 'serialize' + tname + 'View',
                                 [('JsonGenerator', 'g'),
                                  (tname + '.View', 'view')],
                                 throws=['IOException']):
                    with java.If(w, 'view.isEmpty()'):
                        w('return;')
                    w('g.writeArrayFieldStart("{}");', tname)
                    with java.For(w, '{} item : view', tname):
                        w('g.writeStartObject();')
                        for (fname, f) in datamodel.sorted_fields(t):
                            jfname = java.name(fname)
                            method = java.CamelCase(jfname)
                            type_ = datamodel.typeref(f, module)[2]
                            extra = '{}'
                            which_type = type_.WhichOneof('type')
                            if which_type == 'primitive':
                                (jsontype,
                                 extra) = JSON_GEN_MAP[type_.primitive]
                                if type_.primitive == type_.DECIMAL:
                                    for c in type_.constraint:
                                        if c.scale:
                                            access = (
                                                '{0} == null ? null : item.{0}.setScale({1}, '
                                                'java.math.RoundingMode.HALF_UP)'
                                            ).format(jfname, c.scale)
                                            break
                                else:
                                    access = jfname
                            elif which_type == 'enum':
                                jsontype = 'Number'
                                access = jfname + '.getValue()'
                            elif which_type == 'tuple':
                                access = jfname
                            else:
                                raise RuntimeError(
                                    'Unexpected field type for JSON export: ' +
                                    which_type)
                            w(u'writeField(g, "{}", {});', jfname,
                              extra.format('item.' + access))
                        w(u'g.writeEndObject();')
                    w(u'g.writeEndArray();')
            else:
                # fieldname, entity
                with java.Method(w,
                                 'public',
                                 'void',
                                 'serialize', [('JsonGenerator', 'g'),
                                               ('String', 'fieldname'),
                                               (tname, 'entity')],
                                 throws=['IOException']):
                    with java.If(w, 'entity == null'):
                        w(u'return;')
                    w(u'g.writeFieldName(fieldname);')
                    w(u'serialize(g, entity);')

                # entity
                with java.Method(w,
                                 'public',
                                 'void',
                                 'serialize', [('JsonGenerator', 'g'),
                                               (tname, 'entity')],
                                 throws=['IOException']):
                    w(u'g.writeStartObject();')
                    for (fname, f) in datamodel.sorted_fields(t):
                        jfname = java.name(fname)
                        method = java.CamelCase(jfname)
                        type_ = datamodel.typeref(f, module)[2]
                        which_type = ''
                        if type_ is None:
                            if f.WhichOneof(
                                    'type') == 'set' and f.set.HasField(
                                        'primitive'):
                                which_type = 'tuple'
                        else:
                            which_type = type_.WhichOneof('type')
                        extra = '{}'
                        if which_type == 'primitive':
                            access = 'entity.get{}()'.format(method)
                            (jsontype, extra) = JSON_GEN_MAP[type_.primitive]
                            if type_.primitive == type_.DECIMAL:
                                for c in type_.constraint:
                                    if c.scale:
                                        access = (
                                            'entity.{} == null ? null : entity.get{}().setScale({}, '
                                            'java.math.RoundingMode.HALF_UP)'
                                        ).format(jfname, method, c.scale)
                                        break
                            w(u'writeField(g, "{}", {});', jfname, access)
                        elif which_type == 'enum':
                            access = 'entity.{} == null ? null : entity.get{}().getValue()'.format(
                                jfname, method)
                            w(u'writeField(g, "{}", {});', jfname, access)
                        elif which_type == 'tuple':
                            w(u'serialize(g, "{}", entity.get{}());'.format(
                                fname, method))
                        else:
                            raise RuntimeError(
                                'Unexpected field type for JSON export: ' +
                                which_type)
                    # end for
                    w(u'g.writeEndObject();')
                w()

                # view, fieldname
                with java.Method(w,
                                 'public',
                                 'void',
                                 'serialize', [('JsonGenerator', 'g'),
                                               ('String', 'fieldname'),
                                               (tname + '.View', 'view')],
                                 throws=['IOException']):
                    with java.If(w, 'view == null || view.isEmpty()'):
                        w(u'return;')
                    w(u'g.writeArrayFieldStart(fieldname);')
                    with java.For(w, '{} item : view', tname):
                        w(u'serialize(g, item);')
                    w(u'g.writeEndArray();')

        for t in ['Boolean', 'String']:
            w()
            with java.Method(w,
                             'private',
                             'void',
                             'writeField', [('JsonGenerator', 'g'),
                                            ('String', 'fieldname'),
                                            (t, 'value')],
                             throws=['IOException']):
                with java.If(w, 'value != null'):
                    w('g.write{}Field(fieldname, value);', t)

        # TODO(sahejsingh): implement for ['Boolean', 'Integer', 'Double', 'BigDecimal', 'DateTime', 'LocalDate', 'UUID']
        w()
        with java.Method(w,
                         'private',
                         'void',
                         'serialize', [('JsonGenerator', 'g'),
                                       ('String', 'fieldname'),
                                       ('HashSet<String>', 'value')],
                         throws=['IOException']):
            with java.If(w, 'value == null || value.isEmpty()'):
                w(u'return;')
            w(u'g.writeArrayFieldStart(fieldname);')
            with java.For(w, 'String item : value', t):
                w(u'g.writeString(item);')
            w(u'g.writeEndArray();')

        w()
        with java.Method(w,
                         'private',
                         'void',
                         'writeField', [('JsonGenerator', 'g'),
                                        ('String', 'fieldname'),
                                        ('Integer', 'value')],
                         throws=['IOException']):
            with java.If(w, 'value != null'):
                w('g.writeNumberField(fieldname, value.intValue());')

        w()
        with java.Method(w,
                         'private',
                         'void',
                         'writeField', [('JsonGenerator', 'g'),
                                        ('String', 'fieldname'),
                                        ('Double', 'value')],
                         throws=['IOException']):
            with java.If(w, 'value != null'):
                w('g.writeNumberField(fieldname, value.doubleValue());')

        w()
        with java.Method(w,
                         'private',
                         'void',
                         'writeField', [('JsonGenerator', 'g'),
                                        ('String', 'fieldname'),
                                        ('BigDecimal', 'value')],
                         throws=['IOException']):
            with java.If(w, 'value != null'):
                w('g.writeNumberField(fieldname, value);')

        w()
        with java.Method(w,
                         'private',
                         'void',
                         'writeField', [('JsonGenerator', 'g'),
                                        ('String', 'fieldname'),
                                        ('DateTime', 'value')],
                         throws=['IOException']):
            with java.If(w, 'value != null'):
                w('g.writeStringField(fieldname, iso8601DateTime.print(value));'
                  )

        w()
        with java.Method(w,
                         'private',
                         'void',
                         'writeField', [('JsonGenerator', 'g'),
                                        ('String', 'fieldname'),
                                        ('LocalDate', 'value')],
                         throws=['IOException']):
            with java.If(w, 'value != null'):
                w('g.writeStringField(fieldname, iso8601Date.print(value));')

        w()
        with java.Method(w,
                         'private',
                         'void',
                         'writeField', [('JsonGenerator', 'g'),
                                        ('String', 'fieldname'),
                                        ('UUID', 'value')],
                         throws=['IOException']):
            with java.If(w, 'value != null'):
                w('g.writeStringField(fieldname, value.toString());')

        w('\nprivate final DateTimeFormatter iso8601Date = '
          'ISODateTimeFormat.date();')
        w('private final DateTimeFormatter iso8601DateTime = '
          'ISODateTimeFormat.dateTime();')
Beispiel #12
0
def deserializer(context):
    (app, module, package, model_class, write_file, _, _) = context

    facade = bool(context.wrapped_model)

    w = writer.Writer('java')

    java.Package(w, package)

    java.StandardImports(w)

    java.Import(w, 'java.io.IOException')
    w.head()
    java.Import(w, 'java.text.ParseException')
    w.head()
    java.Import(w, 'com.fasterxml.jackson.core.JsonParseException')
    java.Import(w, 'com.fasterxml.jackson.core.JsonParser')
    java.Import(w, 'com.fasterxml.jackson.core.JsonToken')
    java.Import(w, 'com.fasterxml.jackson.databind.JsonDeserializer')
    java.Import(w, 'com.fasterxml.jackson.databind.DeserializationContext')
    w.head()
    java.Import(w, 'org.joda.time.format.DateTimeFormatter')
    java.Import(w, 'org.joda.time.format.ISODateTimeFormat')

    if facade:
        model_name = syslx.fmt_app_name(context.wrapped_model.name)
        modelpkg = syslx.View(context.wrapped_model.attrs)['package'].s
        w.head()
        java.Import(w, modelpkg + '.*')
    else:
        model_name = model_class

    has_tables = any(
        t.HasField('relation') for (tname, t) in sorted(app.types.iteritems()))

    w()
    with java.Class(w,
                    model_class + 'JsonDeserializer',
                    write_file,
                    package=package,
                    extends='JsonDeserializer<' + model_class + '>'):
        w()
        with java.Method(w,
                         'public',
                         model_class,
                         'deserialize',
                         [('JsonParser', 'p'),
                          ('DeserializationContext', 'provider')],
                         throws=['IOException', 'JsonParseException'],
                         override=True):
            w('{0} model = new {0}();', model_name)
            if facade:
                w('{0} facade = new {0}(model);', model_class)
            w()
            w('eatToken(p, JsonToken.START_OBJECT);')
            with java.While(w, 'p.getCurrentToken() != JsonToken.END_OBJECT'):
                with java.Switch(w, 'eatName(p)'):
                    for (tname, t) in sorted(app.types.iteritems()):
                        if t.HasField('relation'):
                            w(('case "{0}": deserialize{0}Table(p, '
                               'model.get{0}Table()); break;'), tname)
                    w('default: skipJson(p);')
            w('expectToken(p, JsonToken.END_OBJECT);')
            w()
            if facade:
                w('return facade;')
            else:
                w('return model;')

        for (tname, t) in sorted(app.types.iteritems()):
            if not t.HasField('relation') and t.HasField('tuple'):
                # HashSet<User defined type>
                with java.Method(w,
                                 'private',
                                 tname + '.View',
                                 'deserialize' + tname + 'View',
                                 [('JsonParser', 'p')],
                                 throws=['IOException', 'JsonParseException']):
                    w()
                    w('{0}.Set view = new {0}.Set();', tname)
                    w('eatToken(p, JsonToken.START_ARRAY);')
                    with java.While(
                            w, 'p.getCurrentToken() != JsonToken.END_ARRAY'):
                        w('{0} entity = {0}._PRIVATE_new();', tname)
                        w('deserialize(p, entity);')
                        w('view.add(entity);')
                    w('p.nextToken();')
                    w('return view;')

                with java.Method(w,
                                 'public',
                                 tname,
                                 'deserialize', [('JsonParser', 'p'),
                                                 (tname, 'entity')],
                                 throws=['IOException', 'JsonParseException'],
                                 override=False):
                    w()
                    w('eatToken(p, JsonToken.START_OBJECT);')
                    with java.If(w, 'entity == null'):
                        w('entity = {0}._PRIVATE_new();', tname)
                    with java.While(
                            w, 'p.getCurrentToken() != JsonToken.END_OBJECT'):
                        with java.Switch(w, 'eatName(p)'):
                            for (fname, f) in datamodel.sorted_fields(t):
                                jfname = java.name(fname)
                                (typename, _,
                                 type_) = datamodel.typeref(f, module)
                                extra = '{}'
                                set_with_primitive = False

                                if type_ is None:
                                    if f.WhichOneof(
                                            'type'
                                    ) == 'set' and f.set.HasField('primitive'):
                                        which_type = 'tuple'
                                        set_with_primitive = True
                                        type_ = f.set
                                else:
                                    which_type = type_.WhichOneof('type')

                                if which_type == 'primitive':
                                    jsontype = JSON_PARSE_MAP[type_.primitive]
                                    if isinstance(jsontype, tuple):
                                        (jsontype, extra) = jsontype
                                elif which_type == 'enum':
                                    jsontype = 'IntValue'
                                    extra = typename + '.from({})'
                                elif which_type == 'tuple':
                                    if set_with_primitive:
                                        extra = 'deserializeArray(p)'
                                    elif f.WhichOneof('type') == 'set':
                                        extra = 'deserialize{}View(p)'.format(
                                            f.set.type_ref.ref.path[-1])
                                    elif f.WhichOneof('type') == 'type_ref':
                                        extra = 'deserialize(p, entity.get{}())'.format(
                                            jfname)
                                    jsontype = ''
                                else:
                                    raise RuntimeError(
                                        'Unexpected field type for JSON export: '
                                        + which_type)
                                private = ''
                                if type_.primitive in [
                                        sysl_pb2.Type.DATE,
                                        sysl_pb2.Type.DATETIME
                                ]:
                                    with java.Case(w, '"{}"', jfname):
                                        w(('entity.{}set{}('
                                           'p.getCurrentToken() == JsonToken.VALUE_NULL'
                                           ' ? null : {}); p.nextToken(); break;'
                                           ), private, java.CamelCase(jfname),
                                          extra.format(
                                              'p.get{}()'.format(jsontype)))
                                else:
                                    w(('case "{}": entity.{}set{}(p.getCurrentToken() == '
                                       'JsonToken.VALUE_NULL ? null : {}); {} break;'
                                       ), jfname, private,
                                      java.CamelCase(jfname),
                                      extra.format(
                                          'p.get{}()'.format(jsontype)),
                                      '' if which_type == 'tuple' else
                                      'p.nextToken();')

                            w('default: skipJson(p);')
                    w('p.nextToken();')
                    w('return entity;')
            continue

            pkey = datamodel.primary_key_params(t, context.module)
            pkey_fields = {f for (_, f, _) in pkey}
            fkeys = {
                java.name(fname): type_info
                for (fname, _,
                     type_info) in datamodel.foreign_keys(t, context.module)
            }

            private_setters = pkey_fields | set(fkeys.iterkeys())

            w()
            with java.Method(w,
                             'private',
                             'void',
                             'deserialize' + tname + 'Table',
                             [('JsonParser', 'p'),
                              (tname + '.Table', 'table')],
                             throws=['IOException', 'JsonParseException']):
                w('eatToken(p, JsonToken.START_ARRAY);')
                with java.While(w,
                                'p.getCurrentToken() != JsonToken.END_ARRAY'):
                    w('eatToken(p, JsonToken.START_OBJECT);')
                    w('{0} entity = {0}._PRIVATE_new(table.model());', tname)
                    with java.While(
                            w, 'p.getCurrentToken() != JsonToken.END_OBJECT'):
                        with java.Switch(w, u'eatName(p)'):
                            for (fname, f) in datamodel.sorted_fields(t):
                                jfname = java.name(fname)
                                (typename, _,
                                 type_) = datamodel.typeref(f, module)
                                extra = '{}'
                                which_type = type_.WhichOneof('type')
                                if which_type == 'primitive':
                                    jsontype = JSON_PARSE_MAP[type_.primitive]
                                    if isinstance(jsontype, tuple):
                                        (jsontype, extra) = jsontype
                                elif which_type == 'enum':
                                    jsontype = 'IntValue'
                                    extra = typename + '.from({})'
                                else:
                                    raise RuntimeError(
                                        'Unexpected field type for JSON export: '
                                        + which_type)
                                private = '_PRIVATE_' if jfname in private_setters else ''
                                if type_.primitive in [
                                        sysl_pb2.Type.DATE,
                                        sysl_pb2.Type.DATETIME
                                ]:
                                    with java.Case(w, '"{}"', jfname):
                                        w(('entity.{}set{}('
                                           'p.getCurrentToken() == JsonToken.VALUE_NULL'
                                           ' ? null : {}); break;'), private,
                                          java.CamelCase(jfname),
                                          extra.format(
                                              'p.get{}()'.format(jsontype)))
                                else:
                                    w(('case "{}": entity.{}set{}(p.getCurrentToken() == '
                                       'JsonToken.VALUE_NULL ? null : {}); break;'
                                       ), jfname, private,
                                      java.CamelCase(jfname),
                                      extra.format(
                                          'p.get{}()'.format(jsontype)))
                            with java.Default(w):
                                w('skipJson(p);')
                                w('continue;')
                        w('p.nextToken();')
                    w('p.nextToken();')
                    w()
                    w('table.insert(entity);')
                w('p.nextToken();')

        # HashSet<Primitive Type>
        with java.Method(w,
                         'private',
                         'HashSet<String>',
                         'deserializeArray', [('JsonParser', 'p')],
                         throws=['IOException', 'JsonParseException']):
            w()
            w('HashSet<String> view = new HashSet<String>();')
            w('eatToken(p, JsonToken.START_ARRAY);')
            with java.While(w, 'p.getCurrentToken() != JsonToken.END_ARRAY'):
                w('expectToken(p, JsonToken.VALUE_STRING);')
                w('view.add(p.getText());')
                w('p.nextToken();')
            w('p.nextToken();')
            w('return view;')

        with java.Method(w,
                         '\nprivate',
                         'void',
                         'eatToken', [('JsonParser', 'p'),
                                      ('JsonToken', 'token')],
                         throws=['IOException']):
            w(u'expectToken(p, token);')
            w(u'p.nextToken();')

        with java.Method(w, '\nprivate', 'void', 'expectToken',
                         [('JsonParser', 'p'), ('JsonToken', 'token')]):
            with java.If(w, 'p.getCurrentToken() != token'):
                w(('System.err.printf("<<Unexpected token: %s (expecting %s)>>\\n", '
                   'tokenName(p.getCurrentToken()), tokenName(token));'))
                w('throw new {}Exception();', model_name)

        with java.Method(w,
                         '\nprivate',
                         'String',
                         'eatName', [('JsonParser', 'p')],
                         throws=['IOException']):
            w('expectToken(p, JsonToken.FIELD_NAME);')
            w('String name = p.getCurrentName();')
            w('p.nextToken();')
            w('return name;')

        with java.Method(w, '\nprivate', 'String', 'tokenName',
                         [('JsonToken', 'token')]):
            with java.If(w, 'token == null'):
                w('return "null";')
            with java.Switch(w, 'token'):
                for tok in (
                        'END_ARRAY END_OBJECT FIELD_NAME NOT_AVAILABLE START_ARRAY '
                        'START_OBJECT VALUE_EMBEDDED_OBJECT VALUE_FALSE VALUE_NULL '
                        'VALUE_NUMBER_FLOAT VALUE_NUMBER_INT VALUE_STRING VALUE_TRUE'
                ).split():
                    w('case {0}: return "{0}";', tok)
            w('return "";')

        # TODO: refactor into base class
        # TODO: replace recursion with depth counter
        with java.Method(w,
                         '\nprivate',
                         'void',
                         'skipJson', [('JsonParser', 'p')],
                         throws=['IOException']):
            w('JsonToken tok = p.getCurrentToken();')
            w('p.nextToken();')
            with java.Switch(w, 'tok'):
                for tok in (
                        'END_ARRAY END_OBJECT FIELD_NAME NOT_AVAILABLE '
                        'VALUE_EMBEDDED_OBJECT VALUE_FALSE VALUE_NULL '
                        'VALUE_NUMBER_FLOAT VALUE_NUMBER_INT VALUE_STRING VALUE_TRUE'
                ).split():
                    w('case {}: break;', tok)
                with java.Case(w, 'START_ARRAY'):
                    with java.While(
                            w, 'p.getCurrentToken() != JsonToken.END_ARRAY'):
                        w('skipJson(p);')
                    w('p.nextToken();')
                    w('break;')
                with java.Case(w, 'START_OBJECT'):
                    with java.While(
                            w, 'p.getCurrentToken() != JsonToken.END_OBJECT'):
                        w('p.nextToken();')
                        w('skipJson(p);')
                    w('p.nextToken();')
                    w('break;')

        # TODO: Is permissive dateTimeParser OK for date types?
        w('\nprivate final DateTimeFormatter iso8601DateTime = '
          'ISODateTimeFormat.dateTimeParser();')

        w()
Beispiel #13
0
def serializer(context):
    (app, module, package, model_class, write_file, _, _) = context

    facade = bool(context.wrapped_model)

    w = writer.Writer('java')

    java.Package(w, package)

    java.StandardImports(w)

    java.Import(w, 'java.text.ParseException')
    w.head()
    java.Import(w, 'javax.xml.stream.XMLStreamException')
    java.Import(w, 'javax.xml.stream.XMLStreamWriter')
    w.head()
    java.Import(w, 'org.joda.time.format.DateTimeFormatter')
    java.Import(w, 'org.joda.time.format.ISODateTimeFormat')

    if facade:
        model_name = syslx.fmt_app_name(context.wrapped_model.name)
        modelpkg = syslx.View(context.wrapped_model.attrs)['package'].s
        w.head()
        java.Import(w, modelpkg + '.*')
    else:
        modelpkg = package

    with java.Class(w,
                    '\n{}XmlSerializer'.format(model_class),
                    write_file,
                    package=package):
        with java.Method(w,
                         '\npublic',
                         'void',
                         'serialize',
                         [(model_class, 'facade' if facade else 'model'),
                          ('XMLStreamWriter', 'xsw')],
                         throws=['XMLStreamException']):
            if facade:
                w('{} model = facade.getModel();', model_name)

            w('xsw.writeStartElement("{}");', model_class)
            for (tname, ft, t) in syslx.sorted_types(context):
                if t.WhichOneof('type') == 'relation':
                    w('serialize(model.get{0}Table(), xsw, "{0}");', tname)
            w('xsw.writeEndElement();')

        for (tname, ft, t) in syslx.sorted_types(context):
            java.SeparatorComment(w)

            if t.WhichOneof('type') in ['relation', 'tuple']:
                with java.Method(w,
                                 '\npublic',
                                 'void',
                                 'serialize',
                                 [(modelpkg + '.' + tname + '.View', 'view'),
                                  ('XMLStreamWriter', 'xsw'),
                                  ('String', 'tag')],
                                 throws=['XMLStreamException']):
                    with java.If(w, 'view == null || view.isEmpty()'):
                        w('return;')
                    if t.WhichOneof('type') == 'relation':
                        w('xsw.writeStartElement("{}List");', tname)
                    order = [
                        o.s for o in syslx.View(t.attrs)['xml_order'].a.elt
                    ]
                    if order:
                        order_logic = []
                        for o in order:
                            order_logic.append(
                                '            i = io.sysl.ExprHelper.doCompare'
                                '(a.get{0}(), b.get{0}());\n'
                                '            if (i != 0) return i;\n'.format(
                                    java.CamelCase(o)))
                        order_by = (
                            '.orderBy(\n'
                            '    new java.util.Comparator<{0}> () {{\n'
                            '        @Override\n'
                            '        public int compare({0} a, {0} b) {{\n'
                            '            int i;\n'
                            '{1}'
                            '            return 0;\n'
                            '        }}\n'
                            '    }})\n').format(tname, ''.join(order_logic))
                    else:
                        order_by = ''

                    with java.For(w, '{} item : view{}',
                                  modelpkg + '.' + tname, order_by):
                        w('serialize(item, xsw, tag);', tname)
                    if t.WhichOneof('type') == 'relation':
                        w('xsw.writeEndElement();')

                with java.Method(w,
                                 '\npublic',
                                 'void',
                                 'serialize',
                                 [(modelpkg + '.' + tname, 'entity'),
                                  ('XMLStreamWriter', 'xsw')],
                                 throws=['XMLStreamException']):
                    w('serialize(entity, xsw, "{}");', tname)

                with java.Method(w,
                                 '\npublic',
                                 'void',
                                 'serialize',
                                 [(modelpkg + '.' + tname, 'entity'),
                                  ('XMLStreamWriter', 'xsw'),
                                  ('String', 'tag')],
                                 throws=['XMLStreamException']):
                    with java.If(w, 'entity == null'):
                        w('return;')
                    w('xsw.writeStartElement(tag);', tname)
                    for wantAttrs in [True, False]:
                        for (fname, f) in datamodel.sorted_fields(t):
                            jfname = java.name(fname)
                            method = java.CamelCase(jfname)
                            tref = datamodel.typeref(f, module)
                            type_ = tref[2]
                            if not type_:
                                continue
                            extra = ''
                            which_type = type_.WhichOneof('type')
                            if which_type == 'primitive':
                                extra = XML_GEN_MAP[type_.primitive]
                                if type_.primitive == type_.DECIMAL:
                                    for c in type_.constraint:
                                        if c.scale:
                                            access = 'round(entity.get{}(), {})'.format(
                                                method, c.scale)
                                            break
                                    else:
                                        access = 'round(entity.get{}(), 0)'.format(
                                            method)
                                else:
                                    access = 'entity.get{}()'.format(method)
                            elif which_type == 'enum':
                                access = 'entity.get{}().getValue()'.format(
                                    method)
                            elif which_type == 'tuple':
                                access = 'entity.get{}()'.format(method)
                            else:
                                raise RuntimeError(
                                    'Unexpected field type for XML export: ' +
                                    which_type)
                            if wantAttrs == ('xml_attribute'
                                             in syslx.patterns(f.attrs)):
                                if wantAttrs:
                                    w('serializeAttr("{}", {}{}, xsw);',
                                      jfname, access, extra)
                                else:
                                    # TODO: Why is 'index' bad? (NB: This was a debug hook, but the author forgot why.)
                                    assert jfname != 'index'
                                    w('serializeField("{}", {}{}, xsw);',
                                      jfname, access, extra)
                    w('xsw.writeEndElement();')

                with java.Method(w,
                                 '\npublic',
                                 'void',
                                 'serializeField',
                                 [('String', 'fieldname'),
                                  (modelpkg + '.' + tname + '.View', 'view'),
                                  ('XMLStreamWriter', 'xsw')],
                                 throws=['XMLStreamException']):
                    with java.If(w, 'view != null && !view.isEmpty()'):
                        w('serialize(view, xsw, fieldname);')

                with java.Method(w,
                                 '\npublic',
                                 'void',
                                 'serializeField',
                                 [('String', 'fieldname'),
                                  (modelpkg + '.' + tname, 'entity'),
                                  ('XMLStreamWriter', 'xsw')],
                                 throws=['XMLStreamException']):
                    with java.If(w, 'entity != null'):
                        w('serialize(entity, xsw, fieldname);')

        def serialize(t, access, extra_args=None):
            with java.Method(
                    w,
                    '\nprivate',
                    'void',
                    'serialize',
                ([(t, 'value')] +
                 (extra_args or []) + [('XMLStreamWriter', 'xsw')]),
                    throws=['XMLStreamException']):
                w('xsw.writeCharacters({});', access)

        serialize('String', 'value')
        serialize('Boolean', 'value.toString()')
        serialize('Integer', 'value.toString()')
        serialize('Double', 'value.toString()')
        serialize('BigDecimal', 'value.toString()')
        serialize('UUID', 'value.toString()')
        serialize('DateTime', 'fmt.print(value)',
                  [('DateTimeFormatter', 'fmt')])
        serialize('LocalDate', 'iso8601Date.print(value)')

        def serializeField(t, access, extra_args=None):
            with java.Method(
                    w,
                    '\nprivate',
                    'void',
                    'serializeField',
                ([('String', 'fieldname'), (t, 'value')] +
                 (extra_args or []) + [('XMLStreamWriter', 'xsw')]),
                    throws=['XMLStreamException']):
                with java.If(w, 'value != null'):
                    w('xsw.writeStartElement(fieldname);')
                    w('serialize(value{}, xsw);',
                      ''.join(', ' + arg for (_, arg) in extra_args or []))
                    w('xsw.writeEndElement();')

            with java.Method(
                    w,
                    '\nprivate',
                    'void',
                    'serializeAttr',
                ([('String', 'fieldname'), (t, 'value')] +
                 (extra_args or []) + [('XMLStreamWriter', 'xsw')]),
                    throws=['XMLStreamException']):
                with java.If(w, 'value != null'):
                    w('xsw.writeAttribute(fieldname, {});', access)

        serializeField('String', 'value')
        serializeField('Boolean', 'value.toString()')
        serializeField('Integer', 'value.toString()')
        serializeField('Double', 'value.toString()')
        serializeField('BigDecimal', 'value.toString()')
        serializeField('UUID', 'value.toString()')
        serializeField('DateTime', 'fmt.print(value)',
                       [('DateTimeFormatter', 'fmt')])
        serializeField('LocalDate', 'iso8601Date.print(value)')

        with java.Method(w, '\nprivate final', 'BigDecimal', 'round',
                         [('BigDecimal', 'd'), ('int', 'scale')]):
            w('return d == null ? d : '
              'd.setScale(scale, java.math.RoundingMode.HALF_UP);')

        w('\nprivate final DateTimeFormatter iso8601Date = '
          'ISODateTimeFormat.date();')
        w('private final DateTimeFormatter iso8601DateTime = '
          'ISODateTimeFormat.dateTime();')
Beispiel #14
0
def deserializer(context):
    (app, module, package, model_class, write_file, _, _) = context

    facade = bool(context.wrapped_model)

    w = writer.Writer('java')

    java.Package(w, package)

    java.StandardImports(w)

    java.Import(w, 'javax.xml.stream.XMLStreamConstants')
    java.Import(w, 'javax.xml.stream.XMLStreamException')
    java.Import(w, 'javax.xml.stream.XMLStreamReader')
    w.head()
    java.Import(w, 'java.text.ParseException')
    w.head()
    java.Import(w, 'org.joda.time.format.DateTimeFormatter')
    java.Import(w, 'org.joda.time.format.ISODateTimeFormat')

    if facade:
        model_name = syslx.fmt_app_name(context.wrapped_model.name)
        modelpkg = syslx.View(context.wrapped_model.attrs)['package'].s
        w.head()
        java.Import(w, modelpkg + '.*')
    else:
        model_name = model_class
        modelpkg = package

    with java.Class(w,
                    '\n{}XmlDeserializer'.format(model_class),
                    write_file,
                    package=package):
        with java.Method(
                w,
                'public',
                'void',
                'deserialize', [(model_class, 'facade' if facade else 'model'),
                                ('XMLStreamReader', 'xsr')],
                throws=[model_name + 'Exception', 'XMLStreamException']):
            if facade:
                w('{} model = facade.getModel();', model_name)
            w('expect(XMLStreamConstants.START_ELEMENT, xsr.next());')
            with java.While(w,
                            'xsr.next() == XMLStreamConstants.START_ELEMENT'):
                with java.Switch(w, 'xsr.getLocalName()'):
                    for (tname, ft, t) in syslx.sorted_types(context):
                        if t.HasField('relation'):
                            w(
                                'case "{0}List": deserialize(model.get{0}Table(), xsr); break;',
                                tname)
                            w(
                                'case "{0}": deserializeOne(model.get{0}Table(), xsr); break;',
                                tname)
                    w('default: skipElement(xsr);')
            w('expect(XMLStreamConstants.END_ELEMENT, xsr.getEventType());')

        for (tname, ft, t) in syslx.sorted_types(context):
            if not t.HasField('relation'):
                continue
            pkey = datamodel.primary_key_params(t, context.module)
            pkey_fields = {f for (_, f, _) in pkey}
            fkeys = {
                java.name(fname): type_info
                for (fname, _,
                     type_info) in datamodel.foreign_keys(t, context.module)
            }

            private_setters = pkey_fields | set(fkeys.iterkeys())

            with java.Method(w,
                             '\nprivate',
                             'void',
                             'deserialize',
                             [(modelpkg + '.' + tname + '.Table', 'table'),
                              ('XMLStreamReader', 'xsr')],
                             throws=['XMLStreamException']):
                with java.While(
                        w, 'xsr.next() == XMLStreamConstants.START_ELEMENT'):
                    w('deserializeOne(table, xsr);')
                w('expect(XMLStreamConstants.END_ELEMENT, xsr.getEventType());'
                  )

            with java.Method(w,
                             '\nprivate',
                             'void',
                             'deserializeOne',
                             [(modelpkg + '.' + tname + '.Table', 'table'),
                              ('XMLStreamReader', 'xsr')],
                             throws=['XMLStreamException']):
                w('{0} entity = {0}._PRIVATE_new(table.model());',
                  modelpkg + '.' + tname)
                with java.While(
                        w, 'xsr.next() == XMLStreamConstants.START_ELEMENT'):
                    with java.Switch(w, 'xsr.getLocalName()'):
                        for (fname, f) in datamodel.sorted_fields(t):
                            jfname = java.name(fname)
                            (typename, _, type_) = datamodel.typeref(f, module)
                            extra = '{}'
                            which_type = type_.WhichOneof('type')
                            if which_type == 'primitive':
                                xmltype = XML_PARSE_MAP[type_.primitive]
                                if isinstance(xmltype, tuple):
                                    (xmltype, extra) = xmltype
                            elif which_type == 'enum':
                                xmltype = 'IntValue'
                                extra = typename + '.from({})'
                            else:
                                raise RuntimeError(
                                    'Unexpected field type for XML export: ' +
                                    which_type)

                            private = '_PRIVATE_' if jfname in private_setters else ''

                            if type_.primitive in [
                                    sysl_pb2.Type.DATE, sysl_pb2.Type.DATETIME
                            ]:
                                w(
                                    'case "{}": entity.{}set{}(read{}(xsr, {})); break;',
                                    jfname, private, java.CamelCase(jfname),
                                    typename, extra)
                            else:
                                w(
                                    'case "{}": entity.{}set{}(read{}(xsr)); break;',
                                    jfname, private, java.CamelCase(jfname),
                                    typename)
                        w('default: skipField(xsr);')
                w('table.insert(entity);')
                w('expect(XMLStreamConstants.END_ELEMENT, xsr.getEventType());'
                  )

        with java.Method(w, '\nprivate', 'void', 'expect',
                         [('int', 'expected'), ('int', 'got')]):
            with java.If(w, 'got != expected'):
                w('System.err.printf(\v'
                  '"<<Unexpected token: %s (expecting %s)>>\\n", \v'
                  'tokenName(got), tokenName(expected));')
                w('throw new {}Exception();', model_name)

        with java.Method(w, '\nprivate', 'String', 'tokenName',
                         [('int', 'token')]):
            with java.Switch(w, 'token'):
                for tok in (
                        'ATTRIBUTE CDATA CHARACTERS COMMENT DTD END_DOCUMENT '
                        'END_ELEMENT ENTITY_DECLARATION ENTITY_REFERENCE NAMESPACE '
                        'NOTATION_DECLARATION PROCESSING_INSTRUCTION SPACE START_DOCUMENT '
                        'START_ELEMENT'.split()):
                    w('case XMLStreamConstants.{0}: return "{0}";', tok)
            w('return new Integer(token).toString();')

        def read(t, access, extra_args=None):
            with java.Method(w,
                             '\nprivate',
                             t,
                             'read' + t, [('XMLStreamReader', 'xsr')],
                             throws=['XMLStreamException']):
                with java.If(w, '!getCharacters(xsr)'):
                    w('return null;')
                w('{} result = {};', t, access)
                w('expect(XMLStreamConstants.END_ELEMENT, xsr.next());')
                w('return result;')

        read('String', 'xsr.getText()')
        read('Boolean', 'Boolean.parseBoolean(xsr.getText())')
        read('Integer', 'Integer.parseInt(xsr.getText())')
        read('Double', 'Double.parseDouble(xsr.getText())')
        read('BigDecimal', 'new BigDecimal(xsr.getText())')
        read('UUID', 'UUID.fromString(xsr.getText())')

        with java.Method(w,
                         '\nprivate',
                         'DateTime',
                         'readDateTime', [('XMLStreamReader', 'xsr'),
                                          ('DateTimeFormatter', 'fmt')],
                         throws=['XMLStreamException']):
            with java.If(w, '!getCharacters(xsr)'):
                w('return null;')
            w('DateTime result = fmt.parseDateTime(xsr.getText());')
            w('expect(XMLStreamConstants.END_ELEMENT, xsr.next());')
            w('return result;')

        with java.Method(w,
                         '\nprivate',
                         'LocalDate',
                         'readLocalDate', [('XMLStreamReader', 'xsr'),
                                           ('DateTimeFormatter', 'fmt')],
                         throws=['XMLStreamException']):
            with java.If(w, '!getCharacters(xsr)'):
                w('return null;')
            w('LocalDate result = fmt.parseLocalDate(xsr.getText());')
            w('expect(XMLStreamConstants.END_ELEMENT, xsr.next());')
            w('return result;')

        with java.Method(w,
                         '\nprivate',
                         'void',
                         'skipField', [('XMLStreamReader', 'xsr')],
                         throws=['XMLStreamException']):
            with java.If(w, 'getCharacters(xsr)'):
                w('expect(XMLStreamConstants.END_ELEMENT, xsr.next());')

        with java.Method(w,
                         '\nprivate',
                         'boolean',
                         'getCharacters', [('XMLStreamReader', 'xsr')],
                         throws=['XMLStreamException']):
            w('int tok = xsr.next();')
            with java.If(w, 'tok == XMLStreamConstants.END_ELEMENT'):
                w('return false;')
            w('expect(XMLStreamConstants.CHARACTERS, tok);')
            w('return true;')

        with java.Method(w,
                         '\nprivate',
                         'void',
                         'skipElement', [('XMLStreamReader', 'xsr')],
                         throws=['XMLStreamException']):
            with java.While(w, 'xsr.next() != XMLStreamConstants.END_ELEMENT'):
                with java.If(
                        w,
                        'xsr.getEventType() == XMLStreamConstants.START_ELEMENT'
                ):
                    w('skipElement(xsr);')

        # TODO: Is permissive dateTimeParser OK for date types?
        w('\nprivate final DateTimeFormatter iso8601DateTime = '
          'ISODateTimeFormat.dateTimeParser();')

        w()
Beispiel #15
0
def swagger_file(app, module, root_class, write_file):
    def assign(root, path, value):
        if value is not None:
            for part in path[:-1]:
                root = root.setdefault(part, {})
            root[path[-1]] = value
        return value

    used_definitions = set()
    used_models = set()

    header = {}

    assign(header, ['swagger'], '2.0')
    paths = assign(header, ['paths'], {})
    definitions = assign(header, ['definitions'], {})

    for path in [['version'], ['title'], ['description'], ['contact', 'name'],
                 ['contact', 'email']]:
        assign(header, ['info'] + path,
               syslx.View(app.attrs)['.'.join(path)].s)

    assign(header, ['info', 'title'], app.long_name)

    typerefs = set()

    def swagger_type(t):
        if t.WhichOneof('type') == 'set':
            return {'type': 'array', 'items': swagger_type(t.set)}

        # TODO: Probably should use datamodel.typeref
        if t.WhichOneof('type') == 'type_ref':
            # TODO: What is the impact of removing this?
            #assert len(t.type_ref.ref.path) == 1
            model = t.type_ref.ref.path[0]
            if model in module.apps:
                used_models.add(model)
                return {'$ref': '#/definitions/' + model}

        type_ = datamodel.typeref(t, module)[2]
        if type_ is None:
            return None

        which_type = type_.WhichOneof('type')

        if which_type == 'primitive':
            return TYPE_MAP[type_.primitive]
        elif which_type == 'enum':
            return {'type': 'number', 'format': 'integer'}
        elif which_type in ['tuple', 'relation']:
            deftype = '.'.join(t.type_ref.ref.path)
            used_definitions.add(deftype)
            return {'$ref': '#/definitions/' + deftype}
        else:
            # return {'type': 'sysl:' + type_.WhichOneof('type')}
            raise RuntimeError('Unexpected field type for Swagger '
                               'export: ' + which_type)

    for (epname, endpt) in (sorted(app.endpoints.iteritems(),
                                   key=lambda t: t[0].lower())):
        if not endpt.HasField('rest_params'):
            continue

        rp = endpt.rest_params
        path = paths.setdefault(rp.path, {})
        method = path.setdefault(
            sysl_pb2.Endpoint.RestParams.Method.Name(rp.method).lower(), {})
        params = method['parameters'] = []
        for qp in rp.query_param:
            assert qp.loc, 'missing QueryParam.loc'
            params.append({
                'name':
                qp.name,
                'in':
                sysl_pb2.Endpoint.RestParams.QueryParam.Loc.Name(
                    qp.loc).lower(),
                'required':
                not qp.type.opt,
            })
            params[-1].update(TYPE_MAP[qp.type.primitive])

        assign(method, ['description'], endpt.docstring)

        for stmt in endpt.stmt:
            if stmt.WhichOneof('stmt') == 'ret':
                m = rex.match(
                    ur'''
          (?:
            (\d+)
            (?:·\((.*?)\))?
            (?:·:)?
            (?:·<:(·set·of)?·([\w\.]+))?
            (?:·or·{((?:\d+,)*\d+)})?
          ) | (?:
            one•of·{((?:\d+·,·)*\d+·)}
          )
          $
          ''', stmt.ret.payload)
                if m:
                    [status, descr, setof, type_, statuses,
                     statuses2] = m.groups()
                    resp = assign(method, ['responses', status], {})
                    assign(
                        resp, ['description'], descr or STATUS_MAP.get(
                            int(status or '0'), '(no description)'))
                    if type_:
                        schema = assign(resp, ['schema'], {})
                        if setof:
                            schema['type'] = 'array'
                            items = schema['items'] = {}
                        else:
                            items = schema
                        items['$ref'] = '#/definitions/' + type_
                        used_definitions.add(type_)
                    if statuses or statuses2:
                        for s in (statuses or statuses2).split(','):
                            assign(method, ['responses', s, 'description'],
                                   STATUS_MAP[int(s)])
                else:
                    print stmt.ret.payload
                    raise Exception('Bad return statement')

        body = syslx.View(endpt.attrs)['body'].s
        if body:
            params.append({
                'name': 'requestBody',
                'in': 'body',
                'required': True,
                'schema': {
                    '$ref': '#/definitions/' + body
                }
            })
            if body == 'PoOrder':
                used_models.add(body)
            else:
                used_definitions.add(body)

    used_defs2 = used_definitions.copy()
    used_definitions.clear()

    # Figure out which types are used
    while True:
        for (tname, t) in sorted(app.types.iteritems()):
            if tname in used_defs2:
                if t.WhichOneof('type') in ['relation', 'tuple']:
                    entity = getattr(t, t.WhichOneof('type'))
                    for (fname, f) in entity.attr_defs.iteritems():
                        swagger_type(f)

        used_definitions -= used_defs2
        if not used_definitions:
            break

        used_defs2 |= used_definitions

    for (tname, t) in sorted(app.types.iteritems()):
        if tname not in used_defs2:
            continue

        if t.WhichOneof('type') in ['relation', 'tuple']:
            properties = {}
            definition = definitions[tname] = {'properties': properties}

            entity = getattr(t, t.WhichOneof('type'))

            for (fname, f) in entity.attr_defs.iteritems():
                jfname = java.name(fname)
                properties[jfname] = swagger_type(f)

    for modelname in used_models:
        defn = definitions[modelname] = {}
        props = defn['properties'] = {}
        for (tname, t) in module.apps[modelname].types.iteritems():
            props[tname] = {
                'type': 'array',
                'items': {
                    '$ref': '#/definitions/' + tname
                }
            }

        # TODO: dedup with above logic
        for (tname, t) in module.apps[modelname].types.iteritems():
            if t.WhichOneof('type') in ['relation', 'tuple']:
                properties = {}
                definition = definitions[tname] = {'properties': properties}

                entity = getattr(t, t.WhichOneof('type'))

                for (fname, f) in entity.attr_defs.iteritems():
                    jfname = java.name(fname)
                    (a, type_info, type_) = datamodel.typeref(f, module)
                    if type_info is None:
                        properties[jfname] = swagger_type(f)
                    else:
                        #assert type_.WhichOneof('type') == 'primitive'
                        properties[jfname] = swagger_type(type_)

    write_file(yaml.dump(no_utf8(header)), root_class + '.swagger.yaml')
Beispiel #16
0
def deserializer(context):
    (app, module, package, model_class, write_file, _, _) = context

    facade = bool(context.wrapped_model)

    w = writer.Writer('java')

    java.Package(w, package)

    java.StandardImports(w)

    java.Import(w, 'javax.xml.stream.XMLStreamConstants')
    java.Import(w, 'javax.xml.stream.XMLStreamException')
    java.Import(w, 'javax.xml.stream.XMLStreamReader')
    w.head()
    java.Import(w, 'java.text.ParseException')
    w.head()
    java.Import(w, 'org.joda.time.format.DateTimeFormatter')
    java.Import(w, 'org.joda.time.format.ISODateTimeFormat')

    if facade:
        model_name = syslx.fmt_app_name(context.wrapped_model.name)
        modelpkg = syslx.View(context.wrapped_model.attrs)['package'].s
        w.head()
        java.Import(w, modelpkg + '.*')
    else:
        model_name = model_class
        modelpkg = package

    with java.Class(w, '\n{}XmlDeserializer'.format(model_class), write_file,
                    package=package):
        with java.Method(w, 'public', 'void', 'deserialize',
                         [(model_class, 'facade' if facade else 'model'),
                          ('XMLStreamReader', 'xsr')],
                         throws=[model_name + 'Exception', 'XMLStreamException']):
            if facade:
                w('{} model = facade.getModel();', model_name)
            w('expect(XMLStreamConstants.START_ELEMENT, xsr.next());')
            with java.While(w, 'xsr.next() == XMLStreamConstants.START_ELEMENT'):
                with java.Switch(w, 'xsr.getLocalName()'):
                    for (tname, ft, t) in syslx.sorted_types(context):
                        if t.HasField('relation'):
                            w('case "{0}List": deserialize(model.get{0}Table(), xsr); break;',
                              tname)
                            w('case "{0}": deserializeOne(model.get{0}Table(), xsr); break;',
                              tname)
                    w('default: skipElement(xsr);')
            w('expect(XMLStreamConstants.END_ELEMENT, xsr.getEventType());')

        for (tname, ft, t) in syslx.sorted_types(context):
            if not t.HasField('relation'):
                continue
            pkey = datamodel.primary_key_params(t, context.module)
            pkey_fields = {f for (_, f, _) in pkey}
            fkeys = {
                java.name(fname): type_info
                for (fname, _, type_info) in datamodel.foreign_keys(t, context.module)}

            private_setters = pkey_fields | set(fkeys.iterkeys())

            with java.Method(w, '\nprivate', 'void', 'deserialize',
                             [(modelpkg + '.' + tname + '.Table', 'table'),
                              ('XMLStreamReader', 'xsr')],
                             throws=['XMLStreamException']):
                with java.While(w, 'xsr.next() == XMLStreamConstants.START_ELEMENT'):
                    w('deserializeOne(table, xsr);')
                w('expect(XMLStreamConstants.END_ELEMENT, xsr.getEventType());')

            with java.Method(w, '\nprivate', 'void', 'deserializeOne',
                             [(modelpkg + '.' + tname + '.Table', 'table'),
                              ('XMLStreamReader', 'xsr')],
                             throws=['XMLStreamException']):
                w('{0} entity = {0}._PRIVATE_new(table.model());',
                  modelpkg + '.' + tname)
                with java.While(w, 'xsr.next() == XMLStreamConstants.START_ELEMENT'):
                    with java.Switch(w, 'xsr.getLocalName()'):
                        for (fname, f) in datamodel.sorted_fields(t):
                            jfname = java.name(fname)
                            (typename, _, type_) = datamodel.typeref(f, module)
                            extra = '{}'
                            which_type = type_.WhichOneof('type')
                            if which_type == 'primitive':
                                xmltype = XML_PARSE_MAP[type_.primitive]
                                if isinstance(xmltype, tuple):
                                    (xmltype, extra) = xmltype
                            elif which_type == 'enum':
                                xmltype = 'IntValue'
                                extra = typename + '.from({})'
                            else:
                                raise RuntimeError(
                                    'Unexpected field type for XML export: ' + which_type)

                            private = '_PRIVATE_' if jfname in private_setters else ''

                            if type_.primitive in [
                                    sysl_pb2.Type.DATE, sysl_pb2.Type.DATETIME]:
                                w('case "{}": entity.{}set{}(read{}(xsr, {})); break;',
                                  jfname, private, java.CamelCase(jfname), typename, extra)
                            else:
                                w('case "{}": entity.{}set{}(read{}(xsr)); break;',
                                  jfname, private, java.CamelCase(jfname), typename)
                        w('default: skipField(xsr);')
                w('table.insert(entity);')
                w('expect(XMLStreamConstants.END_ELEMENT, xsr.getEventType());')

        with java.Method(w, '\nprivate', 'void', 'expect',
                         [('int', 'expected'), ('int', 'got')]):
            with java.If(w, 'got != expected'):
                w('System.err.printf(\v'
                  '"<<Unexpected token: %s (expecting %s)>>\\n", \v'
                  'tokenName(got), tokenName(expected));')
                w('throw new {}Exception();', model_name)

        with java.Method(w, '\nprivate', 'String', 'tokenName', [('int', 'token')]):
            with java.Switch(w, 'token'):
                for tok in ('ATTRIBUTE CDATA CHARACTERS COMMENT DTD END_DOCUMENT '
                            'END_ELEMENT ENTITY_DECLARATION ENTITY_REFERENCE NAMESPACE '
                            'NOTATION_DECLARATION PROCESSING_INSTRUCTION SPACE START_DOCUMENT '
                            'START_ELEMENT'.split()):
                    w('case XMLStreamConstants.{0}: return "{0}";', tok)
            w('return new Integer(token).toString();')

        def read(t, access, extra_args=None):
            with java.Method(w, '\nprivate', t, 'read' + t,
                             [('XMLStreamReader', 'xsr')],
                             throws=['XMLStreamException']):
                with java.If(w, '!getCharacters(xsr)'):
                    w('return null;')
                w('{} result = {};', t, access)
                w('expect(XMLStreamConstants.END_ELEMENT, xsr.next());')
                w('return result;')

        read('String', 'xsr.getText()')
        read('Boolean', 'Boolean.parseBoolean(xsr.getText())')
        read('Integer', 'Integer.parseInt(xsr.getText())')
        read('Double', 'Double.parseDouble(xsr.getText())')
        read('BigDecimal', 'new BigDecimal(xsr.getText())')
        read('UUID', 'UUID.fromString(xsr.getText())')

        with java.Method(w, '\nprivate', 'DateTime', 'readDateTime',
                         [('XMLStreamReader', 'xsr'),
                          ('DateTimeFormatter', 'fmt')],
                         throws=['XMLStreamException']):
            with java.If(w, '!getCharacters(xsr)'):
                w('return null;')
            w('DateTime result = fmt.parseDateTime(xsr.getText());')
            w('expect(XMLStreamConstants.END_ELEMENT, xsr.next());')
            w('return result;')

        with java.Method(w, '\nprivate', 'LocalDate', 'readLocalDate',
                         [('XMLStreamReader', 'xsr'),
                          ('DateTimeFormatter', 'fmt')],
                         throws=['XMLStreamException']):
            with java.If(w, '!getCharacters(xsr)'):
                w('return null;')
            w('LocalDate result = fmt.parseLocalDate(xsr.getText());')
            w('expect(XMLStreamConstants.END_ELEMENT, xsr.next());')
            w('return result;')

        with java.Method(w, '\nprivate', 'void', 'skipField',
                         [('XMLStreamReader', 'xsr')], throws=['XMLStreamException']):
            with java.If(w, 'getCharacters(xsr)'):
                w('expect(XMLStreamConstants.END_ELEMENT, xsr.next());')

        with java.Method(w, '\nprivate', 'boolean', 'getCharacters',
                         [('XMLStreamReader', 'xsr')], throws=['XMLStreamException']):
            w('int tok = xsr.next();')
            with java.If(w, 'tok == XMLStreamConstants.END_ELEMENT'):
                w('return false;')
            w('expect(XMLStreamConstants.CHARACTERS, tok);')
            w('return true;')

        with java.Method(w, '\nprivate', 'void', 'skipElement',
                         [('XMLStreamReader', 'xsr')], throws=['XMLStreamException']):
            with java.While(w, 'xsr.next() != XMLStreamConstants.END_ELEMENT'):
                with java.If(w,
                             'xsr.getEventType() == XMLStreamConstants.START_ELEMENT'):
                    w('skipElement(xsr);')

        # TODO: Is permissive dateTimeParser OK for date types?
        w('\nprivate final DateTimeFormatter iso8601DateTime = '
          'ISODateTimeFormat.dateTimeParser();')

        w()
Beispiel #17
0
def swagger_file(app, module, root_class, write_file):
    def assign(root, path, value):
        if value is not None:
            for part in path[:-1]:
                root = root.setdefault(part, {})
            root[path[-1]] = value
        return value

    used_definitions = set()
    used_models = set()

    header = {}

    assign(header, ['swagger'], '2.0')
    paths = assign(header, ['paths'], {})
    definitions = assign(header, ['definitions'], {})

    for path in [
        ['version'],
        ['title'],
        ['description'],
        ['contact', 'name'],
            ['contact', 'email']]:
        assign(header, ['info'] + path,
               syslx.View(app.attrs)['.'.join(path)].s)

    assign(header, ['info', 'title'], app.long_name)

    typerefs = set()

    def swagger_type(t):
        if t.WhichOneof('type') == 'set':
            return {'type': 'array', 'items': swagger_type(t.set)}

        # TODO: Probably should use datamodel.typeref
        if t.WhichOneof('type') == 'type_ref':
            # TODO: What is the impact of removing this?
            #assert len(t.type_ref.ref.path) == 1
            model = t.type_ref.ref.path[0]
            if model in module.apps:
                used_models.add(model)
                return {'$ref': '#/definitions/' + model}

        type_ = datamodel.typeref(t, module)[2]
        if type_ is None:
            return None

        which_type = type_.WhichOneof('type')

        if which_type == 'primitive':
            return TYPE_MAP[type_.primitive]
        elif which_type == 'enum':
            return {'type': 'number', 'format': 'integer'}
        elif which_type in ['tuple', 'relation']:
            deftype = '.'.join(t.type_ref.ref.path)
            used_definitions.add(deftype)
            return {'$ref': '#/definitions/' + deftype}
        else:
            # return {'type': 'sysl:' + type_.WhichOneof('type')}
            raise RuntimeError(
                'Unexpected field type for Swagger '
                'export: ' + which_type)

    for (epname, endpt) in (
            sorted(app.endpoints.iteritems(), key=lambda t: t[0].lower())):
        if not endpt.HasField('rest_params'):
            continue

        rp = endpt.rest_params
        path = paths.setdefault(rp.path, {})
        method = path.setdefault(
            sysl_pb2.Endpoint.RestParams.Method.Name(rp.method).lower(), {})
        params = method['parameters'] = []
        for qp in rp.query_param:
            assert qp.loc, 'missing QueryParam.loc'
            params.append({
                'name': qp.name,
                'in': sysl_pb2.Endpoint.RestParams.QueryParam.Loc.Name(qp.loc).lower(),
                'required': not qp.type.opt,
            })
            params[-1].update(TYPE_MAP[qp.type.primitive])

        assign(method, ['description'], endpt.docstring)

        for stmt in endpt.stmt:
            if stmt.WhichOneof('stmt') == 'ret':
                m = rex.match(ur'''
          (?:
            (\d+)
            (?:·\((.*?)\))?
            (?:·:)?
            (?:·<:(·set·of)?·([\w\.]+))?
            (?:·or·{((?:\d+,)*\d+)})?
          ) | (?:
            one•of·{((?:\d+·,·)*\d+·)}
          )
          $
          ''', stmt.ret.payload)
                if m:
                    [status, descr, setof, type_, statuses, statuses2] = m.groups()
                    resp = assign(method, ['responses', status], {})
                    assign(resp, ['description'],
                           descr or STATUS_MAP.get(int(status or '0'), '(no description)'))
                    if type_:
                        schema = assign(resp, ['schema'], {})
                        if setof:
                            schema['type'] = 'array'
                            items = schema['items'] = {}
                        else:
                            items = schema
                        items['$ref'] = '#/definitions/' + type_
                        used_definitions.add(type_)
                    if statuses or statuses2:
                        for s in (statuses or statuses2).split(','):
                            assign(method, ['responses', s, 'description'],
                                   STATUS_MAP[int(s)])
                else:
                    print stmt.ret.payload
                    raise Exception('Bad return statement')

        body = syslx.View(endpt.attrs)['body'].s
        if body:
            params.append({
                'name': 'requestBody',
                'in': 'body',
                'required': True,
                'schema': {'$ref': '#/definitions/' + body}
            })
            if body == 'PoOrder':
                used_models.add(body)
            else:
                used_definitions.add(body)

    used_defs2 = used_definitions.copy()
    used_definitions.clear()

    # Figure out which types are used
    while True:
        for (tname, t) in sorted(app.types.iteritems()):
            if tname in used_defs2:
                if t.WhichOneof('type') in ['relation', 'tuple']:
                    entity = getattr(t, t.WhichOneof('type'))
                    for (fname, f) in entity.attr_defs.iteritems():
                        swagger_type(f)

        used_definitions -= used_defs2
        if not used_definitions:
            break

        used_defs2 |= used_definitions

    for (tname, t) in sorted(app.types.iteritems()):
        if tname not in used_defs2:
            continue

        if t.WhichOneof('type') in ['relation', 'tuple']:
            properties = {}
            definition = definitions[tname] = {
                'properties': properties
            }

            entity = getattr(t, t.WhichOneof('type'))

            for (fname, f) in entity.attr_defs.iteritems():
                jfname = java.name(fname)
                properties[jfname] = swagger_type(f)

    for modelname in used_models:
        defn = definitions[modelname] = {}
        props = defn['properties'] = {}
        for (tname, t) in module.apps[modelname].types.iteritems():
            props[tname] = {
                'type': 'array',
                'items': {'$ref': '#/definitions/' + tname}
            }

        # TODO: dedup with above logic
        for (tname, t) in module.apps[modelname].types.iteritems():
            if t.WhichOneof('type') in ['relation', 'tuple']:
                properties = {}
                definition = definitions[tname] = {
                    'properties': properties
                }

                entity = getattr(t, t.WhichOneof('type'))

                for (fname, f) in entity.attr_defs.iteritems():
                    jfname = java.name(fname)
                    (a, type_info, type_) = datamodel.typeref(f, module)
                    if type_info is None:
                        properties[jfname] = swagger_type(f)
                    else:
                        #assert type_.WhichOneof('type') == 'primitive'
                        properties[jfname] = swagger_type(type_)

    write_file(yaml.dump(no_utf8(header)), root_class + '.swagger.yaml')