Package org.objectweb.speedo.generation.jorm

Source Code of org.objectweb.speedo.generation.jorm.JormMIGenerator

/**
* Copyright (C) 2001-2005 France Telecom R&D
*/
package org.objectweb.speedo.generation.jorm;

import org.objectweb.jorm.api.PException;
import org.objectweb.jorm.compiler.api.JormCompilerConfigurator;
import org.objectweb.jorm.compiler.api.JormCompilerParameter;
import org.objectweb.jorm.compiler.lib.JormCompiler;
import org.objectweb.jorm.metainfo.api.Class;
import org.objectweb.jorm.metainfo.api.ClassProject;
import org.objectweb.jorm.metainfo.api.GenClassRef;
import org.objectweb.jorm.metainfo.api.Manager;
import org.objectweb.jorm.metainfo.api.Mapping;
import org.objectweb.jorm.metainfo.api.NameDef;
import org.objectweb.jorm.metainfo.api.TypedElement;
import org.objectweb.speedo.api.ExceptionHelper;
import org.objectweb.speedo.api.SpeedoException;
import org.objectweb.speedo.api.SpeedoProperties;
import org.objectweb.speedo.generation.api.SpeedoXMLError;
import org.objectweb.speedo.generation.lib.AbstractGeneratorComponent;
import org.objectweb.speedo.lib.Personality;
import org.objectweb.speedo.metadata.SpeedoClass;
import org.objectweb.speedo.metadata.SpeedoField;
import org.objectweb.speedo.metadata.SpeedoIdentity;
import org.objectweb.speedo.metadata.SpeedoXMLDescriptor;
import org.objectweb.util.monolog.api.BasicLevel;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

/**
* Build the JORM meta information
*
* @author S.Chassande-Barrioz
*/
public class JormMIGenerator extends AbstractGeneratorComponent {
    public final static String LOGGER_NAME = SpeedoProperties.LOGGER_NAME
            + ".generation.jorm.migen";
    /**
     * Jorm classes intended for JORM generation
     */
    protected JormCompiler jormcompiler;

    public JormMIGenerator(Personality p) {
      super(p);
    }
   
    /**
     * Instanciates and configures partialy a JormCompiler required for the
     * .pd parsing and fetching a configured MIManager
     */
    public boolean init() throws SpeedoException {
        if (scp.getXmldescriptor().isEmpty()) {
            return false;
        }
        logger = scp.loggerFactory.getLogger(LOGGER_NAME);
        jormcompiler = new JormCompiler();
        JormCompilerParameter jcp = jormcompiler.getCompilerParameter();
        JormCompilerConfigurator jcc = jormcompiler.getCompilerConfigurator();
        try {
            jcc.configure();
            jcp.loadConfFile(jcc.getGlobalJormcOptsFile(), jcc.knownMappers());
            jcc.setLoggerFactory(scp.loggerFactory);
            int idx = scp.mapperName.indexOf('.');
            if (idx == -1) {
                jcc.removeMapper(scp.mapperName);
                jcc.addSubMapper(scp.mapperName, "generic");
            } else {
                String actualmn = scp.mapperName.substring(0, idx);
                jcc.removeMapper(actualmn);
                jcc.addSubMapper(actualmn, scp.mapperName.substring(idx + 1));
            }
            if (logger.isLoggable(BasicLevel.DEBUG)) {
                logger.log(BasicLevel.DEBUG, "jormcOpts file:"
                        + jcc.getJormcOptsFile());
                Iterator it = jcc.knownMappers();
                while (it.hasNext()) {
                    String mapperName = (String) it.next();
                    logger.log(BasicLevel.DEBUG, mapperName + " sub mappers: "
                            + jcc.getSubMappers(mapperName));
                }
            }
        } catch (PException e) {
            logger.log(BasicLevel.ERROR, "Impossible to configure Jorm",
                    ExceptionHelper.getNested(e));
            throw new SpeedoException("Impossible to configure Jorm", e);
        }
        scp.generatorsContext.put("jormcompiler", jormcompiler);
        return true;
    }

