Domino数据迁移

    实际项目中,有时需要将Domino系统的数据迁移到J2EE系统中,因此需要通过Domino的接口获取Domino的数据然后存放到J2EE系统中。

    Domino提供了Java访问接口(NCSO.jar),通过它可以很方便的访问Domino。以下是实际项目中开发的数据迁移功能部分代码,仅供参考。

/**
 * DominoDataImporter domino数据处理接口,负责将domino数据存入到J2EE系统
 *
 * @version 1.0 2011-5-16
 * @author zhanzhengqiang
 */
public interface DominoDataImporter {

    /**
     * 文档处理
     * @param document 待处理文档
     * @return true 成功,false失败
     */
    public boolean dealDocument(DominoDocument document);
}    

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Vector;

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

import lotus.domino.DateTime;
import lotus.domino.Document;
import lotus.domino.EmbeddedObject;
import lotus.domino.Item;
import lotus.domino.NotesException;
import lotus.domino.RichTextItem;

/**
 * DominoDocument Domino文档封装类,提供文档中各种数据的访问方法
 *
 * @version 1.0 2011-5-16
 * @author zhanzhengqiang
 */
public class DominoDocument {

    /**
     * 日志对象
     */
    private static Log log = LogFactory.getLog(DominoDocument.class);
    
    /**
     * Domino文档
     */
    private Document document;
    
    /**
     * 构造方法
     * @param document
     */
    public DominoDocument(Document document) {
        this.document = document;
    }
    
    /**
     * 获取字符串域(单值域)值
     * @param itemName
     * @return 没有返回""
     */
    public String getString(String itemName) {
        String retValue = "";
        try {
            if (document.hasItem(itemName)) {
                retValue = document.getItemValueString(itemName);
            } else {
                log.debug("域" + itemName + "不存在");
            }
        } catch (NotesException e) {
            log.error("获取域" + itemName + "的值失败:" + e.getMessage());
            retValue = "";
        }
        if (log.isDebugEnabled()) {
            log.debug("获取到域[" + itemName + "]的值为:" + retValue);
        }
        return retValue;
    }
    
    /**
     * 获取字符串列表(多值域)值
     * @param itemName
     * @return 域值列表
     */
    public List getStringList(String itemName) {
        List retValue = new ArrayList();
        try {
            if (document.hasItem(itemName)) {
                log.debug("多值域域值列表:");
                Vector retItem = document.getItemValue(itemName);
                for (int i = 0; i < retItem.size(); i++) {
                    if (log.isDebugEnabled()) {
                        log.debug("域值" + (i+1) + "为:" + retItem.get(i));
                    }
                    retValue.add(retItem.get(i));
                }
            } else {
                log.debug("域" + itemName + "不存在");
            }
        } catch (NotesException e) {
            log.error("获取域" + itemName + "的值失败:" + e.getMessage());
        }
        return retValue;
    }
    
    /**
     * 获取日期时间域值
     * @param itemName
     * @return
     */
    public Date getDateTime(String itemName) {
        Date retValue = null;
        try {
            if (document.hasItem(itemName)) {
                Vector retItem = document.getItemValueDateTimeArray(itemName);
                if (!retItem.isEmpty()) {
                    DateTime dateTime = (DateTime)retItem.get(0);
                    retValue = dateTime.toJavaDate();
                }
            } else {
                log.debug("域" + itemName + "不存在");
            }
        } catch (NotesException e) {
            log.error("获取日期时间域" + itemName + "的值失败:" + e.getMessage());
        }
        if (log.isDebugEnabled()) {
            log.debug("获取到日期时间域[" + itemName + "]的值为:" + retValue);
        }
        return retValue;
    }
    
    /**
     * 获取整数域值
     * @param itemName
     * @return
     */
    public int getInteger(String itemName) {
        int retValue = 0;
        try {
            if (document.hasItem(itemName)) {
                retValue = document.getItemValueInteger(itemName);
            } else {
                log.debug("域" + itemName + "不存在");
            }
        } catch (NotesException e) {
            log.error("获取整数域" + itemName + "的值失败:" + e.getMessage());
        }
        if (log.isDebugEnabled()) {
            log.debug("获取到整数域[" + itemName + "]的值为:" + retValue);
        }
        return retValue;
    }
    
