def get_colid(col):
    coltgv = TaggedValues(col)
    colid = coltgv.direct('id','sql:column',None) or \
        coltgv.direct('id','sql:primary',None)    
    if not colid:
        colid = col.name
    return colid
def calculate_joins(source, targetclass, otherclass, otherendname, nullable=False, force_fullname=False):
    joins = []
    pks = get_pks(otherclass)
    my_pks=get_pks(source)
    
    if not pks:
        raise ValueError,'class %s has no primary key defined' % dotted_path(otherclass)
    try:
        lastattr = targetclass.attributes()[-1]
    except IndexError:
        lastattr = None

    for pk in pks:
        pkname = get_colid(pk)
        #import pdb;pdb.set_trace()
        fkname = get_fkname(source, pkname, otherendname, force_fullname=force_fullname)
        # this stmt will be attached to otherend in order to be used
        # for the join in the relationship stmt
        joinstmt = '%s.%s == %s.%s' % (
            source.name, fkname, otherclass.name, pkname)
        if not targetclass.attributes(fkname):
            attr = Attribute()
            attr.__name__ = str(attr.uuid)
            if lastattr:
                targetclass.insertafter(attr, lastattr)
            else:
                targetclass.insertfirst(attr)

            attr.targets = [fkname]
            fk = "ForeignKey('%s.%s')" % (
                get_tablename(otherclass), pkname)
            options = {}
            typename = pk.type.name
            # handle custom types (PrimitveType)
            if pk.type.stereotype('sql:sql_type'):
                tgv = TaggedValues(pk.type)
                typename = tgv.direct(
                    'classname', 'sql:sql_type', typename)
                import_from = tgv.direct(
                    'import_from', 'sql:sql_type', None)
                if import_from:
                    imps = Imports(module)
                    imps.set(import_from, [[typename, None]])
                    
            if nullable:
                options['nullable'] = 'True'
            else:
                options['nullable'] = 'False'

            if not my_pks:
                options['primary_key'] = 'True'
                
            oparray = []
            for k in options:
                oparray.append('%s = %s' % (k, options[k]))
            attr.value = 'Column(%s, %s, %s)' % (
                typename, fk, ', '.join(oparray))

        joins.append(joinstmt)
        return joins
def generate_static_view(self, source, target):
    directory = read_target_node(source, target.target)
    tok = token('pyramid_configuration', True, static_views=[])
    tgv = TaggedValues(source)
    
    path = source.name
    url = tgv.direct('url', 'pyramid:static_view', source.name)
    tok.static_views.append([url, path, ''])
    
    # if from_template is given, copy the files from the given 
    # resource template into the target
    from_template = tgv.direct('from_template', 'pyramid:static_view', None)  
    if from_template:
        basepath = os.path.dirname(agx.generator.pyramid.__file__)
        srcpath = os.path.join(basepath, 'resources', 'static_templates', from_template)
        tgtpath = os.path.join(*directory.fs_path)
        if not os.path.exists(tgtpath):
            os.makedirs(tgtpath)
            
        # copy over the files
        flist = os.listdir(srcpath)
        for f in flist:
            srcfile = os.path.join(srcpath, f)
            tgtfile = os.path.join(tgtpath, f)
            if not os.path.exists(tgtfile):
                if os.path.isdir(srcfile):
                    shutil.copytree(srcfile, tgtfile)
                else:
                    shutil.copy(srcfile, tgtfile)
def sql_config(self, source, target):
    """writes the sql config.
    """
    nsmap = {
        None: 'http://namespaces.zope.org/zope',
        'saconfig':'http://namespaces.zope.org/db',
    }
    tg = read_target_node(source, target.target)
    conf = zcautils.get_zcml(tg, 'configure.zcml', nsmap=nsmap)
    tgv = TaggedValues(source)

    engine_name = tgv.direct('engine_name', 'sql:z3c_saconfig', 'default')
    engine_url = tgv.direct(
        'engine_url', 'sql:z3c_saconfig', 'sqlite:///test.db')
    session_name = tgv.direct('session_name', 'sql:z3c_saconfig', 'default')

    zcautils.set_zcml_directive(
        tg, 'configure.zcml', 'include', 'package',
        'z3c.saconfig', file='meta.zcml')
    zcautils.set_zcml_directive(
        tg, 'configure.zcml', 'saconfig:engine', 'name',
        engine_name, url=engine_url)
    zcautils.set_zcml_directive(
        tg, 'configure.zcml', 'saconfig:session', 'name',
        session_name, engine=engine_name)
def interfacegeneralization(self, source, target):
    """Create generalization between interfaces .
    """
    inheritance = Inheritance(source)
    targetclass = read_target_node(source, target.target)
    if targetclass:
        tok = token(str(targetclass.uuid), True, depends_on=set())
    for obj in inheritance.values():
        tok.depends_on.add(read_target_node(obj.context, target.target))
        if not obj.context.name in targetclass.bases:
            targetclass.bases.append(obj.context.name)
            tgv = TaggedValues(obj.context)
            import_from = tgv.direct('import', 'pyegg:stub')
            if import_from is not UNSET:
                imp = Imports(targetclass.__parent__)
                imp.set(import_from, [[obj.context.name, None]])
        derive_from = read_target_node(obj.context, target.target)
        if not derive_from:
            continue
        if targetclass.__parent__ is not derive_from.__parent__:
            imp = Imports(targetclass.__parent__)
            imp.set(class_base_name(derive_from),
                    [[derive_from.classname, None]])
    if targetclass and not targetclass.bases:
        targetclass.bases.append('Interface')
def sqlcontentclass_engine_created_handler(self, source, target):
    """create and register the handler for the IEngineCreatedEvent.
    """
    if source.stereotype('pyegg:stub'):
        return

    targetpack=read_target_node(source,target.target)
    targetpack['saconfig.py']=Module()
    module = targetpack['saconfig.py']
    imps = Imports(module)

    # check if one of the parent packages has the z3c_saconfig stereotype
    z3c_saconfig=get_z3c_saconfig(source)
        
    # add engine-created handler
    if z3c_saconfig:
        eggtgv=TaggedValues(z3c_saconfig)
        engine_name = eggtgv.direct(
                'engine_name', 'sql:z3c_saconfig', 'default')
        
        globalfuncs = [f for f in module.filtereditems(IFunction)]
        globalfuncnames = [f.functionname for f in globalfuncs]
        if 'engineCreatedHandler' not in globalfuncnames:
            imps.set('z3c.saconfig.interfaces',
                     [['IEngineCreatedEvent', None]])
            imps.set('zope', [['component', None]])
            imps.set('z3c.saconfig.interfaces',[['IEngineFactory',None]])
            imps.set('sqlalchemy.ext.declarative','declarative_base')
            #att = [att for att in module.filtereditems(IAttribute) \
            #       if att.targets == ['Base']][0]
            bases=module.attributes('Base')
            if not bases:
                base=Attribute('Base','declarative_base()')
                module.insertafterimports(base)
            else:
                base=bases[0]
                   
            ff = Function('engineCreatedHandler')
            # 'engineCreatedHandler'
            ff.__name__ = ff.uuid 
            ff.args = ('event',)
            dec = Decorator('component.adapter')
            dec.__name__ = dec.uuid
            dec.args = ('IEngineCreatedEvent',)
            ff.insertfirst(dec)
            block_lines = [
                "fact = component.queryUtility(IEngineFactory, '%s')" \
                    % engine_name,
                "if fact and fact._args == event.engine_args:",
                "    Base.metadata.create_all(event.engine)",
            ]
            block = Block('\n'.join(block_lines))
            block.__name__ = block.uuid
            ff.insertlast(block)
            module.insertafter(ff, base)

            prov = Block('component.provideHandler(engineCreatedHandler)')
            prov.__name__ = prov.uuid
            module.insertafter(prov, ff)