    public String getTitle() {
        return "Building Jorm Meta Information...";
    }
    public void process() throws SpeedoException {
        try {
            process2();
        } catch(PException e) {
            throw new SpeedoException("Error during Jorm generation", e);
        }
    }
    /**
     * Performs the JORM Meta Information building.
     */
    public void process2() throws SpeedoException, PException {
        if (scp.getXmldescriptor().isEmpty()) {
            return;
        }
        // The list of .pd files specified by the user
        Collection pdfiles = jormcompiler.getCompilerParameter()
                .getInputFiles();
        if (logger.isLoggable(BasicLevel.DEBUG)) {
            for (Iterator it = pdfiles.iterator(); it.hasNext();)
                logger.log(BasicLevel.DEBUG, "source file: " + it.next());
        }

        // The list of SpeedoClass requiring the JMI generation
        ArrayList notFoundMOs = new ArrayList();
        for (Iterator itDesc = scp.getXmldescriptor().values().iterator(); itDesc
                .hasNext();) {
            SpeedoXMLDescriptor desc = (SpeedoXMLDescriptor) itDesc.next();
            List scs = desc.getSpeedoClasses();
            for (int i = 0; i < scs.size(); i++) {
                SpeedoClass sc = (SpeedoClass) scs.get(i);
                String fn = sc.getJormFileName();
                logger.log(BasicLevel.DEBUG, "looking for the file: " + fn);
                if (!pdfiles.contains(fn)) {
                    // No .pd file is availlable, add the SpeedoClass into the
                    // list
                    notFoundMOs.add(sc);
                }
            }
        }

        // if .pd files are not specified by the user then the jorm meta
        // information is generated
        jormcompiler.setupLogger();
        jormcompiler.setupMIManager();
        if (!notFoundMOs.isEmpty()) {
            JormMIBuilder jmib = new JormMIBuilder(jormcompiler.getMIManager(),
                    scp.nmf, logger);
            jmib.createMI(notFoundMOs, scp.projectName, scp.mapperName);
        }

        if (pdfiles.size() > 0) {
            // parse the .pd files ==> Collection(jorm MetaObject)
            isCompatible();
        }
    }
    /**
     * Verifies that all persistent capable field for jdo is described in JORM.
     *
     * @exception org.objectweb.speedo.generation.api.SpeedoXMLError if JORM an JDO MetaData are not coherent
     */
    protected void isCompatible() throws SpeedoException {

        List except = new ArrayList();

        Manager manager = jormcompiler.getMIManager();
        for (Iterator itDesc = scp.getXmldescriptor().values().iterator(); itDesc.hasNext();) {
            SpeedoXMLDescriptor desc = (SpeedoXMLDescriptor) itDesc.next();
            List scs = desc.getSpeedoClasses();
            for (int i=0; i<scs.size(); i++) {
                compareClass((SpeedoClass) scs.get(i), manager, except);
            }
        }
        if (!except.isEmpty() && logger.isLoggable(BasicLevel.ERROR))
            for (Iterator it = except.iterator(); it.hasNext();)
                logger.log(BasicLevel.ERROR, it.next());
    }

