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 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]])
예제 #3
0
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_)
예제 #4
0
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 grokforcontentclass(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
    # add the schemaclass to realizes, the rest is done by the
    # zcagenerator::zcarealize_finalize handler
    impltok = token(str(klass.uuid), True, realizes=[], provides=None)
    impltok.realizes.insert(0, {'name': schemaclassname})

    require = "grok.name('%s')" % dotted_path(source)
    require_exists = False

    for block in klass.blocks():
        for line in block.lines:
            if line == require:
                require_exists = True

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

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

    if block.lines:
        klass.insertfirst(block)
def grokforcontentclass(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
    # add the schemaclass to realizes, the rest is done by the
    # zcagenerator::zcarealize_finalize handler
    impltok = token(str(klass.uuid), True, realizes=[], provides=None)
    impltok.realizes.insert(0, {'name': schemaclassname})

    require = "grok.name('%s')" % dotted_path(source)
    require_exists = False

    for block in klass.blocks():
        for line in block.lines:
            if line == require:
                require_exists = True

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

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

    if block.lines:
        klass.insertfirst(block)
예제 #7
0
def gsprofilesetuphandlers(self, source, target):
    """Create jsregistry.xml
    """
    package = target.anchor
    default = package['profiles']['default']
    egg = egg_source(source)
    egg_name = egg.name
    path = dotted_path(egg) + '.setuphandlers.install'

    markerfilename = '%s_marker.txt' % dotted_path(egg)

    #create setuphandlers.py
    setupname = 'setuphandlers.py'
    if setupname not in package.keys():
        setup = JinjaTemplate()
        package[setupname] = setup
        setup.template = 'agx.generator.plone:templates/setuphandlers.py.jinja'
        setup.params = {'egg': path, 'markerfilename': markerfilename}

    #create the markerfile
    if not markerfilename in default.keys():
        markerfile = default[markerfilename] = DTMLTemplate()
        markerfile.template = \
            'agx.generator.plone:templates/productname_marker.txt'

    # read or create import_steps.xml
    if 'import_steps.xml' in default:
        xml = default['import_steps.xml']
    else:
        xml = default['import_steps.xml'] = DTMLTemplate()

    # set template used for import_steps.xml
    xml.template = 'agx.generator.plone:templates/import_steps.xml'

    # set template params
    xml.params = {
        'eggid': path,
        'handler': path,
        'handlertitle': 'Installer for ' + dotted_path(egg),
        'version': '1',  # XXX: extend profile with import step version.
        'description': '',  # XXX: extend profile with import step version.
    }
def gsprofilesetuphandlers(self, source, target):
    """Create jsregistry.xml
    """
    package = target.anchor
    default = package['profiles']['default']
    egg = egg_source(source)
    egg_name = egg.name
    path = dotted_path(egg) + '.setuphandlers.install'

    markerfilename = '%s_marker.txt' % dotted_path(egg)

    #create setuphandlers.py
    setupname = 'setuphandlers.py'
    if setupname not in package.keys():
        setup = JinjaTemplate()
        package[setupname] = setup
        setup.template = 'agx.generator.plone:templates/setuphandlers.py.jinja'
        setup.params = {'egg':path, 'markerfilename':markerfilename}

    #create the markerfile
    if not markerfilename in default.keys():
        markerfile = default[markerfilename] = DTMLTemplate()
        markerfile.template = \
            'agx.generator.plone:templates/productname_marker.txt'

    # read or create import_steps.xml
    if 'import_steps.xml' in default:
        xml = default['import_steps.xml']
    else:
        xml = default['import_steps.xml'] = DTMLTemplate()

    # set template used for import_steps.xml
    xml.template = 'agx.generator.plone:templates/import_steps.xml'

    # set template params
    xml.params = {
        'eggid' : path,
        'handler' : path,
        'handlertitle' : 'Installer for ' + dotted_path(egg),
        'version': '1', # XXX: extend profile with import step version.
        'description':'',# XXX: extend profile with import step version.
    }
def setup_entry_points(self, source, target):
    # hooks in the entry point as a token, so that it gets generated 
    # by pyeggs eggdocuments handler
    
    if not is_generator_egg(source):
        return

    ept = """[agx.generator]
        register = %s:register"""
    tok = token('entry_points', True, defs=[])
    tok.defs.append(ept % dotted_path(source))
예제 #10
0
def setup_entry_points(self, source, target):
    # hooks in the entry point as a token, so that it gets generated
    # by pyeggs eggdocuments handler

    if not is_generator_egg(source):
        return

    ept = """[agx.generator]
        register = %s:register"""
    tok = token('entry_points', True, defs=[])
    tok.defs.append(ept % dotted_path(source))
예제 #11
0
def createpermission(self, source, target):
    targetclass = read_target_node(source, target.target)
    module = targetclass.parent
    targetdir = module.parent
    path = class_base_name(targetclass)
    # prevent python class from being generated
    sts = [st.name for st in source.stereotypes]

    # only if no other steroetypes are attached
    if 'zca:permission' in sts and len(sts) == 1:
        # class also has to be deleted from __init__
        init = targetdir['__init__.py']
        for imp in init.imports():
            if imp.fromimport == path and imp.names[0][0] == source.name:
                del init[imp.__name__]
        del module[targetclass.__name__]

    # and now write the permission definition into confure.zcml
    zcmlpath = targetdir.path
    zcmlpath.append('configure.zcml')
    fullpath = os.path.join(*zcmlpath)

    if 'configure.zcml' not in targetdir.keys():
        zcml = ZCMLFile(fullpath)
        targetdir['configure.zcml'] = zcml
    else:
        zcml = targetdir['configure.zcml']
    addZcmlRef(targetdir, zcml)

    id = TaggedValues(source).direct('id', 'zca:permission')
    if id is UNSET:
        permid = dotted_path(source)
    else:
        permid = id

    found_directives = zcml.filter(tag='permission', attr='id', value=permid)
    if found_directives:
        directive = found_directives[0]
    else:     
        directive = SimpleDirective(name='permission', parent=zcml)

    directive.attrs['id'] = permid
    title = TaggedValues(source).direct('title', 'zca:permission')
    if not title is UNSET:
        directive.attrs['title'] = title

    description = TaggedValues(source).direct('description', 'zca:permission')
    if not description is UNSET:
        directive.attrs['description'] = description
def generate_ini_files(self, source, target):
    print "generate_ini_files"
    egg = target.anchor
    
    for name in ['development.ini']:
        egg.factories[name] = JinjaTemplate
            
        if name not in egg.keys():
            egg[name] = JinjaTemplate()
            egg[name].template = templatepath(name + '.jinja')
            egg[name].params = {'package':source.name,
                                        'host':'0.0.0.0',
                                        'port':'8080'}
    
    ept = """[paste.app_factory]
        main = %s:main"""
    tok = token('entry_points', True, defs=[])
    tok.defs.append(ept % dotted_path(source))
예제 #13
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))
예제 #15
0
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
예제 #16
0
def zcaeventforcollect(self, source, target):
    pack = source.parent
    adaptee = source.supplier
    adapter = source.client
    target = read_target_node(pack, target.target)
    targetadaptee = read_target_node(adaptee, target)
    tok = token(str(adapter.uuid), True, fors=[])
    adapteetok = token(str(adaptee.uuid), True, fullpath=None)
    if targetadaptee:
        adapteetok.fullpath = dotted_path(adaptee)
    # its a stub
    else:
        adapteetok.fullpath = '.'.join(
            [TaggedValues(adaptee).direct('import',
                                          'pyegg:stub'), adaptee.name])
    if isinstance(target, python.Module):
        targetdir = target.parent
    else:
        targetdir = target
    tok.fors.append(adaptee)