def make_generators(self, source, target):
    if source.stereotype('pyegg:stub'):
        return
    egg = egg_source(source)
    eggtarget = read_target_node(egg, target.target)
    zcml = get_zcml(eggtarget, 'configure.zcml',
                    nsmap={None: 'http://namespaces.zope.org/zope', 
                           'agx': 'http://namespaces.zope.org/agx'})
    tgv = TaggedValues(source)

    # if transform isnt specified as tgv, get it from dependency relations to
    # other generators
    transform = tgv.direct('transform', 'generator:generator', None)
    if not transform:
        transforms = token(str(source.uuid), True, transforms=[]).transforms
        if len(transforms) > 1:
            msg = 'Currently only one transform per generator allowed (%s)'
            msg = msg % source.name
            raise ValueError(msg)
        elif len(transforms) == 1:
            transform = transforms[0].name

    if not transform:
        transform = 'uml2fs'

    # if depends isnt specified as tgv, get it from dependency relations to
    # transforms
    depend = tgv.direct('depends', 'generator:generator', None)
    if not depend:
        depends = token(str(source.uuid), True, depends_on=[]).depends_on
        if len(depends) > 1:
            msg = 'Currently only one depends per generator allowed (%s)'
            msg = msg % source.name
            raise ValueError(msg)
        elif len(depends) == 1:
            depend = depends[0].name

    if not depend:
        depend = 'NO'

    directives = zcml.filter(tag='agx:generator', attr='name')

    directive = None
    for d in directives:
        if d.attrs['name'] == source.name:
            directive = d
            break

    if not directive:
        directive = SimpleDirective(name='agx:generator', parent=zcml)

    directive.attrs['name'] = source.name
    directive.attrs['transform'] = transform
    directive.attrs['depends'] = depend

    set_zcml_directive(eggtarget, 'configure.zcml', 'agx:generator',
                       'name', source.name, overwrite=True)
def inheritancetokenizer(self, source, target):
    """Write inheritanceorder to token.
    """
    tgv = TaggedValues(source)
    order = tgv.direct('order', 'pyegg:derive', -1)
    if order == -1:
        return
    tok = token(source.specific.path, True, order=dict())
    tok.order[source.general.name] = order
def zcaadapts(self, source, target):
    adapter = source
    if adapter.stereotype('pyegg:function'):
        # XXX: <<function>> <<adapter>> on class
        return
    targetadapter = read_target_node(adapter, target.target)
    tok = token(str(adapter.uuid), True)
    pack = source.parent
    target = read_target_node(pack, target.target)
    targetclass = read_target_node(adapter, target)
    if isinstance(target, python.Module):
        targetdir = target.parent
    else:
        targetdir = target
    path = targetdir.path
    path.append('adapters.zcml')
    fullpath = os.path.join(*path)
    if 'adapters.zcml' not in targetdir.keys():
        zcml = ZCMLFile(fullpath)
        targetdir['adapters.zcml'] = zcml
    else:
        zcml = targetdir['adapters.zcml']
    addZcmlRef(targetdir, zcml)
    targettok = token(str(targetclass.uuid), True, realizes=[], provides=None)
    if not hasattr(tok, 'adapts'):
        msg = 'adapter class %s has no <<adapts>> dependency' \
            % dotted_path(adapter)
        raise ValueError(msg)
    _for = [token(str(adaptee.uuid), False).fullpath for adaptee in tok.adapts]
    factory = class_full_name(targetadapter)
    tgv = TaggedValues(adapter)
    name = tgv.direct('name', 'zca:adapter')
    found_adapts = zcml.filter(tag='adapter', attr='factory', value=factory)
    if found_adapts:
        adapts = found_adapts[0]
    else:     
        adapts = SimpleDirective(name='adapter', parent=zcml)
    adapts.attrs['for'] = _for
    if not name is UNSET:
        adapts.attrs['name'] = name
    adapts.attrs['factory'] = factory
    # write the provides which is collected in the zcarealize handler
    if len(targettok.realizes) == 1:
        provides = targettok.realizes[0]
    else:
        provides = targettok.provides
    if not provides:
        msg = 'adapter class %s has no interface realization' \
            % dotted_path(adapter)
        raise ValueError(msg)
    adapts.attrs['provides'] = provides['path']

    if hasattr(tok, 'permission'):
        adapts.attrs['permission'] = tok.permission
 def set_args_kwargs_code(source, function):
     tgv = TaggedValues(source)
     _args = tgv.direct('args', 'pyegg:function')
     _kwargs = tgv.direct('kwargs', 'pyegg:function')
     _code = tgv.direct('code', 'pyegg:function')
     if _args is not UNSET:
         function.s_args = _args
     if _kwargs is not UNSET:
         function.s_kwargs = _kwargs
     if _code is not UNSET:
         if not function.blocks():
             function.insertlast(Block(_code))
Beispiel #11
0
def finalize_handler(self, source, target):
    func = read_target_node(source, target.target)
    tok = token(str(source.uuid), True, scopes=[], generators=[])
    tgv = TaggedValues(source)
    order = tgv.direct('order', 'generator:handler', None)
    func.args = ['self', 'source', 'target']

    # ...or by dependency on a generator
    if tok.generators:
        generatornames = [g.name for g in tok.generators]
    else:
        # the generator can be defined by tgv
        generatornames = [tgv.direct('generator', 'generator:handler', None)]

    for scope in tok.scopes:
        stgv = TaggedValues(scope)

        scopename = stgv.direct('scopename', 'generator:class_scope', None) or \
           stgv.direct('scopename', 'generator:simple_scope', None) or \
           scope.name.lower()

        transform = stgv.direct('transform', 'generator:class_scope', None) or \
           stgv.direct('transform', 'generator:class_scope', None) or \
           'uml2fs'

        transformarg = "'%s'" % transform
        scopenamearg = "'%s'" % scopename
        decfound = None

        for generatorname in generatornames:
            generatornamearg = "'%s'" % generatorname
            # find the dec
            for dec in func.decorators():
                if dec.args[1] == transformarg \
                  and dec.args[2] == generatornamearg \
                  and dec.args[3] == scopenamearg:
                    decfound = dec
            if decfound:
                dec = decfound
            # if not found make it
            else:
                dec = Decorator()
                dec.decoratorname = 'handler'
                dec.__name__ = dec.uuid
                func.insertfirst(dec)
            # define the args for the generator
            dec.args = [
                "'%s'" % source.name, transformarg, generatornamearg,
                scopenamearg
            ]
            if not order is None:
                dec.kwargs['order'] = order
def console_scripts_collect(self, source, target):
    # collect information to define console_script entry points
    tok = token('console_scripts', True, defs={})
    tgv = TaggedValues(source)
    name = tgv.direct('script_name', 'pyegg:console_script', source.name)
    tgt = read_target_node(source, target.target)
    
    if source.stereotype('pyegg:function') and not source.parent.stereotype('pyegg:pymodule'):
        path = class_base_name(tgt.parent)
    else:
        path = class_base_name(tgt)
        
    tok.defs[name] = '%s:%s' % (path, source.name)
def pyfunctionfromclass(self, source, target):
    """Convert Class to function if class has stereotype function set.
    """
    if not is_class_a_function(source):
        return

    class_ = read_target_node(source, target.target)
    dec_keys = [dec.name for dec in class_.decorators()]
    decorators = [class_.detach(key) for key in dec_keys]
    module = class_.parent
    container = module
    if not source.parent.stereotype('pyegg:pymodule'):
        container = module.parent['__init__.py']
    functions = container.functions(class_.classname)
    if functions:
        if len(functions) > 1:
            raise "expected exactly one function by name '%s'" \
                % class_.classname
        function = functions[0]
    else:
        function = python.Function(class_.classname)
        function.__name__ = function.uuid
        container.insertlast(function)
    del module[str(class_.uuid)]

    # resync target to function, class was deleted
    writesourcepath(source, function)
    write_source_to_target_mapping(source, function)

    tgv = TaggedValues(source)
    _args = tgv.direct('args', 'pyegg:function')
    _kwargs = tgv.direct('kwargs', 'pyegg:function')
    _code = tgv.direct('code', 'pyegg:function')
    if _args is not UNSET:
        function.s_args = _args
    if _kwargs is not UNSET:
        function.s_kwargs = _kwargs
    if _code is not UNSET:
        if not function.blocks():
            function.insertlast(Block(_code))

    other_decorators = function.decorators()
    for dec in decorators:
        exists = 0
        for other in other_decorators:
            if dec.equals(other):
                exists = 1
        if exists:
            continue
        function[str(dec.uuid)] = dec
