//$Id: ForeignerListener.java,v 1.1 2007-3-17 下午03:06:05 chaostone Exp $ /* * * Copyright c 2005-2009. * * Licensed under GNU LESSER General Public License, Version 3. * http://www.gnu.org/licenses * */ /******************************************************************************** * @author chaostone * * MODIFICATION DESCRIPTION * * Name Date Description * ============ ============ ============ *chaostone 2007-3-17 Created * ********************************************************************************/ package org.beanfuse.transfer.importer.listener; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.lang.StringUtils; import org.beanfuse.entity.Model; import org.beanfuse.model.Entity; import org.beanfuse.model.EntityUtils; import org.beanfuse.persist.EntityDao; import org.beanfuse.persist.EntityService; import org.beanfuse.transfer.TransferResult; import org.beanfuse.transfer.importer.MultiEntityImporter; /** * 导入数据外键监听器<br> * 这里尽量使用entityDao,因为在使用entityService加载其他代码时,hibernate会保存还未修改外的"半成对象"<br> * 从而造成有些外键是空对象的错误<br> * 如果外键不存在,则目标中的外键会置成null;<br> * 如果外键是空的,那么目标的外键取决于importer.isIgnoreNull取值 * * @author chaostone * */ public class ImporterForeignerListener extends ItemImporterListener { protected EntityDao entityDao; protected Map foreigersMap = new HashMap(); private static final int CACHE_SIZE = 500; private String[] foreigerKeys = { "code" }; private boolean multiEntity = false; public ImporterForeignerListener(EntityService entityService) { if (null != entityService) { entityDao = entityService.getEntityDao(); } } public ImporterForeignerListener(EntityDao entityDao) { this.entityDao = entityDao; } public void startTransfer(TransferResult tr) { if (importer.getClass().equals(MultiEntityImporter.class)) { multiEntity = true; } super.startTransfer(tr); } public void endTransferItem(TransferResult tr) { // 过滤所有外键 for (int i = 0; i < importer.getAttrs().length; i++) { // getAttrs()得到属性,即表的第二行 String attr = importer.getAttrs()[i]; String processed = importer.processAttr(attr); int foreigerKeyIndex = 0; boolean isforeiger = false; for (; foreigerKeyIndex < foreigerKeys.length; foreigerKeyIndex++) { if (processed.endsWith("." + foreigerKeys[foreigerKeyIndex])) {// ? isforeiger = true; break; } } if (!isforeiger) continue; String codeValue = (String) importer.getCurData().get(attr); try { Object foreiger = null; // 外键的代码是空的 if (StringUtils.isEmpty(codeValue)) continue; Object entity = null; if (multiEntity) { entity = ((MultiEntityImporter) importer).getCurrent(attr); } else { entity = importer.getCurrent(); } attr = importer.processAttr(attr); Object nestedForeigner = PropertyUtils.getProperty(entity, StringUtils.substring( attr, 0, attr.lastIndexOf("."))); if (nestedForeigner instanceof Entity) { String className = EntityUtils.getEntityClassName(nestedForeigner.getClass()); Map foreignerMap = (Map) foreigersMap.get(className); if (null == foreignerMap) { foreignerMap = new HashMap(); foreigersMap.put(className, foreignerMap); } if (foreignerMap.size() > CACHE_SIZE) foreignerMap.clear(); foreiger = foreignerMap.get(codeValue); if (foreiger == null) { List foreigners = entityDao.load(Class.forName(className), foreigerKeys[foreigerKeyIndex], new Object[] { codeValue }); if (!foreigners.isEmpty()) { foreiger = foreigners.iterator().next(); foreignerMap.put(codeValue, foreiger); } else { tr.addFailure("error.model.notExist", codeValue); } } } String parentAttr = StringUtils.substring(attr, 0, attr.lastIndexOf(".")); Model.getPopulator().populateValue(parentAttr, foreiger, entity); } catch (Exception e) { throw new RuntimeException(e); } } } public void addForeigerKey(String key) { String[] foreigers = new String[foreigerKeys.length + 1]; int i = 0; for (; i < foreigerKeys.length; i++) { foreigers[i] = foreigerKeys[i]; } foreigers[i] = key; foreigerKeys = foreigers; } }