PyModelMason.py :  » Database » Modeling-Framework » Modeling-0.9 » Modeling » ModelMasons » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Database » Modeling Framework 
Modeling Framework » Modeling 0.9 » Modeling » ModelMasons » PyModelMason.py
# -*- coding: iso-8859-1 -*-
#-----------------------------------------------------------------------------
# Modeling Framework: an Object-Relational Bridge for python
#
# Copyright (c) 2001-2004 Sbastien Bigaret <sbigaret@users.sourceforge.net>
# All rights reserved.
#
# This file is part of the Modeling Framework.
#
# This code is distributed under a "3-clause BSD"-style license;
# see the LICENSE file for details.
#-----------------------------------------------------------------------------


"""
PyModelMason generates the python package, modules and classes described
in a model, ready to be used w/ the modeling framework.

Its templates are located in sub-package 'Python_bricks'. The generated code
is compatible with python v2.1 and v2.2.

Given a model, it can generate the appropriate python code in two different
ways: the flat, or 'compact' scheme, and the 'base' scheme.

The former one generates all files within a single directory (namely: in
package model.packageName()), none of which (except the models) can be
overwritten when the code is regenerated.

The so-called 'base' scheme adds a subpackage 'MDL' within the generated
package. All files within MDL/ are ALWAYS overwritten when the python code is
regenerated, while others (in the root package) are never overwritten if they
exist.  This is probably the one you want to use if your model changes often.
  
  CVS information

    $Id: PyModelMason.py 974 2006-02-26 14:06:07Z sbigaret $
  
"""
__version__='$Revision: 974 $'[11:-2]

import time, os, string, sys

from ModelMason import ModelMason
from Cheetah.Template import Template

from Python_bricks import init,init_base,model,base_module,module_base,module_compact,setup_tmpl

class InvalidModelError(Exception):
  "Raised by checkModelIsValid()"
  pass

def checkModelIsValid(model, generation_scheme):
  """
  Checks that the supplied model is valid for a given python-code generation
  scheme:

    - if 'generation_scheme' is 'compact', all models are valid,

    - if 'generation_scheme' is 'base', the model is valid iff a class/entity does
      not share the same module than any of its subclasses

  Parameters:

    model -- a instance of Modeling.Model.Model

    generation_scheme -- either 'compact' or 'base'

  Returns: None

  Raises InvalidModelError if the model is invalid.
  
  Note: this is NOT validation of the model itself (responsability of
        Modeling.ModelValidation)
  
  """
  if generation_scheme=='compact': return
  if generation_scheme=='base':
    
    # Build ordered list of entities
    oe=[]
    entities=list(model.entities())
    entities_processed=[]
    for entity in [e for e in entities if not e.parentEntity()]:
      oe.append(entity)
      entities_processed.append(entity.name())
      entities.remove(entity)
    while entities:
      es=[e for e in entities if e.parentEntity().name() in entities_processed]
      for entity in es:
        entities.remove(entity)
        entities_processed.append(entity.name())
        oe.append(entity)
    # check every parent against it subentities
    for e in oe:
      parent_moduleName=e.moduleName()
      subs=e.allSubEntities()
      for sub in subs:
        if sub.moduleName()==parent_moduleName:
          raise InvalidModelError, "Model is invalid wrt the 'base' generation scheme: entity '%s' and its subentity '%s' share the same moduleName.\nEither correct this or use the 'compact' generation scheme"%(e.name(), sub.name())
  else:
    raise ValueError, "Invalid value for 'generation_scheme' (%s), should be either 'base' or 'compact'"%use_scheme

