com.pactera.edg.am.metamanager.extractor.adapter.mapping.impl.RecordExtractMappingServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.pactera.edg.am.metamanager.extractor.adapter.mapping.impl.RecordExtractMappingServiceImpl.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.adapter.mapping.impl;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.MultiMap;
import org.apache.commons.collections.map.MultiValueMap;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.pactera.edg.am.metamanager.app.bo.TRecordClassifier;
import com.pactera.edg.am.metamanager.app.bo.TRecordFeature;
import com.pactera.edg.am.metamanager.app.bo.TRecordRelationship;
import com.pactera.edg.am.metamanager.app.recordextra.vo.TRecordConfigFull;
import com.pactera.edg.am.metamanager.core.common.connect.ConnectionVisitor;
import com.pactera.edg.am.metamanager.core.common.connect.ResultSetGetter;
import com.pactera.edg.am.metamanager.core.dao.session.SessionInterceptor;
import com.pactera.edg.am.metamanager.extractor.adapter.mapping.IMetadataMappingService;
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.util.AdapterExtractorContext;
import com.pactera.edg.am.metamanager.extractor.util.MetadataMap;
import com.pactera.edg.am.metamanager.extractor.util.MetadataMap.MdKey;

/**
 * ??+?
 * ???
 *
 * @author fbchen
 * @version 1.0  Date: 2010-1-15 ?03:39:18
 */
public class RecordExtractMappingServiceImpl extends BaseMappingServiceImpl implements IMetadataMappingService {
    private static Log log = LogFactory.getLog(RecordExtractMappingServiceImpl.class);

    // ?N?
    public static final int SIZE = 5000;

    // 
    private ConnectionVisitor connectionVisitor;

    protected ConnectionVisitor getConnectionVisitor() {
        return connectionVisitor;
    }

    public void setConnectionVisitor(ConnectionVisitor connectionVisitor) {
        this.connectionVisitor = connectionVisitor;
    }

    // ??KEYClassifier+|+InstanceIdVALUEInstance
    private MetadataMap mdReferences = new MetadataMap();

    // ?Key?TRecordRelationshipValueMultiMap:(?uid-->?uid)
    private Map<TRecordRelationship, MultiMap> depReferences = new HashMap<TRecordRelationship, MultiMap>();

    /**
     * TRecordConfigFull
     */
    private TRecordConfigFull cfg = null;

    /**
     * RMI???
     * @return TRecordConfigFull
     */
    private TRecordConfigFull getTRecordConfigFull() {
        AdapterExtractorContext context = AdapterExtractorContext.getInstance();
        String datasourceId = context.getDatasourceId();
        return context.getIClassifier().getRecordConfigFullBy(datasourceId);
    }

    /* (non-Javadoc)
     * @see com.pactera.edg.am.metamanager.extractor.adapter.mapping.IMetadataMappingService
     * #metadataMapping(com.pactera.edg.am.metamanager.extractor.bo.mm.AppendMetadata)
     */
    public void metadataMapping(AppendMetadata metadata) throws Exception {
        SessionInterceptor si = new SessionInterceptor();
        si.setSessionFactory(connectionVisitor.getSessionFactory());
        try {
            // Session
            si.beginIntercept();

            // rmi??
            this.cfg = this.getTRecordConfigFull();
            List<TRecordClassifier> tops = cfg.getTopConfigedClassifier();

            // ???
            for (int i = 0; i < tops.size(); i++) {
                MMMetaModel childmm = this.extractData(metadata.getMetaModel(), metadata.getMetadata(), cfg,
                        tops.get(i));
                metadata.getChildMetaModels().add(childmm);
            }

            // ???
            metadata.setDDependencies(this.extractDependency(cfg));

            // ??
            this.mdReferences.clear();
            this.depReferences.clear();

        } finally {
            // ??
            si.endIntercept(); //Session
            connectionVisitor.destroy();
        }
    }