def generatescopeclass(self, source, target):
    """Generates scope classes.
    """
    if source.stereotype('pyegg:stub'):
        return
    
    targetclass = read_target_node(source, target.target)
    
    module = targetclass.parent

    methods = [m for m in targetclass.functions()]
    methnames = [m.functionname for m in methods]
    methname = '__call__'
    tgv = TaggedValues(source)
    stereotypes = tgv.direct('stereotypes', 'generator:class_scope', None) or \
        tgv.direct('stereotypes', 'generator:simple_scope', None) or []
    transform = tgv.direct('transform', 'generator:class_scope', None) or \
        tgv.direct('transform', 'generator:simple_scope', None) or \
        'uml2fs'

    if stereotypes:
        for st in stereotypes:
            if ':' not in st:
                msg = 'you have to specify the stereotype in the form ' + \
                      '"namespace:stereotype", but forgot the namespace ' + \
                      '(scope %s, stereotype %s)' % (source.name, st)
                raise ValueError(msg)

    #if not stereotypes:
    #    msg = 'scope %s must have a stereotype attribute!!' % source.name
    #    raise ValueError(msg)

    if 'Scope' not in targetclass.bases:
        targetclass.bases.append('Scope')

    if methname not in methnames:
        f = Function()
        f.functionname = methname
        f.args = ['self', 'node']
        f.__name__ = str(f.uuid)
        targetclass.insertfirst(f)

        bl = Block()
        bl.__name__ = str(bl.uuid)
        conds = ["node.stereotype('%s') is not None" % st for st in stereotypes]
        cond = ' or '.join(conds)
        bl.lines.append("return %s" % cond)

        f.insertfirst(bl)
def zcarealize(self, source, target):
    klass = source.implementingClassifier
#    if klass.stereotype('pyegg:function'):
#        # XXX: <<function>> <<adapter>> on class
#        return

    ifacename = source.contract.name
    targetclass = read_target_node(klass, target.target)
    targetinterface = read_target_node(source.contract, target.target)
    tok = token(str(targetclass.uuid), True, realizes=[], provides=None)

    ifdef = {'name':source.contract.name}
    if targetinterface:
        ifdef['path'] = dotted_path(source.contract)
    # then its a stub
    else:
        tgv = TaggedValues(source.contract)
        impf = tgv.direct('import', 'pyegg:stub')
        if not impf:
            msg = 'Stub class %s needs a TaggedValue for "import"' \
                % dotted_path(klass)
            raise ValueError(msg)
        ifdef['path'] = '.'.join([impf, ifdef['name']])

    tok.realizes.append(ifdef)
    if source.stereotype('zca:provides'):
        tok.provides = ifdef

    # import the interface
    tgv = TaggedValues(source.contract)
    import_from = tgv.direct('import', 'pyegg:stub')
    imp = Imports(targetclass.__parent__)

    if targetinterface:    
        tok = token(str(targetclass.uuid), True, depends_on=set())
        tok.depends_on.add(targetinterface)

    # if (targetinterface is None -> Stub) or targetinterface is in another
    # module -> import
    if not targetinterface \
      or targetclass.__parent__ is not targetinterface.__parent__:
        # we have a stub interface
        if import_from is not UNSET:
            basepath = import_from
            imp.set(basepath, [[source.contract.name, None]])
        else:
            basepath = class_base_name(targetinterface)
            imp.set(basepath, [[targetinterface.classname, None]])
Beispiel #16
0
def gsdynamicview(self, source, target):
    """Add view method to FTI's of all dependent content types.
    """
    if not source.supplier.stereotype('plone:content_type') \
      or not source.client.stereotype('plone:dynamic_view'):
        return

    view = source.client
    content_type = source.supplier
    package = read_target_node(egg_source(content_type), target.target)
    default = package['profiles']['default']
    full_name = type_id(content_type, target.target)
    name = '%s.xml' % full_name
    type_xml = default['types'][name]
    tgv = TaggedValues(view)
    viewname = tgv.direct('name', 'plone:dynamic_view', view.name)
    type_xml.params['ctype']['view_methods'].append(viewname)
Beispiel #17
0
def generate_vanilla_profile(self, source, target):
    egg = egg_source(source)
    if not is_generator_egg(egg):
        return

    tgv = TaggedValues(source)
    profilename = tgv.direct('name', 'generator:profile', source.name)

    basepath = os.path.dirname(agx.generator.generator.__file__)
    profilepath = os.path.join(basepath, 'resources', 'vanilla_profile')

    # read the model files
    model_di = open(os.path.join(profilepath, 'model.profile.di')).read()
    model_uml = open(os.path.join(profilepath, 'model.profile.uml')).read()
    model_notation = open(os.path.join(profilepath,
                                       'model.profile.notation')).read()

    eggdir = read_target_node(egg_source(source), target.target)

    # create profiles dir
    if 'profiles' not in eggdir.keys():
        profiles = Directory()
        profiles.__name__ = 'profiles'
        eggdir['profiles'] = profiles

    profiles = eggdir['profiles']

    # add the model files with correct name and change the references
    if profilename + '.profile.di' not in profiles.keys():
        ff = File()
        ff._data = model_di.replace('model.profile.notation',
                                    profilename + '.profile.notation')
        profiles[profilename + '.profile.di'] = ff

    if profilename + '.profile.uml' not in profiles.keys():
        ff = File()
        ff._data = model_uml.replace('profilename_changeme', profilename)
        profiles[profilename + '.profile.uml'] = ff

    if profilename + '.profile.notation' not in profiles.keys():
        ff = File()
        ff._data = model_notation.replace('model.profile.uml',
                                          profilename + '.profile.uml')
        profiles[profilename + '.profile.notation'] = ff
Beispiel #18
0
def generate_profile_location(self, source, target):
    targetclass = read_target_node(source, target.target)
    module = targetclass.parent

    ifspec = {
        'path': 'agx.core.interfaces.IProfileLocation',
        'name': 'IProfileLocation',
    }
    tok = token(str(targetclass.uuid), False, realizes=[])
    if ifspec not in tok.realizes:
        tok.realizes.append(ifspec)

    tgv = TaggedValues(source)
    name = tgv.direct('profile_name', 'generator:profile', None)
    if not name:
        name = source.name
        #msg = 'profile_name tagged value not defined for %s!' % source.name
        #raise ValueError(msg)

    imps = Imports(module)
    frompath = '.'.join(ifspec['path'].split('.')[:-1])
    imps.set(frompath, [[ifspec['name'], None]])

    attributenames = [att.targets[0] for att in targetclass.attributes()]
    if 'name' not in attributenames:
        att = Attribute()
        att.__name__ = att.uuid
        targetclass[att.name] = att
        att.targets = ['name']
        att.value = "'%s.profile.uml'" % name

    if 'package' not in attributenames:
        att = Attribute()
        att.__name__ = att.uuid
        targetclass[att.name] = att
        att.targets = ['package']
        att.value = dotted_path(source.parent)
        imps.set('', [[att.value, None]])
        # remove the import from this class
        init = targetclass.parent.parent['__init__.py']
        fromimp = '.'.join(implicit_dotted_path(source).split('.')[:-1])
        imps = [imp for imp in init.imports() if imp.fromimport == fromimp]
        for imp in imps:
            init.detach(str(imp.uuid))
def generate_profile_location(self, source, target):
    targetclass = read_target_node(source, target.target)
    module = targetclass.parent

    ifspec = {
        'path': 'agx.core.interfaces.IProfileLocation',
        'name': 'IProfileLocation',
    }
    tok = token(str(targetclass.uuid), False, realizes=[])
    if ifspec not in tok.realizes:
        tok.realizes.append(ifspec)

    tgv = TaggedValues(source)
    name = tgv.direct('profile_name', 'generator:profile', None)
    if not name:
        name=source.name
        #msg = 'profile_name tagged value not defined for %s!' % source.name
        #raise ValueError(msg)

    imps = Imports(module)
    frompath = '.'.join(ifspec['path'].split('.')[:-1])
    imps.set(frompath, [[ifspec['name'], None]])

    attributenames = [att.targets[0] for att in targetclass.attributes()]
    if 'name' not in attributenames:
        att = Attribute()
        att.__name__ = att.uuid
        targetclass[att.name] = att
        att.targets = ['name']
        att.value = "'%s.profile.uml'" % name

    if 'package' not in attributenames:
        att = Attribute()
        att.__name__ = att.uuid
        targetclass[att.name] = att
        att.targets = ['package']
        att.value = dotted_path(source.parent)
        imps.set('', [[att.value, None]])
        # remove the import from this class
        init = targetclass.parent.parent['__init__.py']
        fromimp = '.'.join(implicit_dotted_path(source).split('.')[:-1])
        imps = [imp for imp in init.imports() if imp.fromimport == fromimp]
        for imp in imps:
            init.detach(str(imp.uuid))
