def finalize_handler(self, source, target): func = read_target_node(source, target.target) tok = token(str(source.uuid), True, scopes=[], generators=[]) tgv = TaggedValues(source) order = tgv.direct('order', 'generator:handler', None) func.args = ['self', 'source', 'target'] # ...or by dependency on a generator if tok.generators: generatornames = [g.name for g in tok.generators] else: # the generator can be defined by tgv generatornames = [tgv.direct('generator', 'generator:handler', None)] for scope in tok.scopes: stgv = TaggedValues(scope) scopename = stgv.direct('scopename', 'generator:class_scope', None) or \ stgv.direct('scopename', 'generator:simple_scope', None) or \ scope.name.lower() transform = stgv.direct('transform', 'generator:class_scope', None) or \ stgv.direct('transform', 'generator:class_scope', None) or \ 'uml2fs' transformarg = "'%s'" % transform scopenamearg = "'%s'" % scopename decfound = None for generatorname in generatornames: generatornamearg = "'%s'" % generatorname # find the dec for dec in func.decorators(): if dec.args[1] == transformarg \ and dec.args[2] == generatornamearg \ and dec.args[3] == scopenamearg: decfound = dec if decfound: dec = decfound # if not found make it else: dec = Decorator() dec.decoratorname = 'handler' dec.__name__ = dec.uuid func.insertfirst(dec) # define the args for the generator dec.args = [ "'%s'" % source.name, transformarg, generatornamearg, scopenamearg ] if not order is None: dec.kwargs['order'] = order
def 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 generatescopeclass(self, source, target): """Generates scope classes. """ if source.stereotype('pyegg:stub'): return targetclass = read_target_node(source, target.target) module = targetclass.parent methods = [m for m in targetclass.functions()] methnames = [m.functionname for m in methods] methname = '__call__' tgv = TaggedValues(source) stereotypes = tgv.direct('stereotypes', 'generator:class_scope', None) or \ tgv.direct('stereotypes', 'generator:simple_scope', None) or [] transform = tgv.direct('transform', 'generator:class_scope', None) or \ tgv.direct('transform', 'generator:simple_scope', None) or \ 'uml2fs' if stereotypes: for st in stereotypes: if ':' not in st: msg = 'you have to specify the stereotype in the form ' + \ '"namespace:stereotype", but forgot the namespace ' + \ '(scope %s, stereotype %s)' % (source.name, st) raise ValueError(msg) #if not stereotypes: # msg = 'scope %s must have a stereotype attribute!!' % source.name # raise ValueError(msg) if 'Scope' not in targetclass.bases: targetclass.bases.append('Scope') if methname not in methnames: f = Function() f.functionname = methname f.args = ['self', 'node'] f.__name__ = str(f.uuid) targetclass.insertfirst(f) bl = Block() bl.__name__ = str(bl.uuid) conds = [ "node.stereotype('%s') is not None" % st for st in stereotypes ] cond = ' or '.join(conds) bl.lines.append("return %s" % cond) f.insertfirst(bl)
def gsdynamicview(self, source, target): """Add view method to FTI's of all dependent content types. """ if not source.supplier.stereotype('plone:content_type') \ or not source.client.stereotype('plone:dynamic_view'): return view = source.client content_type = source.supplier package = read_target_node(egg_source(content_type), target.target) default = package['profiles']['default'] full_name = type_id(content_type, target.target) name = '%s.xml' % full_name type_xml = default['types'][name] tgv = TaggedValues(view) viewname = tgv.direct('name', 'plone:dynamic_view', view.name) type_xml.params['ctype']['view_methods'].append(viewname)
def generate_vanilla_profile(self, source, target): egg = egg_source(source) if not is_generator_egg(egg): return tgv = TaggedValues(source) profilename = tgv.direct('name', 'generator:profile', source.name) basepath = os.path.dirname(agx.generator.generator.__file__) profilepath = os.path.join(basepath, 'resources', 'vanilla_profile') # read the model files model_di = open(os.path.join(profilepath, 'model.profile.di')).read() model_uml = open(os.path.join(profilepath, 'model.profile.uml')).read() model_notation = open(os.path.join(profilepath, 'model.profile.notation')).read() eggdir = read_target_node(egg_source(source), target.target) # create profiles dir if 'profiles' not in eggdir.keys(): profiles = Directory() profiles.__name__ = 'profiles' eggdir['profiles'] = profiles profiles = eggdir['profiles'] # add the model files with correct name and change the references if profilename + '.profile.di' not in profiles.keys(): ff = File() ff._data = model_di.replace('model.profile.notation', profilename + '.profile.notation') profiles[profilename + '.profile.di'] = ff if profilename + '.profile.uml' not in profiles.keys(): ff = File() ff._data = model_uml.replace('profilename_changeme', profilename) profiles[profilename + '.profile.uml'] = ff if profilename + '.profile.notation' not in profiles.keys(): ff = File() ff._data = model_notation.replace('model.profile.uml', profilename + '.profile.uml') profiles[profilename + '.profile.notation'] = ff
def 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_zcml(self, source, target): if source.stereotype('pyegg:stub'): return targetclass = read_target_node(source, target.target) module = targetclass.parent blocks = module.blocks() egg = egg_source(source) eggtarget = read_target_node(egg, target.target) tgv = TaggedValues(source) #name = tgv.direct('name', 'generator:profile', None) set_zcml_directive(eggtarget, 'configure.zcml', 'utility', 'name', implicit_dotted_path(source), provides="agx.core.interfaces.IProfileLocation", component=implicit_dotted_path(source))
def createschemaclass(self, source, target): """create the schema interface class on the fly. """ klass = read_target_node(source, target.target) module = klass.parent schemaclassname = 'I' + klass.classname found = module.classes(schemaclassname) if found: schemaclass = found[0] else: schemaclass = python.Class(classname=schemaclassname) schemaclass.__name__ = schemaclass.uuid module.insertbefore(schemaclass, klass) # expose it in __init__ imp = Imports(module.parent['__init__.py']) imp.set(class_base_name(schemaclass), [[schemaclassname, None]]) # mark the content class for deletion if not needed createit = TaggedValues(source).direct('create_contentclass', 'plone:content_type', False) if not (createit or klass.functions()): token(str(klass.uuid), True, dont_generate=True)
def zcviewdepcollect(self, source, target): """Collect all view dependencies """ scope = getUtility(IScope, 'uml2fs.viewclass') pack = source.parent dep = source context = source.supplier view = source.client if not scope(view): #we are only interested in views! return target = read_target_node(pack, target.target) targetcontext = read_target_node(context, target) targetview = read_target_node(view, target) tok = token(str(view.uuid), True, browserpages=[]) contexttok = token(str(context.uuid), True, fullpath=None) if targetcontext: try: dont_generate = token(str(targetcontext.uuid), False, dont_generate=False).dont_generate if dont_generate: iface = targetcontext.parent.classes( 'I' + targetcontext.classname)[0] contexttok.fullpath = class_full_name(iface) else: contexttok.fullpath = class_full_name(targetcontext) # dont_generate doesnt seem to be defined here except ComponentLookupError: pass # its a stub else: contexttok.fullpath = '.'.join([ TaggedValues(context).direct('import', 'pyegg:stub'), context.name ]) if isinstance(target, python.Module): targetdir = target.parent else: targetdir = target tok.browserpages.append(dep)
def plonebrowserview(self, source, target): view = source if view.stereotype('pyegg:function'): # XXX: <<function>> <<adapter>> on class return tok = token(str(view.uuid), True, browserpages=[]) pack = source.parent target = read_target_node(pack, target.target) targetclass = read_target_node(view, target) if isinstance(target, python.Module): targetdir = target.parent else: targetdir = target path = targetdir.path path.append('browser.zcml') fullpath = os.path.join(*path) if 'browser.zcml' not in targetdir: zcml = ZCMLFile(fullpath) zcml.nsmap['browser'] = 'http://namespaces.zope.org/browser' targetdir['browser.zcml'] = zcml else: zcml = targetdir['browser.zcml'] addZcmlRef(targetdir, zcml) targettok = token(str(targetclass.uuid), True, browserpages=[], provides=None) _for = [token(str(context.supplier.uuid), False).fullpath \ for context in tok.browserpages] or ['*'] classpath = class_full_name(targetclass) tgv = TaggedValues(view) # create the templates dir if 'templates' not in targetdir.keys(): targetdir['templates'] = Directory('templates') templates = targetdir['templates'] templates.factories['.pt'] = XMLTemplate #create the browser:page entries for bp in tok.browserpages or [None]: #name of view: if it should have a constant name, change the last param viewname = tgv.direct('name', 'plone:view', None) or \ tgv.direct('name', 'plone:dynamic_view', view.xminame.lower()) name_raw = tgv.direct('name', 'plone:view', None) or \ tgv.direct('name', 'plone:vdynamic_view', None) name = name_raw or view.xminame.lower() template_name_raw = tgv.direct('template_name', 'plone:view', None) or \ tgv.direct('template_name', 'plone:dynamic_view', None) template_name = template_name_raw or name + '.pt' permission = tgv.direct('permission', 'plone:view', None) or \ tgv.direct('permission', 'plone:dynamic_view', None) layer = tgv.direct('layer', 'plone:view', None) or \ tgv.direct('layer', 'plone:dynamic_view', None) if bp: bptgv = TaggedValues(bp) bptok = token(str(bp.supplier.uuid), False) _for = bptok.fullpath print 'xminame:', bp, bp.xminame # consider uuid as an unset name if bp.xminame is None or re.match( '[\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12}', bp.xminame): bpname = None else: bpname = bp.xminame.lower() if bp.xminame: viewname = bp.xminame viewname = bptgv.direct('name', 'plone:view', None) or \ bptgv.direct('name', 'plone:dynamic_view', viewname) name = bptgv.direct('name', 'plone:view', None) or \ bptgv.direct('name', 'plone:dynamic_view', bpname or name) # override template name template_name = bptgv.direct( 'template_name', 'plone:view', None) or \ bptgv.direct( 'template_name', 'plone:dynamic_view', None) or \ template_name_raw or name + '.pt' permission = bptgv.direct('permission', 'plone:view', None) or \ bptgv.direct('permission', 'plone:dynamic_view', permission) layer = bptgv.direct('layer', 'plone:view', None) or \ bptgv.direct('layer', 'plone:dynamic_view', layer) else: _for = '*' found_browserpages = zcml.filter(tag='browser:page', attr='name', value=viewname) browser = None templatepath = 'templates/' + template_name if found_browserpages: for br in found_browserpages: #check if it really matches if br.attrs.get('class') == classpath and \ _for == br.attrs['for']: browser = br break if not browser: browser = SimpleDirective(name='browser:page', parent=zcml) browser.attrs['for'] = _for if viewname and not viewname is UNSET: browser.attrs['name'] = viewname browser.attrs['class'] = classpath browser.attrs['template'] = templatepath browser.attrs['permission'] = permission or 'zope2.View' if layer: browser.attrs['layer'] = layer # spit out the page vanilla template if template_name not in templates.keys(): pt = XMLTemplate() templates[template_name] = pt # set template for viewtemplate pt.template = 'agx.generator.plone:templates/viewtemplate.pt'
def make_generators(self, source, target): if source.stereotype('pyegg:stub'): return egg = egg_source(source) eggtarget = read_target_node(egg, target.target) zcml = get_zcml(eggtarget, 'configure.zcml', nsmap={ None: 'http://namespaces.zope.org/zope', 'agx': 'http://namespaces.zope.org/agx' }) tgv = TaggedValues(source) # if transform isnt specified as tgv, get it from dependency relations to # other generators transform = tgv.direct('transform', 'generator:generator', None) if not transform: transforms = token(str(source.uuid), True, transforms=[]).transforms if len(transforms) > 1: msg = 'Currently only one transform per generator allowed (%s)' msg = msg % source.name raise ValueError(msg) elif len(transforms) == 1: transform = transforms[0].name if not transform: transform = 'uml2fs' # if depends isnt specified as tgv, get it from dependency relations to # transforms depend = tgv.direct('depends', 'generator:generator', None) if not depend: depends = token(str(source.uuid), True, depends_on=[]).depends_on if len(depends) > 1: msg = 'Currently only one depends per generator allowed (%s)' msg = msg % source.name raise ValueError(msg) elif len(depends) == 1: depend = depends[0].name if not depend: depend = 'NO' directives = zcml.filter(tag='agx:generator', attr='name') directive = None for d in directives: if d.attrs['name'] == source.name: directive = d break if not directive: directive = SimpleDirective(name='agx:generator', parent=zcml) directive.attrs['name'] = source.name directive.attrs['transform'] = transform directive.attrs['depends'] = depend set_zcml_directive(eggtarget, 'configure.zcml', 'agx:generator', 'name', source.name, overwrite=True)
def 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)