    /**
     * ??????
     * ???????
     * @param parentMetamodel 
     * @param parentMetadata ?
     * @param cfg ?
     * @param cls 
     * @return MMMetaModel???????
     * @throws SQLException 
     */
    protected MMMetaModel extractData(MMMetaModel parentMetamodel, MMMetadata parentMetadata, TRecordConfigFull cfg,
            TRecordClassifier cls) throws SQLException {
        MMMetaModel mm = this.getMetamodel(parentMetamodel, cls.getClassifier());

        // ?
        List<TRecordRelationship> depList = cfg.findDependencyByToClassifier(cls.getClassifier());

        if (log.isInfoEnabled()) {
            StringBuffer sb = new StringBuffer();
            sb.append("?Classifier=").append(cls.getCpath());
            sb.append(" IdRef=").append(cls.getIdRef());
            sb.append(" InstanceCodeRef=").append(cls.getInstanceCodeRef());
            sb.append(" InstanceNameRef=").append(cls.getInstanceNameRef());
            sb.append(" SQL=").append(cls.getSqlScript());
            log.info(sb.toString());
        }
        ResultSetGetter rs = null;
        Page page = new Page(0, SIZE);
        while (true) {
            rs = connectionVisitor.query(cls.getSqlScript(), page.startIndex, page.pageSize);
            if (log.isInfoEnabled()) {
                log.info("" + (page.startIndex / page.pageSize + 1) + ""
                        + (rs.getRowCount()) + "?");
            }
            for (int i = 0; i < rs.getRowCount(); i++) {
                Map<String, Object> row = rs.getRow(i);
                List<TRecordFeature> fs = cfg.findClassFeature(cls.getCpath());
                MMMetadata d = this.generateMetadata(parentMetadata, row, cls, fs);
                MdKey mdKey = MetadataMap.getMetadataKey(d);
                if (!this.mdReferences.containsKey(mdKey)) {//??????
                    this.mdReferences.put(mdKey, d); //
                    mm.addMetadata(d);
                    mm.setHasMetadata(true);
                }

                // ??
                this.prepareDependencyRelation(row, depList);
            }

            if (rs.getRowCount() < SIZE) { //??
                break;
            }
            page.next();
        }

        // ??
        if (mm.getMetadatas().isEmpty()) {
            return mm;
        }
        // ???
        List<TRecordRelationship> comList = cfg.findClassComposition(cls.getCpath());
        for (int i = 0; i < comList.size(); i++) {
            TRecordRelationship comRel = comList.get(i);
            this.extractChildData(mm, cfg, comRel);
        }

        return mm;
    }

    /**
     * ???????MapfromKey&lt;-&gt;toKey
     * @param parentMetamodel 
     * @param cfg ?
     * @param comRel ?
     * @throws SQLException ?
     */
    protected void extractChildData(MMMetaModel parentMetamodel, TRecordConfigFull cfg, TRecordRelationship comRel)
            throws SQLException {
        TRecordClassifier cls = cfg.findChildClassifier(comRel.getCpath(), comRel.getToClassifier());
        if (cls == null) {
            log.warn("??" + comRel.getCpath() + "/" + comRel.getToClassifier());
            return;
        }
        MMMetaModel mm = this.getMetamodel(parentMetamodel, cls.getClassifier());

        // ?Composition:KEY??KeyVALUE?Key
        Map<MdKey, MdKey> map = null;
        if (comRel.useSql()) {
            map = this.queryCompositionRelation(comRel); //?
            if (map.isEmpty()) { //??
                return;
            }
        }

        // ?dependency prepare
        List<TRecordRelationship> depList = cfg.findDependencyByToClassifier(cls.getClassifier());

        // ???
        if (log.isInfoEnabled()) {
            StringBuffer sb = new StringBuffer();
            sb.append("?Classifier=").append(cls.getCpath());
            sb.append(" IdRef=").append(cls.getIdRef());
            sb.append(" InstanceCodeRef=").append(cls.getInstanceCodeRef());
            sb.append(" InstanceNameRef=").append(cls.getInstanceNameRef());
            sb.append(" SQL=").append(cls.getSqlScript());
            log.info(sb.toString());
        }
        ResultSetGetter rs = null;
        Page page = new Page(0, SIZE);
        while (true) {
            rs = connectionVisitor.query(cls.getSqlScript(), page.startIndex, page.pageSize);
            if (log.isInfoEnabled()) {
                log.info("" + (page.startIndex / page.pageSize + 1) + ""
                        + (rs.getRowCount()) + "?");
            }
            for (int i = 0; i < rs.getRowCount(); i++) {
                Map<String, Object> row = rs.getRow(i);
                String uid = extractValue(row, cls.getIdRef());
                MdKey childKey = MetadataMap.getMetadataKey(cls.getClassifier(), uid);
                MdKey parentKey = this.getParentMetadataKey(row, comRel, map, childKey); //?
                if (parentKey == null) {
                    continue;
                }

                // ??????
                MMMetadata parentMetadata = this.mdReferences.get(parentKey);
                if (parentMetadata == null) {
                    //log.warn("???" + comRel.getCpath());
                    continue;
                }

                List<TRecordFeature> fs = cfg.findClassFeature(cls.getCpath()); //
                MMMetadata d = this.generateMetadata(parentMetadata, row, cls, fs);
                MdKey mdKey = MetadataMap.getMetadataKey(d);
                if (!this.mdReferences.containsKey(mdKey)) {//??????
                    this.mdReferences.put(mdKey, d); //
                    mm.addMetadata(d);
                    mm.setHasMetadata(true);
                }

                // ??
                this.prepareDependencyRelation(row, depList);
            }

            if (rs.getRowCount() < SIZE) { //??
                break;
            }
            page.next();
        }

        // ??
        if (mm.getMetadatas().isEmpty()) {
            return;
        }
        // ???
        List<TRecordRelationship> comList = cfg.findClassComposition(cls.getCpath());
        for (int i = 0; i < comList.size(); i++) {
            TRecordRelationship childComRel = comList.get(i);
            this.extractChildData(mm, cfg, childComRel); //
        }

    }

