com.pactera.edg.am.metamanager.extractor.increment.impl.IncrementAnalysisServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.pactera.edg.am.metamanager.extractor.increment.impl.IncrementAnalysisServiceImpl.java

Source

/*
 * Copyright 2009 by pactera.edg.am Corporation. Address:HePingLi East Street No.11
 * 5-5, BeiJing,
 * 
 * All rights reserved.
 * 
 * This software is the confidential and proprietary information of pactera.edg.am
 * Corporation ("Confidential Information"). You shall not disclose such
 * Confidential Information and shall use it only in accordance with the terms
 * of the license agreement you entered into with pactera.edg.am.
 */

package com.pactera.edg.am.metamanager.extractor.increment.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.pactera.edg.am.metamanager.app.template.adapter.TemplateTitleCover;
import com.pactera.edg.am.metamanager.extractor.bo.ExtractorLogLevel;
import com.pactera.edg.am.metamanager.extractor.bo.mappingload.Operation;
import com.pactera.edg.am.metamanager.extractor.bo.mm.AbstractMetadata;
import com.pactera.edg.am.metamanager.extractor.bo.mm.AppendMetadata;
import com.pactera.edg.am.metamanager.extractor.bo.mm.MMDDependency;
import com.pactera.edg.am.metamanager.extractor.bo.mm.MMMetaModel;
import com.pactera.edg.am.metamanager.extractor.bo.mm.MMMetadata;
import com.pactera.edg.am.metamanager.extractor.bo.mm.ModifyMetadata;
import com.pactera.edg.am.metamanager.extractor.dao.IMetaModelDao;
import com.pactera.edg.am.metamanager.extractor.dao.IMetadataDao;
import com.pactera.edg.am.metamanager.extractor.dao.ISequenceDao;
import com.pactera.edg.am.metamanager.extractor.ex.CompositionNotFoundException;
import com.pactera.edg.am.metamanager.extractor.ex.MDependencyNotFoundException;
import com.pactera.edg.am.metamanager.extractor.ex.MetaModelNotFoundException;
import com.pactera.edg.am.metamanager.extractor.increment.IGenMetadataService;
import com.pactera.edg.am.metamanager.extractor.increment.IIncrementAnalysisService;
import com.pactera.edg.am.metamanager.extractor.increment.IncrementAnalysisHelper;
import com.pactera.edg.am.metamanager.extractor.util.AdapterExtractorContext;
import com.pactera.edg.am.metamanager.extractor.util.Constants;

/**
 * ??
 * 
 * @author hqchen
 * @version 1.0 Date: Sep 29, 2009
 * 
 */
public class IncrementAnalysisServiceImpl implements IIncrementAnalysisService {

    private Log log = LogFactory.getLog(IncrementAnalysisServiceImpl.class);

    /**
     * ??DAO?
     */
    private IGenMetadataService genMetadataService;

    /**
     * SequenceDao
     */
    private ISequenceDao sequenceDao;

    /**
     * ?DAO?
     */
    private IMetaModelDao metaModelDao;

    /**
     * ??DAO?
     */
    private IMetadataDao metaDataDao;

    /**
     * ?
     */
    private Map<String, Set<String>> errorAttrs = new HashMap<String, Set<String>>();

    /**
     * ??
     */
    private Set<String> errorCompositions = new HashSet<String>(0);

    /**
     * ,???
     */
    private AppendMetadata aMetadata;

    /**
     * Spring
     * 
     * @param sequenceDao
     */
    public void setSequenceDao(ISequenceDao sequenceDao) {
        this.sequenceDao = sequenceDao;
    }

    public void setGenMetadataService(IGenMetadataService genMetadataService) {
        this.genMetadataService = genMetadataService;
    }

    public IMetadataDao getMetaDataDao() {
        return metaDataDao;
    }

    public void setMetaDataDao(IMetadataDao metaDataDao) {
        this.metaDataDao = metaDataDao;
    }