    /**
     * 根据域名获取域中存放的文件
     * @param fieldName
     * @return
     */
    public EmbeddedObject getFileByFieldName(String fieldName) {
        EmbeddedObject retValue = null;
        try {
            if (document.hasItem(fieldName)) {
                Item item = document.getFirstItem(fieldName);
                if (item.getType() == Item.RICHTEXT) {
                    // 转换为RichTextItem
                    RichTextItem rtfItem = (RichTextItem)item;
                    // 取EmbeddedObject
                    Vector embeddedObjects = rtfItem.getEmbeddedObjects();
                    for (int i = 0; i < embeddedObjects.size(); i++) {
                        EmbeddedObject obj = (EmbeddedObject)embeddedObjects.get(i);
                        if (obj.getType() == EmbeddedObject.EMBED_ATTACHMENT) {
                            retValue = obj;
                            break;
                        }
                    }
                }
            } else {
                log.debug("RTF域[" + fieldName + "]不存在");
            }
        } catch (NotesException e) {
            log.error("获取RTF域" + fieldName + "的值失败:" + e.getMessage());
        }
        
        // 输出调试信息
        if (log.isDebugEnabled()) {
            if (retValue != null) {
                try {
                    log.debug("获取RTF域[" + fieldName + "]对应文件为:" + retValue.getName());
                } catch (NotesException e) {}
            } else {
                log.debug("RTF域[" + fieldName + "]暂时没有文件");
            }
        }
        
        return retValue;
    }
    
    /**
     * 根据文件名获取文件
     * @param fileName
     * @return
     */
    public EmbeddedObject getFileByName(String fileName) {
        EmbeddedObject retValue = null;
        try {
            if (document.hasEmbedded()) {
                retValue = document.getAttachment(fileName);
            }
        } catch (NotesException e) {
            log.error("获取文件[" + fileName + "]出错:" + e.getMessage());
        }
        if (log.isDebugEnabled()) {
            log.debug("文件[" + fileName + "]不存在");
        }
        return retValue;
    }
    
    /**
     * 获取所有文件, 根据文件名获取附件,如果文件名含特殊字符会导致获取文件为null
     * 如文件:"附件3:关于中共×××党支部党员大会会议选举结果的报告.doc"
     * @return
     */
    public List getAllFiles() {
        List retValue = new ArrayList();
        try {
            if (document.hasEmbedded()) {
                Vector items = document.getItems();
                for (int i = 0; i < items.size(); i++) {
                    Item item = (Item)items.get(i);
                    // 如果不是附件则跳过
                    if (item.getType() != Item.ATTACHMENT) {
                        continue;
                    }
                    // 根据附件名称获取附件对象
                    String attachName = item.getValueString();
                    if (log.isDebugEnabled()) {
                        log.debug("文件名称:" + attachName);
                    }
                    EmbeddedObject attach = document.getAttachment(attachName);
                    if (attach != null) {
                        retValue.add(attach);
                    } else {
                        log.error("获取文件[" + attachName + "]失败");
                    }
                }
            } else {
                log.debug("文档中没有引入文件");
            }
        } catch (NotesException e) {
            log.error("获取文档所有附加文件出错:" + e.getMessage());
        }
        
        // 输出调试信息
        if (log.isDebugEnabled()) {
            log.debug("获取到文件列表如下:");
            for (int i = 0; i < retValue.size(); i++) {
                EmbeddedObject obj = (EmbeddedObject)retValue.get(i);
                try {
                    log.debug("第" + (i+1) + "个文件:" + obj.getName());
                } catch (NotesException e) {}
            }
        }
        return retValue;
    }

