All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.castor.ddlgen.MappingHelper Maven / Gradle / Ivy

There is a newer version: 1.3.3-rc1
Show newest version
/*
 * Copyright 2006 Le Duc Bao, Ralf Joachim
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package org.castor.ddlgen;

import java.util.Enumeration;
import java.util.Vector;

import org.castor.ddlgen.typeinfo.TypeInfo;
import org.exolab.castor.mapping.Mapping;
import org.exolab.castor.mapping.xml.ClassMapping;
import org.exolab.castor.mapping.xml.FieldMapping;

/** 
 * This class handles all common tasks for manipulating Mapping document.
 * 
 * @author Le Duc Bao
 * @author Ralf Joachim
 * @version $Revision: 5951 $ $Date: 2006-04-25 16:09:10 -0600 (Tue, 25 Apr 2006) $
 * @since 1.1
 */
public final class MappingHelper {
    //--------------------------------------------------------------------------

    /** Mapping document. */
    private Mapping _mapping;

    /** Type mapper. */
    private TypeMapper _typeMapper;

    //--------------------------------------------------------------------------

    /**
     * Get mapping document.
     * 
     * @return Mapping document.
     */
    public Mapping getMapping() {
        return _mapping;
    }

    /**
     * set mapping document.
     * 
     * @param mapping Mapping document.
     */
    public void setMapping(final Mapping mapping) {
        _mapping = mapping;
    }

    /**
     * Get type mapper.
     * 
     * @return Type mapper.
     */
    public TypeMapper getTypeMapper() {
        return _typeMapper;
    }

    /**
     * Set type mapper.
     * 
     * @param typeMapper Type mapper.
     */
    public void setTypeMapper(final TypeMapper typeMapper) {
        _typeMapper = typeMapper;
    }

    //--------------------------------------------------------------------------

    /**
     * Return the ClassMapping which associated with parameter name.
     * 
     * @param name Name of class to get ClassMapping of.
     * @return ClassMapping of the named class or null if no such
     *         ClassMapping was found.
     */
    public ClassMapping getClassMappingByName(final String name) {
        Enumeration ec = _mapping.getRoot().enumerateClassMapping();
        while (ec.hasMoreElements()) {
            ClassMapping cm = (ClassMapping) ec.nextElement();
            String cmName = cm.getName();
            if ((cmName != null) && cmName.equals(name)) { return cm; }
        }
        return null;
    }