    /**
     * ???,???
     * 
     * @param aMetadata
     *            
     * 
     * @see com.pactera.edg.am.metamanager.extractor.increment.IIncrementAnalysisService#incrementAnalysis(java.lang.ref.SoftReference)
     */
    public Map<Operation, AppendMetadata> incrementAnalysis(AppendMetadata aMetadata) throws Throwable {

        this.aMetadata = aMetadata;
        beforeIncrementAnalysis();

        // ?
        AppendMetadata createAMetadata = aMetadata.cloneAppendMetadata();
        // ?
        AppendMetadata modifyAMetadata = aMetadata.cloneAppendMetadata();

        try {
            String dCode = aMetadata.getMetadata().getCode();
            String mCode = aMetadata.getMetaModel().getCode();
            // --------------------????------------------------
            // ID
            String logMsg = new StringBuilder(":").append(dCode).append(",:")
                    .append(mCode).append(" ???...").toString();
            log.info(logMsg);
            AdapterExtractorContext.addExtractorLog(ExtractorLogLevel.INFO, logMsg);

            List<AbstractMetadata> metadatas = getAMetadatas(aMetadata);
            // ?
            Set<MMMetaModel> newMetaModels = aMetadata.getChildMetaModels();
            Set<MMMetaModel> createMetaModels = new HashSet<MMMetaModel>(newMetaModels.size());
            Set<MMMetaModel> modifyMetaModels = new HashSet<MMMetaModel>(newMetaModels.size());

            for (Iterator<MMMetaModel> iter = newMetaModels.iterator(); iter.hasNext();) {
                MMMetaModel newMetaModel = iter.next();
                if (newMetaModel.isHasMetadata()) {
                    // ?
                    // ?,?
                    MMMetaModel createMetaModel = newMetaModel.cloneOnlyMetaModel();
                    MMMetaModel modifyMetaModel = newMetaModel.cloneOnlyMetaModel();
                    compareRootMetaModel(createMetaModel, modifyMetaModel, metadatas, newMetaModel);
                    /**
                     * @author wengn
                     * @date 2011-11-9
                     * @desc ???
                     */
                    if (newMetaModels.size() != 1 && "AmSystem".equals(newMetaModel.getCode())) {
                        continue;
                    } else {
                        createMetaModels.add(createMetaModel);
                        modifyMetaModels.add(modifyMetaModel);
                    }
                }
            }

            createAMetadata.setChildMetaModels(createMetaModels);
            modifyAMetadata.setChildMetaModels(modifyMetaModels);

            Map<Operation, AppendMetadata> incrementMetadata = new HashMap<Operation, AppendMetadata>(2);
            incrementMetadata.put(Operation.CREATE, createAMetadata);
            incrementMetadata.put(Operation.MODIFY, modifyAMetadata);

            log.info("????!");
            AdapterExtractorContext.addExtractorLog(ExtractorLogLevel.INFO, "????!");
            // ------------------????----------------------------
            logMsg = new StringBuilder(":").append(dCode).append(",:").append(mCode)
                    .append(" ????...").toString();
            log.info(logMsg);
            AdapterExtractorContext.addExtractorLog(ExtractorLogLevel.INFO, logMsg);

            List<MMDDependency> dependencies = aMetadata.getDDependencies();
            if (dependencies != null) {
                // ?
                createAMetadata.setDDependencies(
                        genCreateDependencies(dependencies, incrementMetadata.get(Operation.CREATE)));
            }
            log.info("?????!");
            AdapterExtractorContext.addExtractorLog(ExtractorLogLevel.INFO,
                    "?????!");

            printWarn();
            return incrementMetadata;
        } catch (Throwable t) {
            throw t;
        } finally {
            // ?
            errorAttrs.clear();
            errorCompositions.clear();
        }
    }

    private void beforeIncrementAnalysis() {
        IncrementAnalysisHelper helper = new IncrementAnalysisHelper();
        helper.verify(aMetadata);

    }

    /**
     * ??,?,
     * 
     * @throws CompositionNotFoundException
     */
    private void printWarn() throws CompositionNotFoundException {
        String logMsg = null;
        if (errorAttrs.size() > 0) {
            logMsg = "??,?,??!:\n"
                    + errorAttrs.toString();
            log.warn(logMsg);
            AdapterExtractorContext.addExtractorLog(ExtractorLogLevel.INFO, logMsg);
        }
        if (errorCompositions.size() > 0) {
            logMsg = "???,?,"
                    + "????!:\n"
                    + errorCompositions.toString();
            log.error(logMsg);
            // ?,?,!
            throw new CompositionNotFoundException(logMsg);
        }

    }

    /**
     * ???,???,???,????
     * 
     * @param dependencies
     *            ??
     * @param aNamespace
     *            ??
     * @return ???
     * @throws MDependencyNotFoundException
     */
    private List<MMDDependency> genCreateDependencies(List<MMDDependency> dependencies,
            AppendMetadata createAMetadata) throws MDependencyNotFoundException {

        String aNamespace = aMetadata.getMetadata().genNamespace();
        // ??metadataId??
        List<MMDDependency> dbDependencies;

        String aMetaModelCode = aMetadata.getMetaModel().getCode();
        if ("ETLActivity".equals(aMetaModelCode) || "Catalog".equals(aMetaModelCode)
                || "Pc86PowerCenter".equals(aMetaModelCode) || "AmRepository".equals(aMetaModelCode)
                || "MappingFolder".equals(aMetaModelCode)) { // ||
            // "AmDataStandard".equals(aMetaModelCode))
            // {
            // ETEL,Catalog

            dbDependencies = genSubCreateDependencies();
        } else {
            // ???(?)
            dbDependencies = genMetadataService.genDbDependencies(aNamespace.concat("/"));
        }

        return comareDependencies(dependencies, dbDependencies, createAMetadata);
    }

