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 pyclass(self, source, target):
    """Create python classes.
    """
    if source.stereotype('pyegg:stub'):
        return
    # skip class generation if previous custom handler mark this class as
    # already handled
    custom_handled = token('custom_handled_classes', True, classes=list())
    handled_classes = [str(uuid) for uuid in custom_handled.classes]
    if str(source.uuid) in handled_classes:
        return

    name = source.name
    module = target.anchor
    try:
        set_copyright(source, module)
    except AttributeError:
        msg = 'Package "%s" must have either <<pymodule>> or ' + \
              '<<pypackage>> stereotype'
        msg = msg % dotted_path(module)
        raise ValueError(msg)
    if module.classes(name):
        class_ = module.classes(name)[0]
        target.finalize(source, class_)
        return
    class_ = python.Class(name)
    module[str(class_.uuid)] = class_
    if not is_class_a_function(source) \
      and not source.parent.stereotype('pyegg:pymodule'):
        imp = Imports(module.parent['__init__.py'])
        imp.set(class_base_name(class_), [[class_.classname, None]])

    target.finalize(source, class_)
def setup_i18n(self, source, target):
    tdir = read_target_node(source, target.target)
    init = tdir['__init__.py']
    imps = Imports(init)
    imps.set('pyramid.i18n', 'TranslationStringFactory')
    if not init.attributes('_'):
        att = Attribute(['_'], "TranslationStringFactory('%s')" % source.name)
        att.__name__ = str(att.uuid)
        init.insertafterimports(att)
def apiexporter(self, source,target):
    """Takes classes with 'api' stereotype and imports them into 
    the pyegg's __init__.py.
    """
    egg = egg_source(source)
    targetegg = read_target_node(egg, target.target)
    init = targetegg['__init__.py']
    imps = Imports(init)
    klass = read_target_node(source, target.target)
    imps.set(class_base_name(klass), [[source.name, None]])
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 autoimport(self, source,target):
    """Takes classes with 'api' stereotype and imports them into 
    the pyegg's __init__.py.
    """
    targetob = read_target_node(source, target.target)
    if IModule.providedBy(targetob) or IDirectory.providedBy(targetob):
        init = targetob.parent['__init__.py']
    else:
        init = targetob.parent.parent['__init__.py']
    imps = Imports(init)
    imps.set(None, [[source.name, None]])
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 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 behaviorschema(self, source, target):
    schema = read_target_node(source, target.target)
    module = schema.parent

    # check whether this behavior has schema attributes
    if not 'form.Schema' in schema.bases:
        schema.bases.append('form.Schema')

    alsoprovides = "alsoProvides(%s, form.IFormFieldProvider)" \
        % schema.classname

    alsoprovides_exists = False

    for block in module.blocks():
        for line in block.lines:
            if line == alsoprovides:
                alsoprovides_exists = True

    block = python.Block()
    block.__name__ = str(uuid.uuid4())

    if not alsoprovides_exists:
        block.lines.append(alsoprovides)

    if block.lines:
        module.insertafter(block, schema)

    egg = egg_source(source)

    imp = Imports(schema.parent)
    imp.set(egg.name, [['_', None]])
    imp.set('plone.directives', [['form', None]])
    imp.set('zope.interface', [['alsoProvides', None]])
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 #11
0
def plone__init__(self, source, target):
    egg = egg_source(source)
    eggname = egg.name
    targetdir = read_target_node(source, target.target)
    module = targetdir['__init__.py']

    imp = Imports(module)
    imp.set('zope.i18nmessageid', [['MessageFactory', None]])

    value = 'MessageFactory("%s")' % eggname
    atts = [att for att in module.attributes() if '_' in att.targets]

    if atts:
        atts[0].value = value
    else:
        module['_'] = Attribute('_', value)
def plone__init__(self, source, target):
    egg = egg_source(source)
    eggname = egg.name
    targetdir = read_target_node(source, target.target)
    module = targetdir['__init__.py']

    imp = Imports(module)
    imp.set('zope.i18nmessageid', [['MessageFactory', None]])

    value = 'MessageFactory("%s")' % eggname
    atts = [att for att in module.attributes() if '_' in att.targets]

    if atts:
        atts[0].value = value
    else:
        module['_'] = Attribute('_', value)