    /**
     * 获取所有文件
     * @return
     */
    public List getAllFiles2() {
        List retValue = new ArrayList();
        HashMap fileNames = new HashMap();
        try {
            if (document.hasEmbedded()) {
                Vector items = document.getItems();
                for (int i = 0; i < items.size(); i++) {
                    Item item = (Item)items.get(i);
                    // 如果不是RichTextItem则跳过
                    if (item.getType() != Item.RICHTEXT) {
                        continue;
                    }
                    Vector embeddedObjects = ((RichTextItem)item).getEmbeddedObjects();
                    if (embeddedObjects.size() <= 0) {
                        log.debug("域[" + item.getName() + "]不包含文件");
                    }    
                    
                    for (int k = 0; k < embeddedObjects.size(); k++) {
                        EmbeddedObject embeddedObject = (EmbeddedObject)embeddedObjects.get(k);
                        if (embeddedObject.getType() == EmbeddedObject.EMBED_ATTACHMENT) {
                            // 判断是否已经添加,没有添加
                            String gettedFileName = embeddedObject.getName();
                            if (fileNames.get(gettedFileName) == null) {
                                retValue.add(embeddedObject);
                                fileNames.put(gettedFileName, "");
                                if (log.isDebugEnabled()) {
                                    log.debug("获取到文件:" + gettedFileName);
                                }
                            }
                        }
                    }
                }
            } else {
                log.debug("文档中没有引入文件");
            }
        } catch (NotesException e) {
            log.error("获取文档所有附加文件出错:" + e.getMessage());
        }
        
        // 输出调试信息
        if (log.isDebugEnabled()) {
            log.debug("获取到文件列表如下:");
            for (int i = 0; i < retValue.size(); i++) {
                EmbeddedObject obj = (EmbeddedObject)retValue.get(i);
                try {
                    log.debug("第" + (i+1) + "个文件:" + obj.getName());
                } catch (NotesException e) {}
            }
        }
        return retValue;
    }
    
    /**
     * 获取文档UNID
     * @return 如果不存在则返回null
     */
    public String getUNID() {
        String unid = null;
        try {
            unid = document.getUniversalID();
        } catch (NotesException e) {
            log.error("获取文档UNID出错");
        }
        return unid;
    }
    
    /**
     * @return the document
     */
    public Document getDocument() {
        return document;
    }
}

/**
 * ImportParams Domino数据导入参数封装类
 *
 * @version 1.0 2011-5-18
 * @author zhanzhengqiang
 */
public class ImportParams {

    /**
     * Domino服务器地址
     */
    private String server;
    
    /**
     * Domino服务器端口
     */
    private String port;
    
    /**
     * 连接Domino服务器用户名
     */
    private String userName;
    
    /**
     * 连接Domino服务器密码
     */
    private String password;
    
    /**
     * 导入Domino数据库路径
     */
    private String database;
    
    /**
     * 导入Domino数据库视图
     */
    private String view;
    
    /**
     * 导入Domino数据查询条件
     * 如FORM=\"frmDispDocComFile\"&IsTrashDoc!=\"false\"
     */
    private String formula;
    
    /**
     * 导入Domino文档UnID
     */
    private String unid;

    // 忽略seter,getter方法及构造方法
}

import lotus.domino.Database;
import lotus.domino.Document;
import lotus.domino.DocumentCollection;
import lotus.domino.NotesException;
import lotus.domino.NotesFactory;
import lotus.domino.Session;
import lotus.domino.View;

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

/**
 * DominoDataImportUtil Domino数据导入工具类,
 *     负责连接Domino数据库,获取文档记录,文档的处理由DominoDataImporter接口实现类完成
 *
 * @version 1.0 2011-5-16
 * @author zhanzhengqiang
 */
public class DominoDataImportUtil {
    
    /**
     * 日志对象 
     */
    private static Log log = LogFactory.getLog(DominoDataImportUtil.class);
    
    /**
     * 导入失败文档数上限,超过上限导入终止 
     */
    private static final int IMPORT_FAIL_NUM_LIMIT = 10;
    
    /**
     * 私有构造方法
     */
    private DominoDataImportUtil() {
    }
    