    private List<MMDDependency> genSubCreateDependencies() {
        List<MMDDependency> dbDependencies = new ArrayList<MMDDependency>();
        Set<MMMetaModel> metaModels = aMetadata.getChildMetaModels();

        for (MMMetaModel metaModel : metaModels) {
            if (metaModel.isHasMetadata()) {
                List<AbstractMetadata> metadatas = metaModel.getMetadatas();

                // ??
                List<AbstractMetadata> dbMetadatas = genMetadataService.genChildMetadatas(getAMetadatas(aMetadata),
                        metaModel);

                if (metadatas.size() > Constants.MAX_METADATA_SIZE) {
                    // ?,IN????
                    Set<String> metadataNamespaces = new HashSet<String>(metadatas.size());
                    for (AbstractMetadata metadata : metadatas) {
                        // int compareInt =
                        // Collections.binarySearch(dbMetadatas, metadata,
                        // new Comparator<AbstractMetadata>() {
                        //
                        // public int compare(AbstractMetadata o1,
                        // AbstractMetadata o2) {
                        // return o1.getCode().compareTo(o2.getCode());
                        // }
                        // });
                        // if (compareInt >= 0) {
                        // metadataNamespaces.add(dbMetadatas.get(compareInt).getNamespace());
                        // }

                        String mdCode = metadata.getCode();
                        for (AbstractMetadata dbMetadata : dbMetadatas) {
                            if (dbMetadata.getCode().equals(mdCode)) {
                                // ??,?,???,????
                                metadataNamespaces.add(((MMMetadata) dbMetadata).genNamespace());
                                break;
                            }
                        }
                    }
                    dbDependencies.addAll(genMetadataService.genDbDependencies(metadataNamespaces));

                } else {
                    for (AbstractMetadata metadata : metadatas) {
                        String mdCode = metadata.getCode();
                        // ?,,!!
                        for (AbstractMetadata dbMetadata : dbMetadatas) {
                            if (dbMetadata.getCode().equals(mdCode)) {
                                // ??,?,???,????
                                String namespace = ((MMMetadata) dbMetadata).genNamespace();
                                // ???(?)
                                dbDependencies.addAll(genMetadataService.genDbDependencies(namespace));
                                break;
                            }
                        }
                    }
                }
            }
        }

        return dbDependencies;
    }

    /**
     * ????
     * 
     * @param dependencies
     *            ??
     * @param dbDependencies
     *            ??
     * @return ???
     * @throws MDependencyNotFoundException
     */
    private List<MMDDependency> comareDependencies(List<MMDDependency> dependencies,
            List<MMDDependency> dbDependencies, AppendMetadata createAMetadata)
            throws MDependencyNotFoundException {
        //ID
        List<String> invalidRuleIds = new ArrayList<String>();
        //???
        List<MMDDependency> createDependencies = new ArrayList<MMDDependency>();

        // ?code
        genRelationCode(dependencies);

        if (dbDependencies == null || dbDependencies.size() == 0) {
            // ??,?
            //AdapterExtractorContext.getInstance().setNewDependency(dependencies);
            //return dependencies;

            for (MMDDependency newDependency : dependencies) {
                /**
                 * @author wengn
                 * @date 2011-12-9
                 * @desc ??????????
                 */
                getInvalidIds(invalidRuleIds, createDependencies, newDependency);

                /**
                 * @author wengn
                 * @date 2011-12-9
                 * @desc ?????
                */
                if (invalidRuleIds.size() != 0 && createDependencies.size() != 0) {
                    createDependencyFilter(createAMetadata, invalidRuleIds, createDependencies);
                }
            }
            return createDependencies;
        }

        // ??
        Collections.sort(dbDependencies);
        Collections.sort(dependencies);

        int dbIndex = 0, newIndex = 0, compareInt, newSize = dependencies.size(), dbSize = dbDependencies.size();

        while (newIndex < newSize && dbIndex < dbSize) {
            MMDDependency newDependency = dependencies.get(newIndex);

            compareInt = newDependency.compareTo(dbDependencies.get(dbIndex));
            if (compareInt > 0) {
                // DB,?
                dbIndex++;
            } else if (compareInt < 0) {
                /**
                 * @author wengn
                 * @date 2011-12-1
                 * @desc ??????????
                 */
                getInvalidIds(invalidRuleIds, createDependencies, newDependency);
                newIndex++;
            } else {
                // ?,DB?,?NEW???,??
                dbIndex++;
                newIndex++;
                // ??
                AdapterExtractorContext.getInstance().addDependency(newDependency);

            }
        }
        while (newIndex < newSize) {
            // ?,?!
            MMDDependency dependency = dependencies.get(newIndex++);
            // ?DB?
            createDependencies.add(dependency);
            // ??
            AdapterExtractorContext.getInstance().addDependency(dependency);
        }
        while (dbIndex < dbSize) {
            // ?,?
            break;
        }
        /**
         * @author wengn
         * @date 2011-12-6
         * @desc ?????
        */
        if (invalidRuleIds.size() != 0 && createDependencies.size() != 0) {
            createDependencyFilter(createAMetadata, invalidRuleIds, createDependencies);
        }
        return createDependencies;
    }

    /**
     * ID???
     * @author wengn
     * @date 2011-12-6
     * @param createAMetadata ?
     * @param invalidRuleIds ID
     * @param createDependencies ??
     */
    private void createDependencyFilter(AppendMetadata createAMetadata, List<String> invalidRuleIds,
            List<MMDDependency> createDependencies) {
        List<MMDDependency> tempDependencies = new ArrayList<MMDDependency>();//??
        for (MMDDependency dependency : createDependencies) {
            tempDependencies.add(dependency);
        }
        for (int i = 0; i < tempDependencies.size(); i++) {
            MMDDependency dependency = tempDependencies.get(i);
            for (int j = 0; j < invalidRuleIds.size(); j++) {
                String invalidRuleId = (String) invalidRuleIds.get(j);
                if (dependency.getOwnerMetadata().getCode().indexOf(invalidRuleId) != -1
                        || dependency.getValueMetadata().getCode().indexOf(invalidRuleId) != -1) {
                    //ID???
                    createDependencies.remove(dependency);
                }
            }
        }

        Set<MMMetaModel> metaModels = createAMetadata.getChildMetaModels();
        //?????,????
        createMetaModelsFilter(invalidRuleIds, metaModels);
        //??
        createAMetadata.setChildMetaModels(metaModels);
    }

    /**
     * ?ID
     * @author wengn
     * @date 2011-12-6
     * @param invalidRuleIds ID
     * @param createDependencies ???
     * @param newDependency ??
     */
    private void getInvalidIds(List<String> invalidRuleIds, List<MMDDependency> createDependencies,
            MMDDependency newDependency) {
        boolean flag = true;
        if (newDependency.getCode().indexOf("-AmColumn-") != -1
                || newDependency.getCode().indexOf("-AmColumnCodeItem-") != -1) {//?????
            if (!"Dep-AmColumn-AmCommonRealCode".equals(newDependency.getCode())) {//??????
                //?
                flag = metaDataDao.existMetadata(newDependency.getOwnerMetadata().getParentMetadata().getId(),
                        newDependency.getOwnerMetadata());
            }
        }
        if (flag) {//??
            createDependencies.add(newDependency);
            // ??
            AdapterExtractorContext.getInstance().addDependency(newDependency);
        } else {//??????,????????,?,???
            String tempRuleId = newDependency.getValueMetadata().getCode();
            String invalidRuleId = "";
            if (tempRuleId.indexOf("-") != -1) {
                invalidRuleId = tempRuleId.substring(0, tempRuleId.indexOf("-"));
            } else {
                invalidRuleId = tempRuleId;
            }
            invalidRuleIds.add(invalidRuleId);
            //
            log.info(": " + invalidRuleId
                    + " ,???!");
            AdapterExtractorContext.addExtractorLog(ExtractorLogLevel.WARN, ": " + invalidRuleId
                    + " ,???!");
        }
    }

    /**
     * ????? 
     * @author wengn
     * @date 2011-11-20
     * @param invalidRuleIds ID
     * @param metaModels ??
     */
    private void createMetaModelsFilter(List<String> invalidRuleIds, Set<MMMetaModel> metaModels) {
        for (MMMetaModel metaModel : metaModels) {
            if (metaModel.isHasMetadata()) {
                List<AbstractMetadata> list = metaModel.getMetadatas();
                List<AbstractMetadata> tempList = new ArrayList<AbstractMetadata>();// ?
                for (AbstractMetadata am : list) {
                    tempList.add(am);
                }
                for (AbstractMetadata am : tempList) {
                    for (int j = 0; j < invalidRuleIds.size(); j++) {
                        String invalidRuleId = invalidRuleIds.get(j);
                        if (am.getCode().indexOf(invalidRuleId) != -1) {
                            // ???
                            list.remove(am);
                        }
                    }
                }
            }

            //?
            if (metaModel.isHasChildMetaModel()) {
                createMetaModelsFilter(invalidRuleIds, metaModel.getChildMetaModels());
            }
        }
    }