def generate_view_class(self, source, target):
    targetklass = read_target_node(source, target.target)
    try:
        module = targetklass.parent
    except AttributeError:
        # if there is no parent, this handler is not responsible
        return
    tdir = module.parent
    
    try:
        tok = token(str(source.uuid), False)
        has_view_methods = tok.has_view_methods
    except:
        has_view_methods = False
        
    view_class = source.stereotype('pyramid:view_class')
    
    # create init method
    if view_class or has_view_methods:
        inits = targetklass.functions('__init__')
        if inits:
            init = inits[0]
        else:
            init = Function('__init__')
            targetklass.insertfirst(init)
        
        # import pdb;pdb.set_trace()    
        init.args = ['context', 'request']
    
        if not init.blocks('self.request'):
            init.insertfirst(Block('self.request = request'))
        if not init.blocks('self.context'):
            init.insertfirst(Block('self.context = context'))
            
        # if its a view_class create the global_template
        if view_class:
            gtemplate = view_class.taggedvalue('global_template').value
            from_gtemplate = view_class.taggedvalue('from_global_template').value
            create_template_file(tdir, gtemplate, from_gtemplate)
            imps = Imports(module)
            imps.set('pyramid.renderers', 'get_renderer')
            
            if not init.blocks('global_template'):
                init.insertlast(Block('renderer = get_renderer("%s")' % gtemplate))
                init.insertlast(Block('self.global_template = renderer.implementation()'))
                init.insertlast(Block('self.macros = self.global_template.macros'))
def schemaclass(self, source, target):
    schema = getschemaclass(source,target)
    klass = read_target_node(source, target.target)
    module = schema.parent

    view = module.classes('%sView' % klass.classname)[0]
    tok = token(str(view.uuid), True, depends_on=set())
    tok.depends_on.add(schema)

    if not 'form.Schema' in schema.bases:
        schema.bases.append('form.Schema')

    egg = egg_source(source)

    imp = Imports(schema.parent)
    imp.set(egg.name, [['_', None]])
    imp.set('plone.directives', [['form', None]])
def behaviorschema(self, source, target):
    schema = read_target_node(source, target.target)
    module = schema.parent

    # check whether this behavior has schema attributes
    if not 'form.Schema' in schema.bases:
        schema.bases.append('form.Schema')

    alsoprovides = "alsoProvides(%s, form.IFormFieldProvider)" \
        % schema.classname

    alsoprovides_exists = False

    for block in module.blocks():
        for line in block.lines:
            if line == alsoprovides:
                alsoprovides_exists = True

    block = python.Block()
    block.__name__ = str(uuid.uuid4())

    if not alsoprovides_exists:
        block.lines.append(alsoprovides)

    if block.lines:
        module.insertafter(block, schema)

    egg = egg_source(source)

    imp = Imports(schema.parent)
    imp.set(egg.name, [['_', None]])
    imp.set('plone.directives', [['form', None]])
    imp.set('zope.interface', [['alsoProvides', None]])
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 sqlassociationclasses(self, source, target):
    # generate the foreign keys + relations from the assoc class to
    # its relation ends
    end0 = source.memberEnds[0]
    klass0 = end0.type
    end1 = source.memberEnds[1]
    klass1 = end1.type
    targetclass=read_target_node(source,target.target)
    targetklass0=read_target_node(klass0, target.target)
    targetklass1=read_target_node(klass1, target.target)
    module=targetclass.parent

    if not klass0.stereotype('sql:sql_content'):
        return
    if not klass1.stereotype('sql:sql_content'):
        return
    
    #generate the foreign key properties
    joins0=calculate_joins(source, targetclass, klass0, end0.name, nullable = False, force_fullname=True)
    joins1=calculate_joins(source, targetclass, klass1, end1.name, nullable = False, force_fullname=True)

    #generate the association_proxy attributes
    templ='''association_proxy("%s", "%s", 
                            creator=lambda c: %s(%s=c))'''
    for klass,targetklass_, end, otherend, joins in ((klass0,targetklass1, end0, end1, joins0), (klass1, targetklass0, end1, end0, joins1)):
        if end.type != otherend.type:
            relname=source.name.lower()+'s' 
        else:
            relname=end.name+'_assocs'
            
        proxyname=end.name
        token(str(end.uuid),True,relname=relname,joins=joins)
        
        #XXX: if a sql_content class has 2 generalisation links to
        #other sql_content classes (which makes no sense for sqlalchemy)
        # targetklass_.attributes() leads to an
        #infinite loop (some odict stuff)
        if not targetklass_.attributes(proxyname):
            code=templ % (relname, get_tablename(klass), source.name, end.name)
            targetklass_.insertafterlastattr(Attribute(proxyname, code))
    
    #import association_proxy
    imps=Imports(module)
    imps.set('sqlalchemy.ext.associationproxy','association_proxy')