def generate_vanilla_profile(self, source, target):
    egg = egg_source(source)
    if not is_generator_egg(egg):
        return

    tgv = TaggedValues(source)
    profilename = tgv.direct('name', 'generator:profile', source.name)

    basepath = os.path.dirname(agx.generator.generator.__file__)
    profilepath = os.path.join(basepath, 'resources', 'vanilla_profile')

    # read the model files
    model_di = open(os.path.join(profilepath, 'model.profile.di')).read()
    model_uml = open(os.path.join(profilepath, 'model.profile.uml')).read()
    model_notation = open(
        os.path.join(profilepath, 'model.profile.notation')).read()

    eggdir = read_target_node(egg_source(source), target.target)

    # create profiles dir
    if 'profiles' not in eggdir.keys():
        profiles = Directory()
        profiles.__name__ = 'profiles'
        eggdir['profiles'] = profiles

    profiles = eggdir['profiles']

    # add the model files with correct name and change the references
    if profilename + '.profile.di' not in profiles.keys():
        ff = File()
        ff._data = model_di.replace(
            'model.profile.notation', profilename + '.profile.notation')
        profiles[profilename + '.profile.di'] = ff

    if profilename + '.profile.uml' not in profiles.keys():
        ff = File()
        ff._data = model_uml.replace('profilename_changeme', profilename)
        profiles[profilename + '.profile.uml'] = ff
    
    if profilename + '.profile.notation' not in profiles.keys():
        ff = File()
        ff._data = model_notation.replace(
            'model.profile.uml', profilename + '.profile.uml')
        profiles[profilename + '.profile.notation'] = ff
def pydecorator(self, source, target):
    """Create Decorator.
    """
    tgv = TaggedValues(source)
    name = tgv.direct('name', 'pyegg:decorator', None)
    if not name:
        raise ValueError, 'decorator for %s must have a TaggedValue "name"' % \
            dotted_path(source)
    args = tgv.direct('args', 'pyegg:decorator', None)
    kwargs = tgv.direct('kwargs', 'pyegg:decorator', None)
    container = read_target_node(source, target.target)
    if container.decorators(name):
        decorator = container.decorators(name)[0]
    else:
        decorator = python.Decorator(name)
        container[str(decorator.uuid)] = decorator
    if args is not None:
        decorator.s_args = args
    if kwargs is not None:
        decorator.s_kwargs = kwargs
def pyattribute(self, source, target):
    """Create Attribute.
    """
    if source.parent.stereotype('pyegg:stub'):
        return
    expression = None
    tgv = TaggedValues(source)
    expression = tgv.direct('expression', 'pyegg:expression', None)
    name = source.name
    container = target.anchor
    if container.attributes(name):
        attribute = container.attributes(name)[0]
        if expression is not None:
            attribute.value = expression
        target.finalize(source, attribute)
        return
    value = expression is not None and expression or 'None' 
    attribute = python.Attribute([name], value=value)
    container[str(attribute.uuid)] = attribute
    target.finalize(source, attribute)
def transform_attribute(source, target, group, fetch_tgv):
    field_def = lookup_field_def(source, group)
    attribute = read_target_node(source, target.target)
    if not attribute:  # attribute has been removed
        return
    attribute.value = field_def['factory']
    tgv = TaggedValues(source)
    fetch_tgv(tgv, attribute, field_def['stereotype'])
    imp = Imports(attribute.parent.parent)
    imp.set(field_def['import_from'], [[field_def['import'], None]])
    if field_def['depends']:
        pass  # XXX write to setup.py setup_dependencies
def finalize_handler(self, source, target):
    func = read_target_node(source, target.target)
    tok = token(str(source.uuid), True, scopes=[], generators=[])
    tgv = TaggedValues(source)
    order = tgv.direct('order', 'generator:handler', None)
    func.args = ['self', 'source', 'target']

    # ...or by dependency on a generator
    if tok.generators:
        generatornames = [g.name for g in tok.generators]
    else:
        # the generator can be defined by tgv
        generatornames = [tgv.direct('generator', 'generator:handler', None)]

    for scope in tok.scopes:
        stgv = TaggedValues(scope)

        scopename = stgv.direct('scopename', 'generator:class_scope', None) or \
           stgv.direct('scopename', 'generator:simple_scope', None) or \
           scope.name.lower()

        transform = stgv.direct('transform', 'generator:class_scope', None) or \
           stgv.direct('transform', 'generator:class_scope', None) or \
           'uml2fs'

        transformarg = "'%s'" % transform
        scopenamearg = "'%s'" % scopename
        decfound = None

        for generatorname in generatornames:
            generatornamearg = "'%s'" % generatorname
            # find the dec
            for dec in func.decorators():
                if dec.args[1] == transformarg \
                  and dec.args[2] == generatornamearg \
                  and dec.args[3] == scopenamearg:
                    decfound = dec
            if decfound:
                dec = decfound
            # if not found make it
            else:
                dec = Decorator()
                dec.decoratorname = 'handler'
                dec.__name__ = dec.uuid
                func.insertfirst(dec)
            # define the args for the generator
            dec.args = ["'%s'" % source.name, transformarg,
                        generatornamearg, scopenamearg]
            if not order is None:
                dec.kwargs['order'] = order
def sql_sample(self, source, target):
    if not source.stereotype('sql:z3c_saconfig'):
        return
    root=target.anchor
    tgv = TaggedValues(source)
    engine_name = tgv.direct('engine_name', 'sql:z3c_saconfig', 'default')
    engine_url = tgv.direct(
        'engine_url', 'sql:z3c_saconfig', 'sqlite:///test.db')
    session_name = tgv.direct('session_name', 'sql:z3c_saconfig', 'default')

    # write the readme
    fname = 'sample-sqlalchemy.py'
    if fname not in root.keys():
        readme = JinjaTemplate()
        readme.template = templatepath(fname + '.jinja')
        readme.params = {
            'engine_name': engine_name,
            'engine_url': engine_url,
            'session_name': session_name,
            'packagename': dotted_path(source),
        }
        root[fname] = readme
Beispiel #26
0
def generatescopeclass(self, source, target):
    """Generates scope classes.
    """
    if source.stereotype('pyegg:stub'):
        return

    targetclass = read_target_node(source, target.target)

    module = targetclass.parent

    methods = [m for m in targetclass.functions()]
    methnames = [m.functionname for m in methods]
    methname = '__call__'
    tgv = TaggedValues(source)
    stereotypes = tgv.direct('stereotypes', 'generator:class_scope', None) or \
        tgv.direct('stereotypes', 'generator:simple_scope', None) or []
    transform = tgv.direct('transform', 'generator:class_scope', None) or \
        tgv.direct('transform', 'generator:simple_scope', None) or \
        'uml2fs'

    if stereotypes:
        for st in stereotypes:
            if ':' not in st:
                msg = 'you have to specify the stereotype in the form ' + \
                      '"namespace:stereotype", but forgot the namespace ' + \
                      '(scope %s, stereotype %s)' % (source.name, st)
                raise ValueError(msg)

    #if not stereotypes:
    #    msg = 'scope %s must have a stereotype attribute!!' % source.name
    #    raise ValueError(msg)

    if 'Scope' not in targetclass.bases:
        targetclass.bases.append('Scope')

    if methname not in methnames:
        f = Function()
        f.functionname = methname
        f.args = ['self', 'node']
        f.__name__ = str(f.uuid)
        targetclass.insertfirst(f)

        bl = Block()
        bl.__name__ = str(bl.uuid)
        conds = [
            "node.stereotype('%s') is not None" % st for st in stereotypes
        ]
        cond = ' or '.join(conds)
        bl.lines.append("return %s" % cond)

        f.insertfirst(bl)