    /**
     * ???CODE:,?,?,?,?,?, ,
     * 
     * @param dependencies
     * @throws MDependencyNotFoundException
     */
    private void genRelationCode(List<MMDDependency> dependencies) throws MDependencyNotFoundException {
        Map<String, String> relationCodeCache = AdapterExtractorContext.getInstance().getRelationCodeCache();

        Set<String> errorCodes = new HashSet<String>();
        for (MMDDependency dependency : dependencies) {
            // ?HASHCODE
            // int hashCode = dependency.hashCode();
            String relationMetaModel = new StringBuilder(dependency.getOwnerMetadata().getClassifierId())
                    .append("_").append(dependency.getOwnerRole()).append("_")
                    .append(dependency.getValueMetadata().getClassifierId()).append("_")
                    .append(dependency.getValueRole()).toString();

            if (relationCodeCache.containsKey(relationMetaModel)) {
                // ??HASHCODE
                String code = relationCodeCache.get(relationMetaModel);
                if (code != null) {
                    dependency.setCode(code);
                }
            } else {
                String code = metaModelDao.genRelationCode(dependency);
                if (code == null) {
                    errorCodes.add(new StringBuilder("?:")
                            .append(dependency.getOwnerMetadata().getClassifierId()).append(",:")
                            .append(dependency.getOwnerRole()).append(",?:")
                            .append(dependency.getValueMetadata().getClassifierId()).append(",:")
                            .append(dependency.getValueRole()).toString());
                } else {
                    dependency.setCode(code);
                    // ?
                    relationCodeCache.put(relationMetaModel, dependency.getCode());
                }
            }
        }
        if (errorCodes.size() > 0) {
            String logMsg = "???:\n" + errorCodes.toString();
            log.error(logMsg);
            AdapterExtractorContext.addExtractorLog(ExtractorLogLevel.ERROR, logMsg);

            throw new MDependencyNotFoundException(errorCodes.toString());
        }

    }

    private List<AbstractMetadata> getAMetadatas(AppendMetadata aMetadata) {
        List<AbstractMetadata> dsMetadatas = new ArrayList<AbstractMetadata>(1);
        dsMetadatas.add(aMetadata.getMetadata());
        return dsMetadatas;
    }

    /**
     * ?,??,?
     * 
     * @param createMetaModel
     *            ?
     * @param modifyMetaModel
     *            ?
     * @param parentMetadatas
     *            ,??
     * @param newMetaModel
     *            ?
     * @throws MetaModelNotFoundException
     */
    private void compareRootMetaModel(MMMetaModel createMetaModel, MMMetaModel modifyMetaModel,
            List<AbstractMetadata> parentMetadatas, MMMetaModel newMetaModel) throws MetaModelNotFoundException {

        String aMetaModelCode = aMetadata.getMetaModel().getCode();
        if ("ETLActivity".equals(aMetaModelCode) || "Catalog".equals(aMetaModelCode)
                || "Pc86PowerCenter".equals(aMetaModelCode) || "AmRepository".equals(aMetaModelCode)
                || "MappingFolder".equals(aMetaModelCode) || "AmDataStandard".equals(aMetaModelCode)) {
            // ETEL,Catalog

            // ?,?,??CODE
            genMetaModelInfo(createMetaModel, modifyMetaModel);

            // ??
            List<AbstractMetadata> dbMetadatas = genMetadataService.genChildMetadatas(parentMetadatas,
                    createMetaModel);

            List<AbstractMetadata> realDbMetadatas = new ArrayList<AbstractMetadata>();
            List<AbstractMetadata> newMetadatas = newMetaModel.getMetadatas();
            for (AbstractMetadata newMetadata : newMetadatas) {
                String newMetadataCode = newMetadata.getCode();
                for (AbstractMetadata dbMetadata : dbMetadatas) {
                    if (dbMetadata.getCode().equals(newMetadataCode)) {
                        realDbMetadatas.add(dbMetadata);
                    }
                }
            }
            // ??
            // parentMetadatas = null;
            // ??
            compareMetadatas(createMetaModel, modifyMetaModel, newMetaModel, realDbMetadatas);

            if (newMetaModel.isHasChildMetaModel()) {
                // ?
                createMetaModel.setHasChildMetaModel(true);
                modifyMetaModel.setHasChildMetaModel(true);
                genChildMetaModels(createMetaModel, modifyMetaModel, realDbMetadatas, newMetaModel);
            }
        } else {
            compareMetaModel(createMetaModel, modifyMetaModel, parentMetadatas, newMetaModel);
        }
    }