    /**
     * ?????????<br>
     * ??depReferences?????
     * @param cfg ?
     * @return ?
     * @throws SQLException ?
     */
    protected List<MMDDependency> extractDependency(TRecordConfigFull cfg) throws SQLException {
        // ??
        List<TRecordRelationship> depList = cfg.findAllDependency();
        for (int i = 0; i < depList.size(); i++) {
            if (depList.get(i).useSql()) {
                this.queryDependencyRelation(depList.get(i));
            }
        }

        // ? (???????)
        List<MMDDependency> result = new ArrayList<MMDDependency>();
        for (Iterator<TRecordRelationship> depIt = this.depReferences.keySet().iterator(); depIt.hasNext();) {
            TRecordRelationship depc = depIt.next();
            MultiMap map = this.depReferences.get(depc);
            for (Iterator<?> fromIt = map.keySet().iterator(); fromIt.hasNext();) {
                String fromId = (String) fromIt.next();
                Collection<?> toIds = (Collection<?>) map.get(fromId); //MultiMap
                if (toIds == null || toIds.isEmpty()) {
                    continue;
                }
                MdKey fromKey = MetadataMap.getMetadataKey(depc.getFromClassifier(), fromId);
                List<MMMetadata> fromMetadatas = this.mdReferences.getByInherit(fromKey, cfg.getInherits());
                if (fromMetadatas == null || fromMetadatas.isEmpty()) {
                    continue;
                }
                for (Iterator<?> toIt = toIds.iterator(); toIt.hasNext();) {
                    String toId = (String) toIt.next();
                    MdKey toKey = MetadataMap.getMetadataKey(depc.getToClassifier(), toId);
                    List<MMMetadata> toMetadatas = this.mdReferences.getByInherit(toKey, cfg.getInherits());
                    if (toMetadatas == null || toMetadatas.isEmpty()) {
                        continue;
                    }

                    for (Iterator<MMMetadata> it1 = fromMetadatas.iterator(); it1.hasNext();) {
                        MMMetadata fromMetadata = it1.next();
                        for (Iterator<MMMetadata> it2 = toMetadatas.iterator(); it2.hasNext();) {
                            MMMetadata toMetadata = it2.next();
                            MMDDependency dependency = new MMDDependency();
                            dependency.setOwnerMetadata(fromMetadata);
                            dependency.setValueMetadata(toMetadata);
                            dependency.setOwnerRole(depc.getFromRole());
                            dependency.setValueRole(depc.getToRole());
                            result.add(dependency);
                        }
                    }
                }
            }
        }

        return result;
    }