Beispiel #27
0
def generate_profile_location_zcml(self, source, target):
    if source.stereotype('pyegg:stub'):
        return

    targetclass = read_target_node(source, target.target)
    module = targetclass.parent
    blocks = module.blocks()
    egg = egg_source(source)
    eggtarget = read_target_node(egg, target.target)

    tgv = TaggedValues(source)
    #name = tgv.direct('name', 'generator:profile', None)

    set_zcml_directive(eggtarget,
                       'configure.zcml',
                       'utility',
                       'name',
                       implicit_dotted_path(source),
                       provides="agx.core.interfaces.IProfileLocation",
                       component=implicit_dotted_path(source))
def createschemaclass(self, source, target):
    """create the schema interface class on the fly.
    """
    klass = read_target_node(source, target.target)
    module = klass.parent
    schemaclassname = 'I' + klass.classname
    found = module.classes(schemaclassname)
    if found:
        schemaclass = found[0]
    else:
        schemaclass = python.Class(classname=schemaclassname)
        schemaclass.__name__ = schemaclass.uuid
        module.insertbefore(schemaclass, klass)
    # expose it in __init__
    imp = Imports(module.parent['__init__.py'])
    imp.set(class_base_name(schemaclass), [[schemaclassname, None]])
    # mark the content class for deletion if not needed
    createit = TaggedValues(source).direct('create_contentclass',
                                           'plone:content_type', False)
    if not (createit or klass.functions()):
        token(str(klass.uuid), True, dont_generate=True)
Beispiel #29
0
def zcviewdepcollect(self, source, target):
    """Collect all view dependencies
    """
    scope = getUtility(IScope, 'uml2fs.viewclass')
    pack = source.parent
    dep = source
    context = source.supplier
    view = source.client
    if not scope(view):  #we are only interested in views!
        return
    target = read_target_node(pack, target.target)
    targetcontext = read_target_node(context, target)
    targetview = read_target_node(view, target)
    tok = token(str(view.uuid), True, browserpages=[])
    contexttok = token(str(context.uuid), True, fullpath=None)

    if targetcontext:
        try:
            dont_generate = token(str(targetcontext.uuid),
                                  False,
                                  dont_generate=False).dont_generate
            if dont_generate:
                iface = targetcontext.parent.classes(
                    'I' + targetcontext.classname)[0]
                contexttok.fullpath = class_full_name(iface)
            else:
                contexttok.fullpath = class_full_name(targetcontext)
        # dont_generate doesnt seem to be defined here
        except ComponentLookupError:
            pass
    # its a stub
    else:
        contexttok.fullpath = '.'.join([
            TaggedValues(context).direct('import', 'pyegg:stub'), context.name
        ])
    if isinstance(target, python.Module):
        targetdir = target.parent
    else:
        targetdir = target
    tok.browserpages.append(dep)
def getservicepath(source):
    tgv = TaggedValues(source)
    name = tgv.direct('name', 'cornice:service', source.name.lower())
    path = tgv.direct('path', 'cornice:service', '/' + name)

    return path
Beispiel #31
0
def make_generators(self, source, target):
    if source.stereotype('pyegg:stub'):
        return
    egg = egg_source(source)
    eggtarget = read_target_node(egg, target.target)
    zcml = get_zcml(eggtarget,
                    'configure.zcml',
                    nsmap={
                        None: 'http://namespaces.zope.org/zope',
                        'agx': 'http://namespaces.zope.org/agx'
                    })
    tgv = TaggedValues(source)

    # if transform isnt specified as tgv, get it from dependency relations to
    # other generators
    transform = tgv.direct('transform', 'generator:generator', None)
    if not transform:
        transforms = token(str(source.uuid), True, transforms=[]).transforms
        if len(transforms) > 1:
            msg = 'Currently only one transform per generator allowed (%s)'
            msg = msg % source.name
            raise ValueError(msg)
        elif len(transforms) == 1:
            transform = transforms[0].name

    if not transform:
        transform = 'uml2fs'

    # if depends isnt specified as tgv, get it from dependency relations to
    # transforms
    depend = tgv.direct('depends', 'generator:generator', None)
    if not depend:
        depends = token(str(source.uuid), True, depends_on=[]).depends_on
        if len(depends) > 1:
            msg = 'Currently only one depends per generator allowed (%s)'
            msg = msg % source.name
            raise ValueError(msg)
        elif len(depends) == 1:
            depend = depends[0].name

    if not depend:
        depend = 'NO'

    directives = zcml.filter(tag='agx:generator', attr='name')

    directive = None
    for d in directives:
        if d.attrs['name'] == source.name:
            directive = d
            break

    if not directive:
        directive = SimpleDirective(name='agx:generator', parent=zcml)

    directive.attrs['name'] = source.name
    directive.attrs['transform'] = transform
    directive.attrs['depends'] = depend

    set_zcml_directive(eggtarget,
                       'configure.zcml',
                       'agx:generator',
                       'name',
                       source.name,
                       overwrite=True)
def generate_view_function(self, source, target):
    tgv = TaggedValues(source)
    func = read_target_node(source, target.target)
    
    if IPythonClass.providedBy(func.parent):
        # We have a method
        module = func.parent.parent
        klass = source.parent
        token(str(klass.uuid), True, has_view_methods=True)
        is_method = True
    else:
        module = func.parent
        is_method = False
    
    imps = Imports(module)
        
    funccode = "return Response('this is the stub for view %s')" % source.name
    
    # name of view
    route_name = tgv.direct('route_name', 'pyramid:view', source.name)
    if route_name == '/':
        route_name = ''
        
    if not func.decorators('view_config'):
        func.insertfirst(Decorator('view_config'))
    
    dec = func.decorators('view_config')[0]
    dec.kwargs['name'] = "'%s'" % route_name
    
    # necessary imports
    imps.set('pyramid.view', 'view_config')
    
    # the request argument
    if not is_method and not 'request' in func.args:
        func.args.append('request')
        
    # create the page template
    template = tgv.direct('template', 'pyramid:view', None)
    # template from which the template file will be generated
    from_template = tgv.direct('from_template', 'pyramid:view', None)
    if from_template and from_template != 'none' and not template:
        template = source.name + '.pt'
        
    print 'template name:', template, from_template
    if template:
        tdir = module.parent
        # set the renderer parameter based on the template name
        dec.kwargs['renderer'] = "'%s'" % template
    
        # create the template in target dir
        template_code = tgv.direct('template_code', 'pyramid:view', None)
        create_template_file(tdir, template, from_template, template_code=template_code and template_code.strip())   
                 
        # generate default function body
        funccode = '''return {"page_title": "%s"}''' % source.name
    
    # if given set the renderer parameter
    renderer = tgv.direct('renderer', 'pyramid:view', None)
    if renderer and not dec.kwargs.get('renderer'):
        dec.kwargs['renderer'] = "'%s'" % renderer
        
    # if view function is empty, make a default code displaying info
    if not func.blocks():
        func.insertfirst(Block(funccode))
        imps.set('pyramid.response', 'Response')