    protected void compareClass(SpeedoClass clas,
                                Manager manager,
                                List except) throws SpeedoException {
        debug = logger.isLoggable(BasicLevel.DEBUG);
        if (debug) {
            logger.log(BasicLevel.DEBUG,
                    "Verify the definition of the class " + clas.getFQName());
        }
        Class classJorm = manager.getClass(clas.getFQName());
        if (classJorm == null) {
            throw new SpeedoException("Jorm description of the class '"
                    + clas.getFQName() + "' is not availlable");
        }
        NameDef pName = null;
        SpeedoClass sc = clas;
        while(sc.getSuperClassName() != null) {
            SpeedoClass scl = sc;
            sc = sc.moPackage.xmlDescriptor.smi.getSpeedoClass(sc.getSuperClassName(), sc.moPackage);
            if (sc == null) {
                throw new SpeedoException("Class " + scl.getFQName()
                        + " not defined in the jorm meta information");
            }
        }
        Class pclassJorm = manager.getClass(sc.getFQName());
        pName = getClassNameDef(pclassJorm);

        if (classJorm == null) {
            throw new SpeedoXMLError("Class '" + clas.name + "' not defined in JORM metadata");
        }

        // Comparison from JDO
        clas.jormclass = classJorm;
        for (Iterator efield = clas.fields.values().iterator(); efield.hasNext();) {
            SpeedoField field = (SpeedoField) efield.next();
            String fieldName = field.name;

            // Fields with this persistent modifier shouldn't stay in JDO Metadata
            if (field.persistenceStatus == SpeedoField.NONE)
                continue;

            TypedElement tElem = classJorm.getTypedElement(fieldName);
            if (tElem == null) {
                throw new SpeedoXMLError("Field '" + fieldName
                    + "' not defined in JORM metadata of the class '"
                    + clas.getFQName() + "'");
            }

            // for application identity key fields have to be compared
            if (field.primaryKey) {
                boolean found = false;
                for (Iterator it = pName.iterateField(); it.hasNext() && !found;) {
                    found = fieldName.equals(it.next());
                }
                if (!found) {
                    throw new SpeedoXMLError("Field '" + fieldName
                        + "' not defined in Class NameDef's Fields of the class '"
                        + clas.getFQName() + "'");
                }
            }

            if (tElem instanceof GenClassRef && field.jdoTuple == null)
                throw new SpeedoXMLError("field '" + fieldName + "' should be a tuple in JDO metadata of the class '" + clas.getFQName() + "'");
        }

        // Comparison from JORM
        for (Iterator jormfield = classJorm.getFields().iterator(); jormfield.hasNext();) {
            TypedElement te = (TypedElement) jormfield.next();
            String fieldName = te.getName();
            if (!clas.fields.containsKey(fieldName)
                    && !isContainerIdField(classJorm, te, clas))
                throw new SpeedoXMLError("Field '" + fieldName + "' of the class '"
                            + clas.getFQName() + "' is not defined in the '"
                            + clas.moPackage.xmlDescriptor.xmlFile
                            + "' file (found: " + clas.fields.keySet() + ").");
        }

        // for application identity key fields have to be compared
        if (clas.getIdentityType() == SpeedoIdentity.USER_ID) {
            SpeedoClass classWithId = clas;
            while(classWithId.getSuperClassName() != null) {
                classWithId = classWithId.getSpeedoClassFromContext(classWithId.getSuperClassName());
            }
            boolean found = false;
            for (Iterator it = pName.iterateField(); it.hasNext() && !found;) {
                String fn = (String) it.next();
                SpeedoField sf = (SpeedoField) classWithId.fields.get(fn);
                if (sf == null) {
                    logger.log(BasicLevel.WARN, "Field " + fn + " defined in the identifier of "
                            + classWithId.name
                            + ".pd file but not availlable in the class (or .pd file).");
                } else if (!sf.primaryKey) {
                    except.add("Field " + fn + " defined in the "
                            + classWithId.name
                            + ".pd file but is not marked as a primary key field in the "
                            + classWithId.moPackage.xmlDescriptor.xmlFile
                            + " file.");
                }
            }
        }
    }

    private boolean isContainerIdField(Class clazz,
                                       TypedElement te,
                                       SpeedoClass sc) throws SpeedoException {
        return sc.identity.isDataStore()
                && getClassNameDef(clazz).getNameRef()
                .getProjection().containsValue(te.getName());
    }


    private Mapping getMapping(Class clazz) throws SpeedoException {
        ClassProject cp = clazz.getClassProject(scp.projectName);
        if (cp == null) {
            throw new SpeedoException("No classproject found for the class "
                    + clazz.getFQName() + " and  the project " + scp.projectName);
        }
        int idx =  scp.mapperName.indexOf('.');
        Mapping m = cp.getMapping(idx == -1
                ? scp.mapperName
                : scp.mapperName.substring(0, idx));
        if (m == null) {
            throw new SpeedoException("No mapping found for the class "
                    + clazz.getFQName() + ",  the project " + scp.projectName
                    + " and  the mapper " + scp.mapperName);
        }
        return m;
    }

    private NameDef getClassNameDef(Class clazz) throws SpeedoException {
        return (NameDef) getMapping(clazz).getClassMapping()
                .getIdentifierMapping().getLinkedMO();
    }
   
}
TOP

Related Classes of org.objectweb.speedo.generation.jorm.JormMIGenerator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.