    /**
     * ?,??,?
     * 
     * @param createMetaModel
     *            ?
     * @param modifyMetaModel
     *            ?
     * @param parentMetadatas
     *            ,??
     * @param newMetaModel
     *            ?
     * @throws MetaModelNotFoundException
     */
    private void compareMetaModel(MMMetaModel createMetaModel, MMMetaModel modifyMetaModel,
            List<AbstractMetadata> parentMetadatas, MMMetaModel newMetaModel) throws MetaModelNotFoundException {

        // ?,?,??CODE
        genMetaModelInfo(createMetaModel, modifyMetaModel);

        // ??
        List<AbstractMetadata> dbMetadatas = genMetadataService.genChildMetadatas(parentMetadatas, createMetaModel);
        // ??
        // parentMetadatas = null;
        // ??
        compareMetadatas(createMetaModel, modifyMetaModel, newMetaModel, dbMetadatas);

        if (newMetaModel.isHasChildMetaModel()) {
            // ?
            createMetaModel.setHasChildMetaModel(true);
            modifyMetaModel.setHasChildMetaModel(true);
            genChildMetaModels(createMetaModel, modifyMetaModel, dbMetadatas, newMetaModel);
        }

    }

    /**
     * ??,??,?,,??IO?
     * 
     * @param createMetaModel
     *            ?
     * @param modifyMetaModel
     *            ?
     * @throws MetaModelNotFoundException
     */
    private void genMetaModelInfo(MMMetaModel createMetaModel, MMMetaModel modifyMetaModel)
            throws MetaModelNotFoundException {
        String parentMCode = createMetaModel.getParentMetaModel().getCode();
        String code = createMetaModel.getCode();
        String codeKey = new StringBuilder(parentMCode).append("_").append(code).toString();

        if (AdapterExtractorContext.getInstance().getMetaModelsAttrs().containsKey(codeKey)) {
            // ?
            createMetaModel.setMAttrs(AdapterExtractorContext.getInstance().getMetaModelsAttrs().get(codeKey));
            createMetaModel
                    .setCompedRelationCode(AdapterExtractorContext.getInstance().getMetaModelsComp().get(codeKey));

            modifyMetaModel.setMAttrs(AdapterExtractorContext.getInstance().getMetaModelsAttrs().get(codeKey));
            modifyMetaModel
                    .setCompedRelationCode(AdapterExtractorContext.getInstance().getMetaModelsComp().get(codeKey));
        } else {
            try {
                metaModelDao.genStorePositionByApi(createMetaModel);
                metaModelDao.setCompedRelation(createMetaModel.getParentMetaModel(), createMetaModel);
            } catch (CompositionNotFoundException c) {
                errorCompositions
                        .add(new StringBuilder().append(parentMCode).append("-->").append(code).toString());
            }

            modifyMetaModel.setMAttrs(createMetaModel.getMAttrs());
            modifyMetaModel.setCompedRelationCode(createMetaModel.getCompedRelationCode());

            AdapterExtractorContext.getInstance().addMetaModelAttrs(codeKey, createMetaModel.getMAttrs());
            AdapterExtractorContext.getInstance().addMetaModelComp(codeKey,
                    createMetaModel.getCompedRelationCode());
        }

    }

    /**
     * ??,?,?
     * 
     * @param createMetaModel
     *            ?
     * @param modifyMetaModel
     *            ?
     * @param parentMetadatas
     *            ??
     * @param newMetaModel
     * @throws MetaModelNotFoundException
     */
    private void genChildMetaModels(MMMetaModel createMetaModel, MMMetaModel modifyMetaModel,
            List<AbstractMetadata> parentMetadatas, MMMetaModel newMetaModel) throws MetaModelNotFoundException {
        Set<MMMetaModel> childNewMetaModels = newMetaModel.getChildMetaModels();

        Set<MMMetaModel> childCreateMetaModels = new HashSet<MMMetaModel>(childNewMetaModels.size());
        Set<MMMetaModel> childModifyMetaModels = new HashSet<MMMetaModel>(childNewMetaModels.size());

        for (Iterator<MMMetaModel> iter = childNewMetaModels.iterator(); iter.hasNext();) {
            MMMetaModel childNewMetaModel = iter.next();
            if (childNewMetaModel.isHasMetadata()) {
                // ?
                // ?,?
                MMMetaModel childCreateMetaModel = childNewMetaModel.cloneOnlyMetaModel();
                MMMetaModel childModifyMetaModel = childNewMetaModel.cloneOnlyMetaModel();
                compareMetaModel(childCreateMetaModel, childModifyMetaModel, parentMetadatas, childNewMetaModel);
                childCreateMetaModels.add(childCreateMetaModel);
                childModifyMetaModels.add(childModifyMetaModel);
            }
        }
        createMetaModel.setChildMetaModels(childCreateMetaModels);
        modifyMetaModel.setChildMetaModels(childModifyMetaModels);

    }