def generatescopereg(self, source, target):
    if source.stereotype('pyegg:stub'):
        return

    targetclass = read_target_node(source, target.target)
    module = targetclass.parent
    blocks = module.blocks()

    tgv = TaggedValues(source)

    transform = tgv.direct('transform', 'generator:class_scope', None) or \
        tgv.direct('transform', 'generator:simple_scope', None) or \
        'uml2fs'

    interfaces = tgv.direct('interfaces', 'generator:class_scope', None) or \
        tgv.direct('interfaces', 'generator:simple_scope', None)

    scopename = tgv.direct('scopename', 'generator:class_scope', None) or \
        tgv.direct('scopename', 'generator:simple_scope', None) or \
        source.name.lower()

    #do some common imports
    imps = Imports(module)
    imps.set('node.ext.uml.interfaces', [
        ['IOperation', None],
        ['IClass', None],
        ['IPackage', None],
        ['IInterface', None],
        ['IInterfaceRealization', None],
        ['IDependency', None],
        ['IProperty', None],
        ['IAssociation', None],
    ])

    imps.set('agx.core', [
        ['handler', None],
        ['Scope', None],
        ['registerScope', None],
        ['token', None],
    ])

    # make the register statement
    if interfaces:
        ifstring = "[%s]" % ','.join(interfaces)
    else:
        ifstring = None

    if source.stereotype('generator:class_scope'):
        classname = source.name
    else:
        classname = 'Scope'

    reg = "registerScope('%s', '%s', %s, %s)" % \
        (scopename, transform, ifstring, classname)

    # look if the reg stmt already exists
    regsearch = "registerScope('%s'" % scopename
    blockfound = None
    for b in blocks:
        for i in range(len(b.lines)):
            lcode = b.lines[i].strip().replace(' ', '')
            if lcode.startswith(regsearch):
                # replace the line
                b.lines[i] = reg
                return

    # else make a new block after the class declaration    
    bl = Block()
    bl.__name__ = str(bl.uuid)
    bl.lines.append(reg)
    classes = [c for c in module.classes() if c.classname == source.name]
    if classes:
        klass = classes[0]
        module.insertafter(bl, klass)
    else:
        module.insertlast(bl)
def get_tablename(klass):
    tgv = TaggedValues(klass)
    return tgv.direct('tablename', 'sql:sql_content', klass.name.lower())
def pyattribute(self, source, target):
    """Create Attribute.
    """
    klass = source.parent
    if klass.stereotype('pyegg:stub'):
        return
    if not klass.stereotype('sql:sql_content'):
        return
    targetclass = read_target_node(klass, target.target)
    module = targetclass.parent

    read_target_node(source, target.target)

    typename = source.type.name
    options = {}

    if source.stereotype('sql:primary'):
        options['primary_key'] = 'True'

    colid = None

    # retrieve options if the primitive type has <<sql_type>>
    if source.type.stereotype('sql:sql_type'):
        tgv = TaggedValues(source.type)
        typename = tgv.direct('classname', 'sql:sql_type', typename)
        default = tgv.direct('default', 'sql:sql_type', None)
        if default:
            options['default'] = default
        import_from = tgv.direct('import_from', 'sql:sql_type', None)
        if import_from:
            imps = Imports(module)
            imps.set(import_from, [[typename, None]])

    positionals = [typename]

    # collect params from column stereotype
    if source.stereotype('sql:column') or source.stereotype('sql:primary'):
        coltgv = TaggedValues(source)
        # id
        colid = coltgv.direct('id', 'sql:column', None) or \
            coltgv.direct('id', 'sql:primary', None)

        if colid:
            positionals.insert(0, "'%s'" % colid)

        # index
        index = coltgv.direct('index', 'sql:column', None) or \
            source.stereotype('sql:primary')
        if index:
            options['index'] = 'True'

        # default
        default = coltgv.direct('default', 'sql:column', None) or \
            coltgv.direct('dafault', 'sql:primary', None) or \
            options.get('default')
        if default:
            options['default'] = default

        # nullable
        not_null = None
        if coltgv.direct('not_null', 'sql:column', None) is not None:
            not_null = coltgv.direct('not_null', 'sql:column')
        if not_null is not None:
            options['nullable'] = {
                'true': False,
                'false': True,
            }[not_null]

        # server_default
        server_default = coltgv.direct(
            'server_default', 'sql:column', None) or coltgv.direct(
                'server_default', 'sql:primary', None)
        if server_default:
            options['server_default'] = server_default

        # sequence
        sequence = coltgv.direct('sequence', 'sql:column', None) or \
            coltgv.direct('sequence', 'sql:primary', None)
        if sequence:
            positionals.append("Sequence('%s')" % sequence)

    targetatt = read_target_node(source, target.target)

    if options:
        oparray = []
        for k in options:
            oparray.append('%s = %s' % (k, options[k]))
        targetatt.value = 'Column(%s,%s)' % (
            ','.join(positionals), ', '.join(oparray))
    else:
        targetatt.value = 'Column(%s)' % (','.join(positionals))
Beispiel #36
0
def plonebrowserview(self, source, target):
    view = source
    if view.stereotype('pyegg:function'):
        # XXX: <<function>> <<adapter>> on class
        return

    tok = token(str(view.uuid), True, browserpages=[])
    pack = source.parent
    target = read_target_node(pack, target.target)
    targetclass = read_target_node(view, target)

    if isinstance(target, python.Module):
        targetdir = target.parent
    else:
        targetdir = target

    path = targetdir.path
    path.append('browser.zcml')
    fullpath = os.path.join(*path)
    if 'browser.zcml' not in targetdir:
        zcml = ZCMLFile(fullpath)
        zcml.nsmap['browser'] = 'http://namespaces.zope.org/browser'
        targetdir['browser.zcml'] = zcml
    else:
        zcml = targetdir['browser.zcml']
    addZcmlRef(targetdir, zcml)

    targettok = token(str(targetclass.uuid),
                      True,
                      browserpages=[],
                      provides=None)

    _for = [token(str(context.supplier.uuid), False).fullpath \
            for context in tok.browserpages] or ['*']

    classpath = class_full_name(targetclass)
    tgv = TaggedValues(view)

    # create the templates dir
    if 'templates' not in targetdir.keys():
        targetdir['templates'] = Directory('templates')

    templates = targetdir['templates']
    templates.factories['.pt'] = XMLTemplate

    #create the browser:page entries
    for bp in tok.browserpages or [None]:
        #name of view: if it should have a constant name, change the last param
        viewname = tgv.direct('name', 'plone:view', None) or \
            tgv.direct('name', 'plone:dynamic_view', view.xminame.lower())
        name_raw = tgv.direct('name', 'plone:view', None) or \
            tgv.direct('name', 'plone:vdynamic_view', None)

        name = name_raw or view.xminame.lower()

        template_name_raw = tgv.direct('template_name', 'plone:view', None) or \
            tgv.direct('template_name', 'plone:dynamic_view', None)

        template_name = template_name_raw or name + '.pt'
        permission = tgv.direct('permission', 'plone:view', None) or \
            tgv.direct('permission', 'plone:dynamic_view', None)
        layer = tgv.direct('layer', 'plone:view', None) or \
            tgv.direct('layer', 'plone:dynamic_view', None)

        if bp:
            bptgv = TaggedValues(bp)
            bptok = token(str(bp.supplier.uuid), False)
            _for = bptok.fullpath

            print 'xminame:', bp, bp.xminame
            # consider uuid as an unset name
            if bp.xminame is None or re.match(
                    '[\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12}', bp.xminame):
                bpname = None
            else:
                bpname = bp.xminame.lower()

            if bp.xminame:
                viewname = bp.xminame
            viewname = bptgv.direct('name', 'plone:view', None) or \
                bptgv.direct('name', 'plone:dynamic_view', viewname)

            name = bptgv.direct('name', 'plone:view', None) or \
                bptgv.direct('name', 'plone:dynamic_view', bpname or name)

            # override template name
            template_name = bptgv.direct(
                'template_name', 'plone:view', None) or \
                bptgv.direct(
                    'template_name', 'plone:dynamic_view', None) or \
                template_name_raw or name + '.pt'

            permission = bptgv.direct('permission', 'plone:view', None) or \
                bptgv.direct('permission', 'plone:dynamic_view', permission)
            layer = bptgv.direct('layer', 'plone:view', None) or \
                bptgv.direct('layer', 'plone:dynamic_view', layer)
        else:
            _for = '*'

        found_browserpages = zcml.filter(tag='browser:page',
                                         attr='name',
                                         value=viewname)

        browser = None
        templatepath = 'templates/' + template_name

        if found_browserpages:
            for br in found_browserpages:  #check if it really matches
                if br.attrs.get('class') == classpath and \
                     _for == br.attrs['for']:
                    browser = br
                    break

        if not browser:
            browser = SimpleDirective(name='browser:page', parent=zcml)

        browser.attrs['for'] = _for
        if viewname and not viewname is UNSET:
            browser.attrs['name'] = viewname
        browser.attrs['class'] = classpath
        browser.attrs['template'] = templatepath
        browser.attrs['permission'] = permission or 'zope2.View'

        if layer:
            browser.attrs['layer'] = layer

        # spit out the page vanilla template
        if template_name not in templates.keys():
            pt = XMLTemplate()
            templates[template_name] = pt
            # set template for viewtemplate
            pt.template = 'agx.generator.plone:templates/viewtemplate.pt'