    /**
     * ???Key??Key??<br>
     * 1?useSql??Map????Key<br>
     * 2??useSql?row????
     * @param row ?
     * @param comRel ?
     * @param comMap ??Map?null
     * @param childMetadataKey ??Key
     * @return ??Keynull
     */
    private MdKey getParentMetadataKey(Map<String, Object> row, TRecordRelationship comRel,
            Map<MdKey, MdKey> comMap, MdKey childMetadataKey) {
        MdKey parentKey = null; //?
        if (comRel.useSql()) {
            if (comMap.containsKey(childMetadataKey)) {
                parentKey = comMap.get(childMetadataKey);
            }
        } else {
            String parentId = extractValue(row, comRel.getFromColumns());
            parentKey = MetadataMap.getMetadataKey(comRel.getFromClassifier(), parentId);
        }
        return parentKey;
    }

    /**
     * ??????????
     * @param row 
     * @param depList ?(???)
     */
    private void prepareDependencyRelation(Map<String, Object> row, List<TRecordRelationship> depList) {
        if (depList == null || depList.isEmpty()) {
            return;
        }
        for (int i = 0; i < depList.size(); i++) {
            TRecordRelationship depc = depList.get(i);
            if (depc.useSql()) {
                continue;
            }
            MultiMap map = this.depReferences.get(depc);
            if (map == null) {
                map = new MultiValueMap();
                this.depReferences.put(depc, map);
            }
            String fromId = extractValue(row, depc.getFromColumns());
            String toId = extractValue(row, depc.getToColumns());
            map.put(fromId, toId);
        }
    }

    /**
     * ????
     * @param depc ?
     * @return MultiMapKEY?{@link #getMetadataKey(String, String)}
     * @throws SQLException ?
     */
    private MultiMap queryDependencyRelation(TRecordRelationship depc) throws SQLException {
        if (log.isInfoEnabled()) {
            StringBuffer sb = new StringBuffer();
            sb.append("?FROM=").append(depc.getFromClassifier());
            sb.append(" TO=").append(depc.getToClassifier());
            sb.append(" FromRole=").append(depc.getFromRole()).append(" ToRole=").append(depc.getToRole());
            sb.append(" FromColumns=").append(depc.getFromColumns()).append(" ToColumns=")
                    .append(depc.getToColumns());
            sb.append("  SQL=").append(depc.getRelSqlScript());
            log.info(sb.toString());
        }

        MultiMap map = this.depReferences.get(depc);
        if (map == null) {
            map = new MultiValueMap();
            this.depReferences.put(depc, map);
        }

        Page page = new Page(0, SIZE);
        ResultSetGetter rs = null;
        while (true) {
            rs = connectionVisitor.query(depc.getRelSqlScript(), page.startIndex, page.pageSize);
            if (log.isInfoEnabled()) {
                log.info("" + (page.startIndex / page.pageSize + 1) + ""
                        + (rs.getRowCount()) + "?");
            }
            for (int i = 0, count = rs.getRowCount(); i < count; i++) {
                Map<String, Object> row = rs.getRow(i);
                String fromId = extractValue(row, depc.getFromColumns());
                String toId = extractValue(row, depc.getToColumns());
                MdKey fromKey = MetadataMap.getMetadataKey(depc.getFromClassifier(), fromId);
                MdKey toKey = MetadataMap.getMetadataKey(depc.getToClassifier(), toId);
                if (!this.mdReferences.containsKeyInherit(fromKey, cfg.getInherits())) {
                    continue; // From??
                }
                if (!this.mdReferences.containsKeyInherit(toKey, cfg.getInherits())) {
                    continue; // To??
                }
                map.put(fromId, toId);
            }

            if (rs.getRowCount() < SIZE) { //??
                break;
            }
            page.next();
        }
        return map;
    }

