[Modeling-cvs] ProjectModeling/Modeling/ModelMasons ModelMason.py,1.5,1.6 PyModelMason.py,1.6,1.7
Status: Abandoned
Brought to you by:
sbigaret
From: <sbi...@us...> - 2003-04-20 14:16:52
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons In directory sc8-pr-cvs1:/tmp/cvs-serv28351/ModelMasons Modified Files: ModelMason.py PyModelMason.py Log Message: Refactored ModelMasons: ModelMason and PyModelMason are now clearer than they used to be. See PyModelMason for an example of use. Fixed: bug #710817 Index: ModelMason.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons/ModelMason.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** ModelMason.py 4 Feb 2003 08:06:35 -0000 1.5 --- ModelMason.py 20 Apr 2003 14:16:42 -0000 1.6 *************** *** 26,30 **** ModelMason ! Documentation forthcoming CVS information --- 26,30 ---- ModelMason ! Documentation forthcoming. See PyModelMason for an example of use. CVS information *************** *** 40,86 **** class ModelMason: - _bricksBaseDirectory=None ! def __init__(self, model, rootPath, verbose_mode=0): """ Initializes the ModelMason so that the built files are based on the supplied model. - The following instance variable must be initialized: - - - self._bricksBaseDirectory: where the bricks should be found - - - self._productBaseDirectory: where to put the generated files - - Subclasses may decide to supply a default value for the product's base - directory when parameter 'rootPath' is not supplied. - Parameters: ! model -- a Modeling.Model instance ! ! rootPath -- the directory in which the generated files should be dropped ! ! verbose_mode -- if set to a true value, the building process will log ! some informations in sys.stderr while generating the files ! """ ! self._model = model ! self._productBaseDirectory = rootPath ! self._verbose_mode=verbose_mode ! def bricksBaseDirectory(self): """ ! ! Returns the directory where the bricks/templates can be found. Any ! statement which generates files shouldn't put these anywhere but inside ! the directory path returned by this method. - Default implementation returns self._bricksBaseDirectory ; this variable - shouldn't be directly manipulated, rather it should be set at - initialization time and accessed through this method. - """ - return self._bricksBaseDirectory - def fullPathForBrick(self, aBrick): """ --- 40,79 ---- class ModelMason: ! def __init__(self, model, rootPath, concreteBuilder, bricksDir, ! verbose_mode=0): """ Initializes the ModelMason so that the built files are based on the supplied model. Parameters: ! model -- the model from which the generated python package should be ! generated ! rootPath -- path of a directory where the corresponding package should ! be dropped ! ! concreteBuilder -- the module containing the concrete builder ! ! bricksDir -- path for the directory containing the templates, relative ! to the path where the module of 'concreteBuilder' is stored ! ! verbose_mode -- whether logging is activated or not, see log(). When ! true, the building process logs some informations in sys.stderr while ! generating the files ! Subclasses may decide to supply a default value for the product's base ! directory when parameter 'rootPath' is not supplied. """ ! self.model = model ! self.rootPath=rootPath ! packagePathList=[rootPath] ! packagePathList.extend(string.split(self.model.packageName(), '.')) ! self.packagePath = apply(os.path.join, packagePathList) ! self.bricksPath=os.path.join(os.path.dirname(concreteBuilder.__file__), ! bricksDir) ! self.verbose_mode=verbose_mode def fullPathForBrick(self, aBrick): """ *************** *** 88,120 **** This is the preferred way for accessing bricks """ ! return os.path.join(self.bricksBaseDirectory(), aBrick) - def productBaseDirectory(self): - """ - Returns the directory where the generated file should be put. Any methods - manipulating templates must search them whithin the directory returned - by this method. - - Default implementation returns self._productBaseDirectory ; this variable - shouldn't be directly manipulated, rather it should be set at - initialization time and accessed through this method --since subclasses - may decide to return a dynamically computed value for this instead of a - value predetermined at initialization time. - """ - return self._productBaseDirectory - def fullPathForGeneratedFile(self, filename): "Returns the full path for a given generated filename." ! return os.path.join(self.productBaseDirectory(), filename) ! def createEmptyFile(self,filename): """ Create the empty file 'filename' ; the filename is a relative path (relative to 'self.productBaseDirectory()') """ ! f = open(self.fullPathForGeneratedFile(filename),"w") f.close() ! def copyFile(self, templateFilename, destinationFilename): """ Copy the template file to the destination file, unchanged. Both filenames --- 81,105 ---- This is the preferred way for accessing bricks """ ! return os.path.join(self.bricksPath(), aBrick) def fullPathForGeneratedFile(self, filename): "Returns the full path for a given generated filename." ! return os.path.join(self.packagePath, filename) ! def createEmptyFile(self,filename,overwrite=0): """ Create the empty file 'filename' ; the filename is a relative path (relative to 'self.productBaseDirectory()') """ ! if not os.path.isabs(filename): ! filename=self.fullPathForGeneratedFile(filename) ! if not overwrite and os.path.exists(filename): ! self.log('File %s exists, skipping\n'%filename) ! return ! self.log('Creating empty file %s\n'%filename) ! f = open(filename,"w") f.close() ! def copyFile(self, templateFilename, destinationFilename,overwrite=0): """ Copy the template file to the destination file, unchanged. Both filenames *************** *** 122,125 **** --- 107,116 ---- productBaseDirectory. """ + if not os.path.isabs(filename): + filename=self.fullPathForGeneratedFile(filename) + if not overwrite and os.path.exists(filename): + self.log('File %s exists, skipping\n'%filename) + return + self.log('Creating file %s\n'%destinationFilename) _f1 = open(self.fullPathForGeneratedFile(destinationFilename),'w') _f2 = open(self.fullPathForBrick(templateFilename),'r') *************** *** 128,168 **** _f2.close() ! def templateObjectForFile(self, templateFile, searchList=[]): """ Initializes a Template object from the supplied templateFile. Overrides this to perform any additional initializations for Templates, such as ! building a namespace/searchList for the template. ! Parameter 'templateFile' is a relative path: relative to the bricksBaseDir. Default implementation simply returns the Template object """ ! templateFile = self.fullPathForBrick(templateFile) ! ! templateObj = Template(file=templateFile, searchList=searchList) ! return templateObj - def createFileFromTemplateFile(self, templateFile, destFile, searchList=[]): - """ - Both filenames should be relative to, respectively, bricksBaseDirectory - and productBaseDirectory. - """ - if self._verbose_mode: sys.stderr.write(">> Generating %s..." % destFile) - destFile = self.fullPathForGeneratedFile(destFile) - f = open(destFile,'w') - f.write("%s" % self.templateObjectForFile(templateFile, - searchList=searchList)) - if self._verbose_mode: sys.stderr.write("Done\n") ! def createFileFromTemplate(self, template, destFile, searchList=[]): """ ! template: a Cheetah.Template object ! destFile: the destination file path, relative to productBaseDirectory """ ! if self._verbose_mode: sys.stderr.write(">> Generating %s... " % destFile) destFile = self.fullPathForGeneratedFile(destFile) f = open(destFile,'w') ! f.write("%s" % self.templateObjectForTemplate(template, ! searchList=searchList)) ! if self._verbose_mode: sys.stderr.write("Done\n") def build(self): --- 119,169 ---- _f2.close() ! _marker=[] ! def templateObjectForTemplate(self, template, namespace=_marker): """ Initializes a Template object from the supplied templateFile. Overrides this to perform any additional initializations for Templates, such as ! building a namespace for the template. ! Parameters: ! ! template -- a Cheetah.Template object ! ! namespace -- the template will use that namespace. If ommitted, it ! defaults to self.tmpl_namespace() ! Default implementation simply returns the Template object """ ! if namespace is self._marker: namespace=self.tmpl_namespace() ! namespace=self.fix_tmpl_namespace(namespace) ! #for dict in namespace: ! for key in namespace.keys(): ! setattr(template, key, namespace[key]) ! return template ! def createFileFromTemplate(self, template, destFile, namespace=_marker, ! overwrite=0): """ ! Parameters: ! ! template -- a Cheetah.Template object ! ! namespace -- the template will use that namespace. If ommitted, it ! defaults to self.tmpl_namespace() ! ! destFile -- the destination file path, relative to productBaseDirectory ! """ ! if namespace is self._marker: namespace=self.tmpl_namespace() ! namespace=self.fix_tmpl_namespace(namespace) destFile = self.fullPathForGeneratedFile(destFile) + if not overwrite and os.path.exists(destFile): + self.log("File %s exists, skipping\n"%destFile) + return + self.log("Generating %s... " % destFile) f = open(destFile,'w') ! f.write("%s"%self.templateObjectForTemplate(template,namespace=namespace)) ! self.log("done\n") def build(self): *************** *** 172,174 **** """ pass ! --- 173,256 ---- """ pass ! ! ! def fix_tmpl_namespace(self, namespace): ! """ ! Internally used to make any values in the namespace callable --if a value ! is an instance or a python object, it is by a lambda function returning ! the value. We make this because Cheetah sometimes requires a callable. ! """ ! # builtin callable() does not work on instances derived from ! # ZODB.Persistent, we use that one instead ! def _callable(o): ! if hasattr(o,'__class__'): return hasattr(o,'__call__') ! return callable(o) ! d={} ! for k,v in namespace.items(): ! if _callable(v): d[k]=v ! else: d[k]=lambda p=v: p ! return d ! ! def tmpl_namespace(self): ! """ ! This method returns a dictionary used by templates to search for specific ! values. ! ! Default implementation returns:: ! ! {'model': self.model} ! ! Subclasses override this method to provide their own namespace ! """ ! return {'model': self.model} ! ! def build_package(self): ! """ ! Creates all the necessary directories for the package, which can be ! something like A.B.C.MyPackage. Creates an empty '__init__.py' in each ! sub-directories if needed: existing __init__.py are not overwritten. ! """ ! currentPath=self.rootPath ! packList=[] ! for pack in string.split(self.model.packageName(), '.')[:-1]: ! currentPath=os.path.join(currentPath, pack) ! self.log('Creating directory %s... '%currentPath) ! try: ! os.mkdir(currentPath) ! except: self.log('no\n') ! else: self.log('ok\n') ! ! init=os.path.join(currentPath, '__init__.py') ! if os.path.exists(init): ! self.log('%s exists, skipping\n'%init) ! else: ! self.log('Creating %s\n'%init) ! f=open(init,'w') ; f.close() ! ! # Last, create self.packagePath ! self.log('Creating directory %s... '%self.packagePath) ! try: ! os.mkdir(self.packagePath) ! except: self.log('no\n') ! else: self.log('ok\n') ! ! def log(self, msg): ! "Logs the msg to stderr if self.verbose_mode is true" ! if self.verbose_mode: ! sys.stderr.write(msg) ! ! ! def entitiesSet(self): ! """ ! Returns a list of list of entities, where Entities in the same list share ! the same 'moduleName' ! """ ! d={} ! for entity in self.model.entities(): ! moduleName=entity.moduleName() ! if d.get(moduleName): ! d[moduleName].append(entity) ! else: d[moduleName]=[entity] ! ! return d.values() ! Index: PyModelMason.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons/PyModelMason.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** PyModelMason.py 4 Feb 2003 08:08:28 -0000 1.6 --- PyModelMason.py 20 Apr 2003 14:16:43 -0000 1.7 *************** *** 48,171 **** supplied model. """ - self._model = model - self._verbose_mode=verbose_mode - self._rootPath=_path = rootPath - packagePath=apply(os.path.join, string.split(model.packageName(), '.')) - self._productBaseDirectory = os.path.join(_path,"%s/" %packagePath) import Modeling ! self._bricksBaseDirectory = os.path.join( ! os.path.dirname(Modeling.ModelMasons.PyModelMason.__file__), ! "Python_bricks/") ! ! # ! packList=[] ! for pack in string.split(self._model.packageName(), '.'): ! packList.append(pack) ! packagePath=apply(os.path.join, packList) ! self._productBaseDirectory=os.path.join(self._rootPath,"%s/" %packagePath) ! ! ! def templateObjectForFile(self,templateFile, searchList=[]): ! """ ! Overrides ModelMason implementation so that the namespace passed to the ! Template object contains: self, an Entity, a Model and a Relationship ! """ ! templateFile = self.fullPathForBrick(templateFile) ! ! # The following lambda forms are needed since the Cheetah framework ! # sometimes really wants callable objects. This obviously solves the pb. ! if not searchList: ! _self = lambda p=self: p ! entities = lambda p=self._entities: p ! model = lambda p=self._model: p ! nameSpace = {'myself': _self, ! 'model' : model, ! 'entities': entities, ! } ! searchList=[nameSpace] ! templateObj = Template(file=templateFile, searchList=searchList) ! return templateObj ! def templateObjectForTemplate(self,template, searchList=[]): """ ! Overrides ModelMason implementation so that the namespace passed to the ! Template object contains: self, an Entity, a Model and a Relationship """ ! if not searchList: ! _self = lambda p=self: p ! entities = lambda p=self._entities: p ! model = lambda p=self._model: p ! nameSpace = {'myself': _self, ! 'model' : model, ! 'entities': entities, ! } ! searchList=[nameSpace] ! for dict in searchList: ! for key in dict.keys(): ! setattr(template, key, dict[key]) ! return template def build(self): "-" ! try: ! packagePath='' ! packList=[] ! for pack in string.split(self._model.packageName(), '.'): ! packList.append(pack) ! packagePath=apply(os.path.join, packList) ! intermediate_dir=os.path.join(self._rootPath,"%s/" %packagePath) ! os.makedirs(intermediate_dir, 0700) ! self.createEmptyFile('__init__.py') ! ! #os.makedirs(self.productBaseDirectory(), 0700) ! self.createEmptyFile("TODO.txt") ! self.createEmptyFile("README.txt") ! self.createEmptyFile("VERSION.txt") ! self.createEmptyFile("INSTALL.txt") ! self.createEmptyFile("DEPENDENCIES.txt") ! except OSError: ! pass ! ! # quick and DIRTY ! self._entities=[]#=self._model.entities()[0] ! modelFileName='model_'+self._model.name()+'.xml' ! self._model.saveModelAsXMLFile(self.fullPathForGeneratedFile(modelFileName)) ! encoding='iso-8859-1' ! doc=self._model.getXMLDOM(encoding=encoding) ! from xml.dom.ext import PrettyPrint ! import StringIO ! _strIO=StringIO.StringIO() ! PrettyPrint(doc, stream=_strIO, encoding=encoding) ! modelStr=_strIO.getvalue() ! _strIO.close() self.createFileFromTemplate(model.model(), ! "model_%s.py"%self._model.name(), ! searchList=[{'model_str':modelStr}]) del modelStr ! self.createFileFromTemplate(init.init(),"__init__.py") self.createFileFromTemplate(setup_tmpl.setup_tmpl(),"setup.py") ! # Attention : self._entity is used by method createFileFromTemplate. for self._entities in self.entitiesSet(): - #l_class_name = string.lower(self._entity.className()) module_name = self._entities[0].moduleName() self.createFileFromTemplate(module.module(),"%s.py" % module_name) - def entitiesSet(self): - """ - Returns a list of list of entities, where Entities in the same list share - the same 'moduleName' - """ - d={} - for entity in self._model.entities(): - moduleName=entity.moduleName() - if d.get(moduleName): - d[moduleName].append(entity) - else: d[moduleName]=[entity] - - return d.values() - - --- 48,106 ---- supplied model. """ import Modeling ! ModelMason.__init__(self, model, rootPath, ! Modeling.ModelMasons.PyModelMason, 'Python_bricks', ! verbose_mode) ! self._entities=[] # used during build ! def tmpl_namespace(self): """ ! Namespace for templates: contains keys 'myself', 'model' and 'entities' ! NB: 'entities' is set during build(), when generating modules. """ ! nameSpace = {'myself': self, ! 'model' : self.model, ! 'entities': self._entities, ! } ! return nameSpace def build(self): "-" ! # Build as many directories with __init__.py as needed ! self.build_package() ! # empty files ! self.createEmptyFile("TODO.txt",overwrite=0) ! self.createEmptyFile("README.txt",overwrite=0) ! self.createEmptyFile("VERSION.txt",overwrite=0) ! self.createEmptyFile("INSTALL.txt",overwrite=0) ! self.createEmptyFile("DEPENDENCIES.txt",overwrite=0) ! ! # model_<modelName>.xml ! modelFileName='model_'+self.model.name()+'.xml' ! modelFileName=self.fullPathForGeneratedFile(modelFileName) ! self.log('Generating %s... '%modelFileName) ! self.model.saveModelAsXMLFile(modelFileName) ! self.log('done\n') + # model_<modelName>.py + xml=open(modelFileName) + modelStr=xml.read() + xml.close() self.createFileFromTemplate(model.model(), ! "model_%s.py"%self.model.name(), ! namespace={'model_str':modelStr}, ! overwrite=1) del modelStr ! ! # package's __init__.py ! self.createFileFromTemplate(init.init(),"__init__.py",overwrite=0) ! # setup.py self.createFileFromTemplate(setup_tmpl.setup_tmpl(),"setup.py") ! # modules for self._entities in self.entitiesSet(): module_name = self._entities[0].moduleName() self.createFileFromTemplate(module.module(),"%s.py" % module_name) |