def zcarealize_finalize(self, source, target):
    # get the collected realizes 
    klass = source
    try:
        targetclass = read_target_node(klass, target.target)
        # stub
        if not targetclass:
            return

        targettok = token(str(targetclass.uuid), False)
        # class has no interfaces
        if not hasattr(targettok, 'realizes'):
            return
        ifacenames = [r['name'] for r in targettok.realizes]
        imptext = 'implements(%s)' % ','.join(ifacenames)
        docstrings = targetclass.filteredvalues(IDocstring)

        module = targetclass.__parent__
        imp = Imports(module)
        imp.set('zope.interface', [['implements', None]])
        # delete all implements stmts
        try:
            blocks = targetclass.filteredvalues(IBlock)
            for b in blocks:
                b.lines = \
                    [l for l in b.lines if not l.startswith('implements(')]
                if not b.lines:
                    del targetclass[str(b.uuid)]
            # XXX: should be reparsed
        except KeyError, e:
            print 'error during delete: %s' % str(e)

        if klass.stereotype('pyegg:function'):
            return
    
        block = Block(imptext)
        block.__name__ = 'implements'
        targetclass.insertfirst(block)

        if docstrings:
            imp = targetclass.detach('implements')
            targetclass.insertafter(imp, docstrings[0])
Beispiel #19
0
def zcviewfinalize(self, source, target):
    """Create zope interface.
    """
    if source.stereotype('pyegg:stub') is not None:
        return

    view = source
    targetview = read_target_node(view, target.target)
    name = source.name
    module = targetview.parent
    imp = Imports(module)
    imp.set('Products.Five', [['BrowserView', None]])
    set_copyright(source, module)
    if module.classes(name):
        class_ = module.classes(name)[0]
    else:
        class_ = python.Class(name)
        module[name] = class_

    if 'BrowserView' not in targetview.bases:
        targetview.bases.append('BrowserView')