    /**
     * Collect sql type of all identities for class with given name. It also takes care
     * on multiple column identities and extended classes.
     * 
     * 
     * <mapping>
     *   <class name="myapp.OtherProductGroup" >
     *     <map-to table="other_prod_group" xml="group" />
     *     <field name="id" type="integer" identity="true">
     *       <sql name="id" type="integer"/>
     *     </field>
     *   </class>
     * 
     *   <class name="myapp.ProductGroup" identity="id">
     *     <map-to table="prod_group" xml="group" />
     *     <field name="id" type="myapp.OtherProductGroup" >
     *       <sql name="prod_id" />
     *     </field>
     *   </class>
     * 
     *   <class name="myapp.Product" identity="id">
     *     <field name="group" type="myapp.ProductGroup">
     *       <sql name="group_id" />
     *     </field>
     *   </class>
     * </mapping>     
     * 
* * @param className Name of class to get type of identities of. * @return Array of sql types of all identities. * @throws GeneratorException If failed to resolve sql type of identities. */ public synchronized String[] resolveTypeReferenceForIds(final String className) throws GeneratorException { ClassMapping cm = getClassMappingByName(className); if (cm != null) { return resolveTypeReferenceForIds(cm); } throw new GeneratorException("can not find class " + className); } /** * Collect sql type of all identities for a ClassMapping. It also takes care on * multiple column identities and extended classes. * * @param cm ClassMapping to get type of identities of. * @return Array of sql types of all identities. * @throws GeneratorException If failed to resolve sql type of identities. */ public String[] resolveTypeReferenceForIds(final ClassMapping cm) throws GeneratorException { boolean isFoundKey = false; String[] ids = cm.getIdentity(); Vector types = new Vector(); Enumeration ef = cm.getClassChoice().enumerateFieldMapping(); boolean isExistFieldId = isUseFieldIdentity(cm); // Go through all fields. while (ef.hasMoreElements()) { FieldMapping fm = (FieldMapping) ef.nextElement(); // Identity are defined at field. if (isExistFieldId && fm.getIdentity()) { // Get field type. TypeInfo typeinfo = null; String sqltype = fm.getSql().getType(); if (sqltype != null) { typeinfo = _typeMapper.getType(sqltype); } if (typeinfo == null) { String[] refRefType = resolveTypeReferenceForIds(fm .getType()); for (int l = 0; l < refRefType.length; l++) { types.add(refRefType[l]); isFoundKey = true; } } else { for (int i = 0; i < fm.getSql().getNameCount(); i++) { types.add(fm.getSql().getType()); isFoundKey = true; } } } else if (!isExistFieldId) { // Identities are defined at class tag. String fieldName = fm.getName(); for (int j = 0; j < ids.length; j++) { // If sqlnames[i] equals ids[j] we found a reference type. if (fieldName.equals(ids[j])) { // Check for type if this table is a reference table. TypeInfo typeinfo = null; String sqltype = fm.getSql().getType(); // Verify if sqltype exists. if (sqltype != null) { typeinfo = _typeMapper.getType(sqltype); } if (typeinfo == null) { ClassMapping cmRef = getClassMappingByName(fm.getType()); // If cmRef is null, the reference class could not be found // so we need to use field type. if (cmRef == null) { typeinfo = _typeMapper.getType(fm.getType()); if (typeinfo == null) { throw new TypeNotFoundException( "Can't resolve type " + fm.getType()); } int count = fm.getSql().getNameCount(); if (count == 0) { count = fm.getSql().getManyKeyCount(); } for (int l = 0; l < count; l++) { types.add(fm.getType()); isFoundKey = true; } } else { // Resolve type for reference class. String[] refRefType = resolveTypeReferenceForIds( fm.getType()); for (int l = 0; l < refRefType.length; l++) { types.add(refRefType[l]); isFoundKey = true; } } } else { types.add(fm.getSql().getType()); isFoundKey = true; } } } } } // If there is no identity found, looking in the extend class. if (!isFoundKey && (cm.getExtends() != null)) { ClassMapping extendClass = (ClassMapping) cm.getExtends(); String[] refRefType = resolveTypeReferenceForIds(extendClass); for (int l = 0; l < refRefType.length; l++) { types.add(refRefType[l]); } } return (String[]) types.toArray(new String[types.size()]); } /** * Check if identities of given ClassMapping are defined at its FieldMappings. * * @param cm ClassMapping to check for identity definitions at FieldMapping. * @return true if identities are defined at fieldMapping. */ public boolean isUseFieldIdentity(final ClassMapping cm) { Enumeration ef = cm.getClassChoice().enumerateFieldMapping(); while (ef.hasMoreElements()) { FieldMapping fm = (FieldMapping) ef.nextElement(); if (fm.getIdentity()) { return true; } } return false; } /** * Check if given FieldMapping is an identity at given ClassMapping. *
     * <class name="myapp.ProductGroup" identity="id">
     *     <field name="id" type="integer" >
     *         <sql name="id1 id2" type="integer"/>
     *     </field>
     * </class>
     * 
* * @param cm ClassMapping. * @param fm FieldMapping. * @return true if FieldMapping is an identity at ClassMapping. */ public boolean isIdentity(final ClassMapping cm, final FieldMapping fm) { String[] ids = cm.getIdentity(); String fieldName = fm.getName(); for (int j = 0; j < ids.length; j++) { if (ids[j].equalsIgnoreCase(fieldName)) { return true; } } return false; } /** * The identity definitions at class and field are alternative syntax. If * both are specified the one at field should take precedence over the class * one. In other words if both are specified the one at class will be * ignored. * * @param cm ClassMapping to get sql names of identities of. * @param ext Recursivly search for identities in extended ClassMappings. * @return Array of sql names of identities of given ClassMapping. */ public String[] getClassMappingSqlIdentity(final ClassMapping cm, final boolean ext) { Vector ids = new Vector(); String[] identities = cm.getIdentity(); // If child defines identity with same or no type, // use name from child and type from parent. if (ext && cm.getExtends() != null && identities.length == 0) { identities = getClassMappingIdentity((ClassMapping) cm.getExtends()); } Enumeration ef = cm.getClassChoice().enumerateFieldMapping(); boolean isExistFieldId = isUseFieldIdentity(cm); while (ef.hasMoreElements()) { FieldMapping fm = (FieldMapping) ef.nextElement(); // Add all sql columns into identity list. if (isExistFieldId && fm.getIdentity()) { isExistFieldId = true; int ncount = fm.getSql().getNameCount(); for (int i = 0; i < ncount; i++) { ids.add(fm.getSql().getName(i)); } } else if (!isExistFieldId) { // If using class identity, find out all correspondent column names. String fieldName = fm.getName(); for (int j = 0; j < identities.length; j++) { if (fieldName.equals(identities[j])) { // Check for type if this table is a reference table. int ncount = fm.getSql().getNameCount(); for (int i = 0; i < ncount; i++) { ids.add(fm.getSql().getName(i)); } } } } } // Get identities from parent. if (ext && (cm.getExtends() != null) && (ids.size() == 0)) { return getClassMappingSqlIdentity((ClassMapping) cm.getExtends(), ext); } return (String[]) ids.toArray(new String[ids.size()]); } /** * The identity definitions at class and field are alternative syntax. If * both are specified the one at field should take precedence over the class * one. In other words if both are specified the one at class will be * ignored. * * @param cm ClassMapping to get identity names of. * @return Array of identity names of given ClassMapping. */ public String[] getClassMappingIdentity(final ClassMapping cm) { Vector ids = new Vector(); boolean isExistFieldId = false; Enumeration ef = cm.getClassChoice().enumerateFieldMapping(); while (ef.hasMoreElements()) { FieldMapping fm = (FieldMapping) ef.nextElement(); // Add names of all identity columns to list. if (isExistFieldId && fm.getIdentity()) { isExistFieldId = true; ids.add(fm.getName()); } } if (!isExistFieldId) { String[] identities = cm.getIdentity(); for (int i = 0; i < identities.length; i++) { ids.add(identities[i]); } } // If this is a child class, use its parents identities. if ((cm.getExtends() != null) && (ids.size() == 0)) { return getClassMappingIdentity((ClassMapping) cm.getExtends()); } return (String[]) ids.toArray(new String[ids.size()]); } //-------------------------------------------------------------------------- }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy