Changeset 8048


Ignore:
Timestamp:
06/01/12 13:34:40 (8 years ago)
Author:
mnagni
Message:

Now
1) does not generate classes which do not respect python syntax
2) transform the attributes name to a python complaint syntax (substitute an underscore)
3) better import of the externallyMapped classes

Still generate double (append a copy) to some classes.

Location:
mauRepo/xmi2sqlalchemy/trunk/src
Files:
1 added
11 edited

Legend:

Unmodified
Added
Removed
  • mauRepo/xmi2sqlalchemy/trunk/src/main/java/ndg/services/newmoon/velocity/python/GenerateClasses.java

    r8043 r8048  
    4444import org.apache.commons.collections.Closure; 
    4545import org.apache.velocity.context.Context; 
     46import org.slf4j.Logger; 
     47import org.slf4j.LoggerFactory; 
    4648 
    4749/** 
     
    5153public class GenerateClasses implements Closure { 
    5254         
     55        private final Logger logger = LoggerFactory.getLogger(GenerateClasses.class); 
    5356        private final static String templateFile = "velocity/python/pythonClass.vm"; 
    5457        private List<NewmoonException> exceptions = new ArrayList<NewmoonException>(); 
     
    6871                classModel, imports, stereotype, attributes 
    6972        }; 
     73         
    7074         
    7175        /* (non-Javadoc) 
     
    98102        private void writeAll(ClassModel cm) throws IOException { 
    99103                        PythonClassModel pcm = new PythonClassModel(cm); 
    100                         if (pcm.skipIt()) 
    101                                 return;  
     104                        if (pcm.skipIt()) { 
     105                                logger.info("Skipping python class generation for " + pcm.toString()); 
     106                                return; 
     107                        } 
     108                                            
    102109                        vcontext.put(CONTEXT.imports.name(), pcm.generateImports());                     
    103110                        vcontext.put(CONTEXT.stereotype.name(), pcm.getStereotypeImplementation()); 
  • mauRepo/xmi2sqlalchemy/trunk/src/main/java/ndg/services/newmoon/velocity/python/GenerateModuleHelper.java

    r8009 r8048  
    3535import java.io.FileWriter; 
    3636import java.io.IOException; 
    37 import java.util.Properties; 
    3837 
    3938import ndg.services.newmoon.UMLElementsArchive; 
    40 import ndg.services.newmoon.UMLElementsArchive.PropertyMap; 
    4139import ndg.services.newmoon.collect.ClassModel.STEREOTYPE; 
    4240import ndg.services.newmoon.xmiModel.UMLClass; 
    43 import ndg.services.newmoon.xmiModel.UMLClassDataType; 
    4441import ndg.services.newmoon.xmiModel.UMLModel; 
    45 import ndg.services.newmoon.xmiModel.UMLPackage; 
    4642import ndg.services.newmoon.xmiModel.UMLStereotype; 
    4743import ndg.services.newmoon.xmiModel.UML_ID; 
     
    4945 
    5046import org.apache.commons.io.FileUtils; 
    51 import org.apache.commons.io.IOUtils; 
    5247import org.apache.commons.lang.StringUtils; 
    5348import org.slf4j.Logger; 
     
    5954 */ 
    6055public class GenerateModuleHelper { 
    61          
    62         private static Properties xmiToSQLMaps = null; 
    6356 
    6457        private final File baseDir; 
     
    7467                this.baseDir = baseDir;                  
    7568        } 
    76          
    77          
    7869         
    7970        /** 
     
    9182                        logger.debug(content); 
    9283        } 
    93          
    94  
    95         public static Properties getXMIClassToSQLMap() { 
    96                 if (xmiToSQLMaps == null) 
    97                         xmiToSQLMaps = UMLElementsArchive.getInstance().loadProperties(PropertyMap.XMI_TO_SQL_MAP); 
    98                 return xmiToSQLMaps;             
    99         } 
    100          
    101         public static String encodeUMLPackageName(UMLPackage umlPackage) { 
    102                 String path = StringUtils.replaceChars(umlPackage.toString(), ' ', '_').toLowerCase(); 
    103                 path = StringUtils.replaceChars(path, '.', File.separatorChar).toLowerCase(); 
    104                 return StringUtils.replaceChars(path, ':', '_').toLowerCase(); 
    105         } 
    106          
    107         public static boolean skipElement(UMLClassDataType clazz){ 
    108                 return getXMIClassToSQLMap().containsKey(clazz.getName())  
    109                                 || clazz.getName().equals("EARootClass"); 
    110         } 
    111          
    112  
    11384         
    11485        public boolean isEnumLike(UMLClass umlClass) { 
  • mauRepo/xmi2sqlalchemy/trunk/src/main/java/ndg/services/newmoon/velocity/python/GenerateTables.java

    r8041 r8048  
    4646import ndg.services.newmoon.velocity.python.support.AssociationTable; 
    4747import ndg.services.newmoon.velocity.python.support.ForeignKey; 
    48 import ndg.services.newmoon.velocity.python.support.ImportCollector; 
    4948import ndg.services.newmoon.velocity.python.support.OverriddenAttribute; 
    5049import ndg.services.newmoon.velocity.python.support.Relationship; 
  • mauRepo/xmi2sqlalchemy/trunk/src/main/java/ndg/services/newmoon/velocity/python/GenerateTablesClosure.java

    r8040 r8048  
    155155                                        || am.isVoidable(); 
    156156 
    157                         Relationship rl = new Relationship(parent, child, am.getName(), nullable, am.hasMultiplicity()); 
     157                        Relationship rl = new Relationship(parent, child, NmVelocityHelper.checkName(am.getName()), nullable, am.hasMultiplicity()); 
    158158 
    159159                        if (am.hasMultiplicity() && parent.equals(child)) { 
     
    206206                return (classModel.isCodeList()  
    207207                                || classModel.isEnumeration() 
    208                                 || checkIfIsPrimitiveAttribute(classModel)); 
    209         } 
    210  
    211         private boolean checkIfIsPrimitiveAttribute(ClassModel classModel) { 
    212                 return GenerateModuleHelper.getXMIClassToSQLMap().containsKey(classModel.getAssociatedClass().getName()); 
    213         } 
     208                                || NmVelocityHelper.isExternallyMapped(classModel.getAssociatedClass().getName())); 
     209        } 
     210 
     211 
    214212         
    215213        private boolean tableModelExists(ClassModel classModel) { 
  • mauRepo/xmi2sqlalchemy/trunk/src/main/java/ndg/services/newmoon/velocity/python/NmVelocityHelper.java

    r8043 r8048  
    3232package ndg.services.newmoon.velocity.python; 
    3333 
    34 import ndg.services.newmoon.collect.AttributeModel; 
     34import java.util.HashSet; 
     35import java.util.Properties; 
     36import java.util.Set; 
     37 
     38import ndg.services.newmoon.UMLElementsArchive; 
     39import ndg.services.newmoon.UMLElementsArchive.PropertyMap; 
     40 
     41import org.apache.commons.collections.CollectionUtils; 
     42import org.apache.commons.lang.StringUtils; 
    3543 
    3644/** 
     
    4149public class NmVelocityHelper { 
    4250 
    43         public boolean attributeHasMultiplicity(AttributeModel am) { 
    44                 return am != null ? am.hasMultiplicity() : false;        
    45         }   
     51        private static Properties xmiToSQLMaps = null; 
     52         
     53        private static final Set<String> pythonKeywordSet = new HashSet<String>(); 
     54         
     55        private static final String pythonKeyword = "and, del, from, not, while, " + 
     56                        "as, elif, global, or, with," + 
     57                        "assert, else, if, pass, yield," + 
     58                        "break, except, import, print," + 
     59                        "class, exec, in, raise," + 
     60                        "continue, finally, is, return," + 
     61                        "def, for, lambda, try"; 
     62         
     63        /** 
     64         * Checks is a given string is a python keyword   
     65         */ 
     66        public static String checkName(String name) { 
     67                if (CollectionUtils.isEmpty(pythonKeywordSet)) { 
     68                        String[] keys = StringUtils.split(pythonKeyword, ","); 
     69                        keys = StringUtils.stripAll(keys); 
     70                        CollectionUtils.addAll(pythonKeywordSet, keys); 
     71                } 
     72                return pythonKeyword.contains(name) ? name + "_" : name; 
     73        } 
     74         
     75        public static boolean isValidPythonName(String text) { 
     76                return StringUtils.containsNone(text, "[]<>.,*/|\\@:;+-#!%^£$()"); 
     77        }  
     78         
     79        /** 
     80         * Checks if the given class name is mapped by {@link PropertyMap.XMI_TO_SQL_MAP} 
     81         * @param className a class name 
     82         * @return <code>true</code> if the internal map has a key with such class name,  
     83         * <code>false</code> otherwise  
     84         **/ 
     85        public static boolean isExternallyMapped(String className) { 
     86                return getXMIToSQL().containsKey(className); 
     87        } 
     88         
     89        /** 
     90         * Returns an array containg on the first element the name of the package from 
     91         * where import and on the second the name of which class import 
     92         * @param className a class name 
     93         * @return a two elements array, <code>null</code> if {@link #isExternallyMapped(String)} returns <code>false</code>  
     94         * */ 
     95        public static String[] getMappedImportImport(String className) { 
     96                String[] ret = null; 
     97                if (isExternallyMapped(className)) { 
     98                        ret = new String[2]; 
     99                        String clazz = getXMIToSQL().getProperty(className); 
     100                        ret[0] = StringUtils.substringBeforeLast(clazz, "."); 
     101                        ret[1] = StringUtils.substringAfterLast(clazz, "."); 
     102                }  
     103                return ret; 
     104        } 
     105         
     106        public static String getMappedClass(String className) { 
     107                String[] ret = getMappedImportImport(className); 
     108                if (ret != null) {                       
     109                        return ret[1]; 
     110                }  
     111                return className; 
     112        }        
     113         
     114        /** 
     115         * Transforms a name in a python lexically correct form. 
     116         * This is done replacing the illegal character with an underscore ('_').  
     117         * Characted case is not changed. The list of replacements is 
     118         *  
     119         * <ul> 
     120         * <li>space</li> 
     121         * <li>-</li> 
     122         * <li>(</li> 
     123         * <li>)</li>  
     124         * </ul> 
     125         * @param text the name to transform 
     126         * @return the tranformed name 
     127         **/ 
     128        public static String transformToPythonName(String text) { 
     129                String trans = StringUtils.replaceChars(text, '-', '_').toLowerCase(); 
     130                 trans = StringUtils.replaceChars(trans, ')', '_').toLowerCase(); 
     131                 trans = StringUtils.replaceChars(trans, '(', '_').toLowerCase(); 
     132                return StringUtils.replaceChars(trans, ' ', '_'); 
     133        }        
     134         
     135        /** 
     136        public static String encodeUMLPackageName(UMLPackage umlPackage) { 
     137                String path = StringUtils.replaceChars(umlPackage.toString(), ' ', '_').toLowerCase(); 
     138                path = StringUtils.replaceChars(path, '.', File.separatorChar).toLowerCase(); 
     139                return StringUtils.replaceChars(path, ':', '_').toLowerCase(); 
     140        } 
     141        */ 
     142        private static Properties getXMIToSQL() { 
     143                if (xmiToSQLMaps == null) 
     144                        xmiToSQLMaps = UMLElementsArchive.getInstance().loadProperties(PropertyMap.XMI_TO_SQL_MAP); 
     145                return xmiToSQLMaps;             
     146        } 
    46147} 
  • mauRepo/xmi2sqlalchemy/trunk/src/main/java/ndg/services/newmoon/velocity/python/PythonAttributeModel.java

    r8043 r8048  
    6060 
    6161        /** 
     62         * @return the attributeName 
     63         */ 
     64        @Override 
     65        public String getName() { 
     66                return NmVelocityHelper.checkName(super.getName()); 
     67        }        
     68         
     69        /** 
    6270         * @return the parentName 
    6371         */ 
     
    7280                return typeName; 
    7381        } 
     82 
     83        /* (non-Javadoc) 
     84         * @see java.lang.Object#hashCode() 
     85         */ 
     86        @Override 
     87        public int hashCode() { 
     88                final int prime = 31; 
     89                int result = (getName() == null) ? 0 : getName().hashCode(); 
     90                result = prime * result; 
     91                return result; 
     92        } 
     93 
     94        /* (non-Javadoc) 
     95         * @see java.lang.Object#equals(java.lang.Object) 
     96         */ 
     97        @Override 
     98        public boolean equals(Object obj) { 
     99                if (this == obj) 
     100                        return true; 
     101                if (getClass() != obj.getClass()) 
     102                        return false; 
     103                PythonAttributeModel other = (PythonAttributeModel) obj;                 
     104                if (getName() == null) { 
     105                        if (other.getName() != null) 
     106                                return false; 
     107                } else if (!getName().equals(other.getName())) 
     108                        return false; 
     109                return true; 
     110        } 
    74111} 
  • mauRepo/xmi2sqlalchemy/trunk/src/main/java/ndg/services/newmoon/velocity/python/PythonClassModel.java

    r8043 r8048  
    6363                this.getAttributeModel().addAll(cm.getAttributeModel()); 
    6464        } 
    65          
     65          
    6666        public boolean skipIt() { 
    6767                return this.getAssociatedClass().getClass().equals(ASEnumeration.class)  
    6868                                || this.getAssociatedClass().getClass().equals(ASCodeList.class) 
    69                                 || this.getAssociatedClass().getClass().equals(ASUnion.class); 
     69                                || this.getAssociatedClass().getClass().equals(ASUnion.class) 
     70                                || !validateClass(); 
     71        } 
     72         
     73        private boolean validateClass() { 
     74                for (ClassModel cm : getParents()) { 
     75                        if (!NmVelocityHelper.isValidPythonName(cm.getAssociatedClass().getName())) { 
     76                                return false; 
     77                        } 
     78                } 
     79                return NmVelocityHelper.isValidPythonName(this.getAssociatedClass().getName()); 
    7080        } 
    7181         
     
    90100                return closure.getImportMap(); 
    91101        }                
    92          
     102 
     103        /* 
    93104        private void importInheritedTypes(ClassModel classModel, List toImport) { 
    94105                if (!CollectionUtils.isEmpty(classModel.getParents())) { 
     
    96107                                importInheritedTypes(cm, toImport); 
    97108                        } 
    98                 } 
    99                          
     109                }                
    100110                CollectionUtils.addAll(toImport, classModel.getAttributeModel().iterator()); 
    101111        } 
     112        */ 
    102113         
    103114        public UMLClass getStereotypeImplementation() { 
     
    110121        public Set<PythonAttributeModel> getAttributes(){ 
    111122                Set<PythonAttributeModel> attributes = new HashSet<PythonAttributeModel>(); 
    112                  
    113123                extractAttributes(this.getAttributeModel(), attributes, null); 
    114                 for (ClassModel cm : this.getParents()) { 
    115                         extractParentAttributes(cm, attributes, cm); 
    116                 } 
     124                for (ClassModel grandfather : this.getParents()) { 
     125                        extractAttributes(grandfather.getAttributeModel(), attributes, grandfather); 
     126                        extractParentAttributes(grandfather, attributes, grandfather); 
     127                }                
    117128                return attributes; 
     129        } 
     130 
     131        private void extractParentAttributes(ClassModel cm, Set<PythonAttributeModel> attributes, ClassModel parent) { 
     132                extractAttributes(cm.getAttributeModel(), attributes, parent); 
     133                for (ClassModel grandfather : cm.getParents()) { 
     134                        extractParentAttributes(grandfather, attributes, parent);                        
     135                }                
    118136        } 
    119137         
    120138        private void extractAttributes(Set<AttributeModel> am, Set<PythonAttributeModel> pa, ClassModel owner) { 
    121139                for (AttributeModel attribute : am) { 
    122                         //If the attribute has been redefined in a child skips the loop 
    123                         if (pa.contains(new PythonAttributeModel(attribute, null, null))) 
    124                                 continue; 
    125                         if (attribute == null  
    126                                         || attribute.getAssociatedType() == null 
    127                                         || attribute.getAssociatedType().getAssociatedClass() == null 
    128                                         || attribute.getAssociatedType().getAssociatedClass().getName() == null) 
    129                                 continue; 
    130                         //add the new attribute with the proper parent  
    131                         //(null if the attribute is directly from "this" instance) 
    132                         pa.add(new PythonAttributeModel(attribute, 
    133                                         owner,  
    134                                         skipIt() ? null : attribute.getAssociatedType().getAssociatedClass().getName())); 
     140                        CollectionUtils.addIgnoreNull(pa, generatePythonAttribute(attribute, owner)); 
    135141                }                
    136142        } 
    137143         
    138         private void extractParentAttributes(ClassModel cm, Set<PythonAttributeModel> attributes, ClassModel parent) { 
    139                 extractAttributes(cm.getAttributeModel(), attributes, parent); 
    140                 for (ClassModel grandfather : cm.getParents()) { 
    141                         extractParentAttributes(grandfather, attributes, parent); 
    142                 }                
     144        private PythonAttributeModel generatePythonAttribute(AttributeModel am, ClassModel owner) { 
     145                if (am == null  
     146                                || am.getAssociatedType() == null 
     147                                || am.getAssociatedType().getAssociatedClass() == null 
     148                                || am.getAssociatedType().getAssociatedClass().getName() == null) 
     149                        return null; 
     150                String name = am.getAssociatedType().getAssociatedClass().getName(); 
     151                String[] imp = NmVelocityHelper.getMappedImportImport(am.getAssociatedType().getAssociatedClass().getName()); 
     152                if (imp != null) { 
     153                        name = imp[1]; 
     154                } 
     155                return new PythonAttributeModel(am, 
     156                                owner,  
     157                                skipIt() ? null : name);                 
    143158        } 
    144159         
  • mauRepo/xmi2sqlalchemy/trunk/src/main/java/ndg/services/newmoon/velocity/python/support/ImportCollector.java

    r8009 r8048  
    3838 
    3939import ndg.services.newmoon.NmParserHelper; 
    40 import ndg.services.newmoon.velocity.python.GenerateModuleHelper; 
    41 import ndg.services.newmoon.xmiModel.UMLClass; 
     40import ndg.services.newmoon.velocity.python.NmVelocityHelper; 
    4241import ndg.services.newmoon.xmiModel.UMLClassDataType; 
    4342 
     
    5554 
    5655        /** 
    57          * Updates the classes to import. 
    58          * The same as {@link #updateImports(UMLClass, boolean)} with the <code>doCheck<code> 
    59          * parameter set to <code>true</code> 
    60          **/ 
    61         public <T extends UMLClassDataType> void updateImports(T umlClass) { 
    62                 updateImports(umlClass, true); 
    63         } 
    64          
    65         /** 
    6656         * Updates the classes to import. If enabled, checks if the import should be avoided or not 
    6757         * using the {@link GenerateModuleHelper.skipElement(umlClass)} method. 
    6858         *    
    69          * @param umlClass The class to import 
    70          * @param doCheck If <code>false</code> will not check if the import is avoidable  
     59         * @param umlClass The class to import  
    7160         **/ 
    72         public <T extends UMLClassDataType> void updateImports(T umlClass, boolean doCheck) { 
    73                 if (umlClass == null) 
     61        public <T extends UMLClassDataType> void updateImports(T umlClass) { 
     62                if (umlClass == null || umlClass.getName().equals("EARootClass")) 
    7463                        return; 
    7564 
    76                 if (doCheck && GenerateModuleHelper.skipElement(umlClass)) 
    77                         return; 
    78                  
    79                 String key = getModule(umlClass); 
    80                 if (!importMap.containsKey(key)) { 
    81                         importMap.put(key, new HashSet<String>()); 
    82                 } 
    83                 CollectionUtils.addIgnoreNull(importMap.get(key), umlClass.getName()); 
     65                String moduleName = null; 
     66                String className = null; 
     67                if (NmVelocityHelper.isExternallyMapped(umlClass.getName())) { 
     68                        String[] imp = NmVelocityHelper.getMappedImportImport(umlClass.getName()); 
     69                        moduleName = imp[0]; 
     70                        className = imp[1]; 
     71                } else { 
     72                        moduleName = getModule(umlClass); 
     73                        className = umlClass.getName(); 
     74                }                        
     75                updateImportMap(moduleName, className); 
    8476        } 
    8577 
     78        private void updateImportMap(String moduleName, String className) { 
     79                if (!importMap.containsKey(moduleName)) { 
     80                        importMap.put(moduleName, new HashSet<String>()); 
     81                } 
     82                CollectionUtils.addIgnoreNull(importMap.get(moduleName), className);             
     83        } 
     84         
    8685        private String getModule(UMLClassDataType umlClass) { 
    8786                return NmParserHelper.getPackageParentName(umlClass.getUmlPackage()) + "." + umlClass.getName().toLowerCase(); 
  • mauRepo/xmi2sqlalchemy/trunk/src/main/resources/velocity/python/pythonClass.vm

    r8043 r8048  
    1414${stereotype.name}#elseif($superclasses.size() > 0) 
    1515#foreach( $classModel in $superclasses) 
    16 ${classModel.associatedClass.name}#if($foreach.hasNext),#end 
     16##${classModel.associatedClass.name}#if($foreach.hasNext),#end 
     17${vh.getMappedClass(${classModel.associatedClass.name})}#if($foreach.hasNext),#end 
    1718#end 
    1819#end 
     
    2122#macro( asEnumeration $asEnumeration) 
    2223#foreach($item in $asEnumeration.simpleKeyValues) 
    23 ${tab}en_${item.key.replaceAll("[()]", "")} = "${item.value}"  
     24${tab}en_${vh.transformToPythonName($item.key)} = "${item.value}"  
    2425#end 
    2526#end 
     
    2728#macro( asCodeList $asCodeList) 
    2829#foreach($item in $asCodeList.simpleKeyValues) 
    29 ${tab}cl_${item.key.replaceAll("[()]", "")} = "${item.value}"  
     30${tab}cl_${vh.transformToPythonName($item.key)} = "${item.value}"  
    3031#end 
    3132#end 
     
    3738#macro (unionDictionary $attributeModel) 
    3839#foreach($item in $attributeModel) 
    39 '${item.name}':#substituteClassType(${item.associatedType.associatedClass.name})#if($foreach.hasNext),#end   
     40'${item.name}':${vh.getMappedClass(${item.associatedType.associatedClass.name})}#if($foreach.hasNext),#end   
    4041#end 
    4142#end 
     
    4445#macro( importing $toImport) 
    4546#foreach( $key in $toImport.keySet())    
    46 from $key import #foreach( $item in $toImport.get($key)) $item#if($foreach.hasNext),#end 
     47from $key import #foreach( $item in $toImport.get($key)) $item#if($foreach.hasNext),#end #end 
    4748 
    48 #end 
    4949#end 
    5050#end 
     
    8080#if($parents) 
    8181#foreach( $parent in $parents) 
    82 ${tab}${tab}self._${parent.associatedClass.name.toLowerCase()} = ${parent.associatedClass.name}()        
     82${tab}${tab}self._${parent.associatedClass.name.toLowerCase()} = ${vh.getMappedClass(${parent.associatedClass.name})}()          
    8383#end 
    8484#end 
  • mauRepo/xmi2sqlalchemy/trunk/src/main/resources/xmiToSQLMap.properties

    r7998 r8048  
    11#Maps the given key (Classname) to the SQLAlchemy proper class 
    2 CharacterString=TEXT 
    3 Character=String 
    4 Integer=Integer 
    5 Boolean=BOOLEAN 
    6 Real=NUMERIC 
    7 Vector=ARRAY 
    8 Number=NUMERIC 
     2CharacterString=sqlalchemy.types.Text 
     3Character=sqlalchemy.types.String 
     4Integer=sqlalchemy.types.Integer 
     5Boolean=sqlalchemy.types.BOOLEAN 
     6Real=sqlalchemy.dialects.postgresql.REAL 
     7Vector=sqlalchemy.dialects.postgresql.ARRAY 
     8Number=sqlalchemy.types.NUMERIC 
     9 
    910#Date=DATE 
    1011#DateTime=DateTime 
  • mauRepo/xmi2sqlalchemy/trunk/src/test/resources/removeAll

    r8043 r8048  
    1818 AND pg_catalog.pg_table_is_visible(c.oid)   
    1919 ORDER BY 1;   
     20 
Note: See TracChangeset for help on using the changeset viewer.