def sqlrelations_relations(self, source, target):
    """generate relations.
    """
    if source.stereotype('pyegg:stub'):
        return
    if not source.stereotype('sql:sql_content'):
        return

    targetclass = read_target_node(source, target.target)
    module = targetclass.parent
    directory = module.parent
    # get the last attribute and append there the relations
    attrs = targetclass.attributes()
    attrnames = [att.targets[0] for att in attrs]
    try:
        lastattr = targetclass.attributes()[-1]
    except IndexError:
        lastattr = None

    outgoing_relations = token(str(source.uuid),
                               True, outgoing_relations=[]).outgoing_relations
    imps = Imports(module)

    if outgoing_relations:
        imps.set('sqlalchemy.orm', [['relationship', None]])

    for relend in outgoing_relations:
        assoc = relend.association
        if relend==relend.association.memberEnds[0]:
            otherend = relend.association.memberEnds[1]
        else:
            otherend = relend.association.memberEnds[0]

        #Association classes are handled seperately
        #once we support association tables, we have to handle it here
        tgv = TaggedValues(assoc)
        if IAssociationClass.providedBy(assoc):
            # tgv = TaggedValues(otherend) We need to build support for tgvs on 
            # member ends later
            klass = relend.type
            otherclass = relend.association
            relname = token(str(otherend.uuid), True, relname=otherend.name+'_associations').relname
        else:
            klass = relend.type
            otherclass = otherend.type
            relname = otherend.name

        if relname not in attrnames:
            attr = Attribute()
            attr.__name__ = str(attr.uuid)
            if lastattr:
                targetclass.insertafter(attr, lastattr)
            else:
                targetclass.insertfirst(attr)

            attr.targets = [relname]
            options = {}
            # collect options for relationship
            if otherend.aggregationkind == 'composite':
                options['cascade'] = "'all, delete-orphan'"
            if assoc.stereotype('sql:ordered'):
                order_by = tgv.direct('order_by', 'sql:ordered', None)
                if not order_by:
                    msg = 'when setting a relation ordered you have to ' +\
                          'specify order_by!'
                    raise ValueError(msg)
                # if not prefixed, lets prefix it
                if not '.' in order_by:
                    order_by = '%s.%s' % (otherclass.name, order_by)
                options['order_by'] = "'%s'" % order_by
            if assoc.stereotype('sql:attribute_mapped'):
                keyname = tgv.direct('key', 'sql:attribute_mapped', None)
                if not keyname:
                    msg = 'when defining attribute_mapped you have to ' + \
                          'specify a key'
                    raise ValueError(msg)
                if assoc.stereotype('sql:ordered'):
                    # support for ordered mapped collection
                    # in this case we have to provide our own collection
                    # see http://docs.sqlalchemy.org/en/rel_0_7/orm/collections.html,
                    # secion 'Custom Dictionary-Based Collections'
                    fname = 'orderedcollection.py'
                    if fname not in directory:
                        src = JinjaTemplate()
                        src.template = templatepath(fname + '.jinja')
                        src.params = {}
                        directory[fname] = src
                        # XXX: so that emptymoduleremoval doesnt kick the
                        # template out better would be that jinjatemplates
                        # dont get removed at all
                        token('pymodules', True, modules=set()).modules.add(src)
                    options['collection_class'] = \
                        "ordered_attribute_mapped_collection('%s')" % keyname
                    imps.set('orderedcollection',
                             [['ordered_attribute_mapped_collection', None]])
                # unordered
                else:
                    options['collection_class'] = \
                        "attribute_mapped_collection('%s')" % keyname
                    imps.set('sqlalchemy.orm.collections',
                             [['attribute_mapped_collection', None]])

            # make the primaryjoin stmt
            if 1 or not IAssociationClass.providedBy(relend.association):
                tok = token(str(relend.uuid), True, joins=[])
                if tok.joins:
                    options['primaryjoin'] = "'%s'" % ','.join(tok.joins)

            # XXX: .navigable isn't yet correctly parsed from uml, thus the
            # hardcoding
            if True or relend.navigable:
                options['backref'] = "'%s'" % relend.name.lower()
            if assoc.stereotype('sql:lazy'):
                laziness = tgv.direct('laziness', 'sql:lazy', 'dynamic')
                options['lazy'] = "'%s'" % laziness

            #convert options into keyword params
            oparray = []
            for k in options:
                oparray.append('%s = %s' % (k, options[k]))

            attr.value = "relationship('%s', %s)" % (
                otherclass.name, ', '.join(oparray))
Beispiel #38
0
def generatescopereg(self, source, target):
    if source.stereotype('pyegg:stub'):
        return

    targetclass = read_target_node(source, target.target)
    module = targetclass.parent
    blocks = module.blocks()

    tgv = TaggedValues(source)

    transform = tgv.direct('transform', 'generator:class_scope', None) or \
        tgv.direct('transform', 'generator:simple_scope', None) or \
        'uml2fs'

    interfaces = tgv.direct('interfaces', 'generator:class_scope', None) or \
        tgv.direct('interfaces', 'generator:simple_scope', None)

    scopename = tgv.direct('scopename', 'generator:class_scope', None) or \
        tgv.direct('scopename', 'generator:simple_scope', None) or \
        source.name.lower()

    #do some common imports
    imps = Imports(module)
    imps.set('node.ext.uml.interfaces', [
        ['IOperation', None],
        ['IClass', None],
        ['IPackage', None],
        ['IInterface', None],
        ['IInterfaceRealization', None],
        ['IDependency', None],
        ['IProperty', None],
        ['IAssociation', None],
    ])

    imps.set('agx.core', [
        ['handler', None],
        ['Scope', None],
        ['registerScope', None],
        ['token', None],
    ])

    # make the register statement
    if interfaces:
        ifstring = "[%s]" % ','.join(interfaces)
    else:
        ifstring = None

    if source.stereotype('generator:class_scope'):
        classname = source.name
    else:
        classname = 'Scope'

    reg = "registerScope('%s', '%s', %s, %s)" % \
        (scopename, transform, ifstring, classname)

    # look if the reg stmt already exists
    regsearch = "registerScope('%s'" % scopename
    blockfound = None
    for b in blocks:
        for i in range(len(b.lines)):
            lcode = b.lines[i].strip().replace(' ', '')
            if lcode.startswith(regsearch):
                # replace the line
                b.lines[i] = reg
                return

    # else make a new block after the class declaration
    bl = Block()
    bl.__name__ = str(bl.uuid)
    bl.lines.append(reg)
    classes = [c for c in module.classes() if c.classname == source.name]
    if classes:
        klass = classes[0]
        module.insertafter(bl, klass)
    else:
        module.insertlast(bl)
def zcaeventfor(self, source, target):
    adapter = source
    tok = token(str(adapter.uuid), True)
    if not hasattr(tok, 'fors'):
        msg = 'subscriber class %s has no <<for>> dependency' \
            % dotted_path(adapter)
        raise ValueError(msg)

    pack = source.parent
    target = read_target_node(pack, target.target)
    if isinstance(target, python.Module):
        targetdir = target.parent
    else:
        targetdir = target

    path = targetdir.path
    path.append('subscribers.zcml')
    fullpath = os.path.join(*path)
    if 'subscribers.zcml' not in targetdir.keys():
        zcml = ZCMLFile(fullpath)
        targetdir['subscribers.zcml'] = zcml
    else:
        zcml = targetdir['subscribers.zcml']
    addZcmlRef(targetdir, zcml)
    
    targetclass = read_target_node(adapter, target)
    targettok = token(str(targetclass.uuid), True, realizes=[], provides=None)
    # make sure that the event is the second entry in the for list
    if tok.fors[0].stereotype('zca:event'):
        tok.fors.reverse()

    _for = [token(str(adaptee.uuid), False).fullpath for adaptee in tok.fors]
    factory = dotted_path(adapter)
    tgv = TaggedValues(adapter)
    name = tgv.direct('name', 'zca:for')
    isfunc = adapter.stereotype('pyegg:function')
    # functions are declared handler, classes factories
    if isfunc:
        attrname = 'handler'
    else:
        attrname = 'factory'

    found_adapts = zcml.filter(tag='subscriber', attr=attrname, value=factory)
    if found_adapts:
        adapts = found_adapts[0]
    else:     
        adapts = SimpleDirective(name='subscriber', parent=zcml)
    adapts.attrs['for'] = _for
    if not name is UNSET:
        adapts.attrs['name'] = name
    adapts.attrs[attrname] = factory
    # write the provides which is collected in the zcarealize handler
    if len(targettok.realizes) == 1:
        provides = targettok.realizes[0]
    else:
        provides = targettok.provides

    if not isfunc:
        if provides:
            adapts.attrs['provides'] = provides['path']

    if hasattr(tok, 'permission'):
        adapts.attrs['permission'] = tok.permission