    /**
     * ????,?,?
     * 
     * @param createMetaModel
     * @param modifyMetaModel
     * @param newMetadatas
     * @param dbMetadatas
     */
    private void compareMetadatas(MMMetaModel createMetaModel, MMMetaModel modifyMetaModel,
            MMMetaModel newMetaModel, List<AbstractMetadata> dbMetadatas) {

        List<AbstractMetadata> newMetadatas = newMetaModel.getMetadatas();
        int dbSize = dbMetadatas.size(), newSize = newMetadatas.size();

        // ???
        if (dbSize == 0) {
            // ?,???
            genCreateMetaModel(createMetaModel, newMetadatas);
            return;
        }
        if (newSize == 0) {
            // ?
            return;
        }

        // ??
        Collections.sort(newMetadatas, new MetadataComparator());
        Collections.sort(dbMetadatas, new MetadataComparator());

        int dbIndex = 0, newIndex = 0, compareInt;
        // 
        Map<String, String> mAttrs = createMetaModel.getMAttrs();

        List<AbstractMetadata> createMetadatas = new ArrayList<AbstractMetadata>(newSize >> 2);
        List<AbstractMetadata> modifyMetadatas = new ArrayList<AbstractMetadata>(newSize >> 2);

        while (newIndex < newSize && dbIndex < dbSize) {
            MMMetadata newMetadata = (MMMetadata) newMetadatas.get(newIndex);
            // -----------------
            checkMetaModel(newMetadata, mAttrs);
            MMMetadata dbMetadata = (MMMetadata) dbMetadatas.get(dbIndex);
            newMetadata.setStartTime(dbMetadata.getStartTime());
            // ?
            compareInt = newMetadata.compareTo2(dbMetadata);
            if (compareInt > 0) {
                // db?,?
                dbIndex++;
            } else if (compareInt < 0) {
                createMetadatas.add(newMetadata);
                newIndex++;
            } else {
                // ?,DB?,?NEW???
                // ?

                dealSameMetadata(modifyMetadatas, newMetaModel, newMetadata, dbMetadata);
                // ??
                newIndex++;
                dbIndex++;
            }

        }
        while (newIndex < newSize) {
            // ?,?!
            MMMetadata newMetadata = (MMMetadata) newMetadatas.get(newIndex++);
            // -----------------
            checkMetaModel(newMetadata, mAttrs);
            createMetadatas.add(newMetadata);
        }

        while (dbIndex < dbSize) {
            // ?,?
            break;
        }

        if (createMetadatas.size() > 0) {
            // ??ID
            genCreateMetaModel(createMetaModel, createMetadatas);
        }
        if (modifyMetadatas.size() > 0) {
            modifyMetaModel.setMetadatas(modifyMetadatas);
            modifyMetaModel.setHasMetadata(true);
        }
    }

    private void dealSameMetadata(List<AbstractMetadata> modifyMetadatas, MMMetaModel newMetaModel,
            MMMetadata newMetadata, MMMetadata dbMetadata) {
        newMetadata.setId(dbMetadata.getId());
        //?sheetcover??
        Map<String, TemplateTitleCover> tmplTitle = AdapterExtractorContext.getInstance().getIsCover();
        // ???
        String newName = newMetadata.getName() == null ? newMetadata.getCode() : newMetadata.getName();
        boolean isSameName = newName.equals(dbMetadata.getName());
        //      //----add by xks  ???------------
        if (AdapterExtractorContext.getInstance().getIsDBExtract() && tmplTitle != null) {
            String dbClsId = dbMetadata.getClassifierId();
            TemplateTitleCover title = tmplTitle.get(dbClsId);
            //?cover?
            if (title != null) {
                //??1
                if (title.getIsNameCover() != null && title.getIsNameCover().equals("1")) {
                    isSameName = true;
                }
            }
        }

        //----------adn by xks----------------

        if (newMetadata.getClassifierId().equals("Table")) {
            newMetadata.delAttr("nextExtent");
            newMetadata.addAttr("nextExtent", dbMetadata.getAttr("nextExtent"));
        }

        // ?
        ModifyMetadata mMetadata = null;
        mMetadata = newMetadata.genDiffAttrs(newMetaModel, dbMetadata);

        if (mMetadata != null) {
            // ???,?
            mMetadata = cleanNotExistAttr(mMetadata, isSameName);
            if (mMetadata != null) {
                // 
                mMetadata.setParentMetadata(dbMetadata.getParentMetadata());
                mMetadata.setCode(newMetadata.getCode());
                modifyMetadatas.add(mMetadata);
                // ??ID
                AdapterExtractorContext.getInstance().addNewMetadataId(mMetadata.getId(),
                        mMetadata.getClassifierId());
            } else {
                // ???ID
                AdapterExtractorContext.getInstance().addNewMetadataId(dbMetadata.getId(),
                        newMetadata.getClassifierId());
            }
        } else if (isSameName) {
            // ???ID
            AdapterExtractorContext.getInstance().addNewMetadataId(dbMetadata.getId(),
                    newMetadata.getClassifierId());
        } else {
            // ?????,???
            if (!AdapterExtractorContext.getInstance().getIsDBExtract() && newMetaModel.isHaveChangelessAttr()) {
                // ????
                AdapterExtractorContext.getInstance().addNewMetadataId(dbMetadata.getId(),
                        newMetadata.getClassifierId());
            } else {
                ModifyMetadata modifyMetadata = new ModifyMetadata();
                // ?
                modifyMetadata.setParentMetadata(dbMetadata.getParentMetadata());
                modifyMetadata.setCode(newMetadata.getCode());

                modifyMetadata.setId(newMetadata.getId());
                modifyMetadata.setName(
                        (newMetadata.getName() == null || newMetadata.getName().equals("")) ? newMetadata.getCode()
                                : newMetadata.getName());
                modifyMetadata.setClassifierId(newMetadata.getClassifierId());
                modifyMetadata.setStartTime(dbMetadata.getStartTime()); // 

                // ?,???,?,?null -_-!!
                Map<Operation, Map<String, String>> modifyAttrs = new HashMap<Operation, Map<String, String>>(1);
                modifyAttrs.put(Operation.CHANGELESS, newMetadata.getAttrs());
                modifyMetadata.setModifyAttrs(modifyAttrs);

                modifyMetadatas.add(modifyMetadata);
                // ??ID
                AdapterExtractorContext.getInstance().addNewMetadataId(dbMetadata.getId(),
                        newMetadata.getClassifierId());
            }
        }

    }