    /**
     * ????
     * @param comp ?
     * @return MapKEY??KeyVALUE?Key ?{@link #getMetadataKey(String, String)}
     * @throws SQLException ?
     */
    private Map<MdKey, MdKey> queryCompositionRelation(TRecordRelationship comp) throws SQLException {
        if (log.isInfoEnabled()) {
            StringBuffer sb = new StringBuffer();
            sb.append("?FROM=").append(comp.getFromClassifier());
            sb.append(" TO=").append(comp.getToClassifier());
            sb.append(" FromColumns=").append(comp.getFromColumns()).append(" ToColumns=")
                    .append(comp.getToColumns());
            sb.append(" SQL=").append(comp.getRelSqlScript());
            log.info(sb.toString());
        }

        Map<MdKey, MdKey> map = new HashMap<MdKey, MdKey>();
        Page page = new Page(0, SIZE);
        ResultSetGetter rs = null;
        while (true) {
            rs = connectionVisitor.query(comp.getRelSqlScript(), page.startIndex, page.pageSize);
            if (log.isInfoEnabled()) {
                log.info("" + (page.startIndex / page.pageSize + 1) + ""
                        + (rs.getRowCount()) + "?");
            }
            for (int i = 0, count = rs.getRowCount(); i < count; i++) {
                Map<String, Object> row = rs.getRow(i);
                String fromId = extractValue(row, comp.getFromColumns());
                String toId = extractValue(row, comp.getToColumns());
                MdKey fromKey = MetadataMap.getMetadataKey(comp.getFromClassifier(), fromId);
                if (!this.mdReferences.containsKey(fromKey)) { //????
                    continue;
                }
                MdKey toKey = MetadataMap.getMetadataKey(comp.getToClassifier(), toId);
                map.put(toKey, fromKey);
            }

            if (rs.getRowCount() < SIZE) { //??
                break;
            }
            page.next();
        }
        return map;
    }

    /**
     * ????
     * @param rs 
     * @param columnExpr ???
     * @return ????
     */
    protected String extractValue(Map<String, Object> row, String columnExpr) {
        if (StringUtils.isEmpty(columnExpr)) {
            return null;
        }
        Object value = row.get(columnExpr.toUpperCase()); //what if not a column, like OGNL expr?
        if (value == null) {
            value = row.get(columnExpr); //some db donot return uppercase column
        }
        return value == null ? null : String.valueOf(value).trim();
    }

    /**
     * ???????
     * @param parentMetadata ?
     * @param row ?
     * @param cls 
     * @param fs 
     * @return MMMetadata
     */
    private MMMetadata generateMetadata(MMMetadata parentMetadata, Map<String, Object> row, TRecordClassifier cls,
            List<TRecordFeature> fs) {
        MMMetadata d = new MMMetadata();
        d.setClassifierId(cls.getClassifier());
        d.setParentMetadata(parentMetadata);
        parentMetadata.addChildMetadata(d);
        d.setUid(extractValue(row, cls.getIdRef()));
        d.setCode(extractValue(row, cls.getInstanceCodeRef()));
        d.setName(extractValue(row, cls.getInstanceNameRef()));

        Map<String, String> features = new HashMap<String, String>();
        for (int j = 0; fs != null && j < fs.size(); j++) {
            TRecordFeature f = fs.get(j);
            features.put(f.getFeatureCode(), extractValue(row, f.getColumnExpr()));
        }
        d.setAttrs(features);
        return d;
    }

    /**
     * ??
     * @param parentMetamodel 
     * @param classifier ?
     * @return 
     */
    private MMMetaModel getMetamodel(MMMetaModel parentMetamodel, String classifier) {
        MMMetaModel mm = parentMetamodel.getChildMetaModel(classifier);
        if (mm == null) {
            mm = parentMetamodel.addChildMetaModel(classifier);
            parentMetamodel.setHasChildMetaModel(true);
        }
        return mm;
    }

    /**
     * ?
     * @author fbchen
     * @version 1.0  Date: 2010-1-18 ?11:24:19
     */
    protected static class Page {
        int startIndex;
        int endIndex;
        int pageSize;

        // ?
        public Page(int startIndex, int pageSize) {
            this.startIndex = startIndex;
            this.endIndex = startIndex + pageSize;
            this.pageSize = pageSize;
        }

        // 
        public Page next() {
            this.startIndex = this.endIndex;
            this.endIndex = this.endIndex + this.pageSize;
            return this;
        }
    }
}