    /**
     * 基于查询条件做数据库导入,如果没有查询条件,则导入整个数据库
     * @param importParams 导入参数
     * @param dominoDataImporter 文档导入处理对象,负责文档导入的业务处理
     * @param int[] 第一个元素为导入成功文档数,第二个元素为导入失败文档数
     * @throws Exception
     */
    public static int[] importByCondition(ImportParams importParams, 
        DominoDataImporter dominoDataImporter) throws Exception {
        // 获取Session
        Session session = getSession(importParams.getServer(), importParams.getPort(),
                importParams.getUserName(), importParams.getPassword());
        
        // 连接数据库
        Database database = getDataBase(session, importParams.getDatabase());
        
        // 获取数据库文档
        DocumentCollection documents = getDocuments(database, importParams.getFormula());
        
        // 计算总文档数
        int count = documents.getCount();
        // 导入成功文档数
        int succNum = 0;
        // 导入失败文档数
        int failNum = 0;
        
        // 循环处理文档
        Document document = documents.getFirstDocument();
        while (document != null) {
            // 处理文档
            boolean isSucc = dominoDataImporter.dealDocument(new DominoDocument(document));
            // 计算导入成功或失败文档数
            if (isSucc) {
                succNum = succNum + 1;
            } else {
                failNum = failNum + 1;
                // 记录到失败日志文件
            }
            // 失败导入文档超过上线时,终止导入
            if (failNum > IMPORT_FAIL_NUM_LIMIT) {
                break;
            }
            // 获取下一个文档
            document = documents.getNextDocument();
        }
        
        // 构造返回数组
        int[] retValue = new int[] {succNum, count - succNum};
        
        // 返回结果
        return retValue;
    }
    
    /**
     * 根据视图进行数据库导入
     * @param importParams 导入参数
     * @param dominoDataImporter 文档导入处理对象,负责文档导入的业务处理
     * @param int[] 第一个元素为导入成功文档数,第二个元素为导入失败文档数
     * @throws Exception
     */
    public static int[] importByView(ImportParams importParams,  
            DominoDataImporter dominoDataImporter) throws Exception {
        // 获取Session
        Session session = getSession(importParams.getServer(), importParams.getPort(),
                importParams.getUserName(), importParams.getPassword());
        // 连接数据库
        Database database = getDataBase(session, importParams.getDatabase());
        
        // 获取数据库视图
        View view = getView(database, importParams.getView());
        
        // 计算总文档数
        int count = view.getEntryCount();
        // 导入成功文档数
        int succNum = 0;
        // 导入失败文档数
        int failNum = 0;
        
        // 循环处理文档
        Document document = view.getFirstDocument();
        while (document != null) {
            // 处理文档
            boolean isSucc = dominoDataImporter.dealDocument(new DominoDocument(document));
            // 计算导入成功或失败文档数
            if (isSucc) {
                succNum = succNum + 1;
            } else {
                failNum = failNum + 1;
            }
            // 失败导入文档超过上线时,终止导入
            if (failNum > IMPORT_FAIL_NUM_LIMIT) {
                break;
            }
            // 获取下一个文档
            document = view.getNextDocument(document);
        }
        
        // 构造返回数组
        int[] retValue = new int[] {succNum, count - succNum};
        
        // 返回结果
        return retValue;
    }
    
    /**
     * 根据文档UnID导入文档
     * @param importParams 导入参数
     * @param dominoDataImporter 文档导入处理对象,负责文档导入的业务处理
     * @return true 导入成功,false 导入失败
     * @throws Exception
     */
    public static boolean importByUnID(ImportParams importParams,
            DominoDataImporter dominoDataImporter) throws Exception{
        // 获取Session
        Session session = getSession(importParams.getServer(), importParams.getPort(),
                importParams.getUserName(), importParams.getPassword());
        // 连接数据库
        Database database = getDataBase(session, importParams.getDatabase());
        // 根据UnId获取文档
        if (log.isDebugEnabled()) {
            log.debug("导入文档UnID为:" + importParams.getUnid());
        }
        
        // 如果数据库没有打开,则打开数据库
        openDataBaseIfNot(database);
        
        // 根据文档UnID获取文档
        Document document = null;
        try {
            document = database.getDocumentByUNID(importParams.getUnid());
        } catch (NotesException e) {
            throw new Exception("UnID为" + importParams.getUnid() + "的文档不存在");
        }
        if (document == null) {
            throw new Exception("UnID为" + importParams.getUnid() + "的文档为空");
        }
        // 导入文档
        boolean result = dominoDataImporter.dealDocument(new DominoDocument(document));
        
        // 返回导入结果
        return result;
    }
    
