Exemplo n.º 1
0
def _generate_view(module, appname, types):
    """Output integration view"""
    write = writer.Writer('plantuml')

    var_name = _make_varmgr(module, appname, write)

    with write.uml():
        for (appname, name, typespec) in types:
            var_name(name)

            link_sets = collections.defaultdict(
                lambda: collections.defaultdict(list))

            fields = sorted(typespec.tuple.attr_defs.iteritems(),
                            key=_attr_sort_key)
            for (fieldname, fieldtype) in fields:
                cardinality = u' '
                while fieldtype.WhichOneof('type') == 'list':
                    fieldtype = fieldtype.list.type
                    cardinality = u'0..*'

                if fieldtype.WhichOneof('type') == 'set':
                    fieldtype = fieldtype.set
                    cardinality = u'0..*'

                if fieldtype.WhichOneof('type') == 'type_ref':
                    ref = u'.'.join(fieldtype.type_ref.ref.path)
                    # Hacky!
                    if ref.startswith(u'Common Data.'):
                        continue

                    refs = [n for (_, n, _) in types if n.endswith(ref)]

                    line_template = u'{} {{}} *-- "{}" {}'.format(
                        var_name(name), cardinality,
                        var_name(refs[0]) if refs else ref)
                    link_sets[ref][line_template].append(fieldname)

            for (_, line_templates) in link_sets.iteritems():
                if len(line_templates) > 1:
                    for (line_template,
                         fieldnames) in line_templates.iteritems():
                        for fieldname in fieldnames:
                            write(line_template, '"' + fieldname + '"')
                else:
                    for (line_template,
                         fieldnames) in line_templates.iteritems():
                        for _ in fieldnames:
                            write(line_template, '')

    return str(write)
Exemplo n.º 2
0
def main():
    argp = argparse.ArgumentParser(description='import xsd to sysl')

    argp.add_argument('--appname', help='output appname')
    argp.add_argument('--package', help='output package')

    argp.add_argument('input', help='xsd input file')
    argp.add_argument('output', help='sysl output file')

    args = argp.parse_args()

    root = ET.XML(open(args.input).read())

    w = writer.Writer('sysl')

    w('{}{}:', args.appname
      or os.path.splitext(os.path.basename(args.input))[0],
      ' [package="{}"]'.format(args.package) if args.package else '')
    with w.indent():
        toplevel = [(e.get('name'), list(e)[0])
                    for e in findall(root, './xs:element[@name]')]
        secondary = [(ct.get('name'), ct)
                     for ct in findall(root, './xs:complexType[@name]')]

        for (i, (tname, t)) in enumerate(toplevel + secondary):
            w('\n!type {}{}:'[not i:], tname, (' [xml_order=["index"]]' if any(
                attr.get('name') == 'index'
                for attr in findall(t, './xs:attribute')) else ''))

            with w.indent():
                for attr in findall(t, './xs:attribute'):
                    (type_, _) = BASE_TYPE_MAP[attr.get('type')]
                    w('{} <: {}{} [~xml_attribute]', attr.get('name'), type_,
                      '' if attr.get('use') == 'required' else '?')

                for field in (findall(t, './xs:sequence/xs:element') +
                              findall(t, './xs:all/xs:element')):
                    w('{} <: {}', field.get('name'), syslForField(field))

        open(args.output, 'w').write(str(w))
Exemplo n.º 3
0
def interface(interfaces, context):
    (app, module, package, model_class, write_file, _, _) = context

    for interface in interfaces:
        w = writer.Writer('java')

        java.Package(w, package)

        with java.Class(w,
                        interface,
                        write_file,
                        type_='interface',
                        visibility='public',
                        package=package):
            scope = scopes.Scope(module)

            for (epname, endpt) in (sorted(app.endpoints.iteritems(),
                                           key=lambda t:
                                           (t[1].rest_params.path, t[0]))):
                if endpt.attrs['interface'].s != interface:
                    continue
                if not endpt.HasField('rest_params'):
                    continue

                rp = endpt.rest_params
                rest_method = rp.Method.Name(rp.method)
                method_name = (
                    rest_method +
                    rex.sub(r'{(\w+)}', lambda m: m.group(1).upper(),
                            rex.sub(r'[-/]', '_', rp.path)))

                w(
                    'public Object {}({});', method_name,
                    ', '.join('\v{} {}'.format(t, p)
                              for (t,
                                   p) in codeForParams(rp.query_param, scope)))
