// 获得一条MARC/XML记录 // return: // -1 error 包括not found // 0 found // 1 为诊断记录 public int GetOneRecord( string strStyle, int nTest, // 暂时使用 string strPathParam, // int index, string strParameters, // bool bHilightBrowseLine, out string strSavePath, out string strRecord, out string strXmlFragment, out string strOutStyle, out byte[] baTimestamp, out long lVersion, out DigitalPlatform.Z3950.Record record, out Encoding currrentEncoding, out LoginInfo logininfo, out string strError) { strXmlFragment = ""; strRecord = ""; record = null; strError = ""; currrentEncoding = Encoding.UTF8; // this.CurrentEncoding; baTimestamp = null; strSavePath = ""; strOutStyle = "marc"; logininfo = new LoginInfo(); lVersion = 0; int nRet = 0; if (strStyle != "marc" && strStyle != "xml") { strError = "dp2SearchForm只支持获取MARC格式记录和xml格式记录,不支持 '" + strStyle + "' 格式的记录"; return -1; } int index = -1; string strPath = ""; string strDirection = ""; nRet = Global.ParsePathParam(strPathParam, out index, out strPath, out strDirection, out strError); if (nRet == -1) return -1; ListViewItem curItem = null; if (index == -1) { // 找到 Item 行 curItem = ListViewUtil.FindItem(this.listView_browse, strPath, 0); if (curItem == null) { strError = "路径为 '" + strPath + "' 的事项在列表中没有找到"; return -1; } index = this.listView_browse.Items.IndexOf(curItem); // strDirection 方向。为 prev/next/current之一。current可以缺省。 if (strDirection == "prev") { if (index == 0) { strError = "到头"; return -1; } index--; } else if (strDirection == "next") { index++; } } { REDO: if (index >= this.listView_browse.Items.Count) { if (this.m_nCurrentPageNo >= this.m_nTotalPages - 1) { strError = "越过结果集尾部"; return -1; } nRet = DoGetNextBatch(out strError); if (nRet == -1) return -1; WaitSearchFinish(); goto REDO; } curItem = this.listView_browse.Items[index]; } bool bHilightBrowseLine = StringUtil.IsInList("hilight_browse_line", strParameters); bool bForceFullElementSet = StringUtil.IsInList("force_full", strParameters); if (bHilightBrowseLine == true) { // 修改listview中事项的选定状态 for (int i = 0; i < this.listView_browse.SelectedItems.Count; i++) { this.listView_browse.SelectedItems[i].Selected = false; } curItem.Selected = true; curItem.EnsureVisible(); } strPath = curItem.Text; ItemInfo info = (ItemInfo)curItem.Tag; if (bForceFullElementSet == true && info.EelementSet != "F") { // 需要重新装载这一条记录 List<ListViewItem> items = new List<ListViewItem>(); items.Add(curItem); #if NO // 观察和上次操作间隔的时间。保证大于一秒 TimeSpan delta = DateTime.Now - m_timeLastReload; if (delta < new TimeSpan(0,0,1)) Thread.Sleep(1000); #endif int nRedoCount = 0; REDO_RELOAD: m_bErrorBox = false; nRet = ReloadItems(items, 0, "F", out strError); m_timeLastReload = DateTime.Now; if (nRet == -1) { return -1; } bool bError = WaitSearchFinish(); if (bError == true && this.m_exception != null && this.m_exception is WebException) { WebException ex = this.m_exception as WebException; if (ex.Status == WebExceptionStatus.ProtocolError) { // 重做 if (nRedoCount < 2) { nRedoCount++; Thread.Sleep(1000); goto REDO_RELOAD; } // 询问是否重做 DialogResult result = MessageBox.Show(this, "重新装载时发生错误:\r\n\r\n" + strError + "\r\n\r\n是否重试?\r\n\r\n(Yes: 重试; No: 中断操作", "AmazonSearchForm", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); if (result == System.Windows.Forms.DialogResult.Yes) { Thread.Sleep(1000); goto REDO_RELOAD; } return -1; } } info = (ItemInfo)curItem.Tag; } record = new DigitalPlatform.Z3950.Record(); record.m_baRecord = Encoding.UTF8.GetBytes(info.Xml); record.m_strDBName = m_searchParameters != null ? m_searchParameters["SearchIndex"] : ""; record.m_strSyntaxOID = info.PreferSyntaxOID; // ??? record.m_strElementSetName = info.EelementSet; // B F strSavePath = this.CurrentProtocol + ":" + strPath; string strOutputPath = ""; { string strContent = info.Xml; if (strStyle == "marc") { // TODO: 转换为MARC nRet = ConvertXmlToMarc( record.m_strSyntaxOID, strContent, out strRecord, out strError); if (nRet == -1) return -1; strOutStyle = "marc"; if (string.IsNullOrEmpty(record.m_strSyntaxOID) == true) record.m_strSyntaxOID = "1.2.840.10003.5.1"; // UNIMARC return 0; } // 不是MARCXML格式 strRecord = strContent; strOutStyle = "xml"; return 0; } /* return GetOneRecord( true, strStyle, strPath, "", out strRecord, out strXmlFragment, out strOutputPath, out strOutStyle, out baTimestamp, out record, out currrentEncoding, out strError); * */ return 0; }
// 保存记录 // parameters: // strStyle "saveas"另存 其他为普通保存 public int SaveRecord(string strStyle = "save") { string strError = ""; int nRet = 0; string strLastSavePath = MainForm.LastSavePath; if (String.IsNullOrEmpty(strLastSavePath) == false) { string strOutputPath = ""; nRet = ChangePathToAppendStyle(strLastSavePath, out strOutputPath, out strError); if (nRet == -1) { MainForm.LastSavePath = ""; // 避免下次继续出错 2011/3/4 goto ERROR1; } strLastSavePath = strOutputPath; } string strCurrentUserName = ""; string strSavePath = this.SavePath == "" ? strLastSavePath : this.SavePath; if (strStyle == "save" && string.IsNullOrEmpty(this.SavePath) == false && (Control.ModifierKeys & Keys.Control) == 0) { // 2011/8/8 // 保存时如果已经有了路径,就不用打开对话框了 } else { SaveRecordDlg dlg = new SaveRecordDlg(); GuiUtil.SetControlFont(dlg, this.Font); dlg.MainForm = this.MainForm; dlg.GetDtlpSearchParam += new GetDtlpSearchParamEventHandle(dlg_GetDtlpSearchParam); dlg.GetDp2SearchParam += new GetDp2SearchParamEventHandle(dlg_GetDp2SearchParam); if (strStyle == "save") dlg.RecPath = this.SavePath == "" ? strLastSavePath : this.SavePath; else { dlg.RecPath = strLastSavePath; // 2011/6/19 dlg.Text = "另存记录"; } // dlg.StartPosition = FormStartPosition.CenterScreen; this.MainForm.AppInfo.LinkFormState(dlg, "SaveRecordDlg_state"); dlg.UiState = this.MainForm.AppInfo.GetString("MarcDetailForm", "SaveRecordDlg_uiState", ""); dlg.ShowDialog(this); this.MainForm.AppInfo.SetString("MarcDetailForm", "SaveRecordDlg_uiState", dlg.UiState); if (dlg.DialogResult != DialogResult.OK) return 0; MainForm.LastSavePath = dlg.RecPath; strSavePath = dlg.RecPath; strCurrentUserName = dlg.CurrentUserName; } /* if (String.IsNullOrEmpty(this.SavePath) == true) { strError = "缺乏保存路径"; goto ERROR1; } * */ string strProtocol = ""; string strPath = ""; nRet = Global.ParsePath(strSavePath, out strProtocol, out strPath, out strError); if (nRet == -1) goto ERROR1; this.stop.BeginLoop(); this.EnableControls(false); try { // dtlp协议的记录保存 if (strProtocol.ToLower() == "dtlp") { DtlpSearchForm dtlp_searchform = this.GetDtlpSearchForm(); if (dtlp_searchform == null) { strError = "没有连接的或者打开的DTLP检索窗,无法保存记录"; goto ERROR1; } /* string strOutPath = ""; nRet = DtlpChannel.CanonicalizeWritePath(strPath, out strOutPath, out strError); if (nRet == -1) goto ERROR1; strPath = strOutPath; * */ string strOutputPath = ""; byte[] baOutputTimestamp = null; nRet = dtlp_searchform.SaveMarcRecord( strPath, this.MarcEditor.Marc, this.CurrentTimestamp, out strOutputPath, out baOutputTimestamp, out strError); if (nRet == -1) goto ERROR1; // TODO: 时间戳冲突? this.SavePath = strProtocol + ":" + strOutputPath; this.CurrentTimestamp = baOutputTimestamp; this.BiblioChanged = false; // 是否刷新MARC记录? //AutoCloseMessageBox.Show(this, "保存成功"); // MessageBox.Show(this, "保存成功"); return 0; } else if (strProtocol.ToLower() == "dp2library") { dp2SearchForm dp2_searchform = this.GetDp2SearchForm(); if (dp2_searchform == null) { strError = "没有连接的或者打开的dp2检索窗,无法保存记录"; goto ERROR1; } #if NO // 迫使登录一次 if (string.IsNullOrEmpty(strCurrentUserName) == true && string.IsNullOrEmpty(this.CurrentUserName) == true) { string strServerName = ""; string strLocalPath = ""; // 解析记录路径。 // 记录路径为如下形态 "中文图书/1 @服务器" dp2SearchForm.ParseRecPath(strPath, out strServerName, out strLocalPath); string strBiblioDbName = dp2SearchForm.GetDbName(strLocalPath); string strSyntax = ""; nRet = dp2_searchform.GetDbSyntax( null, strServerName, strBiblioDbName, out strSyntax, out strError); } #endif // 保存前的准备工作 { // 初始化 dp2catalog_marc_autogen.cs 的 Assembly,并new MarcDetailHost对象 // return: // -2 清除了Assembly // -1 error // 0 没有重新初始化Assembly,而是直接用以前Cache的Assembly (可能本来就是空) // 1 重新(或者首次)初始化了Assembly nRet = InitialAutogenAssembly(out strError); if (nRet == -1) goto ERROR1; if (this.m_detailHostObj != null) { // 模拟出this.SavePath 2011/11/22 string strOldSavePath = this.textBox_savePath.Text; this.textBox_savePath.Text = strSavePath; try { BeforeSaveRecordEventArgs e = new BeforeSaveRecordEventArgs(); e.CurrentUserName = strCurrentUserName; this.m_detailHostObj.BeforeSaveRecord(this.MarcEditor, e); if (string.IsNullOrEmpty(e.ErrorInfo) == false) { MessageBox.Show(this, "保存前的准备工作失败: " + e.ErrorInfo + "\r\n\r\n但保存操作仍将继续"); } } finally { // 恢复this.SavePath this.textBox_savePath.Text = strOldSavePath; } } } byte[] baTimestamp = this.CurrentTimestamp; string strMARC = this.MarcEditor.Marc; string strFragment = ""; if (this.domXmlFragment != null && this.domXmlFragment.DocumentElement != null) strFragment = this.domXmlFragment.DocumentElement.InnerXml; // 2014/5/12 string strMarcSyntax = ""; if (this.CurrentRecord != null) strMarcSyntax = GetMarcSyntax(this.CurrentRecord.m_strSyntaxOID); // 2014/5/18 if (string.IsNullOrEmpty(this.AutoDetectedMarcSyntaxOID) == false) strMarcSyntax = GetMarcSyntax(this.AutoDetectedMarcSyntaxOID); string strComment = ""; bool bOverwrite = false; if (string.IsNullOrEmpty(this.SavePath) == false) { string strTempProtocol = ""; string strTempPath = ""; nRet = Global.ParsePath(this.SavePath, out strTempProtocol, out strTempPath, out strError); if (nRet == -1) goto ERROR1; string strServerName = ""; string strPurePath = ""; dp2SearchForm.ParseRecPath(strTempPath, out strServerName, out strPurePath); if (dp2SearchForm.IsAppendRecPath(strPurePath) == false) { string strServerUrl = dp2_searchform.GetServerUrl(strServerName); strComment = "copy from " + strPurePath + "@" + strServerUrl; } } else if (string.IsNullOrEmpty(this.textBox_tempRecPath.Text) == false) { strComment = "copy from " + this.textBox_tempRecPath.Text; } string strRights = ""; // 判断是否追加 { string strServerName = ""; string strPurePath = ""; dp2SearchForm.ParseRecPath(strPath, out strServerName, out strPurePath); if (dp2SearchForm.IsAppendRecPath(strPurePath) == false) bOverwrite = true; nRet = dp2_searchform.GetChannelRights( strServerName, out strRights, out strError); if (nRet == -1) goto ERROR1; } bool bForceWverifyData = StringUtil.IsInList("client_forceverifydata", strRights); bool bVerifyed = false; if (bForceWverifyData == true) { GenerateDataEventArgs e1 = new GenerateDataEventArgs(); e1.FocusedControl = this.MarcEditor; // 0: 没有发现校验错误; 1: 发现校验警告; 2: 发现校验错误 nRet = this.VerifyData(this, e1, strSavePath, true); if (nRet == 2) { strError = "MARC 记录经校验发现有错,被拒绝保存。请修改 MARC 记录后重新保存"; goto ERROR1; } bVerifyed = true; } REDO_SAVE_DP2: string strOutputPath = ""; byte[] baOutputTimestamp = null; // return: // -2 timestamp mismatch // -1 error // 0 succeed nRet = dp2_searchform.SaveMarcRecord( true, strPath, strMARC, strMarcSyntax, baTimestamp, strFragment, strComment, out strOutputPath, out baOutputTimestamp, out strError); if (nRet == -1) goto ERROR1; if (nRet == -2) { // 时间戳冲突了 // 装载目标记录 DigitalPlatform.Z3950.Record record = null; Encoding currentEncoding = null; byte[] baTargetTimestamp = null; string strOutStyle = ""; string strTargetMARC = ""; string strError1 = ""; string strOutputSavePath = ""; long lVersion = 0; LoginInfo logininfo = null; string strXmlFragment = ""; nRet = dp2_searchform.GetOneRecord( // true, "marc", //strPath, // 不能有问号? //"", // strDirection, 0, "path:" + strPath, "", out strOutputSavePath, out strTargetMARC, out strXmlFragment, out strOutStyle, out baTargetTimestamp, out lVersion, out record, out currentEncoding, out logininfo, out strError1); if (nRet == -1) { strError = "保存记录时发生错误: " + strError + ",在重装入目标记录的时候又发生错误: " + strError1; goto ERROR1; } nRet = this.LoadXmlFragment(strXmlFragment, out strError1); if (nRet == -1) { strError1 = "保存记录时发生错误: " + strError + ",在重装入目标记录的时候又发生错误: " + strError1; goto ERROR1; } // TODO: 检查源和目标的MARC格式是否一致?是否前面检查过了? TwoBiblioDialog two_biblio_dlg = new TwoBiblioDialog(); GuiUtil.SetControlFont(two_biblio_dlg, this.Font); two_biblio_dlg.Text = "覆盖书目记录"; two_biblio_dlg.MessageText = "即将被覆盖的目标记录和源内容不同。\r\n\r\n请问是否确定要用源内容覆盖目标记录?"; two_biblio_dlg.LabelSourceText = "源"; two_biblio_dlg.LabelTargetText = "目标 " + strPath; two_biblio_dlg.MarcSource = strMARC; two_biblio_dlg.MarcTarget = strTargetMARC; two_biblio_dlg.ReadOnlyTarget = true; // 初始时目标MARC编辑器不让进行修改 this.MainForm.AppInfo.LinkFormState(two_biblio_dlg, "TwoBiblioDialog_state"); two_biblio_dlg.ShowDialog(this); this.MainForm.AppInfo.UnlinkFormState(two_biblio_dlg); if (two_biblio_dlg.DialogResult == DialogResult.Cancel) { strError = "放弃保存"; goto ERROR1; // return 0; // 全部放弃 } if (two_biblio_dlg.DialogResult == DialogResult.No) { strError = "放弃保存"; goto ERROR1; } if (two_biblio_dlg.EditTarget == false) strMARC = two_biblio_dlg.MarcSource; else strMARC = two_biblio_dlg.MarcTarget; baTimestamp = baTargetTimestamp; goto REDO_SAVE_DP2; } this.SavePath = dp2_searchform.CurrentProtocol + ":" + strOutputPath; this.CurrentTimestamp = baOutputTimestamp; this.BiblioChanged = false; this.MarcEditor.ClearMarcDefDom(); this.MarcEditor.RefreshNameCaption(); // 是否刷新MARC记录? // MessageBox.Show(this, "保存成功"); if (bOverwrite == true && this.LinkedSearchForm != null) { // return: // -2 不支持 // -1 error // 0 相关窗口已经销毁,没有必要刷新 // 1 已经刷新 // 2 在结果集中没有找到要刷新的记录 nRet = RefreshCachedRecord("refresh", out strError); if (nRet == -1) MessageBox.Show(this, "记录保存已经成功,但刷新相关结果集内记录时出错: " + strError); } if (this.AutoVerifyData == true && bVerifyed == false) { // API.PostMessage(this.Handle, WM_VERIFY_DATA, 0, 0); GenerateDataEventArgs e1 = new GenerateDataEventArgs(); e1.FocusedControl = this.MarcEditor; // 0: 没有发现校验错误; 1: 发现校验警告; 2: 发现校验错误 nRet = this.VerifyData(this, e1, strSavePath, true); if (nRet == 2) { strError = "MARC 记录经校验发现有错。记录已经保存。请修改 MARC 记录后重新保存"; MessageBox.Show(this, strError); } } return 0; } else if (strProtocol.ToLower() == "unioncatalog") { string strServerName = ""; string strPurePath = ""; dp2SearchForm.ParseRecPath(strPath, out strServerName, out strPurePath); if (String.IsNullOrEmpty(strServerName) == true) { strError = "路径不合法: 缺乏服务器名部分"; goto ERROR1; } if (String.IsNullOrEmpty(strPurePath) == true) { strError = "路径不合法:缺乏纯路径部分"; goto ERROR1; } byte[] baTimestamp = this.CurrentTimestamp; string strMARC = this.MarcEditor.Marc; string strMarcSyntax = ""; string strMarcSyntaxOID = this.GetCurrentMarcSyntaxOID(out strError); if (String.IsNullOrEmpty(strMarcSyntaxOID) == true) { strError = "当前MARC syntax OID为空,无法判断MARC具体格式"; goto ERROR1; } if (strMarcSyntaxOID == "1.2.840.10003.5.1") strMarcSyntax = "unimarc"; if (strMarcSyntaxOID == "1.2.840.10003.5.10") strMarcSyntax = "usmarc"; string strXml = ""; nRet = MarcUtil.Marc2Xml( strMARC, strMarcSyntax, out strXml, out strError); if (nRet == -1) goto ERROR1; string strXml1 = ""; // 将机内使用的marcxml格式转化为marcxchange格式 nRet = MarcUtil.MarcXmlToXChange(strXml, null, out strXml1, out strError); if (nRet == -1) goto ERROR1; // TODO: 是否可以直接使用Z39.50属性对话框中的用户名和密码? 登录失败后才出现登录对话框 if (this.LoginInfo == null) this.LoginInfo = new dp2Catalog.LoginInfo(); bool bRedo = false; REDO_LOGIN: if (string.IsNullOrEmpty(this.LoginInfo.UserName) == true || bRedo == true) { LoginDlg login_dlg = new LoginDlg(); GuiUtil.SetControlFont(login_dlg, this.Font); if (bRedo == true) login_dlg.Comment = strError + "\r\n\r\n请重新登录"; else login_dlg.Comment = "请指定用户名和密码"; login_dlg.UserName = this.LoginInfo.UserName; login_dlg.Password = this.LoginInfo.Password; login_dlg.SavePassword = true; login_dlg.ServerUrl = strServerName; login_dlg.StartPosition = FormStartPosition.CenterScreen; login_dlg.ShowDialog(this); if (login_dlg.DialogResult == System.Windows.Forms.DialogResult.Cancel) { strError = "放弃保存"; goto ERROR1; } this.LoginInfo.UserName = login_dlg.UserName; this.LoginInfo.Password = login_dlg.Password; strServerName = login_dlg.ServerUrl; } if (this.LoginInfo.UserName.IndexOf("/") != -1) { strError = "用户名中不能出现字符 '/'"; goto ERROR1; } string strOutputTimestamp = ""; string strOutputRecPath = ""; // parameters: // strAction 动作。为"new" "change" "delete" "onlydeletebiblio"之一。"delete"在删除书目记录的同时,会自动删除下属的实体记录。不过要求实体均未被借出才能删除。 // return: // -2 登录不成功 // -1 出错 // 0 成功 nRet = UnionCatalog.UpdateRecord( null, strServerName, this.LoginInfo.UserName + "/" + this.LoginInfo.Password, dp2SearchForm.IsAppendRecPath(strPurePath) == true ? "new": "change", strPurePath, "marcxchange", strXml1, ByteArray.GetHexTimeStampString(baTimestamp), out strOutputRecPath, out strOutputTimestamp, out strError); if (nRet == -1) goto ERROR1; if (nRet == -2) { bRedo = true; goto REDO_LOGIN; } this.CurrentTimestamp = ByteArray.GetTimeStampByteArray(strOutputTimestamp); this.SavePath = strProtocol + ":" + strOutputRecPath + "@" + strServerName; this.BiblioChanged = false; this.MarcEditor.ClearMarcDefDom(); this.MarcEditor.RefreshNameCaption(); // 是否刷新MARC记录? // MessageBox.Show(this, "保存成功"); if (dp2SearchForm.IsAppendRecPath(strPurePath) == false && this.LinkedSearchForm != null && this.LinkedSearchForm is ZSearchForm) { nRet = RefreshCachedRecord("refresh", out strError); if (nRet == -1) MessageBox.Show(this, "记录保存已经成功,但刷新相关结果集内记录时出错: " + strError); } return 0; } else if (strProtocol.ToLower() == "z3950") { strError = "目前暂不支持 Z39.50 协议的保存操作"; goto ERROR1; } else if (strProtocol.ToLower() == "amazon") { strError = "目前暂不支持 amazon 协议的保存操作"; goto ERROR1; } else { strError = "无法识别的协议名 '" + strProtocol + "'"; goto ERROR1; } } finally { this.stop.EndLoop(); this.EnableControls(true); } // return 0; ERROR1: MessageBox.Show(this, strError); return -1; }
// 删除记录 // TODO: 需要增加对dp2和UnionCatalog协议的删除功能 public int DeleteRecord() { string strError = ""; if (String.IsNullOrEmpty(this.SavePath) == true) { strError = "缺乏保存路径"; goto ERROR1; } string strProtocol = ""; string strPath = ""; int nRet = Global.ParsePath(this.SavePath, out strProtocol, out strPath, out strError); if (nRet == -1) goto ERROR1; string strChangedWarning = ""; if (this.ObjectChanged == true || this.BiblioChanged == true) { strChangedWarning = "当前有 " + GetCurrentChangedPartName() // strChangedWarning + " 被修改过。\r\n\r\n"; } string strText = strChangedWarning; strText += "确实要删除书目记录 \r\n" + strPath + " "; /* int nObjectCount = this.binaryResControl1.ObjectCount; if (nObjectCount != 0) strText += "和从属的 " + nObjectCount.ToString() + " 个对象"; * */ strText += " ?"; // 警告删除 DialogResult result = MessageBox.Show(this, strText, "MarcDetailForm", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2); if (result != DialogResult.Yes) { return 0; } this.stop.BeginLoop(); this.EnableControls(false); try { // dtlp协议的记录删除 if (strProtocol.ToLower() == "dtlp") { DtlpSearchForm dtlp_searchform = this.GetDtlpSearchForm(); if (dtlp_searchform == null) { strError = "没有连接的或者打开的DTLP检索窗,无法保存记录"; goto ERROR1; } // string strOutputPath = ""; // byte[] baOutputTimestamp = null; nRet = dtlp_searchform.DeleteMarcRecord( strPath, this.CurrentTimestamp, out strError); if (nRet == -1) goto ERROR1; MessageBox.Show(this, "删除成功"); return 1; } // dp2library协议的记录删除 else if (strProtocol.ToLower() == "dp2library") { dp2SearchForm dp2_searchform = this.GetDp2SearchForm(); if (dp2_searchform == null) { strError = "没有连接的或者打开的dp2检索窗,无法进行数据创建"; goto ERROR1; } // string strOutputPath = ""; byte[] baOutputTimestamp = null; // 删除一条MARC/XML记录 // parameters: // strSavePath 内容为"中文图书/1@本地服务器"。没有协议名部分。 // return: // -1 error // 0 suceed nRet = dp2_searchform.DeleteOneRecord( strPath, this.CurrentTimestamp, out baOutputTimestamp, out strError); this.CurrentTimestamp = baOutputTimestamp; // 即便发生错误,也要更新时间戳,以便后面继续删除 if (nRet == -1) goto ERROR1; this.ObjectChanged = false; this.BiblioChanged = false; MessageBox.Show(this, "删除成功"); // TODO: ZSearchForm中的记录是否也要清除? if (this.LinkedSearchForm != null && this.LinkedSearchForm is ZSearchForm) { nRet = RefreshCachedRecord("delete", out strError); if (nRet == -1) MessageBox.Show(this, "记录删除已经成功,但刷新相关结果集内记录时出错: " + strError); } return 1; } else if (strProtocol.ToLower() == "unioncatalog") { string strServerName = ""; string strPurePath = ""; dp2SearchForm.ParseRecPath(strPath, out strServerName, out strPurePath); if (String.IsNullOrEmpty(strServerName) == true) { strError = "路径不合法: 缺乏服务器名部分"; goto ERROR1; } if (String.IsNullOrEmpty(strPurePath) == true) { strError = "路径不合法:缺乏纯路径部分"; goto ERROR1; } byte[] baTimestamp = this.CurrentTimestamp; // TODO: 是否可以直接使用Z39.50属性对话框中的用户名和密码? 登录失败后才出现登录对话框 if (this.LoginInfo == null) this.LoginInfo = new dp2Catalog.LoginInfo(); bool bRedo = false; REDO_LOGIN: if (string.IsNullOrEmpty(this.LoginInfo.UserName) == true || bRedo == true) { LoginDlg login_dlg = new LoginDlg(); GuiUtil.SetControlFont(login_dlg, this.Font); if (bRedo == true) login_dlg.Comment = strError + "\r\n\r\n请重新登录"; else login_dlg.Comment = "请指定用户名和密码"; login_dlg.UserName = this.LoginInfo.UserName; login_dlg.Password = this.LoginInfo.Password; login_dlg.SavePassword = true; login_dlg.ServerUrl = strServerName; login_dlg.StartPosition = FormStartPosition.CenterScreen; login_dlg.ShowDialog(this); if (login_dlg.DialogResult == System.Windows.Forms.DialogResult.Cancel) { strError = "放弃保存"; goto ERROR1; } this.LoginInfo.UserName = login_dlg.UserName; this.LoginInfo.Password = login_dlg.Password; strServerName = login_dlg.ServerUrl; } if (this.LoginInfo.UserName.IndexOf("/") != -1) { strError = "用户名中不能出现字符 '/'"; goto ERROR1; } string strOutputTimestamp = ""; string strOutputRecPath = ""; // parameters: // strAction 动作。为"new" "change" "delete" "onlydeletebiblio"之一。"delete"在删除书目记录的同时,会自动删除下属的实体记录。不过要求实体均未被借出才能删除。 // return: // -2 登录不成功 // -1 出错 // 0 成功 nRet = UnionCatalog.UpdateRecord( null, strServerName, this.LoginInfo.UserName + "/" + this.LoginInfo.Password, "delete", strPurePath, "", // format null, ByteArray.GetHexTimeStampString(baTimestamp), out strOutputRecPath, out strOutputTimestamp, out strError); if (nRet == -1) goto ERROR1; if (nRet == -2) { bRedo = true; goto REDO_LOGIN; } this.CurrentTimestamp = ByteArray.GetTimeStampByteArray(strOutputTimestamp); this.BiblioChanged = false; this.ObjectChanged = false; MessageBox.Show(this, "删除成功"); if (this.LinkedSearchForm != null && this.LinkedSearchForm is ZSearchForm) { nRet = RefreshCachedRecord("delete", out strError); if (nRet == -1) MessageBox.Show(this, "记录删除已经成功,但刷新相关结果集内记录时出错: " + strError); } return 0; } else if (strProtocol.ToLower() == "z3950") { strError = "目前暂不支持 Z39.50 协议的删除操作"; goto ERROR1; } else if (strProtocol.ToLower() == "amazon") { strError = "目前暂不支持 amazon 协议的删除操作"; goto ERROR1; } else { strError = "无法识别的协议名 '" + strProtocol + "'"; goto ERROR1; } } finally { this.stop.EndLoop(); this.EnableControls(true); } // return 0; ERROR1: MessageBox.Show(this, strError); return -1; }
// 装载XML记录 public int LoadRecord(ISearchForm searchform, int index, bool bForceFullElementSet = false) { string strError = ""; string strMARC = ""; this.LinkedSearchForm = searchform; this.SavePath = ""; DigitalPlatform.Z3950.Record record = null; Encoding currentEncoding = null; this.CurrentRecord = null; byte[] baTimestamp = null; string strSavePath = ""; string strOutStyle = ""; LoginInfo logininfo = null; long lVersion = 0; string strXmlFragment = ""; string strParameters = "hilight_browse_line"; if (bForceFullElementSet == true) strParameters += ",force_full"; int nRet = searchform.GetOneRecord( "xml", index, // 即将废止 "index:" + index.ToString(), strParameters, // true, out strSavePath, out strMARC, out strXmlFragment, out strOutStyle, out baTimestamp, out lVersion, out record, out currentEncoding, out logininfo, out strError); if (nRet == -1) goto ERROR1; this.LoginInfo = logininfo; this.CurrentTimestamp = baTimestamp; this.SavePath = strSavePath; this.CurrentEncoding = currentEncoding; // 替换单个0x0a strMARC = strMARC.Replace("\r", ""); strMARC = strMARC.Replace("\n", "\r\n"); // 装入XML编辑器 // this.textBox_xml.Text = strMARC; this.PlainText = strMARC; // 能自动缩进 this.textBox_xml.Select(0, 0); // 装入XML只读Web控件 { string strTempFileName = MainForm.DataDir + "\\xml.xml"; // SUTRS if (record.m_strSyntaxOID == "1.2.840.10003.5.101") strTempFileName = MainForm.DataDir + "\\xml.txt"; using (Stream stream = File.Create(strTempFileName)) { // 写入xml内容 byte[] buffer = Encoding.UTF8.GetBytes(strMARC); stream.Write(buffer, 0, buffer.Length); } this.webBrowser_xml.Navigate(strTempFileName); } this.CurrentRecord = record; if (this.CurrentRecord != null && this.DisplayOriginPage == true) { // 装入二进制编辑器 this.binaryEditor_originData.SetData( this.CurrentRecord.m_baRecord); // 装入原始文本 nRet = this.SetOriginText(this.CurrentRecord.m_baRecord, this.CurrentEncoding, out strError); if (nRet == -1) { this.textBox_originData.Text = strError; } // 数据库名 this.textBox_originDatabaseName.Text = this.CurrentRecord.m_strDBName; // record syntax OID this.textBox_originMarcSyntaxOID.Text = this.CurrentRecord.m_strSyntaxOID; } // 构造路径 string strPath = searchform.CurrentProtocol + ":" + searchform.CurrentResultsetPath + "/" + (index + 1).ToString(); this.textBox_tempRecPath.Text = strPath; this.textBox_xml.Focus(); return 0; ERROR1: MessageBox.Show(this, strError); return -1; }
/* 操作类型 crashReport -- 异常报告 主题 dp2catalog 发送者 xxxx 媒体类型 text 内容 发生未捕获的界面线程异常: Type: System.ObjectDisposedException Message: 无法访问已释放的对象。 对象名:“MarcEditor”。 Stack: 在 System.Windows.Forms.Control.CreateHandle() 在 System.Windows.Forms.Control.get_Handle() 在 DigitalPlatform.Marc.Field.CalculateHeight(Graphics g, Boolean bIgnoreEdit) 在 DigitalPlatform.Marc.FieldCollection.AddInternal(String strName, String strIndicator, String strValue, Boolean bFireTextChanged, Boolean bInOrder, Int32& nOutputPosition) 在 DigitalPlatform.Marc.Record.SetMarc(String strMarc, Boolean bCheckMarcDef, String& strError) 在 DigitalPlatform.Marc.MarcEditor.set_Marc(String value) 在 dp2Catalog.MarcDetailForm.LoadRecord(ISearchForm searchform, Int32 index, Boolean bForceFullElementSet, Boolean bReload) 在 dp2Catalog.dp2SearchForm.LoadDetail(Int32 index, Boolean bOpenNew) 在 dp2Catalog.dp2SearchForm.listView_browse_DoubleClick(Object sender, EventArgs e) 在 System.Windows.Forms.ListView.WndProc(Message& m) 在 DigitalPlatform.GUI.ListViewNF.WndProc(Message& m) 在 System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) dp2Catalog 版本: dp2Catalog, Version=2.4.5698.23777, Culture=neutral, PublicKeyToken=null 操作系统:Microsoft Windows NT 6.1.7601 Service Pack 1 操作时间 2015/8/10 13:48:50 (Mon, 10 Aug 2015 13:48:50 +0800) 前端地址 xxxx 经由 http://dp2003.com/dp2library * */ // 从检索窗装载MARC记录 // parameters: // bForceFullElementSet 是否强制用Full元素集。如果为false,表示无所谓,也就是说按照当前的元素集(有可能是Full,也有可能是Brief) // bReload 是否确保从数据库装载 // return: // -1 出错 // 0 成功 // 2 需要跳过 public int LoadRecord(ISearchForm searchform, int index, bool bForceFullElementSet = false, bool bReload = false) { string strError = ""; this.stop.BeginLoop(); // 在这里启用 stop,可以防止在装载的中途 Form 被关闭、造成 MarcEditor 设置 MARC 字符串过程抛出异常 this.EnableControls(false); try { string strMARC = ""; this.LinkedSearchForm = searchform; // this.SavePath = ""; // 2011/5/5 去除 DigitalPlatform.Z3950.Record record = null; Encoding currentEncoding = null; this.CurrentRecord = null; string strSavePath = ""; byte[] baTimestamp = null; this.m_nDisableInitialAssembly++; // 防止多次初始化Assembly try { string strOutStyle = ""; LoginInfo logininfo = null; string strXmlFragment = ""; long lVersion = 0; string strParameters = "hilight_browse_line"; if (bForceFullElementSet == true) strParameters += ",force_full"; if (bReload == true) strParameters += ",reload"; // 获得一条MARC/XML记录 // return: // -1 error // 0 suceed // 1 为诊断记录 // 2 分割条,需要跳过这条记录 int nRet = searchform.GetOneRecord( "marc", index, // 即将废止 "index:" + index.ToString(), strParameters, // true, out strSavePath, out strMARC, out strXmlFragment, out strOutStyle, out baTimestamp, out lVersion, out record, out currentEncoding, out logininfo, out strError); if (nRet == -1) goto ERROR1; if (nRet == 2) return 2; nRet = this.LoadXmlFragment(strXmlFragment, out strError); if (nRet == -1) goto ERROR1; this.LoginInfo = logininfo; if (strOutStyle != "marc") { strError = "所获取的记录不是marc格式"; goto ERROR1; } this.RecordVersion = lVersion; this.CurrentRecord = record; if (this.m_currentRecord != null) { // 装入二进制编辑器 this.binaryEditor_originData.SetData( this.m_currentRecord.m_baRecord); // 装入ISO2709文本 nRet = this.Set2709OriginText(this.m_currentRecord.m_baRecord, this.CurrentEncoding, out strError); if (nRet == -1) { this.textBox_originData.Text = strError; } // 数据库名 this.textBox_originDatabaseName.Text = this.m_currentRecord.m_strDBName; // Marc syntax OID this.textBox_originMarcSyntaxOID.Text = this.m_currentRecord.m_strSyntaxOID; // 2014/5/18 if (this.UseAutoDetectedMarcSyntaxOID == true) { this.AutoDetectedMarcSyntaxOID = this.m_currentRecord.AutoDetectedSyntaxOID; if (string.IsNullOrEmpty(this.AutoDetectedMarcSyntaxOID) == false) this.textBox_originMarcSyntaxOID.Text = this.AutoDetectedMarcSyntaxOID; } #if NO // 让确定的OID起作用 2008/3/25 if (String.IsNullOrEmpty(this.m_currentRecord.m_strSyntaxOID) == false) this.AutoDetectedMarcSyntaxOID = ""; #endif } else { byte[] baMARC = this.CurrentEncoding.GetBytes(strMARC); // 装入二进制编辑器 this.binaryEditor_originData.SetData( baMARC); // 装入ISO2709文本 nRet = this.Set2709OriginText(baMARC, this.CurrentEncoding, out strError); if (nRet == -1) { this.textBox_originData.Text = strError; } } } finally { this.m_nDisableInitialAssembly--; } this.SavePath = strSavePath; this.CurrentTimestamp = baTimestamp; this.CurrentEncoding = currentEncoding; // 装入MARC编辑器 this.MarcEditor.Marc = strMARC; DisplayHtml(strMARC, this.textBox_originMarcSyntaxOID.Text); // 构造路径 string strPath = searchform.CurrentProtocol + ":" + searchform.CurrentResultsetPath + "/" + (index + 1).ToString(); this.textBox_tempRecPath.Text = strPath; this.MarcEditor.MarcDefDom = null; // 强制刷新字段名提示 this.MarcEditor.RefreshNameCaption(); this.BiblioChanged = false; if (this.MarcEditor.FocusedFieldIndex == -1) this.MarcEditor.FocusedFieldIndex = 0; this.MarcEditor.Focus(); return 0; } finally { this.stop.EndLoop(); this.EnableControls(true); } ERROR1: MessageBox.Show(this, strError); return -1; }
// 获得一条MARC/XML记录 // return: // -1 error 包括not found // 0 found // 1 为诊断记录 public int GetOneRecord( string strStyle, int nTest, string strPathParam, string strParameters, // bool bHilightBrowseLine, out string strSavePath, out string strRecord, out string strXmlFragment, out string strOutStyle, out byte[] baTimestamp, out long lVersion, out DigitalPlatform.OldZ3950.Record record, out Encoding currrentEncoding, out LoginInfo logininfo, out string strError) { strXmlFragment = ""; strRecord = ""; record = null; strError = ""; currrentEncoding = this.CurrentEncoding; baTimestamp = null; strSavePath = ""; strOutStyle = "marc"; logininfo = new LoginInfo(); lVersion = 0; // 防止重入 if (m_bInSearch == true) { strError = "当前窗口正在被一个未结束的长操作使用,无法获得记录。请稍后再试。"; return(-1); } if (strStyle != "marc" && strStyle != "xml") { strError = "DupForm只支持获取MARC格式记录和xml格式记录,不支持 '" + strStyle + "' 格式的记录"; return(-1); } int nRet = 0; int index = -1; string strPath = ""; string strDirection = ""; nRet = Global.ParsePathParam(strPathParam, out index, out strPath, out strDirection, out strError); if (nRet == -1) { return(-1); } if (index == -1) { strError = "暂时不支持没有 index 的用法"; return(-1); } bool bHilightBrowseLine = StringUtil.IsInList("hilight_browse_line", strParameters); if (index >= this.listView_browse.Items.Count) { strError = "越过结果集尾部"; return(-1); } ListViewItem curItem = this.listView_browse.Items[index]; if (bHilightBrowseLine == true) { // 修改listview中事项的选定状态 for (int i = 0; i < this.listView_browse.SelectedItems.Count; i++) { this.listView_browse.SelectedItems[i].Selected = false; } curItem.Selected = true; curItem.EnsureVisible(); } string strPurePath = curItem.Text; string strServerName = this.LibraryServerName; strPath = strPurePath + "@" + this.LibraryServerName; strSavePath = this.CurrentProtocol + ":" + strPath; // 拉上一个dp2检索窗,好办事 dp2SearchForm dp2_searchform = this.GetDp2SearchForm(); if (dp2_searchform == null) { strError = "没有打开的dp2检索窗,无法GetOneRecordSyntax()"; return(-1); } // 获得server url string strServerUrl = dp2_searchform.GetServerUrl(strServerName); if (strServerUrl == null) { strError = "没有找到服务器名 '" + strServerName + "' 对应的URL"; return(-1); } this.Channel = this.Channels.GetChannel(strServerUrl); stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在初始化浏览器组件 ..."); stop.BeginLoop(); this.Update(); this.MainForm.Update(); try { stop.SetMessage("正在装入书目记录 " + strPath + " ..."); string[] formats = null; formats = new string[1]; formats[0] = "xml"; string[] results = null; long lRet = Channel.GetBiblioInfos( stop, strPurePath, "", formats, out results, out baTimestamp, out strError); if (lRet == 0) { strError = "路径为 '" + strPath + "' 的书目记录没有找到 ..."; goto ERROR1; // not found } if (lRet == -1) { goto ERROR1; } // this.BiblioTimestamp = baTimestamp; if (results == null) { strError = "results == null"; goto ERROR1; } if (results.Length != formats.Length) { strError = "result.Length != formats.Length"; goto ERROR1; } string strXml = results[0]; if (strStyle == "marc") { string strMarcSyntax = ""; string strOutMarcSyntax = ""; // 从数据记录中获得MARC格式 nRet = MarcUtil.Xml2Marc(strXml, true, strMarcSyntax, out strOutMarcSyntax, out strRecord, out strError); if (nRet == -1) { strError = "XML转换到MARC记录时出错: " + strError; goto ERROR1; } // 获得书目以外的其它XML片断 nRet = dp2SearchForm.GetXmlFragment(strXml, out strXmlFragment, out strError); if (nRet == -1) { goto ERROR1; } } else { strRecord = strXml; strOutStyle = strStyle; } } finally { stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); } return(0); ERROR1: return(-1); }
// 获得一条MARC/XML记录 // return: // -1 error 包括not found // 0 found // 1 为诊断记录 public int GetOneRecord( string strStyle, int nTest, string strPathParam, string strParameters, // bool bHilightBrowseLine, out string strSavePath, out string strRecord, out string strXmlFragment, out string strOutStyle, out byte[] baTimestamp, out long lVersion, out DigitalPlatform.Z3950.Record record, out Encoding currrentEncoding, out LoginInfo logininfo, out string strError) { strXmlFragment = ""; strRecord = ""; record = null; strError = ""; currrentEncoding = this.CurrentEncoding; baTimestamp = null; strSavePath = ""; strOutStyle = "marc"; logininfo = new LoginInfo(); lVersion = 0; // 防止重入 if (m_bInSearch == true) { strError = "当前窗口正在被一个未结束的长操作使用,无法获得记录。请稍后再试。"; return -1; } if (strStyle != "marc" && strStyle != "xml") { strError = "DupForm只支持获取MARC格式记录和xml格式记录,不支持 '" + strStyle + "' 格式的记录"; return -1; } int nRet = 0; int index = -1; string strPath = ""; string strDirection = ""; nRet = Global.ParsePathParam(strPathParam, out index, out strPath, out strDirection, out strError); if (nRet == -1) return -1; if (index == -1) { strError = "暂时不支持没有 index 的用法"; return -1; } bool bHilightBrowseLine = StringUtil.IsInList("hilight_browse_line", strParameters); if (index >= this.listView_browse.Items.Count) { strError = "越过结果集尾部"; return -1; } ListViewItem curItem = this.listView_browse.Items[index]; if (bHilightBrowseLine == true) { // 修改listview中事项的选定状态 for (int i = 0; i < this.listView_browse.SelectedItems.Count; i++) { this.listView_browse.SelectedItems[i].Selected = false; } curItem.Selected = true; curItem.EnsureVisible(); } string strPurePath = curItem.Text; string strServerName = this.LibraryServerName; strPath = strPurePath + "@" + this.LibraryServerName; strSavePath = this.CurrentProtocol + ":" + strPath; // 拉上一个dp2检索窗,好办事 dp2SearchForm dp2_searchform = this.GetDp2SearchForm(); if (dp2_searchform == null) { strError = "没有打开的dp2检索窗,无法GetOneRecordSyntax()"; return -1; } // 获得server url string strServerUrl = dp2_searchform.GetServerUrl(strServerName); if (strServerUrl == null) { strError = "没有找到服务器名 '" + strServerName + "' 对应的URL"; return -1; } this.Channel = this.Channels.GetChannel(strServerUrl); stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在初始化浏览器组件 ..."); stop.BeginLoop(); this.Update(); this.MainForm.Update(); try { stop.SetMessage("正在装入书目记录 " + strPath + " ..."); string[] formats = null; formats = new string[1]; formats[0] = "xml"; string[] results = null; long lRet = Channel.GetBiblioInfos( stop, strPurePath, "", formats, out results, out baTimestamp, out strError); if (lRet == 0) { strError = "路径为 '" + strPath + "' 的书目记录没有找到 ..."; goto ERROR1; // not found } if (lRet == -1) goto ERROR1; // this.BiblioTimestamp = baTimestamp; if (results == null) { strError = "results == null"; goto ERROR1; } if (results.Length != formats.Length) { strError = "result.Length != formats.Length"; goto ERROR1; } string strXml = results[0]; if (strStyle == "marc") { string strMarcSyntax = ""; string strOutMarcSyntax = ""; // 从数据记录中获得MARC格式 nRet = MarcUtil.Xml2Marc(strXml, true, strMarcSyntax, out strOutMarcSyntax, out strRecord, out strError); if (nRet == -1) { strError = "XML转换到MARC记录时出错: " + strError; goto ERROR1; } // 获得书目以外的其它XML片断 nRet = dp2SearchForm.GetXmlFragment(strXml, out strXmlFragment, out strError); if (nRet == -1) goto ERROR1; } else { strRecord = strXml; strOutStyle = strStyle; } } finally { stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); } return 0; ERROR1: return -1; }
public int GetOneRecord( string strStyle, int nTest, string strPathParam, string strParameters, // bool bHilightBrowseLine, out string strSavePath, out string strMARC, out string strXmlFragment, out string strOutStyle, out byte[] baTimestamp, out long lVersion, out DigitalPlatform.Z3950.Record record, out Encoding currrentEncoding, out LoginInfo logininfo, out string strError) { strXmlFragment = ""; strMARC = ""; record = null; strError = ""; currrentEncoding = this.CurrentEncoding; baTimestamp = null; strSavePath = ""; strOutStyle = "marc"; logininfo = new LoginInfo(); lVersion = 0; if (strStyle != "marc") { strError = "DtlpSearchForm只支持获取MARC格式记录"; return -1; } int nRet = 0; int index = -1; string strPath = ""; string strDirection = ""; nRet = Global.ParsePathParam(strPathParam, out index, out strPath, out strDirection, out strError); if (nRet == -1) return -1; if (index == -1) { string strOutputPath = ""; nRet = InternalGetOneRecord( strStyle, strPath, strDirection, out strMARC, out strOutputPath, out strOutStyle, out baTimestamp, out record, out currrentEncoding, out strError); if (string.IsNullOrEmpty(strOutputPath) == false) strSavePath = this.CurrentProtocol + ":" + strOutputPath; return nRet; } bool bHilightBrowseLine = StringUtil.IsInList("hilight_browse_line", strParameters); // int nRet = 0; // int nStyle = DtlpChannel.XX_STYLE; // 获得详细记录 if (index >= this.listView_browse.Items.Count) { // 如果检索曾经中断过,这里可以触发继续检索 strError = "越过结果集尾部"; return -1; } ListViewItem curItem = this.listView_browse.Items[index]; if (bHilightBrowseLine == true) { // 修改listview中事项的选定状态 for (int i = 0; i < this.listView_browse.SelectedItems.Count; i++) { this.listView_browse.SelectedItems[i].Selected = false; } curItem.Selected = true; curItem.EnsureVisible(); } strPath = curItem.Text; // 将路径转换为内核可以接受的正规形态 strPath = DigitalPlatform.DTLP.Global.ModifyDtlpRecPath(strPath, "ctlno"); strSavePath = this.CurrentProtocol + ":" + strPath; /* byte[] baPackage; nRet = this.DtlpChannel.Search(strPath, nStyle, out baPackage); if (nRet == -1) { int errorcode = this.DtlpChannel.GetLastErrno(); strError = "检索出错:\r\n" + "检索式: " + strPath + "\r\n" + "错误码: " + errorcode + "\r\n" + "错误信息: " + this.DtlpChannel.GetErrorString(errorcode) + "\r\n"; goto ERROR1; } Encoding encoding = this.DtlpChannel.GetPathEncoding(strPath); Package package = new Package(); package.LoadPackage(baPackage, encoding); nRet = package.Parse(PackageFormat.Binary); if (nRet == -1) { strError = "Package::Parse() error"; goto ERROR1; } byte[] content = null; nRet = package.GetFirstBin(out content); if (nRet == -1) { strError = "Package::GetFirstBin() error"; goto ERROR1; } if (content == null || content.Length < 9) { strError = "content length < 9"; goto ERROR1; } baTimestamp = new byte[9]; Array.Copy(content, baTimestamp, 9); byte[] marc = new byte[content.Length - 9]; Array.Copy(content, 9, marc, 0, content.Length - 9); // strMARC = this.CurrentEncoding.GetString(marc); strMARC = encoding.GetString(marc); // 去掉最后若干连续的29字符或者0字符 // 2008/3/11 int nDelta = 0; for (int i = strMARC.Length - 1; i > 24; i--) { char ch = strMARC[i]; if (ch == 0 || ch == 29) nDelta++; else break; } if (nDelta > 0) strMARC = strMARC.Substring(0, strMARC.Length - nDelta); // 自动识别MARC格式 string strOutMarcSyntax = ""; // 探测记录的MARC格式 unimarc / usmarc / reader nRet = MarcUtil.DetectMarcSyntax(strMARC, out strOutMarcSyntax); if (strOutMarcSyntax == "") strOutMarcSyntax = "unimarc"; record = new DigitalPlatform.Z3950.Record(); if (strOutMarcSyntax == "unimarc" || strOutMarcSyntax == "") record.m_strSyntaxOID = "1.2.840.10003.5.1"; else if (strOutMarcSyntax == "usmarc") record.m_strSyntaxOID = "1.2.840.10003.5.10"; else if (strOutMarcSyntax == "dt1000reader") record.m_strSyntaxOID = "1.2.840.10003.5.dt1000reader"; else { // TODO: 可以出现菜单选择 } * */ { string strOutputPath = ""; nRet = InternalGetOneRecord( strStyle, strPath, "current", out strMARC, out strOutputPath, out strOutStyle, out baTimestamp, out record, out currrentEncoding, out strError); if (string.IsNullOrEmpty(strOutputPath) == false) strSavePath = this.CurrentProtocol + ":" + strOutputPath; return nRet; } ERROR1: return -1; }
// 获得一条MARC/XML记录 // return: // -1 error 包括not found // 0 found // 1 为诊断记录 public int GetOneRecord( string strStyle, int nTest, string strPathParam, string strParameters, // bool bHilightBrowseLine, out string strSavePath, out string strRecord, out string strXmlFragment, out string strOutStyle, out byte[] baTimestamp, out long lVersion, out DigitalPlatform.Z3950.Record record, out Encoding currrentEncoding, out LoginInfo logininfo, out string strError) { strXmlFragment = ""; strRecord = ""; record = null; strError = ""; currrentEncoding = this.CurrentEncoding; baTimestamp = null; strSavePath = ""; strOutStyle = "marc"; logininfo = new LoginInfo(); lVersion = 0; #if NO // 防止重入 if (m_bInSearching == true) { strError = "当前窗口正在被一个未结束的长操作使用,无法获得记录。请稍后再试。"; return -1; } #endif if (strStyle != "marc" && strStyle != "xml") { strError = "dp2SearchForm只支持获取MARC格式记录和xml格式记录,不支持 '" + strStyle + "' 格式的记录"; return -1; } int nRet = 0; int index = -1; string strPath = ""; string strDirection = ""; nRet = Global.ParsePathParam(strPathParam, out index, out strPath, out strDirection, out strError); if (nRet == -1) return -1; if (index == -1) { string strOutputPath = ""; nRet = InternalGetOneRecord( true, strStyle, strPath, strDirection, strParameters, // 2013/9/22 out strRecord, out strXmlFragment, out strOutputPath, out strOutStyle, out baTimestamp, out record, out currrentEncoding, out strError); if (string.IsNullOrEmpty(strOutputPath) == false) strSavePath = this.CurrentProtocol + ":" + strOutputPath; return nRet; } bool bHilightBrowseLine = StringUtil.IsInList("hilight_browse_line", strParameters); if (index >= this.listView_browse.Items.Count) { // 如果检索曾经中断过,这里可以触发继续检索 strError = "越过结果集尾部"; return -1; } ListViewItem curItem = this.listView_browse.Items[index]; if (bHilightBrowseLine == true) { // 修改listview中事项的选定状态 for (int i = 0; i < this.listView_browse.SelectedItems.Count; i++) { this.listView_browse.SelectedItems[i].Selected = false; } curItem.Selected = true; curItem.EnsureVisible(); } #if NO if (this.linkMarcFile != null) { BiblioInfo info = null; int nRet = GetBiblioInfo( true, curItem, out info, out strError); if (info == null) { strError = "not found"; return -1; } if (strStyle == "marc") { string strMarcSyntax = ""; string strOutMarcSyntax = ""; // 从数据记录中获得MARC格式 nRet = MarcUtil.Xml2Marc(info.OldXml, true, strMarcSyntax, out strOutMarcSyntax, out strRecord, out strError); if (nRet == -1) { strError = "XML转换到MARC记录时出错: " + strError; return -1; } record = new DigitalPlatform.Z3950.Record(); if (strOutMarcSyntax == "unimarc" || strOutMarcSyntax == "") record.m_strSyntaxOID = "1.2.840.10003.5.1"; else if (strOutMarcSyntax == "usmarc") record.m_strSyntaxOID = "1.2.840.10003.5.10"; else if (strOutMarcSyntax == "dc") record.m_strSyntaxOID = "?"; else { strError = "未知的MARC syntax '" + strOutMarcSyntax + "'"; return -1; } // 获得书目以外的其它XML片断 nRet = GetXmlFragment(info.OldXml, out strXmlFragment, out strError); if (nRet == -1) return -1; } else { strRecord = info.OldXml; strOutStyle = strStyle; record = new DigitalPlatform.Z3950.Record(); record.m_strSyntaxOID = "1.2.840.10003.5.109.10"; } return 0; } #endif strPath = curItem.Text; strSavePath = this.CurrentProtocol + ":" + strPath; { string strOutputPath = ""; nRet = InternalGetOneRecord( true, strStyle, strPath, "", strParameters, // 2013/9/22 out strRecord, out strXmlFragment, out strOutputPath, out strOutStyle, out baTimestamp, out record, out currrentEncoding, out strError); if (string.IsNullOrEmpty(strOutputPath) == false) strSavePath = this.CurrentProtocol + ":" + strOutputPath; return nRet; } }
// 装载XML记录,根据结果集中位置 public int LoadRecord(ISearchForm searchform, int index) { string strError = ""; string strRecordXml = ""; this.LinkedSearchForm = searchform; this.SavePath = ""; DigitalPlatform.Z3950.Record record = null; Encoding currentEncoding = null; this.CurrentRecord = null; byte[] baTimestamp = null; string strSavePath = ""; string strOutStyle = ""; LoginInfo logininfo = null; long lVersion = 0; string strXmlFragment = ""; int nRet = searchform.GetOneRecord( "xml", index, // 即将废止 "index:" + index.ToString(), "hilight_browse_line", // true, out strSavePath, out strRecordXml, out strXmlFragment, out strOutStyle, out baTimestamp, out lVersion, out record, out currentEncoding, out logininfo, out strError); if (nRet == -1) goto ERROR1; this.LoginInfo = logininfo; this.CurrentTimestamp = baTimestamp; this.SavePath = strSavePath; this.CurrentEncoding = currentEncoding; // dp2library协议 if (searchform.CurrentProtocol == "dp2library") { dp2SearchForm dp2_searchform = this.GetDp2SearchForm(); if (dp2_searchform == null) { strError = "没有连接的或者打开的dp2检索窗,无法进行数据创建"; goto ERROR1; } string strProtocol = ""; string strPath = ""; nRet = Global.ParsePath(strSavePath, out strProtocol, out strPath, out strError); if (nRet == -1) goto ERROR1; string strServerName = ""; string strLocalPath = ""; // 解析记录路径。 // 记录路径为如下形态 "中文图书/1 @服务器" dp2SearchForm.ParseRecPath(strPath, out strServerName, out strLocalPath); string strBiblioDbName = dp2SearchForm.GetDbName(strLocalPath); // 获得cfgs\dcdef string strCfgFileName = "dcdef"; string strCfgPath = strBiblioDbName + "/cfgs/" + strCfgFileName + "@" + strServerName; // 和以前的不同,才有必要重新载入 if (this.DcCfgFilename != strCfgPath) { string strCode = ""; byte[] baCfgOutputTimestamp = null; // return: // -1 error // 0 not found // 1 found nRet = dp2_searchform.GetCfgFile(strCfgPath, out strCode, out baCfgOutputTimestamp, out strError); if (nRet == -1 || nRet == 0) goto ERROR1; nRet = this.DcEditor.LoadCfgCode(strCode, out strError); if (nRet == -1) goto ERROR1; this.DcCfgFilename = strCfgPath; } // 接着装入对象资源 { EnableStateCollection save = this.MainForm.DisableToolButtons(); try { // this.binaryResControl1.Channel = dp2_searchform.GetChannel(dp2_searchform.GetServerUrl(strServerName)); nRet = this.binaryResControl1.LoadObject( dp2_searchform.GetChannel(dp2_searchform.GetServerUrl(strServerName)), strLocalPath, strRecordXml, "0", // TODO out strError); if (nRet == -1) { MessageBox.Show(this, strError); return -1; } } finally { save.RestoreAll(); } } } /* // 替换单个0x0a strMARC = strMARC.Replace("\r", ""); strMARC = strMARC.Replace("\n", "\r\n"); * */ // TODO: 再次装入的时候有问题 // 装入DC编辑器 this.DcEditor.Xml = strRecordXml; /* // 装入XML只读Web控件 { string strTempFileName = MainForm.DataDir + "\\xml.xml"; // SUTRS if (record != null) { if (record.m_strSyntaxOID == "1.2.840.10003.5.101") strTempFileName = MainForm.DataDir + "\\xml.txt"; } Stream stream = File.Create(strTempFileName); // 写入xml内容 byte[] buffer = Encoding.UTF8.GetBytes(strRecordXml); stream.Write(buffer, 0, buffer.Length); stream.Close(); this.webBrowser_xml.Navigate(strTempFileName); } * */ this.CurrentRecord = record; /* if (this.CurrentRecord != null) { // 装入二进制编辑器 this.binaryEditor_originData.SetData( this.CurrentRecord.m_baRecord); // 装入原始文本 nRet = this.SetOriginText(this.CurrentRecord.m_baRecord, this.CurrentEncoding, out strError); if (nRet == -1) { this.textBox_originData.Text = strError; } // 数据库名 this.textBox_originDatabaseName.Text = this.CurrentRecord.m_strDBName; // record syntax OID this.textBox_originMarcSyntaxOID.Text = this.CurrentRecord.m_strSyntaxOID; }*/ // 构造结果集路径 string strFullPath = searchform.CurrentProtocol + ":" + searchform.CurrentResultsetPath + "/" + (index + 1).ToString(); this.textBox_tempRecPath.Text = strFullPath; this.BiblioChanged = false; this.DcEditor.Focus(); return 0; ERROR1: MessageBox.Show(this, strError); return -1; }
// 获得一条MARC/XML记录 // return: // -1 error // 0 suceed // 1 为诊断记录 public int GetOneRecord( string strStyle, int nTest, string strPathParam, string strParameters, // bool bHilightBrowseLine, out string strSavePath, out string strMARC, out string strXmlFragment, out string strOutStyle, out byte[] baTimestamp, out long lVersion, out DigitalPlatform.Z3950.Record record, out Encoding currrentEncoding, out LoginInfo logininfo, out string strError) { strXmlFragment = ""; strMARC = ""; record = null; strError = ""; currrentEncoding = null; baTimestamp = null; strSavePath = ""; strOutStyle = ""; logininfo = new LoginInfo(); lVersion = 0; int nRet = 0; int index = -1; string strPath = ""; string strDirection = ""; nRet = Global.ParsePathParam(strPathParam, out index, out strPath, out strDirection, out strError); if (nRet == -1) return -1; if (index == -1) { strError = "暂时不支持没有 index 的用法"; return -1; } bool bHilightBrowseLine = StringUtil.IsInList("hilight_browse_line", strParameters); bool bForceFullElementSet = StringUtil.IsInList("force_full", strParameters); ZConnection connection = this.GetCurrentZConnection(); if (connection == null) { strError = "当前ZConnection为空"; return -1; } if (index >= this.listView_browse.Items.Count) { if (index >= connection.ResultCount) { strError = "越过结果集尾部"; return -1; } // 新装入一批记录 int nCount = Math.Min(connection.TargetInfo.PresentPerBatchCount, connection.ResultCount - this.listView_browse.Items.Count); if (nCount <= 0) { strError = "此时不可能nCount为 " + nCount.ToString(); return -1; } connection.Stop.OnStop += new StopEventHandler(this.DoStop); connection.Stop.SetMessage("从服务器装入记录 ..."); connection.Stop.BeginLoop(); // EnableControls(false); EnableQueryControl(false); this.Update(); this.MainForm.Update(); ActivateStopDisplay(); // 2011/9/11 try { string strElementSetName = ZTargetControl.GetLeftValue(this.comboBox_elementSetName.Text); // this.CurrentTargetInfo.DefaultElementSetName; if (strElementSetName == "B" && connection.TargetInfo.FirstFull == true) strElementSetName = "F"; if (bForceFullElementSet == true) strElementSetName = "F"; RecordCollection records = null; nRet = connection.DoPresent( connection.TargetInfo.DefaultResultSetName, this.listView_browse.Items.Count, // nStart, nCount, // nCount, connection.TargetInfo.PresentPerBatchCount, // 推荐的每次数量 strElementSetName, // "F" strElementSetName, connection.PreferredRecordSyntax, //this.comboBox_recordSyntax.Text), //this.CurrentTargetInfo.PreferredRecordSyntax, true, // 立即显示出来 out records, out strError); if (nRet == -1) { strError = "从 " + this.listView_browse.Items.Count.ToString() + " 开始装入新的一批记录时出错:" + strError; return -1; } else { /* nRet = connection.FillRecordsToVirtualItems( connection.Stop, records, out strError); if (nRet == -1) return -1; DisplayBrowseItems(connection); * */ } } finally { connection.Stop.EndLoop(); connection.Stop.OnStop -= new StopEventHandler(this.DoStop); connection.Stop.Initial(""); // EnableControls(true); EnableQueryControl(true); } if (index >= this.listView_browse.Items.Count) { strError = "index越界"; return -1; } } if (bHilightBrowseLine == true) { // 修改listview中事项的选定状态 for (int i = 0; i < connection.VirtualItems.SelectedIndices.Count; i++) { int temp_index = connection.VirtualItems.SelectedIndices[i]; if (temp_index != index) { if (this.listView_browse.Items[temp_index].Selected != false) this.listView_browse.Items[temp_index].Selected = false; } } ListViewItem curListViewItem = this.listView_browse.Items[index]; if (curListViewItem.Selected != true) curListViewItem.Selected = true; curListViewItem.EnsureVisible(); } // // strSavePath = (index+1).ToString(); // record = (DigitalPlatform.Z3950.Record) connection.VirtualItems[index].Tag; // curListViewItem.Tag; if (record == null) { strError = "VirtualItem Tag为空"; return -1; } if (record.m_nDiagCondition != 0) { strError = "这是一条诊断记录"; strOutStyle = "marc"; strMARC = "012345678901234567890123001这是一条诊断记录"; return 1; } { Debug.Assert(string.IsNullOrEmpty(record.m_strElementSetName) == false, ""); string strCurrentElementSetName = record.m_strElementSetName; string strElementSetName = strCurrentElementSetName; if (strCurrentElementSetName == "B" && connection.TargetInfo.FirstFull == true) strElementSetName = "F"; if (bForceFullElementSet == true) strElementSetName = "F"; if (strCurrentElementSetName != strElementSetName) { connection.Stop.OnStop += new StopEventHandler(this.DoStop); connection.Stop.SetMessage("从服务器装入记录 ..."); connection.Stop.BeginLoop(); EnableQueryControl(false); try { RecordCollection records = null; nRet = connection.DoPresent( connection.TargetInfo.DefaultResultSetName, index, // nStart, 1, // nCount, connection.TargetInfo.PresentPerBatchCount, // 推荐的每次数量 strElementSetName, // "F" strElementSetName, connection.PreferredRecordSyntax, //this.comboBox_recordSyntax.Text), //this.CurrentTargetInfo.PreferredRecordSyntax, true, // 立即显示出来 out records, out strError); if (nRet == -1) { strError = "于 " + index.ToString() + " 位置装入记录时出错:" + strError; return -1; } if (records != null && records.Count > 0) { record = records[0]; } else { Debug.Assert(false, ""); } } finally { connection.Stop.EndLoop(); connection.Stop.OnStop -= new StopEventHandler(this.DoStop); connection.Stop.Initial(""); // EnableControls(true); EnableQueryControl(true); } } } byte[] baRecord = record.m_baRecord; // Encoding.ASCII.GetBytes(record.m_strRecord); currrentEncoding = connection.GetRecordsEncoding( this.MainForm, record.m_strSyntaxOID); // 可能为XML格式 if (record.m_strSyntaxOID == "1.2.840.10003.5.109.10") { // string strContent = Encoding.UTF8.GetString(baRecord); string strContent = currrentEncoding.GetString(baRecord); if (strStyle == "marc") { // 看根节点的名字空间,如果符合MARCXML, 就先转换为USMARC,否则,就直接根据名字空间找样式表加以转换 string strNameSpaceUri = ""; nRet = GetRootNamespace(strContent, out strNameSpaceUri, out strError); if (nRet == -1) { return -1; } if (strNameSpaceUri == Ns.usmarcxml) { string strOutMarcSyntax = ""; // 将MARCXML格式的xml记录转换为marc机内格式字符串 // parameters: // bWarning ==true, 警告后继续转换,不严格对待错误; = false, 非常严格对待错误,遇到错误后不继续转换 // strMarcSyntax 指示marc语法,如果=="",则自动识别 // strOutMarcSyntax out参数,返回marc,如果strMarcSyntax == "",返回找到marc语法,否则返回与输入参数strMarcSyntax相同的值 nRet = MarcUtil.Xml2Marc(strContent, true, "usmarc", out strOutMarcSyntax, out strMARC, out strError); if (nRet == -1) { return -1; } strOutStyle = "marc"; // currrentEncoding = connection.GetRecordsEncoding(this.MainForm, "1.2.840.10003.5.10"); return 0; } } // 不是MARCXML格式 // currrentEncoding = connection.GetRecordsEncoding(this.MainForm, record.m_strMarcSyntaxOID); strMARC = strContent; strOutStyle = "xml"; return 0; } // SUTRS if (record.m_strSyntaxOID == "1.2.840.10003.5.101") { string strContent = currrentEncoding.GetString(baRecord); if (strStyle == "marc") { // TODO: 按照回车草率转换为MARC strMARC = strContent; // strMarcSyntaxOID = "1.2.840.10003.5.10"; strOutStyle = "marc"; return 0; } // 不是MARCXML格式 strMARC = strContent; strOutStyle = "xml"; return 0; } // ISO2709转换为机内格式 nRet = Marc8Encoding.ConvertByteArrayToMarcRecord( baRecord, connection.GetRecordsEncoding(this.MainForm, record.m_strSyntaxOID), // Encoding.GetEncoding(936), true, out strMARC, out strError); if (nRet < 0) { return -1; } // 观察 // connection.TargetInfo.UnionCatalogBindingDp2ServerUrl // 如果配置有绑定的dp2serverurl,则看看记录中有没有901字段, // 如果有,返还为strSavePath和baTimestamp if (connection.TargetInfo != null && String.IsNullOrEmpty(connection.TargetInfo.UnionCatalogBindingDp2ServerName) == false) { string strLocalPath = ""; // 从MARC记录中得到901字段相关信息 // return: // -1 error // 0 not found field 901 // 1 found field 901 nRet = GetField901Info(strMARC, out strLocalPath, out baTimestamp, out strError); if (nRet == -1) return -1; if (nRet == 0) { strError = "MARC记录中未包含901字段,无法完成绑定操作。要具备901字段,请为dp2ZServer服务器的相关数据库增加addField901='true'属性。要避免此报错,也可在Z39.50服务器属性中去掉联合编目绑定定义"; return -1; } strSavePath = "dp2library:" + strLocalPath + "@" + connection.TargetInfo.UnionCatalogBindingDp2ServerName; logininfo.UserName = connection.TargetInfo.UserName; logininfo.Password = connection.TargetInfo.Password; } if (connection.TargetInfo != null && String.IsNullOrEmpty(connection.TargetInfo.UnionCatalogBindingUcServerUrl) == false) { string strLocalPath = ""; // 从MARC记录中得到901字段相关信息 // return: // -1 error // 0 not found field 901 // 1 found field 901 nRet = GetField901Info(strMARC, out strLocalPath, out baTimestamp, out strError); if (nRet == -1) return -1; if (nRet == 0) { strError = "MARC记录中未包含901字段,无法完成绑定操作。要具备901字段,请为dp2ZServer服务器的相关数据库增加addField901='true'属性。要避免此报错,也可在Z39.50服务器属性中去掉联合编目绑定定义"; return -1; } strSavePath = "unioncatalog:" + strLocalPath + "@" + connection.TargetInfo.UnionCatalogBindingUcServerUrl; logininfo.UserName = connection.TargetInfo.UserName; logininfo.Password = connection.TargetInfo.Password; } currrentEncoding = connection.GetRecordsEncoding(this.MainForm, record.m_strSyntaxOID); strOutStyle = "marc"; return 0; }
// 装载XML记录 public int LoadRecord(ISearchForm searchform, int index, bool bForceFullElementSet = false) { string strError = ""; string strMARC = ""; this.LinkedSearchForm = searchform; this.SavePath = ""; DigitalPlatform.Z3950.Record record = null; Encoding currentEncoding = null; this.CurrentRecord = null; byte[] baTimestamp = null; string strSavePath = ""; string strOutStyle = ""; LoginInfo logininfo = null; long lVersion = 0; string strXmlFragment = ""; string strParameters = "hilight_browse_line"; if (bForceFullElementSet == true) { strParameters += ",force_full"; } int nRet = searchform.GetOneRecord( "xml", index, // 即将废止 "index:" + index.ToString(), strParameters, // true, out strSavePath, out strMARC, out strXmlFragment, out strOutStyle, out baTimestamp, out lVersion, out record, out currentEncoding, out logininfo, out strError); if (nRet == -1) { goto ERROR1; } this.LoginInfo = logininfo; this.CurrentTimestamp = baTimestamp; this.SavePath = strSavePath; this.CurrentEncoding = currentEncoding; // 替换单个0x0a strMARC = strMARC.Replace("\r", ""); strMARC = strMARC.Replace("\n", "\r\n"); // 装入XML编辑器 // this.textBox_xml.Text = strMARC; this.PlainText = strMARC; // 能自动缩进 this.textBox_xml.Select(0, 0); // 装入XML只读Web控件 { string strTempFileName = MainForm.DataDir + "\\xml.xml"; // SUTRS if (record.m_strSyntaxOID == "1.2.840.10003.5.101") { strTempFileName = MainForm.DataDir + "\\xml.txt"; } using (Stream stream = File.Create(strTempFileName)) { // 写入xml内容 byte[] buffer = Encoding.UTF8.GetBytes(strMARC); stream.Write(buffer, 0, buffer.Length); } this.webBrowser_xml.Navigate(strTempFileName); } this.CurrentRecord = record; if (this.CurrentRecord != null && this.DisplayOriginPage == true) { // 装入二进制编辑器 this.binaryEditor_originData.SetData( this.CurrentRecord.m_baRecord); // 装入原始文本 nRet = this.SetOriginText(this.CurrentRecord.m_baRecord, this.CurrentEncoding, out strError); if (nRet == -1) { this.textBox_originData.Text = strError; } // 数据库名 this.textBox_originDatabaseName.Text = this.CurrentRecord.m_strDBName; // record syntax OID this.textBox_originMarcSyntaxOID.Text = this.CurrentRecord.m_strSyntaxOID; } // 构造路径 string strPath = searchform.CurrentProtocol + ":" + searchform.CurrentResultsetPath + "/" + (index + 1).ToString(); this.textBox_tempRecPath.Text = strPath; this.textBox_xml.Focus(); return(0); ERROR1: MessageBox.Show(this, strError); return(-1); }