def zcviewfinalize(self, source, target):
    """Create zope interface.
    """
    if source.stereotype('pyegg:stub') is not None:
        return

    view = source
    targetview = read_target_node(view, target.target)
    name = source.name
    module = targetview.parent
    imp = Imports(module)
    imp.set('Products.Five', [['BrowserView', None]])
    set_copyright(source, module)
    if module.classes(name):
        class_ = module.classes(name)[0]
    else:
        class_ = python.Class(name)
        module[name] = class_

    if 'BrowserView' not in targetview.bases:
        targetview.bases.append('BrowserView')
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)
def pyramid_include(self, source, target):
    #creates a pyramid includeme hook if <<pyramid_include>> is applied on the root package
    #egg=egg_source(source)
    targetegg=read_target_node(source,target.target)
    db_attribute_name='db'
    
    tgv=source.stereotype('sql:pyramid_include').taggedvalue('db_attribute_name')
    if tgv:
        db_attribute_name=tgv.value
        
    fname='pyramid_include.py'
    if fname not in targetegg.keys():
        templ=JinjaTemplate()
        templ.template=templatepath('pyramid_include.py.jinja')
        templ.params={
                      'db_attribute_name':db_attribute_name}
        targetegg[fname]=templ
        
    init=targetegg['__init__.py']
    imps=Imports(init)
    imps.set('pyramid_include','includeme')
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 generate_sqlalchemy_config(self, source, target):
    tgt = read_target_node(source, target.target)
    if IModule.providedBy(tgt):
        # target is a module, then its ok
        module = tgt
        target_dir = module.parent
    else:
        # fetch __init__.py
        module = tgt['__init__.py']
        target_dir = tgt
    
    
    # first lets create sqla_config.py that does all the config situps
    fname = 'sqla_config.py'
    package_name = implicit_dotted_path(source)
    templ = JinjaTemplate()
    target_dir.factories[fname] = JinjaTemplate
    templ.template = templatepath(fname) + '.jinja'
    target_dir[fname] = templ
    target_dir[fname].params = {'engine_name':'default', 'package_name':dotted_path(source)}
    
    # now lets call config_db from the __init__.py
    imps = Imports(module)
    imps.set('sqla_config', 'config_db')
    main = module.functions('main')[0]
    term = 'config.make_wsgi_app'
    make_app = main.blocks(term)[0]
    lines = make_app.lines
    # find occurrence of line in block
    index = -1
    found = False
    for i in range(len(lines)):
        if term in lines[i]:
            index = i
        if 'config_db' in lines[i]:
            found = True
            
    tok = token('config', True, main=main, module=module)
    if index != -1 and not found:
        lines.insert(index, 'config_db(config)')
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)
def zcainterface(self, source, target):
    """Create zope interface.
    """
    if source.stereotype('pyegg:stub') is not None:
        return

    name = source.name
    module = target.anchor

    imp = Imports(module)

    imp.set('zope.interface', [['Interface', None]])
    set_copyright(source, module)
    if module.classes(name):
        class_ = module.classes(name)[0]
    else:
        class_ = python.Class(name)
        module[name] = class_
#    if not class_.bases:
#        class_.bases.append('Interface')
    token(str(class_.uuid), True, isInterface=True)
    target.finalize(source, class_)
def create_service(self, source, target):
    """create a module 'services.py' to hold the cornice services
    
    create a docstring at the top of the module.
    create an import statement (from cornice import Service).
    create an attribute of the name of the UML::Class
    and set it to a Service(with parameters)
    parameters are name = name of the
    """
    klass = read_target_node(source, target.target)
    module = klass.parent
    
    # create imports for cornice service
    imps = Imports(module)
    imps.set('cornice', 'Service')  # from cornice import Service
    
    # add the dep
    deps = token('setup_dependencies', True, deps=[])
    if not 'cornice' in deps.deps:
        deps.deps.append('cornice')
    
    # prepare for later: get name of the service
    servicename = getservicename(source)
    servicepath = getservicepath(source)
    
    # create an Attribute that will define a cornice service
    serviceattr = Attribute()
    serviceattr.targets = [source.name]  
    serviceattr.value = 'Service(name="%s", path="%s")' % (servicename, servicepath)
    serviceattr.__name__ = serviceattr.uuid
    
    # lets insert it after the class definition
    if not module.attributes(source.name):
        module.insertafter(serviceattr, klass)

    # mark importme dependencies for pyramid
    tok = token('pyramid_importmes', True, packages=[])
    if 'cornice' not in tok.packages:
        tok.packages.append('cornice')
def schemaclass(self, source, target):
    schema = getschemaclass(source, target)
    klass = read_target_node(source, target.target)
    module = schema.parent

    view = module.classes('%sView' % klass.classname)[0]
    tok = token(str(view.uuid), True, depends_on=set())
    tok.depends_on.add(schema)

    if not 'form.Schema' in schema.bases:
        schema.bases.append('form.Schema')

    egg = egg_source(source)

    imp = Imports(schema.parent)
    imp.set(egg.name, [['_', None]])
    imp.set('plone.directives', [['form', None]])
