实际项目中,有时需要将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自带的帮助手册。