def create_register_func(self, source, target):
    """Creates the register function.
    """
    if not token(str(source.uuid),True,is_generator_egg=False).is_generator_egg:
        return

    init = read_target_node(source, target.target)['__init__.py']
    fname = 'register'
    path = dotted_path(source)
    if fname not in [f.functionname for f in init.functions()]:
        f = Function()
        f.functionname = fname
        f.__name__ = str(f.uuid)
        bl = Block()
        bl.__name__ = str(bl.uuid)
        bl.lines.append('"""register this generator"""')
        bl.lines.append("import %s" % path)
        bl.lines.append("from agx.core.config import register_generator")
        bl.lines.append("register_generator(%s)" % path)
        f.insertfirst(bl)
        init[f.name] = f
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)')
예제 #19
0
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
예제 #20
0
def create_register_func(self, source, target):
    """Creates the register function.
    """
    if not token(str(source.uuid), True,
                 is_generator_egg=False).is_generator_egg:
        return

    init = read_target_node(source, target.target)['__init__.py']
    fname = 'register'
    path = dotted_path(source)
    if fname not in [f.functionname for f in init.functions()]:
        f = Function()
        f.functionname = fname
        f.__name__ = str(f.uuid)
        bl = Block()
        bl.__name__ = str(bl.uuid)
        bl.lines.append('"""register this generator"""')
        bl.lines.append("import %s" % path)
        bl.lines.append("from agx.core.config import register_generator")
        bl.lines.append("register_generator(%s)" % path)
        f.insertfirst(bl)
        init[f.name] = f
예제 #21
0
def collectpermissions(self, source, target):
    permid = dotted_path(source.supplier)
    id = TaggedValues(source.supplier).direct('id', 'zca:permission')
    if not id is UNSET:
        permid = id
    tok = token(str(source.client.uuid), True, permission=permid)
예제 #22
0
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)
예제 #23
0
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