Beispiel #29
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 typeview(self, source, target):
    schema = getschemaclass(source, target)
    klass = read_target_node(source, target.target)
    module = schema.parent
    if IModule.providedBy(module):
        directory = module.parent
    else:
        directory = module
    nsmap = {
        None: 'http://namespaces.zope.org/zope',
        'plone': 'http://namespaces.plone.org/plone',
        'grok': 'http://namespaces.zope.org/grok',
    }
    zcmlfile = get_zcml(directory, 'configure.zcml', nsmap=nsmap)

    # include grok:grok directive if not set yet
    set_zcml_directive(directory, 'configure.zcml', 'grok:grok', 'package',
                       '.')

    classname = '%sView' % klass.classname
    if module.classes(classname):
        view = module.classes(classname)[0]
    else:
        view = python.Class()
        module[uuid.uuid4()] = view
    view.classname = classname

    if not 'dexterity.DisplayForm' in view.bases:
        view.bases.append('dexterity.DisplayForm')

    context = "grok.context(%s)" % schema.classname
    require = "grok.require('zope2.View')"

    context_exists = False
    require_exists = False

    for block in view.blocks():
        for line in block.lines:
            if line == context:
                context_exists = True
            if line == require:
                require_exists = True

    block = python.Block()
    block.__name__ = str(uuid.uuid4())

    if not context_exists:
        block.lines.append(context)
    if not require_exists:
        block.lines.append(require)

    if block.lines:
        view.insertfirst(block)

    template = False
    for attr in view.attributes():
        if 'template' in attr.targets:
            template = attr
            break

    if not template:
        template = python.Attribute()
        template.targets = ['template']
        view[str(uuid.uuid4())] = template

    template.value = "PageTemplate('templates/%s.pt')" \
        % klass.classname.lower()

    imp = Imports(module)
    imp.set('plone.directives', [['dexterity', None]])
    imp.set('five', [['grok', None]])
    imp.set('grokcore.view.components', [['PageTemplate', None]])

    directory = module.parent
    template_name = '%s.pt' % klass.classname.lower()
    template = 'templates/%s' % template_name
    if not 'templates' in directory:
        directory['templates'] = Directory()

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

    if template_name not in templates:
        pt = templates[template_name] = XMLTemplate()
        pt.template = 'agx.generator.dexterity:templates/displayform.pt'
def behavioradapter(self, source, target):
    schema = read_target_node(source, target.target)
    module = schema.parent

    adaptername = schema.classname[1:]
    if module.classes(adaptername):
        adapter = module.classes(adaptername)[0]
    else:
        adapter = python.Class()
        module[uuid.uuid4()] = adapter
    adapter.classname = adaptername

    implements = "implements(%s)" % schema.classname
    implements_exists = False
    for block in adapter.blocks():
        for line in block.lines:
            if line == implements:
                implements_exists = True

    block = python.Block()
    block.__name__ = str(uuid.uuid4())

    if not implements_exists:
        block.lines.append(implements)

    if block.lines:
        adapter.insertfirst(block)

    # ``__init__ only created once``
    # XXX: check if signature changed and raise error
    if not adapter.functions('__init__'):
        init = python.Function(functionname='__init__')
        init.args.append('context')
        block = init[str(uuid.uuid4())] = python.Block()
        block.lines.append('self.context = context')
        adapter[str(uuid.uuid4())] = init

    imp = Imports(module)
    imp.set('zope.interface', [['implements', None]])

    # read or create configure.zcml
    package = module.parent
    if 'configure.zcml' in package:
        configure = package['configure.zcml']
    else:
        path = package.path
        path.append('configure.zcml')
        fullpath = os.path.join(*path)
        configure = ZCMLFile(fullpath)
        configure.nsmap['plone'] = 'http://namespaces.plone.org/plone'
        configure.nsmap['grok'] = 'http://namespaces.zope.org/grok'
        package['configure.zcml'] = configure

    provides = '.%s.%s' % (module.modulename, schema.classname)
    factory = '.%s.%s' % (module.modulename, adapter.classname)

    # XXX: maybe more filters
    if not configure.filter(tag='plone:behavior',
                            attr='factory',
                            value=factory):
        behavior = SimpleDirective(name='plone:behavior', parent=configure)
        behavior.attrs['title'] = adapter.classname
        # XXX: stereotype tgv
        behavior.attrs['description'] = adapter.classname
        behavior.attrs['provides'] = provides
        behavior.attrs['factory'] = factory