class PyModelMason(ModelMason):
  "See the module's documentation for details"
  def __init__(self, model, pymodel_path, rootPath=None, verbose_mode=0,
               generation_scheme='compact', fake_mode=0):
    """
    Initializes the ModelMason so that the built files are based on the
    supplied model.

    :Parameters:
      - `model`: see ModelMason.__init__()
      - `pymodel_path`: 
      - `rootPath`: see ModelMason.__init__()
      - `verbode_mode`: see ModelMason.__init__()
      - `generation_scheme`: either string ``"compact"`` or ``"base"``
      - `fake_mode`: see ModelMason.__init__()
      
    """
    import Modeling
    if generation_scheme not in ('compact', 'base'):
      raise ValueError,"Parameter generation_scheme can be either 'compact' or 'base'"
    checkModelIsValid(model, generation_scheme)
    ModelMason.__init__(self, model, rootPath,
                        Modeling.ModelMasons.PyModelMason, 'Python_bricks',
                        verbose_mode, fake_mode)
    self._entities=[] # used during build
    self.generation_scheme=generation_scheme
    self.base_dir=generation_scheme=='base' and 'MDL' or ''
    self.pymodel_path=pymodel_path
    
  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,
                 'base_dir': self.base_dir,
                 'entitiesSet': self.entitiesSet,
                 }
    return nameSpace


  def build(self):
    "-"
    #-----------------------------------------------------------------
    def create_xmlmodel_files(self, xml_path, py_path):
      "Creates or overwrite the model (.xml and .py)"
      # model_<modelName>.xml
      if os.path.exists(xml_path):
        self.log('Overwriting %s'%xml_path)
      else:
        self.log('Generating %s'%xml_path)
      if not self.fake_mode:
        self.model.saveModelAsXMLFile(xml_path)
        self.log('... done')
      self.log('\n')
      # model_<modelName>.py
      if not self.fake_mode:
        xml=open(xml_path)
        modelStr=xml.read()
        xml.close()
      else:
        modelStr='fake'
      self.createFileFromTemplate(model.model(),
                                  py_path,
                                  namespace={'model_str':modelStr},
                                  overwrite=1)
      del modelStr
    #-----------------------------------------------------------------
    def create_pymodel_file(self, pymodel_path_ori, pymodel_path):
      "Creates or overwrite the pymodel"
      if os.path.exists(pymodel_path):
        self.log('Overwriting %s'%pymodel_path)
      else:
        self.log('Generating %s'%pymodel_path)
      if not self.fake_mode:
        import shutil
        shutil.copy(pymodel_path_ori, pymodel_path)
        self.log('... done')
      self.log('\n')
    #-----------------------------------------------------------------

    # 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)
  
    # package's __init__.py
    self.createFileFromTemplate(init.init(),"__init__.py",overwrite=0)
    # setup.py
    self.createFileFromTemplate(setup_tmpl.setup_tmpl(),"setup.py",overwrite=0)

    # COMPACT generation scheme
    if self.generation_scheme=='compact':
      if not self.pymodel_path:
        # Create model files (.xml/.py)
        xmlp=self.fullPathForGeneratedFile('model_'+self.model.name()+'.xml')
        pyp="model_%s.py"%self.model.name()
        create_xmlmodel_files(self, xmlp, pyp)
      else:
        basePath=self.fullPathForGeneratedFile(self.base_dir)
        create_pymodel_file(self,
                            self.pymodel_path,
                            os.path.join(basePath,
                                         "pymodel_%s.py"%self.model.name()))

      # modules
      for self._entities in self.entitiesSet():
        module_name = self._entities[0].moduleName()
        self.createFileFromTemplate(module_compact.module_compact(),
                                    "%s.py" % module_name,
                                    overwrite=0)
          
    # BASE generation scheme
    elif self.generation_scheme=='base':
      # create 'Base' and model files (.xml/.py)
      basePath=self.fullPathForGeneratedFile(self.base_dir)
      self.log("Creating directory %s"%basePath)
      if not self.fake_mode:
        try:
          os.mkdir(basePath)
        except: self.log('no')
        else:   self.log('ok')
      self.log('\n')
      self.createFileFromTemplate(init_base.init_base(),
                                  os.path.join(self.base_dir,"__init__.py"),
                                  overwrite=1)

      if not self.pymodel_path:
        create_xmlmodel_files(self,
                           os.path.join(basePath,
                                        'model_'+self.model.name()+'.xml'),
                           os.path.join(self.base_dir,
                                        "model_%s.py"%self.model.name()))
      else:
        create_pymodel_file(self,
                            self.pymodel_path,
                            os.path.join(basePath,
                                         "pymodel_%s.py"%self.model.name()))
 
      # modules
      for self._entities in self.entitiesSet():
        module_name = self._entities[0].moduleName()
        self.createFileFromTemplate(module_base.module_base(),
                                    "%s.py" % module_name,
                                    overwrite=0)
        self.createFileFromTemplate(base_module.base_module(),
                                    os.path.join(self.base_dir,
                                                 "%s.py" % module_name),
                                    overwrite=1)
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.