Java tutorial
/* * 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<->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; } } }