Beispiel #32
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 generate_configuration(self, source, target):
    tgt = read_target_node(source, target.target)
    
    if IModule.providedBy(tgt):
        # target is a module, then its ok
        module = tgt
    else:
        # fetch __init__.py
        module = tgt['__init__.py']
        
    tok = token('pyramid_configuration', True,
              imports=[], static_views=[], scans=[])
    
    imps = Imports(module)
    imps.set('wsgiref.simple_server', 'make_server')
    imps.set('pyramid.config', 'Configurator')
    
    # create a function main if not present
    if 'main' not in [f.functionname for f in module.functions()]:
        func = Function('main')
        func.args = ['global_config', '**settings']
        module.insertafterimports(func)
    
    main = module.functions(name='main')[0]
    try:
        srtok = token('site_root', False)
        bootstrap = srtok.bootstrap
    except ComponentLookupError:
        bootstrap = None
        
    if not main.blocks('Configurator'):
        if bootstrap:
            import_if_necessary(module, bootstrap)
            main.insertfirst(Block('config = Configurator(root_factory=bootstrap)'))
        else:
            main.insertfirst(Block('config = Configurator()'))
        
    
    
    # do the configurator stuff
    mainblock = main.blocks('Configurator')[0]
    
    # importmes
    imptok = token('pyramid_importmes', True, packages=[])
    for pack in imptok.packages:
        mainblock.insertlineafter( "config.include('%s')" % pack,'Configurator', ifnotpresent=True)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
    # static views
    for sv in tok.static_views:
        mainblock.insertlineafter('''config.add_static_view('%s', '%s/',%s)''' % \
                (sv[0], sv[1], sv[2]), 'Configurator', ifnotpresent=True)
        
    # scans
    for scan in tok.scans:
        if scan:
            mainblock.insertlineafter("config.scan('%s')" % scan, 'add_static_view', ifnotpresent=True)
        else:
            mainblock.insertlineafter("config.scan()" , 'add_static_view', ifnotpresent=True)
            
    # insert app stuff at end of block
    mainblock.appendline("app = config.make_wsgi_app()", ifnotpresent=True)
    mainblock.appendline("return app", ifnotpresent=True)
             
    if not module.blocks('__main__'):
        module.insertlast(Block('''if __name__ == '__main__':
    app = main()
    server = make_server('0.0.0.0', 8080, app)
    server.serve_forever()'''))
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)
Beispiel #35
0
def common_imports(self, source, target):
    """does common imports for modules with handlers
    """
    handlerscope = getUtility(IScope, 'uml2fs.handler')
    module = read_target_node(source, target.target)
    has_handlers = False
    for klass in source.classes:
        if handlerscope(klass):
            has_handlers = True
            break

    if not has_handlers:
        return

    # 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],
    ])
    imps.set('agx.core.interfaces', [
        ['IScope', None],
    ])
    imps.set('agx.core.util', [
        ['read_target_node', None],
        ['dotted_path', None],
    ])
    imps.set('agx.generator.pyegg.utils', [
        ['class_base_name', None],
        ['implicit_dotted_path', None],
    ])