def sqlcontentclass(self, source, target):
    """sqlalchemy class.
    """
    if source.stereotype('pyegg:stub'):
        return

    targetclass = read_target_node(source, target.target)

    module = targetclass.parent
    imps = Imports(module)
    imps.set('sqlalchemy', [['Column', None],
                           ['Integer', None],
                           ['String', None],
                           ['ForeignKey', None],
                           ['Sequence', None]])

    # find last import and do some assignments afterwards
    lastimport = [imp for imp in module.filtereditems(IImport)][-1]
    globalatts = [att for att in module.filtereditems(IAttribute)]
    classatts = [att for att in targetclass.filtereditems(IAttribute)]

    # generate the Base=declarative_base() statement
    saconfig=get_z3c_saconfig(source)
    if saconfig:
        # if we have a z3c_saconfig setting we import the Base from
        # the corresponding package
        imps.set(dotted_path(saconfig)+'.saconfig','Base')
    else:
        # otherwise we create it by default
        imps.set('sqlalchemy.ext.declarative', 'declarative_base')
        att = Attribute(['Base'], 'declarative_base()')
        att.__name__ = 'Base'
        if not [a for a in globalatts if a.targets == ['Base']]:
            module.insertafter(att, lastimport)

    # generate the __tablename__ attribute
    if not [a for a in classatts if a.targets == ['__tablename__']]:
        tablename = Attribute(['__tablename__'],
                              "'%s'" % (get_tablename(source)))
        tablename.__name__ = '__tablename__'
        targetclass.insertfirst(tablename)

    # if a class is a base class for concrete_table_inheritance it must be
    # abstract
    if source.stereotype('sql:concrete_table_inheritance'):
        if not [a for a in classatts if a.targets == ['__abstract__']]:
            abstract = Attribute(['__abstract__'], "True")
            abstract.__name__ = '__abstract__'
            targetclass.insertfirst(abstract)

    # lets inherit from Base unless we dont inherit from a sql_content class
    has_sql_parent = False
    joined_parents = []
    table_per_class_parents = []
    for inh in Inheritance(source).values():
        if inh.context.stereotype('sql:sql_content'):
            has_sql_parent = True
            if inh.context.stereotype('sql:joined_table_inheritance'):
                joined_parents.append(inh.context)
            elif inh.context.stereotype('sql:concrete_table_inheritance'):
                table_per_class_parents.append(inh.context)
            else:
                msg = 'when inheriting from an sql_content class (%s) ' + \
                      'the parent has to have either ' + \
                      '<<joined_table_inheritance>> or ' + \
                      '<<concrete_table_inheritance>> stereotype! ' + \
                      'see "http://docs.sqlalchemy.org/en/rel_0_7/' + \
                      'orm/inheritance.html" for further info'
                msg = msg % source.name
                raise ValueError(msg) 

    if targetclass.bases == ['object']:
        targetclass.bases = ['Base']
    else:
        if not has_sql_parent and 'Base' not in targetclass.bases:
            targetclass.bases.insert(0, 'Base')

    # if the class has parents that are joined base classes
    # we need __mapper_args__ and a foreign primary key
    for parent in joined_parents:
        pks = get_pks(parent)
        if not pks:
            msg = 'class %s must have a primary key defined!' % parent.name
            raise ValueError(msg)
        pk = pks[0]
        pkname = get_colid(pk)
        pfkname = pkname
        typename = pk.type.name
        if pk.type.stereotype('sql:sql_type'):
            tgv = TaggedValues(pk.type)
            typename = tgv.direct('classname', 'sql:sql_type', typename)
        fk = "ForeignKey('%s.%s')" % (get_tablename(parent), pkname)
        pfkstmt = "Column(%s, %s,primary_key = True)" % (typename, fk)
        if not [a for a in classatts if a.targets == [pfkname]]:
            pfk = Attribute([pfkname], pfkstmt)
            pfk.__name__ = pfkname
            targetclass.insertfirst(pfk)
        if not [a for a in classatts if a.targets == ['__mapper_args__']]:
            mapper_val = "{'polymorphic_identity':'%s'}" % source.name.lower()
            abstract = Attribute(['__mapper_args__'], mapper_val)
            abstract.__name__ = '__mapper_args__'
            targetclass.insertfirst(abstract)
def eggdocuments(self, source, target):
    """Create egg ``setup.py`` and default documents.
    """
    root = target.anchor
    
    # setup.py
    root.factories['setup.py'] = JinjaTemplate

    tgv = TaggedValues(source)
    version = tgv.direct('version', 'pyegg:pyegg', '1.0')
    project = source.name

    cp = tgv.direct('copyright', 'pyegg:pyegg', '')
    cp = cp.split(',')
    cp = [line.strip() for line in cp]

    description = tgv.direct('description', 'pyegg:pyegg', '')

    classifiers = tgv.direct('classifiers', 'pyegg:pyegg', '')
    classifiers = classifiers.split(',')
    classifiers = [cla.strip() for cla in classifiers]

    keywords = tgv.direct('keywords', 'pyegg:pyegg', '')

    author = tgv.direct('author', 'pyegg:pyegg', '')
    author_email = tgv.direct('email', 'pyegg:pyegg', '')

    url = tgv.direct('url', 'pyegg:pyegg', '')

    license_name = tgv.direct('license', 'pyegg:pyegg', '')

    namespace = project.split('.')
    namespace_packages = list()
    if len(namespace) > 1:
        for i in range(len(namespace) - 1):
            namespace_packages.append('"%s"' % '.'.join(namespace[:i + 1]))
    namespace_packages = ', '.join(namespace_packages)

    zip_safe = tgv.direct('zipsafe', 'pyegg:pyegg', 'False')

    if 'setup.py' in root:
        setup = root['setup.py']
    else:
        setup = JinjaTemplate()
        root['setup.py'] = setup

    # read entry_points from token, so that other generators have the chance
    # to define entry_points
    entry_points_tok = token('entry_points', True, defs=[])
    setup_dependencies = token('setup_dependencies', True, deps=[])
    
    setup.template = templatepath('setup.py.jinja')
    setup.params = {
        'cp': cp,
        'version': version,
        'project': project,
        'description': description,
        'classifiers': classifiers,
        'keywords': keywords,
        'author': author,
        'author_email': author_email,
        'url': url,
        'license_name': license_name,
        'namespace_packages': namespace_packages,
        'zip_safe': zip_safe,
        'setup_dependencies': setup_dependencies.deps,
        'entry_points':'\n'.join(entry_points_tok.defs),
    }

    # README.rst
    if 'README.rst' not in root:
        readme = JinjaTemplate()
        root['README.rst'] = readme
        readme.template = templatepath('README.rst.jinja')
        readme.params = setup.params

    # MANIFEST.rst
    if 'MANIFEST.in' not in root:
        manifest = JinjaTemplate()
        root['MANIFEST.rst'] = manifest
        manifest.template = templatepath('MANIFEST.in.jinja')
        manifest.params = {}

    # LICENSE.rst
    if 'LICENSE.rst' not in root:
        license = JinjaTemplate()
        root['LICENSE.rst'] = license
        license.template = templatepath('LICENSE.rst.jinja')
        license.params = {}