    private ModifyMetadata cleanNotExistAttr(ModifyMetadata metadata, boolean isSameName) {
        String metaModelCode = metadata.getClassifierId();
        if (errorAttrs.containsKey(metaModelCode)) {
            // ?
            Map<Operation, Map<String, String>> modifyAttrs = metadata.getModifyAttrs();
            if (modifyAttrs != null) {
                Map<String, String> createAttrs = modifyAttrs.get(Operation.CREATE);
                if (createAttrs != null) {
                    Set<String> errorMAttrs = errorAttrs.get(metaModelCode);
                    for (String errorMAttr : errorMAttrs) {
                        // ?
                        createAttrs.remove(errorMAttr);
                    }
                    if (createAttrs.size() == 0) {
                        modifyAttrs.remove(Operation.CREATE);
                    }
                }

            }
            if ((modifyAttrs == null || modifyAttrs.size() == 0
                    || (modifyAttrs.get(Operation.CREATE) == null && modifyAttrs.get(Operation.DELETE) == null))
                    && metadata.getMAttrs().size() == 0 && isSameName) {
                // ??,?????
                return null;
            }
        }
        return metadata;
    }

    /**
     * ???ID,???ID?,?<br>
     * ID??<s>SEQUENCE?,SEQUENCE20,?20,??</s><br>
     * UUID?32?
     * 
     * @param createMetaModel
     *            ?
     * @param createMetadatas
     *            ??
     */
    private void genCreateMetaModel(MMMetaModel createMetaModel, List<AbstractMetadata> createMetadatas) {
        for (AbstractMetadata createMetadata : createMetadatas) {
            createMetadata.setId(sequenceDao.getUuid());
            // ??ID
            AdapterExtractorContext.getInstance().addNewMetadataId(createMetadata.getId(),
                    createMetadata.getClassifierId());
        }
        createMetaModel.setMetadatas(createMetadatas);
        createMetaModel.setHasMetadata(true);

    }

    private void checkMetaModel(MMMetadata newMetadata, Map<String, String> mAttrs) {
        Map<String, String> dAttrs = newMetadata.getAttrs();
        for (Iterator<String> iter = dAttrs.keySet().iterator(); iter.hasNext();) {
            String metaModelAttr = iter.next();
            if (!mAttrs.containsKey(metaModelAttr)) {
                // ??
                String metaModelCode = newMetadata.getClassifierId();
                if (errorAttrs.containsKey(metaModelCode)) {
                    errorAttrs.get(metaModelCode).add(metaModelAttr);
                } else {
                    Set<String> attrs = new HashSet<String>();
                    attrs.add(metaModelAttr);
                    errorAttrs.put(metaModelCode, attrs);
                }
            }
        }

    }

    /**
     * ??
     * 
     * @author qhchen
     * @version 1.0 Date: Sep 30, 2009
     */
    private static class MetadataComparator implements Comparator<AbstractMetadata> {

        /**
         * ?,?
         * 
         * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
         */
        public int compare(AbstractMetadata o1, AbstractMetadata o2) {
            // ?
            int compareInt = o1.getParentMetadata().getId().compareTo(o2.getParentMetadata().getId());
            if (compareInt == 0) {
                // ?,?code
                compareInt = o1.getCode().compareTo(o2.getCode());
            }
            return compareInt;
        }

    }

    public void setMetaModelDao(IMetaModelDao metaModelDao) {
        this.metaModelDao = metaModelDao;
    }

}