def typeview(self, source, target):
    schema = getschemaclass(source,target)
    klass = read_target_node(source, target.target)
    module = schema.parent
    if IModule.providedBy(module):
        directory = module.parent
    else:
        directory = module
    nsmap = {
        None: 'http://namespaces.zope.org/zope',
        'plone': 'http://namespaces.plone.org/plone',
        'grok': 'http://namespaces.zope.org/grok',
    }
    zcmlfile = get_zcml(directory, 'configure.zcml', nsmap=nsmap)

    # include grok:grok directive if not set yet
    set_zcml_directive(directory, 'configure.zcml',
                       'grok:grok', 'package', '.')

    classname = '%sView' % klass.classname
    if module.classes(classname):
        view = module.classes(classname)[0]
    else:
        view = python.Class()
        module[uuid.uuid4()] = view
    view.classname = classname

    if not 'dexterity.DisplayForm' in view.bases:
        view.bases.append('dexterity.DisplayForm')

    context = "grok.context(%s)" % schema.classname
    require = "grok.require('zope2.View')"

    context_exists = False
    require_exists = False

    for block in view.blocks():
        for line in block.lines:
            if line == context:
                context_exists = True
            if line == require:
                require_exists = True

    block = python.Block()
    block.__name__ = str(uuid.uuid4())

    if not context_exists:
        block.lines.append(context)
    if not require_exists:
        block.lines.append(require)

    if block.lines:
        view.insertfirst(block)

    template = False
    for attr in view.attributes():
        if 'template' in attr.targets:
            template = attr
            break

    if not template:
        template = python.Attribute()
        template.targets = ['template']
        view[str(uuid.uuid4())] = template

    template.value = "PageTemplate('templates/%s.pt')" \
        % klass.classname.lower()

    imp = Imports(module)
    imp.set('plone.directives', [['dexterity', None]])
    imp.set('five', [['grok', None]])
    imp.set('grokcore.view.components', [['PageTemplate', None]])

    directory = module.parent
    template_name = '%s.pt' % klass.classname.lower()
    template = 'templates/%s' % template_name
    if not 'templates' in directory:
        directory['templates'] = Directory()

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

    if template_name not in templates:
        pt = templates[template_name] = XMLTemplate()
        pt.template = 'agx.generator.dexterity:templates/displayform.pt'
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))
def common_imports(self, source, target):
    """does common imports for modules with handlers
    """
    handlerscope = getUtility(IScope, 'uml2fs.handler')
    module = read_target_node(source, target.target)
    has_handlers = False
    for klass in source.classes:
        if handlerscope(klass):
            has_handlers = True
            break

    if not has_handlers:
        return

    # 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],
    ])
    imps.set('agx.core.interfaces', [
        ['IScope', None],
    ])
    imps.set('agx.core.util', [
        ['read_target_node', None],
        ['dotted_path', None],
    ])
    imps.set('agx.generator.pyegg.utils', [
        ['class_base_name', None],
        ['implicit_dotted_path', None],
    ])
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))
def behavioradapter(self, source, target):
    schema = read_target_node(source, target.target)
    module = schema.parent

    adaptername = schema.classname[1:]
    if module.classes(adaptername):
        adapter = module.classes(adaptername)[0]
    else:
        adapter = python.Class()
        module[uuid.uuid4()] = adapter
    adapter.classname = adaptername

    implements = "implements(%s)" % schema.classname
    implements_exists = False
    for block in adapter.blocks():
        for line in block.lines:
            if line == implements:
                implements_exists = True

    block = python.Block()
    block.__name__ = str(uuid.uuid4())

    if not implements_exists:
        block.lines.append(implements)

    if block.lines:
        adapter.insertfirst(block)

    # ``__init__ only created once``
    # XXX: check if signature changed and raise error
    if not adapter.functions('__init__'):
        init = python.Function(functionname='__init__')
        init.args.append('context')
        block = init[str(uuid.uuid4())] = python.Block()
        block.lines.append('self.context = context')
        adapter[str(uuid.uuid4())] = init

    imp = Imports(module)
    imp.set('zope.interface', [['implements', None]])

    # read or create configure.zcml
    package = module.parent
    if 'configure.zcml' in package:
        configure = package['configure.zcml']
    else:
        path = package.path
        path.append('configure.zcml')
        fullpath = os.path.join(*path)
        configure = ZCMLFile(fullpath)
        configure.nsmap['plone'] = 'http://namespaces.plone.org/plone'
        configure.nsmap['grok'] = 'http://namespaces.zope.org/grok'
        package['configure.zcml'] = configure

    provides = '.%s.%s' % (module.modulename, schema.classname)
    factory = '.%s.%s' % (module.modulename, adapter.classname)

    # XXX: maybe more filters
    if not configure.filter(
            tag='plone:behavior', attr='factory', value=factory):
        behavior = SimpleDirective(name='plone:behavior', parent=configure)
        behavior.attrs['title'] = adapter.classname
        # XXX: stereotype tgv
        behavior.attrs['description'] = adapter.classname
        behavior.attrs['provides'] = provides
        behavior.attrs['factory'] = factory
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')