Exemplo n.º 4
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

      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();')

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

    w()
    with java.Method(w, 'private', 'void', 'writeField'.format(t),
        [('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'.format(t),
        [('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'.format(t),
        [('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'.format(t),
        [('JsonGenerator', 'g'),
         ('String', 'fieldname'),
         ('DateTime', 'value'),
         ('DateTimeFormatter', 'fmt')],
        throws=['IOException']):
      with java.If(w, 'value != null'):
        w('g.writeStringField(fieldname, fmt.print(value));')

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

    w()
    with java.Method(w, 'private', 'void', 'writeField'.format(t),
        [('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();')
Exemplo n.º 5
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=has_tables and 'JsonDeserializer<' + model_class + '>'):
    if has_tables:
      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)
        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()
        w('return model;')

    for (tname, t) in sorted(app.types.iteritems()):
      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();')

    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 (
          '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()
Exemplo n.º 6
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')
                            import pdb
                            pdb.set_trace()

                        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()
Exemplo n.º 7
0
def _generate_view(module, args, integrations, highlights, app, apps, endpt):
    write = writer.Writer('plantuml')
    """Output integration view"""

    app_attrs = syslx.View(app.attrs)
    endpt_attrs = syslx.View(endpt.attrs)
    highlight_color = app_attrs['highlight_color'].s
    arrow_color = app_attrs['arrow_color'].s
    indirect_arrow_color = app_attrs['indirect_arrow_color'].s

    diagram_title = ''
    if (app_attrs['title'].s or args.title):
        fmtfn = diagutil.parse_fmt(app_attrs['title'].s or args.title)
        diagram_title = fmtfn(epname=endpt.name, eplongname=endpt.long_name)

    def generate_component_view():

        name_map = {}

        def make_varmgr():
            """Return a variable manager instance."""
            appfmt = syslx.View(module.apps.get(
                args.project).attrs)['appfmt'].s
            appfmt = diagutil.parse_fmt(appfmt)

            def new_var(var, name):
                """Outputs a new definition when VarManager makes a new variable."""

                app = module.apps[name]
                write(
                    '[{}] as {}{}',
                    appfmt(appname=name_map.get(name, name),
                           **diagutil.attr_fmt_vars(app.attrs)).replace(
                               '\n', r'\n'), var,
                    ' <<highlight>>' if name in highlights else '')

            return diagutil.VarManager(new_var)

        with write.uml():

            if diagram_title:
                write('title ' + diagram_title)

            write('hide stereotype')
            write('scale max 16384 height')
            write('skinparam linetype ortho')
            write('skinparam component {{')
            write('  BackgroundColor FloralWhite')
            write('  BorderColor Black')
            write('  ArrowColor Crimson')
            if highlight_color:
                write('  BackgroundColor<<highlight>> ' + highlight_color)
            if arrow_color:
                write('  ArrowColor ' + arrow_color)
            if indirect_arrow_color and indirect_arrow_color != 'none':
                write('  ArrowColor<<indirect>> ' + indirect_arrow_color)
            write('}}')

            var_name = make_varmgr()

            if args.clustered or endpt_attrs['view'].s == 'clustered':
                clusters = diagutil.group_by(
                    apps, key=lambda app: app.partition(' :: ')[0])
                clusters = [(cluster, members) for (cluster, g) in clusters
                            for members in [list(g)] if len(members) > 1]
                name_map = {
                    app: app.partition(' :: ')[-1] or app
                    for (cluster, members) in clusters for app in members
                }
                for (cluster, cluster_apps) in clusters:
                    write('package "{}" {{', cluster)
                    for app in cluster_apps:
                        var_name(app)
                        # write('  {}', var_name(app))
                    write('}}')

            calls_drawn = set()

            if endpt_attrs['view'].s == 'system':
                for ((app_a, _), (app_b, _)) in integrations:
                    direct = {app_a, app_b} & highlights
                    app_a = app_a.partition(' :: ')[0]
                    app_b = app_b.partition(' :: ')[0]
                    if app_a != app_b and (app_a, app_b) not in calls_drawn:
                        if direct or indirect_arrow_color != 'none':
                            write('{} --> {}{}', var_name(app_a),
                                  var_name(app_b),
                                  '' if direct else ' <<indirect>>')
                            calls_drawn.add((app_a, app_b))
            else:
                for ((app_a, _), (app_b, _)) in integrations:
                    if app_a != app_b and (app_a, app_b) not in calls_drawn:
                        direct = {app_a, app_b} & highlights
                        if direct or indirect_arrow_color != 'none':
                            write('{} --> {}{}', var_name(app_a),
                                  var_name(app_b),
                                  '' if direct else ' <<indirect>>')
                            calls_drawn.add((app_a, app_b))

                for appname in apps:
                    for mixin in module.apps[appname].mixin2:
                        mixin_name = syslx.fmt_app_name(mixin.name)
                        mixin_app = module.apps[mixin_name]
                        write('{} <|.. {}', var_name(mixin_name),
                              var_name(appname))

    #TODO Some serious refactoring
    def generate_state_view():
        def make_varmgr(istoplevel=False):
            """Return a variable manager instance."""
            appfmt = syslx.View(module.apps.get(
                args.project).attrs)['appfmt'].s
            appfmt = diagutil.parse_fmt(appfmt)

            def new_var(var, name):
                """Outputs a new definition when VarManager makes a new variable."""

                #TODO dodgy, should be using context (look at syslseqs)
                if istoplevel:
                    template = 'state "{}" as X{}{} {{'
                else:
                    template = '  state "{}" as {}{}'
                    (_, _, name) = name.partition(' : ')

                app = module.apps[name]
                write(
                    template,
                    appfmt(appname=name,
                           **diagutil.attr_fmt_vars(app.attrs)).replace(
                               '\n', r'\n'), var,
                    ' <<highlight>>' if name in highlights else '')

            return diagutil.VarManager(new_var)

        def yield_call_statements(statements):
            for (_, stmt) in enumerate(statements):
                field = stmt.WhichOneof('stmt')
                if field == 'call':
                    yield stmt
                elif field == 'alt':
                    for (_, choice) in enumerate(stmt.alt.choice):
                        for next_stmt in yield_call_statements(choice.stmt):
                            yield next_stmt
                elif field in {'cond', 'loop', 'loop_n', 'foreach', 'group'}:
                    for next_stmt in yield_call_statements(
                            getattr(stmt, field).stmt):
                        yield next_stmt

        with write.uml():

            if diagram_title:
                write('title ' + diagram_title)

            write('left to right direction')
            write('scale max 16384 height')
            write('skinparam nodesep 10')
            #TODO[kirkpatg]: this should probably scale up & down based on nodes & connections
            write('skinparam ranksep 300')
            #write('skinparam linetype polyline')
            write('hide empty description')
            write('skinparam state {{')
            write('  BackgroundColor FloralWhite')
            write('  BorderColor Black')
            write('  ArrowColor Crimson')
            if highlight_color:
                write('  BackgroundColor<<highlight>> ' + highlight_color)
            if arrow_color:
                write('  ArrowColor ' + arrow_color)
            if indirect_arrow_color and indirect_arrow_color != 'none':
                write('  ArrowColor<<indirect>> ' + indirect_arrow_color)
                write('  ArrowColor<<internal>> ' + indirect_arrow_color)
            write('}}')

            var_name = make_varmgr()
            tl_var_name = make_varmgr(True)

            clusters = {}

            # group end points and build the declarations
            for (app_a, ep_a), (app_b, ep_b) in integrations:
                if app_a not in clusters: clusters[app_a] = set()
                if app_b not in clusters: clusters[app_b] = set()

                # create clients in the calling app
                clusters[app_a].add(ep_a)
                if app_a != app_b and not module.apps[app_a].endpoints[
                        ep_a].is_pubsub:
                    clusters[app_a].add(ep_b + " client")

                clusters[app_b].add(ep_b)

            for cluster in clusters:
                tl_var_name(cluster)
                for member in clusters[cluster]:
                    var_name(cluster + ' : ' + member)
                write('}}')

            processed = []
            for ((app_a, ep_a), (app_b, ep_b)) in integrations:
                direct = {app_a, app_b} & highlights

                # build the label
                label = ''
                needs_int = app_a != app_b
                # if 'App1 Event' in ep_a: import pdb; pdb.set_trace()

                # import pdb; pdb.set_trace()
                for stmt in yield_call_statements(
                        module.apps[app_a].endpoints[ep_a].stmt):

                    app_b_name = ' :: '.join(part
                                             for part in stmt.call.target.part)

                    if app_b == app_b_name and ep_b == stmt.call.endpoint:
                        fmt_vars = diagutil.attr_fmt_vars(stmt.attrs)
                        ptrns = syslx.patterns(
                            module.apps[app_b].endpoints[ep_b].attrs)
                        label = diagutil.parse_fmt(app.attrs["epfmt"].s)(
                            needs_int=needs_int,
                            patterns=', '.join(sorted(ptrns)),
                            **fmt_vars)
                        break

                flow = ".".join([app_a, ep_b, app_b, ep_b])
                is_pubsub = module.apps[app_a].endpoints[ep_a].is_pubsub
                ep_b_client = ep_b + " client"
                if app_a != app_b:
                    if is_pubsub:
                        write('{} -{}> {}{}', var_name(app_a + ' : ' + ep_a),
                              '[#black]', var_name(app_b + ' : ' + ep_b),
                              ' : ' + label if label else '')
                    else:
                        write(
                            '{} -{}> {}', var_name(app_a + ' : ' + ep_a),
                            '[#' + indirect_arrow_color +
                            ']-' if indirect_arrow_color else '[#silver]-',
                            var_name(app_a + ' : ' + ep_b_client))
                        if flow not in processed:
                            write('{} -{}> {}{}',
                                  var_name(app_a + ' : ' + ep_b_client),
                                  '[#black]', var_name(app_b + ' : ' + ep_b),
                                  ' : ' + label if label else '')
                            processed.append(flow)

                else:
                    write(
                        '{} -{}> {}{}', var_name(app_a + ' : ' + ep_a),
                        '[#' + indirect_arrow_color +
                        ']-' if indirect_arrow_color else '[#silver]-',
                        var_name(app_b + ' : ' + ep_b),
                        ' : ' + label if label else '')

    if (args.epa) or endpt_attrs['view'].s == 'epa':
        generate_state_view()
    else:
        generate_component_view()

    return str(write)
Exemplo n.º 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 = '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:
                                    if jfname == 'index':
                                        import pdb
                                        pdb.set_trace()
                                    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();')
Exemplo n.º 9
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):
            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())

            if not t.HasField('relation'):
                continue
            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()
Exemplo n.º 10
0
def export(mode, module, appname, outdir, expected_package, entities,
           serializers):
    app = module.apps.get(appname)
    assert app, appname

    package = syslx.View(app.attrs)['package'].s
    if mode != 'xsd':
        assert package == expected_package, (package, expected_package)

    model_class = '_'.join(app.name.part).replace(' ', '')

    write_file = src.util.file.FileWriter(outdir, package, entities)

    inouts = []
    for s in serializers:
        assert '_' in s, s
        (fmt, dirn) = s.split('_')
        fmts = ['json', 'xml'] if fmt == '*' else [fmt]
        dirns = ['in', 'out'] if dirn == '*' else [dirn]
        for fmt in fmts:
            for dirn in dirns:
                inouts.append(fmt + "_" + dirn)
    serializers = set(inouts)
    bogus_serializers = serializers - {
        'json_in', 'json_out', 'xml_in', 'xml_out'
    }
    assert not bogus_serializers, bogus_serializers

    if app.HasField('wrapped'):
        model_name = syslx.fmt_app_name(app.wrapped.name)
        assert model_name in module.apps, ('missing app: ' + repr(model_name),
                                           module.apps.keys(),
                                           app.wrapped.endpoints.keys())
        wrapped_model = module.apps[model_name]
    else:
        wrapped_model = None

    context = Context(app, module, package, model_class, write_file, appname,
                      wrapped_model)

    def serializer_entities():
        return (({appname +
                  'JsonDeserializer'} if 'json_in' in serializers else set()) |
                ({appname +
                  'JsonSerializer'} if 'json_out' in serializers else set()) |
                ({appname +
                  'XmlDeserializer'} if 'xml_in' in serializers else set()) |
                ({appname +
                  'XmlSerializer'} if 'xml_out' in serializers else set()))

    def export_serializers():
        if 'json_in' in serializers:
            json_export.deserializer(context)
        if 'json_out' in serializers:
            json_export.serializer(context)
        if 'xml_in' in serializers:
            xml_export.deserializer(context)
        if 'xml_out' in serializers:
            xml_export.serializer(context)

    if mode == 'model':
        entities |= {appname, appname + 'Exception'} | serializer_entities()

        # Build a foreign key reverse map to enable efficeint navigation
        # in the generated classes
        fk_rmap = datamodel.build_fk_reverse_map(app, module)

        # For each of the "types" in the Application message from the
        # protocol buffer represenation of the sysl generate an
        # "Entity" class
        for (tname, t) in sorted(app.types.iteritems()):
            if not re.match(r'AnonType_\d+__$', tname):
                w = writer.Writer('java')
                java.Package(w, package)
                java.StandardImports(w)
                java_model.export_entity_class(w, tname, t, fk_rmap[tname],
                                               context)

        java_model.export_model_class(fk_rmap, context)
        java_model.export_exception_class(context)
        export_serializers()

    elif mode == 'facade':
        entities |= {appname} | serializer_entities()
        java_facade.export_facade_class(context)
        export_serializers()

    elif mode == 'xsd':
        xsd_export.xsd(context)

    elif mode == 'swagger':
        swagger_export.swagger_file(app, module, model_class, write_file)

    elif mode == 'spring-rest-service':
        interfaces = {
            endpt.attrs['interface'].s
            for endpt in app.endpoints.itervalues()
        }
        assert None not in interfaces, '\n' + '\n'.join(
            sorted([
                endpt.name for endpt in app.endpoints.itervalues()
                for i in [endpt.attrs['interface'].s] if not i
            ],
                   key=lambda name: reversed(name.split())))

        entities |= {model_class + 'Controller'} | set(interfaces)
        src.exporters.api.spring_rest.service(interfaces, context)

    elif mode == 'view':
        entities |= {appname}

        w = writer.Writer('java')
        java.Package(w, package)
        java.StandardImports(w)
        w()
        java.Import(w, 'org.joda.time.DateTime')
        java.Import(w, 'org.joda.time.format.DateTimeFormat')
        java.Import(w, 'org.joda.time.format.DateTimeFormatter')
        w()
        java_model.export_view_class(w, context)
Exemplo n.º 11
0
def xsd(context):

    w = writer.Writer('xml')
    w.increment = 2
    xsd_separator = '<!-- ' + '=' * 55 + ' -->'

    def e(_name, **attrs):
        if _name.endswith('/'):
            w(
                u'<{}{}/>', _name[:-1],
                u''.join(u' {}="{}"'.format(k.replace('_', ':'), v)
                         for (k, v) in attrs.iteritems()))
        else:

            @contextlib.contextmanager
            def f():
                w(
                    u'<{}{}>', _name,
                    u''.join(u' {}="{}"'.format(k.replace('_', ':'), v)
                             for (k, v) in attrs.iteritems()))
                with w.indent():
                    yield
                w(u'</{}>', _name)

            return f()

    def xs(_name, **attrs):
        return e('xs:' + _name, **attrs)

    def build_relational_xsd():
        # top level element contains all entities for
        # relational schemas but will only contain the
        # root entity for hierarchical
        with xs('element', name=context.model_class):
            with xs('complexType'):
                with xs('sequence', minOccurs=1, maxOccurs=1):
                    # each "relation" is a list of things
                    for (tname, ft, t) in syslx.sorted_types(context):
                        if t.HasField('relation'):
                            xs('element/',
                               name=tname + 'List',
                               type=tname + 'List',
                               minOccurs=0)

            # build keys and key refs
            for (tname, ft, t) in syslx.sorted_types(context):
                if t.HasField('relation'):
                    pkey = datamodel.primary_key_params(t, context.module)
                    pkey_fields = {f for (_, f, _) in pkey}
                    has_content = False

                    def xsd_key_header(msg):
                        w('{}', '<!-- ' + msg.center(55) + ' -->')

                    if pkey:
                        if not has_content:
                            has_content = True
                            w()
                            w(xsd_separator)
                            xsd_key_header(tname + ' keys')

                        with xs('key', name='key_' + tname):
                            xs('selector/',
                               xpath='./{0}List/{0}'.format(tname))
                            for f in sorted(pkey_fields):
                                xs('field/', xpath=f)

                    for (i, (fname, _, type_info)) in enumerate(
                            sorted(datamodel.foreign_keys(t, context.module))):
                        if not has_content:
                            has_content = True
                            w()
                            w(xsd_separator)
                            xsd_key_header(tname + ' keyrefs')
                        elif pkey and i == 0:
                            xsd_key_header('keyrefs')
                        fk_type = type_info.parent_path
                        fk_field = type_info.field
                        with xs('keyref',
                                name='keyref_{}_{}'.format(tname, fname),
                                refer='key_' + fk_type):
                            xs('selector/',
                               xpath='./{0}List/{0}'.format(tname))
                            xs('field/', xpath=fname)
                    if has_content:
                        w(xsd_separator)
            w()

        w()
        # construct the entities
        for (tname, ft, t) in syslx.sorted_types(context):
            if t.HasField('relation'):
                with xs('complexType', name=tname + 'List'):
                    with xs('sequence', maxOccurs='unbounded'):
                        with xs('element', name=tname):
                            with xs('complexType'):
                                with xs('all'):
                                    for (fname, f) in sorted(
                                            t.relation.attr_defs.iteritems()):
                                        jfname = java.name(fname)
                                        method = java.CamelCase(jfname)
                                        type_ = datamodel.typeref(
                                            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'
                                        else:
                                            raise RuntimeError(
                                                'Unexpected field type for XSD '
                                                'export: ' + which_type)
                                        xs('element/',
                                           name=jfname,
                                           type=xsdtype,
                                           minOccurs=0)

    def build_hierarchical_xsd():
        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(
                    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)

        # Top level element
        with xs('element', name=context.model_class):
            with xs('complexType'):
                with xs('sequence', minOccurs=1, maxOccurs=1):
                    for (tname, ft, t) in syslx.sorted_types(context):
                        if 'xml_root' in syslx.patterns(t.attrs):
                            xs('element/', name=tname, type=tname, minOccurs=0)
                            break

        w(xsd_separator)

        for (tname, ft, t) in syslx.sorted_types(context):
            with xs('complexType', name=tname):

                with xs('all'):
                    for (fname, f) in sorted(t.tuple.attr_defs.iteritems()):
                        if not 'xml_attribute' in syslx.patterns(f.attrs):
                            if f.HasField('set'):
                                with xs('element', name=fname + 'List'):
                                    with xs('complexType'):
                                        with xs('sequence',
                                                maxOccurs='unbounded'):
                                            build_element(
                                                fname, f, True, False)
                            else:
                                build_element(fname, f, False, False)

                #attributes second
                for (fname, f) in sorted(t.tuple.attr_defs.iteritems()):
                    if 'xml_attribute' in syslx.patterns(f.attrs):
                        build_element(fname, f, True, True)

    def build_xsd():
        for (_, _, t) in syslx.sorted_types(context):
            if t.HasField('relation'):
                build_relational_xsd()
                return
        build_hierarchical_xsd()

    with e('xs:schema',
           xmlns_xs='http://www.w3.org/2001/XMLSchema',
           attributeFormDefault='unqualified',
           elementFormDefault='qualified',
           version='1.0'):
        build_xsd()

    context.write_file(w, context.model_class + '.xsd')
Exemplo n.º 12
0
def main():
    [swagger_path, appname, package, outfile] = sys.argv[1:]

    swag = yaml.load(open(swagger_path))

    w = writer.Writer('sysl')

    if 'info' in swag:

        def info_attrs(info, prefix=''):
            for (name, value) in sorted(info.iteritems()):
                if isinstance(value, dict):
                    info_attrs(value, prefix + name + '.')
                else:
                    w('@{}{} = {}', prefix, name, json.dumps(value))

        title = swag['info'].pop('title', '')
        info_attrs(swag['info'])
    else:
        title = ''

    if 'host' in swag:
        w('@host = {}', json.dumps(swag['host']))

    w(u'{}{} [package={}]:', appname, title and ' ' + json.dumps(title),
      json.dumps(package))

    with w.indent():
        w(u'| {}', swag['info'].get('description', 'No description.'))

        for (path, api) in sorted(swag['paths'].iteritems()):
            # {foo-bar} to {fooBar}
            w(u'\n{}:', re.sub(r'({[^/]*?})', javaParam, path))
            with w.indent():

                if 'parameters' in api:
                    del api['parameters']

                for (i, (method, body)) in enumerate(
                        sorted(api.iteritems(),
                               key=lambda t: METHOD_ORDER[t[0]])):
                    qparams = dict()

                    if body.has_key(
                            'parameters') and 'in' in body['parameters']:
                        qparams = [
                            p for p in body['parameters'] if p['in'] == 'query'
                        ]
                    w(
                        u'{}{}{}:', method.upper(), ' ?' if qparams else '',
                        '&'.join(
                            ('{}={}{}'.format(p['name'], SWAGGER_TYPE_MAP[
                                p['type']], '' if p['required'] else '?') if
                             p['type'] != 'string' else '{name}=string'.format(
                                 **p)) for p in qparams))
                    with w.indent():
                        for line in textwrap.wrap(
                                body.get('description',
                                         'No description.').strip(), 64):
                            w(u'| {}', line)

                        responses = body['responses']
                        errors = ','.join(
                            sorted(str(e) for e in responses if e >= 400))

                        if 200 in responses:
                            r200 = responses[200]
                            if 'schema' in r200:
                                ok = r200['schema']
                                if ok.get('type') == 'array':
                                    items = ok['items']
                                    if '$ref' in items:
                                        itemtype = items['$ref'][
                                            len('#/definitions/'):]
                                        ret = ': <: set of ' + itemtype
                                    else:
                                        ret = ': <: ...'
                                elif ok.has_key('$ref'):
                                    ret = ': <: ' + ok['$ref'][
                                        len('#/definitions/'):]
                                else:
                                    ret = ' (' + r200.get('description') + ')'
                            else:
                                ret = ' (' + r200.get('description') + ')'
                            w(u'return 200{} or {{{}}}', ret, errors)
                        elif 201 in responses:
                            r201 = responses[201]
                            if 'headers' in r201:
                                ok = r201['headers']
                                w(u'return 201 ({}) or {{{}}}',
                                  ok['Location']['description'], errors)
                            else:
                                w(u'return 201 ({})', r201['description'])

                    if i < len(api) - 1:
                        w()

        w()
        w('#' + '-' * 75)
        w('# definitions')

        for (tname, tspec) in sorted(swag['definitions'].iteritems()):
            w()
            w('!type {}:', tname)

            with w.indent():

                tspec_items = tspec.get('properties')

                if tspec_items:
                    for (fname, fspec) in sorted(tspec_items.iteritems()):

                        (ftype, fdescr) = parse_typespec(fspec)
                        w(
                            '{} <: {}{}', fname,
                            ftype if ftype.startswith('set of ')
                            or ftype.endswith('*') else ftype + '?',
                            ' "' + fdescr + '"' if fdescr else '')
                # handle top-level arrays
                elif tspec.has_key('type') and tspec['type'] == 'array':

                    (ftype, fdescr) = parse_typespec(tspec)
                    w(
                        '{} <: {}{}', fname,
                        ftype if ftype.startswith('set of ')
                        or ftype.endswith('*') else ftype + '?',
                        ' "' + fdescr + '"' if fdescr else '')
                else:
                    assert True, tspec

    open(outfile, 'w').write(str(w))
Exemplo n.º 13
0
def controller(interfaces, context):
    (app, module, package, model_class, write_file, _, _) = context

    w = writer.Writer('java')

    java.Package(w, package)

    java.Import(w, 'io.swagger.annotations.Api')
    java.Import(w, 'io.swagger.annotations.ApiOperation')
    java.Import(w, 'io.swagger.annotations.ApiParam')
    java.Import(w, 'io.swagger.annotations.ApiResponse')
    java.Import(w, 'io.swagger.annotations.ApiResponses')
    java.Import(w, 'lombok.extern.slf4j.Slf4j')
    java.Import(w, 'org.springframework.beans.factory.annotation.Autowired')
    java.Import(w, 'org.springframework.web.bind.annotation.PathVariable')
    java.Import(w, 'org.springframework.web.bind.annotation.RequestHeader')
    java.Import(w, 'org.springframework.web.bind.annotation.RequestMapping')
    java.Import(w, 'org.springframework.web.bind.annotation.RequestMethod')
    java.Import(w, 'org.springframework.web.bind.annotation.RequestParam')
    java.Import(w, 'org.springframework.web.bind.annotation.ResponseBody')
    java.Import(w, 'org.springframework.web.bind.annotation.RestController')
    w()

    w('@Api(value = {}, description = {}, position = {})',
      json.dumps(app.long_name),
      json.dumps(syslx.View(app.attrs)['description'].s), 1)
    w('@Slf4j')
    w('@RestController')
    w('@ResponseBody')
    w('@RequestMapping(value = {}, produces = {})', json.dumps('/'),
      json.dumps('application/json;version=1.0;charset=UTF-8;'))

    with java.Class(w,
                    model_class + 'Controller',
                    write_file,
                    visibility='public',
                    package=package):
        for (i, interface) in enumerate(
                sorted({
                    endpt.attrs['interface'].s
                    for endpt in app.endpoints.itervalues()
                })):
            assert interface, '\n' + '\n'.join(
                sorted([
                    endpt.name.split()[1] + ' ' + endpt.name.split()[0]
                    for endpt in app.endpoints.itervalues()
                    for i in [endpt.attrs['interface'].s] if not i
                ]))

            w('\n@Autowired'[not i:])
            w('private {} {};', interface, java.mixedCase(interface))

        scope = scopes.Scope(module)

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

            rp = endpt.rest_params
            rest_method = rp.Method.Name(rp.method)
            method_name = (rest_method +
                           rex.sub(r'{(\w+)}', lambda m: m.group(1).upper(),
                                   rex.sub(r'[-/]', '_', rp.path)))

            def responses(stmts, result=None, cond=''):
                if result is None:
                    result = collections.defaultdict(list)

                for stmt in stmts:
                    which_stmt = stmt.WhichOneof('stmt')
                    if which_stmt == 'cond':
                        responses(stmt.cond.stmt, result,
                                  (cond and cond + ' & ') + stmt.cond.test)
                    elif which_stmt == 'ret':
                        m = rex.match(
                            ur'''
              (?:
                (?:
                  (\d+)·
                  (\([^\)]+\))?·
                  (\w+)?·
                  (?:
                    <:·
                    (empty\s+)?
                    (set\s+of\s+)?
                    ([\w.]+|\.\.\.)
                  )?
                )
                |
                (?:
                  one\s+of·{((?:\d+·,·)*\d+·)}
                )
              )?
              $
              ''', stmt.ret.payload)
                        if m:
                            [
                                status, descr, expr, empty, setof, type_,
                                statuses
                            ] = m.groups()
                            for status in rex.split(ur'·,·', status
                                                    or statuses):
                                status = int(status)
                                result[int(status)].append(
                                    cond or descr
                                    or STATUS_MAP.get(int(status)) or '???')
                        else:
                            print ` stmt.ret.payload `
                            import pdb
                            pdb.set_trace()

                return result

            w()
            w('@RequestMapping(method = RequestMethod.{}, \vpath = {})',
              rest_method, json.dumps(rp.path))
            w('@ApiOperation(value = {})', json.dumps(endpt.docstring))
            w('@ApiResponses({{')
            with w.indent():
                for (status,
                     conds) in sorted(responses(endpt.stmt).iteritems()):
                    w('@ApiResponse(code = {}, message =', status)
                    with w.indent():
                        for (i, cond) in enumerate(conds):
                            w('"<p style=\\"white-space:nowrap\\">{}</p>"{}',
                              cond, ' +' if i < len(conds) - 1 else '')
                    w('),')
            w('}})')

            params = codeForParams(rp.query_param, scope)
            with java.Method(w, 'public', 'Object', method_name, params):
                w('return {}.{}({});',
                  java.mixedCase(endpt.attrs['interface'].s), method_name,
                  ', '.join('\v' + p for (_, p) in params))