    /**
     * 获取Domino Session
     * @return
     */
    private static Session getSession(String server, String port, 
            String userName, String password) throws Exception{
        // 输出配置参数
        if (log.isDebugEnabled()) {
            log.debug("server:" + server + ", port:" + port 
                    + ", username:" + userName + ", password:" + password);
        }
        // 获取Session
        Session session = null;
        try {
            String hostString = server;
            if (port != null && port.trim().equals("")) {
                hostString = server + ":" + port;
            }
            session = NotesFactory.createSession(hostString, userName, password);
        } catch (NotesException e) {
            throw new Exception("创建Session失败,请检查相关参数是否正确", e.getCause());
        }
        // 如果获取Sesion为空,则抛出异常
        if (session == null) {
            throw new Exception("创建Session为空,请检查相关参数是否正确");
        }
        return session;
    }

    /**
     * 获取数据库
     * @param session Domino Session
     * @param dbPath 数据库路径 
     * @return
     * @throws Exception
     */
    private static Database getDataBase(Session session, String dbPath) throws Exception{
        if (log.isDebugEnabled()) {
            log.debug("数据库路径:" + dbPath);
        }
        // 定义返回数据库
        Database database = null;
        try {
            database = session.getDatabase(null, dbPath, false);
        } catch(NotesException e) {
            throw new Exception("获取数据库[" + dbPath + "]失败", e.getCause()) ;
        }
        // 获取数据库为空,抛出异常
        if (database == null) {
            throw new Exception("获取数据库[" + dbPath + "]为空");
        }
        return database;
    }
    
    /**
     * 打开数据库,如果数据库没有打开
     * @param database 数据库
     * @throws Exception
     */
    private static void openDataBaseIfNot(Database database) throws Exception {
        // 如果数据库已经打开,则直接返回
        if (database.isOpen()) {
            return;
        }
        // 打开数据库,如果打开失败则抛出异常
        if (!database.open()) {
            throw new Exception("打开数据库[" + database.getFilePath() + "]失败");
        }
    }
    
    /**
     * 获取数据库视图
     * @param database 数据库
     * @param viewName 视图名
     * @return
     * @throws Exception
     */
    private static View getView(Database database, String viewName) throws Exception {
        if (log.isDebugEnabled()) {
            log.debug("数据库路径:" + database.getFilePath() + ", 视图名称:" + viewName);
        }
        // 如果数据库没有打开,则打开数据库
        openDataBaseIfNot(database);
        
        // 定义返回视图
        View view = null;
        try {
            view = database.getView(viewName);
        } catch (NotesException e) {
            String message = "获取数据库[" + database.getFilePath() + "]的视图[" + viewName + "]失败";
            throw new Exception(message, e.getCause());
        }
        // 获取视图为空,抛出异常
        if (view == null) {
            throw new Exception("获取数据库[" + database.getFilePath() + "]的视图[" + viewName + "]为空");
        }
        if (log.isDebugEnabled()) {
            log.debug("共有文档数:" + view.getEntryCount());
        }
        return view;
    }
    
    /**
     * 获取所有数据库文档
     * @param database 数据库
     * @param formula 查询文档条件
     * @return
     * @throws Exception
     */
    private static DocumentCollection getDocuments(Database database, String formula) throws Exception{
        if (log.isDebugEnabled()) {
            log.debug("从数据库[" + database.getFilePath() + "]中获取满足条件[" + formula + "]的文档");
        }
        // 如果数据库没有打开,则打开数据库
        openDataBaseIfNot(database);
        
        // 获取文档
        DocumentCollection documents = null;
        try {
            // 如果查询条件为空,则获取所有文档
            if (StringUtils.isEmpty(formula)) {
                documents = database.getAllDocuments();
            } else {
                documents = database.search(formula);
            }
        } catch (NotesException e) {
            String message = "获取数据库[" + database.getFilePath() + "]中满足条件[" + formula + "]的文档失败";
            throw new Exception(message, e.getCause());
        }
        if (log.isDebugEnabled()) {
            log.debug("共有文档数:" + documents.getCount());
        }
        return documents;
    }
}
        Domino接口详细说明可以参考Domino自带的帮助手册。
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值