internal static int GetXmlHtml(BiblioInfo info, out string strXml1, out string strXml2, out string strHtml2, out string strError) { strError = ""; strXml1 = ""; strXml2 = ""; strHtml2 = ""; int nRet = 0; strXml1 = info.OldXml; strXml2 = info.NewXml; string strOldMARC = ""; string strOldFragmentXml = ""; if (string.IsNullOrEmpty(strXml1) == false) { string strOutMarcSyntax = ""; // 将XML格式转换为MARC格式 // 自动从数据记录中获得MARC语法 nRet = MarcUtil.Xml2Marc(strXml1, MarcUtil.Xml2MarcStyle.Warning | MarcUtil.Xml2MarcStyle.OutputFragmentXml, "", out strOutMarcSyntax, out strOldMARC, out strOldFragmentXml, out strError); if (nRet == -1) { strError = "XML转换到MARC记录时出错: " + strError; return -1; } } string strNewMARC = ""; string strNewFragmentXml = ""; if (string.IsNullOrEmpty(strXml2) == false) { string strOutMarcSyntax = ""; // 将XML格式转换为MARC格式 // 自动从数据记录中获得MARC语法 nRet = MarcUtil.Xml2Marc(strXml2, MarcUtil.Xml2MarcStyle.Warning | MarcUtil.Xml2MarcStyle.OutputFragmentXml, "", out strOutMarcSyntax, out strNewMARC, out strNewFragmentXml, out strError); if (nRet == -1) { strError = "XML转换到MARC记录时出错: " + strError; return -1; } } if (string.IsNullOrEmpty(strOldMARC) == false && string.IsNullOrEmpty(strNewMARC) == false) { string strOldImageFragment = GetCoverImageHtmlFragment( info.RecPath, strOldMARC); string strNewImageFragment = GetCoverImageHtmlFragment( info.RecPath, strNewMARC); // 创建展示两个 MARC 记录差异的 HTML 字符串 // return: // -1 出错 // 0 成功 nRet = MarcDiff.DiffHtml( strOldMARC, strOldFragmentXml, strOldImageFragment, strNewMARC, strNewFragmentXml, strNewImageFragment, out strHtml2, out strError); if (nRet == -1) return -1; } else if (string.IsNullOrEmpty(strOldMARC) == false && string.IsNullOrEmpty(strNewMARC) == true) { string strImageFragment = GetCoverImageHtmlFragment( info.RecPath, strOldMARC); strHtml2 = MarcUtil.GetHtmlOfMarc(strOldMARC, strOldFragmentXml, strImageFragment, false); } else if (string.IsNullOrEmpty(strOldMARC) == true && string.IsNullOrEmpty(strNewMARC) == false) { string strImageFragment = GetCoverImageHtmlFragment( info.RecPath, strNewMARC); strHtml2 = MarcUtil.GetHtmlOfMarc(strNewMARC, strNewFragmentXml, strImageFragment, false); } return 0; }
// 拷贝构造 public BiblioInfo(BiblioInfo ref_obj) { this.RecPath = ref_obj.RecPath; this.OldXml = ref_obj.OldXml; this.NewXml = ref_obj.NewXml; this.Timestamp = ref_obj.Timestamp; }
/// <summary> /// 获得枚举接口 /// </summary> /// <returns>枚举接口</returns> public IEnumerator GetEnumerator() { Debug.Assert(m_loader != null, ""); List<string> recpaths = new List<string>(); // 缓存中么有包含的那些记录 foreach (ListViewItem item in this.Items) { string strRecPath = item.Text; Debug.Assert(string.IsNullOrEmpty(strRecPath) == false, ""); BiblioInfo info = (BiblioInfo)this.CacheTable[strRecPath]; if (info == null || string.IsNullOrEmpty(info.OldXml) == true) recpaths.Add(strRecPath); } // 注: Hashtable 在这一段时间内不应该被修改。否则会破坏 m_loader 和 items 之间的锁定对应关系 m_loader.RecPaths = recpaths; var enumerator = m_loader.GetEnumerator(); // 开始循环 foreach (ListViewItem item in this.Items) { string strRecPath = item.Text; Debug.Assert(string.IsNullOrEmpty(strRecPath) == false, ""); BiblioInfo info = (BiblioInfo)this.CacheTable[strRecPath]; if (info == null || string.IsNullOrEmpty(info.OldXml) == true) { if (m_loader.Stop != null) { m_loader.Stop.SetMessage("正在获取"+this.DbTypeCaption+"记录 " + strRecPath); } bool bRet = enumerator.MoveNext(); if (bRet == false) { Debug.Assert(false, "还没有到结尾, MoveNext() 不应该返回 false"); // TODO: 这时候也可以采用返回一个带没有找到的错误码的元素 yield break; } DigitalPlatform.CirculationClient.localhost.Record biblio = (DigitalPlatform.CirculationClient.localhost.Record)enumerator.Current; Debug.Assert(biblio.Path == strRecPath, "m_loader 和 items 的元素之间 记录路径存在严格的锁定对应关系"); // 需要放入缓存 if (info == null) { info = new BiblioInfo(); info.RecPath = biblio.Path; } info.OldXml = biblio.RecordBody.Xml; info.Timestamp = biblio.RecordBody.Timestamp; this.CacheTable[strRecPath] = info; yield return new LoaderItem(info, item); } else yield return new LoaderItem(info, item); } }
void _doViewProperty(ListViewItem item, bool bOpenWindow) { if (this.m_biblioTable == null) return; if (item == null) return; // 是否要显示一个空画面? this.MainForm.OpenCommentViewer(bOpenWindow); string strRecPath = item.Text; if (string.IsNullOrEmpty(strRecPath) == true) return; // 存储所获得书目记录 XML BiblioInfo info = (BiblioInfo)this.m_biblioTable[strRecPath]; if (info == null) { info = new BiblioInfo(); info.RecPath = strRecPath; this.m_biblioTable[strRecPath] = info; // 后面任务中会填充 info 的内容,如果必要的话 } BiblioPropertyTask task = new BiblioPropertyTask(); task.BiblioInfo = info; task.Stop = this.stop; this.MainForm.PropertyTaskList.AddTask(task, true); }
internal virtual int GetXmlHtml(BiblioInfo info, out string strXml, out string strHtml2, out string strError) { strError = ""; strXml = ""; strHtml2 = ""; return 0; }
void MessageHub_SearchResponseEvent(object sender, SearchResponseEventArgs e) { if (e.TaskID != _searchParam._searchID) return; if (e.ResultCount == -1 && e.Start == -1) { // 检索过程结束 _searchParam._searchComplete = true; _searchParam._searchCount = (int)_searchParam._manager.GetTotalCount(); return; } string strError = ""; if (e.ResultCount == -1) { strError = e.ErrorInfo; goto ERROR1; } List<string> array = StringUtil.ParseTwoPart(e.LibraryUID, "|"); string strLibraryName = array[0]; // 标记结束一个检索目标 // return: // 0 尚未结束 // 1 结束 // 2 全部结束 int nRet = _searchParam._manager.CompleteTarget(e.LibraryUID, e.ResultCount, e.Records == null ? 0 : e.Records.Count); _searchParam._searchCount = (int)_searchParam._manager.GetTotalCount(); if (nRet == 2) _searchParam._searchComplete = true; // 单独给一个线程来执行 Task.Factory.StartNew(() => FillList(e.Start, strLibraryName, e.Records)); return; #if NO // TODO: 注意来自共享网络的图书馆名不能和 servers.xml 中的名字冲突。另外需要检查,不同的 UID,图书馆名字不能相同,如果发生冲突,则需要给分配 ..1 ..2 这样的编号以示区别 // 需要一直保存一个 UID 到图书馆命的对照表在内存备用 // TODO: 来自共享网络的记录,图标或 @ 后面的名字应该有明显的形态区别 foreach (DigitalPlatform.MessageClient.Record record in e.Records) { MessageHub.DecodeRecord(record, _searchParam._serverPushEncoding); string strXml = record.Data; string strMarcSyntax = ""; string strBrowseText = ""; string strColumnTitles = ""; int nRet = BuildBrowseText(strXml, out strBrowseText, out strMarcSyntax, out strColumnTitles, out strError); if (nRet == -1) goto ERROR1; // string strRecPath = record.RecPath + "@" + (string.IsNullOrEmpty(record.LibraryName) == false ? record.LibraryName : record.LibraryUID); string strRecPath = record.RecPath; #if NO string strDbName = ListViewProperty.GetDbName(strRecPath); _browseTitleTable[strDbName] = strColumnTitles; #endif _browseTitleTable[strMarcSyntax] = strColumnTitles; // 将书目记录放入 m_biblioTable { BiblioInfo info = new BiblioInfo(); info.OldXml = strXml; info.RecPath = strRecPath; info.Timestamp = ByteArray.GetTimeStampByteArray(record.Timestamp); info.Format = strMarcSyntax; this.browseWindow.BiblioTable[strRecPath] = info; } List<string> column_list = StringUtil.SplitList(strBrowseText, '\t'); string[] cols = new string[column_list.Count]; column_list.CopyTo(cols); ListViewItem item = null; this.Invoke((Action)(() => { item = Global.AppendNewLine( this.browseWindow.RecordsList, strRecPath, cols); } )); if (item != null) item.BackColor = Color.LightGreen; #if NO RegisterBiblioInfo info = new RegisterBiblioInfo(); info.OldXml = strXml; // strMARC; info.Timestamp = ByteArray.GetTimeStampByteArray(record.Timestamp); info.RecPath = record.RecPath + "@" + (string.IsNullOrEmpty(record.LibraryName) == false ? record.LibraryName : record.LibraryUID); info.MarcSyntax = strMarcSyntax; #endif _searchParam._searchCount++; } return; #endif ERROR1: // 加入一个文本行 AddErrorLine(strError); }
// 保存一条记录 // 保存成功后, info.Timestamp 会被更新 // parameters: // strStyle force/空 // return: // -2 时间戳不匹配 // -1 出错 // 0 成功 internal override int SaveRecord(string strRecPath, BiblioInfo info, string strStyle, out byte[] baNewTimestamp, out string strError) { strError = ""; baNewTimestamp = null; List<EntityInfo> entityArray = new List<EntityInfo>(); { EntityInfo item_info = new EntityInfo(); item_info.OldRecPath = strRecPath; // 2016/9/7 if (StringUtil.IsInList("force", strStyle)) item_info.Action = "forcechange"; else item_info.Action = "change"; item_info.NewRecPath = strRecPath; item_info.NewRecord = info.NewXml; item_info.NewTimestamp = null; item_info.OldRecord = info.OldXml; item_info.OldTimestamp = info.Timestamp; entityArray.Add(item_info); } // 复制到目标 EntityInfo[] entities = null; entities = new EntityInfo[entityArray.Count]; for (int i = 0; i < entityArray.Count; i++) { entities[i] = entityArray[i]; } EntityInfo[] errorinfos = null; long lRet = 0; if (this.DbType == "item") lRet = this.Channel.SetEntities( null, // this.BiblioStatisForm.stop, "", entities, out errorinfos, out strError); else if (this.DbType == "order") lRet = this.Channel.SetOrders( null, // this.BiblioStatisForm.stop, "", entities, out errorinfos, out strError); else if (this.DbType == "issue") lRet = this.Channel.SetIssues( null, // this.BiblioStatisForm.stop, "", entities, out errorinfos, out strError); else if (this.DbType == "comment") lRet = this.Channel.SetComments( null, // this.BiblioStatisForm.stop, "", entities, out errorinfos, out strError); else { strError = "未知的数据库类型 '" + this.DbType + "'"; return -1; } if (lRet == -1) return -1; // string strWarning = ""; // 警告信息 if (errorinfos == null) return 0; strError = ""; for (int i = 0; i < errorinfos.Length; i++) { #if NO if (String.IsNullOrEmpty(errorinfos[i].RefID) == true) { strError = "服务器返回的EntityInfo结构中RefID为空"; return -1; } #endif if (i == 0) baNewTimestamp = errorinfos[i].NewTimestamp; // 正常信息处理 if (errorinfos[i].ErrorCode == ErrorCodeValue.NoError) continue; strError += errorinfos[i].RefID + "在提交保存过程中发生错误 -- " + errorinfos[i].ErrorInfo + "\r\n"; } if (baNewTimestamp != null) // 2016/9/3 info.Timestamp = baNewTimestamp; // 2013/10/17 if (String.IsNullOrEmpty(strError) == false) return -1; return 0; }
int GetBiblioInfo( bool bCheckSearching, ListViewItem item, out BiblioInfo info, out string strError) { strError = ""; info = null; if (this.m_biblioTable == null) return 0; string strRecPath = item.Text; if (string.IsNullOrEmpty(strRecPath) == true) return 0; // 存储所获得书目记录 XML info = (BiblioInfo)this.m_biblioTable[strRecPath]; if (info == null) { info = new BiblioInfo(); info.RecPath = strRecPath; this.m_biblioTable[strRecPath] = info; } if (string.IsNullOrEmpty(info.OldXml) == true) { if (bCheckSearching == true) { if (this.InSearching == true) return 0; } #if NO string[] results = null; byte[] baTimestamp = null; string strOutputRecPath = ""; // 获得读者记录 long lRet = Channel.GetReaderInfo( stop, "@path:" + strRecPath, "xml", out results, out strOutputRecPath, out baTimestamp, out strError); if (lRet == 0) return -1; // 是否设定为特殊状态? if (lRet == -1) return -1; if (results == null || results.Length == 0) { strError = "results error"; return -1; } string strXml = results[0]; #endif string strXml = ""; byte[] baTimestamp = null; // 获得一条记录 //return: // -1 出错 // 0 没有找到 // 1 找到 int nRet = GetRecord( strRecPath, out strXml, out baTimestamp, out strError); if (nRet == 0 || nRet == 0) return -1; info.OldXml = strXml; info.Timestamp = baTimestamp; info.RecPath = strRecPath; } return 1; }
// 保存一条记录 // 保存成功后, info.Timestamp 会被更新 // return: // -2 时间戳不匹配 // -1 出错 // 0 成功 int SaveItemRecord(string strRecPath, BiblioInfo info, out byte[] baNewTimestamp, out string strError) { strError = ""; baNewTimestamp = null; List<EntityInfo> entityArray = new List<EntityInfo>(); { EntityInfo item_info = new EntityInfo(); item_info.OldRecPath = strRecPath; item_info.Action = "change"; item_info.NewRecPath = strRecPath; item_info.NewRecord = info.NewXml; item_info.NewTimestamp = null; item_info.OldRecord = info.OldXml; item_info.OldTimestamp = info.Timestamp; entityArray.Add(item_info); } // 复制到目标 EntityInfo[] entities = null; entities = new EntityInfo[entityArray.Count]; for (int i = 0; i < entityArray.Count; i++) { entities[i] = entityArray[i]; } EntityInfo[] errorinfos = null; long lRet = 0; lRet = this.Channel.SetEntities( null, // this.BiblioStatisForm.stop, "", entities, out errorinfos, out strError); if (lRet == -1) return -1; // string strWarning = ""; // 警告信息 if (errorinfos == null) return 0; strError = ""; for (int i = 0; i < errorinfos.Length; i++) { #if NO if (String.IsNullOrEmpty(errorinfos[i].RefID) == true) { strError = "服务器返回的EntityInfo结构中RefID为空"; return -1; } #endif if (i == 0) baNewTimestamp = errorinfos[i].NewTimestamp; // 正常信息处理 if (errorinfos[i].ErrorCode == ErrorCodeValue.NoError) continue; strError += errorinfos[i].RefID + "在提交保存过程中发生错误 -- " + errorinfos[i].ErrorInfo + "\r\n"; } info.Timestamp = baNewTimestamp; if (String.IsNullOrEmpty(strError) == false) return -1; return 0; }
internal static int GetXmlHtml(BiblioInfo info, out string strXml, out string strHtml2, out string strError) { strError = ""; strXml = ""; strHtml2 = ""; string strOldXml = ""; string strNewXml = ""; int nRet = 0; strOldXml = info.OldXml; strNewXml = info.NewXml; if (string.IsNullOrEmpty(strOldXml) == false && string.IsNullOrEmpty(strNewXml) == false) { // 创建展示两个 MARC 记录差异的 HTML 字符串 // return: // -1 出错 // 0 成功 nRet = MarcDiff.DiffXml( strOldXml, strNewXml, out strHtml2, out strError); if (nRet == -1) return -1; } else if (string.IsNullOrEmpty(strOldXml) == false && string.IsNullOrEmpty(strNewXml) == true) { strHtml2 = MarcUtil.GetHtmlOfXml(strOldXml, false); } else if (string.IsNullOrEmpty(strOldXml) == true && string.IsNullOrEmpty(strNewXml) == false) { strHtml2 = MarcUtil.GetHtmlOfXml(strNewXml, false); } strXml = MergeXml(strOldXml, strNewXml); return 0; }
// 新加入一行 public ListViewItem AddLine( string strBiblioRecPath, BiblioInfo biblio_info, MarcField field, int index) { // 将 BiblioInfo 储存起来 BiblioInfo existing = (BiblioInfo)this.m_biblioTable[strBiblioRecPath]; if (existing == null) this.m_biblioTable[strBiblioRecPath] = biblio_info; ListViewItem item = new ListViewItem(); SetItemColumns(item, strBiblioRecPath, field, index); this.listView_records.Items.Add(item); LineInfo line_info = new LineInfo(); line_info.OldField = field.Text; line_info.Index = index; item.Tag = line_info; return item; }
// 把对字段的修改合并到书目记录中 // return: // -1 出错 // 0 书目记录没有发生修改 // 1 书目记录发生了修改 int MergeChange(LineInfo line_info, BiblioInfo biblio_info, out string strError) { strError = ""; int nRet = 0; string strXml = biblio_info.NewXml; if (string.IsNullOrEmpty(strXml) == true) strXml = biblio_info.OldXml; string strMARC = ""; string strMarcSyntax = ""; // 将XML格式转换为MARC格式 // 自动从数据记录中获得MARC语法 nRet = MarcUtil.Xml2Marc(strXml, true, null, out strMarcSyntax, out strMARC, out strError); if (nRet == -1) { strError = "XML 转换到 MARC 记录时出错: " + strError; return -1; } if (string.IsNullOrEmpty(line_info.State) == true && string.IsNullOrEmpty(line_info.NewField) == true) { strError = "一般修改情况下的 line_info.NewField 不应该为空"; return -1; } MarcRecord record = new MarcRecord(strMARC); MarcNodeList fields = record.select("field[@name='856']"); if (fields.count > line_info.Index) { if (line_info.State == "delete") fields[line_info.Index].detach(); else fields[line_info.Index].Text = line_info.NewField; } else { if (line_info.State == "delete") return 0; Debug.Assert(false, "除非插入情况,否则走不到这里"); // 添加足够的 856 字段 MarcField tail = null; for (int i = fields.count; i < line_info.Index + 1; i++) { tail = new MarcField("856", " "); record.ChildNodes.insertSequence(tail, InsertSequenceStyle.PreferTail); } Debug.Assert(tail != null, ""); tail.Text = line_info.NewField; } strMARC = record.Text; nRet = MarcUtil.Marc2XmlEx(strMARC, strMarcSyntax, ref strXml, out strError); if (nRet == -1) { strError = "MARC 转换到 XML 记录时出错: " + strError; return -1; } biblio_info.NewXml = strXml; return 1; }
// return: // -2 时间戳不匹配 // -1 出错 // 0 成功 internal override int SaveRecord(string strRecPath, BiblioInfo info, out byte[] baNewTimestamp, out string strError) { strError = ""; ErrorCodeValue kernel_errorcode; string strOutputPath = ""; baNewTimestamp = null; string strExistingXml = ""; string strSavedXml = ""; // string strSavedPath = ""; long lRet = Channel.SetReaderInfo( stop, "change", strRecPath, info.NewXml, info.OldXml, info.Timestamp, out strExistingXml, out strSavedXml, out strOutputPath, out baNewTimestamp, out kernel_errorcode, out strError); if (lRet == -1) { if (Channel.ErrorCode == ErrorCode.TimestampMismatch) return -2; return -1; } info.Timestamp = baNewTimestamp; // 2013/10/17 return 0; }
/// <summary> /// 构造函数 /// </summary> /// <param name="info">书目信息</param> /// <param name="item">关联的 ListViewItem 对象</param> public LoaderItem(BiblioInfo info, ListViewItem item) { this.BiblioInfo = info; this.ListViewItem = item; }
void MessageHub_SearchResponseEvent(object sender, SearchResponseEventArgs e) { if (e.SsearchID != _searchParam._searchID) return; if (e.ResultCount == -1 && e.Start == -1) { // 检索过程结束 _searchParam._searchComplete = true; return; } string strError = ""; if (e.ResultCount == -1) { strError = e.ErrorInfo; goto ERROR1; } // TODO: 注意来自共享网络的图书馆名不能和 servers.xml 中的名字冲突。另外需要检查,不同的 UID,图书馆名字不能相同,如果发生冲突,则需要给分配 ..1 ..2 这样的编号以示区别 // 需要一直保存一个 UID 到图书馆命的对照表在内存备用 // TODO: 来自共享网络的记录,图标或 @ 后面的名字应该有明显的形态区别 foreach (BiblioRecord record in e.Records) { string strXml = record.Data; string strMarcSyntax = ""; string strBrowseText = ""; string strColumnTitles = ""; int nRet = BuildBrowseText(strXml, out strBrowseText, out strMarcSyntax, out strColumnTitles, out strError); if (nRet == -1) goto ERROR1; string strRecPath = record.RecPath + "@" + (string.IsNullOrEmpty(record.LibraryName) == false ? record.LibraryName : record.LibraryUID); #if NO string strDbName = ListViewProperty.GetDbName(strRecPath); _browseTitleTable[strDbName] = strColumnTitles; #endif _browseTitleTable[strMarcSyntax] = strColumnTitles; // 将书目记录放入 m_biblioTable { BiblioInfo info = new BiblioInfo(); info.OldXml = strXml; info.RecPath = strRecPath; info.Timestamp = ByteArray.GetTimeStampByteArray(record.Timestamp); info.Format = strMarcSyntax; this.m_biblioTable[strRecPath] = info; } List<string> column_list = StringUtil.SplitList(strBrowseText, '\t'); string[] cols = new string[column_list.Count]; column_list.CopyTo(cols); ListViewItem item = null; this.Invoke((Action)(() => { item = Global.AppendNewLine( this.listView_records, strRecPath, cols); } )); if (item != null) item.BackColor = Color.LightGreen; #if NO RegisterBiblioInfo info = new RegisterBiblioInfo(); info.OldXml = strXml; // strMARC; info.Timestamp = ByteArray.GetTimeStampByteArray(record.Timestamp); info.RecPath = record.RecPath + "@" + (string.IsNullOrEmpty(record.LibraryName) == false ? record.LibraryName : record.LibraryUID); info.MarcSyntax = strMarcSyntax; #endif _searchParam._searchCount++; } return; ERROR1: // 加入一个文本行 { string[] cols = new string[1]; cols[0] = strError; this.Invoke((Action)(() => { ListViewItem item = Global.AppendNewLine( this.listView_records, "error", cols); } )); } }
/// <summary> /// 获得枚举接口 /// </summary> /// <returns>枚举接口</returns> public IEnumerator GetEnumerator() { Debug.Assert(m_loader != null, ""); Hashtable dup_table = new Hashtable(); // 确保 recpaths 中不会出现重复的路径 List<string> recpaths = new List<string>(); // 缓存中没有包含的那些记录 foreach (ListViewItem item in this.Items) { string strRecPath = item.Text; Debug.Assert(string.IsNullOrEmpty(strRecPath) == false, ""); if (dup_table.ContainsKey(strRecPath) == true) continue; BiblioInfo info = (BiblioInfo)this.CacheTable[strRecPath]; if (info == null || string.IsNullOrEmpty(info.OldXml) == true) { recpaths.Add(strRecPath); dup_table[strRecPath] = true; } } // 注: Hashtable 在这一段时间内不应该被修改。否则会破坏 m_loader 和 items 之间的锁定对应关系 m_loader.RecPaths = recpaths; var enumerator = m_loader.GetEnumerator(); // 开始循环 foreach (ListViewItem item in this.Items) { string strRecPath = item.Text; Debug.Assert(string.IsNullOrEmpty(strRecPath) == false, ""); BiblioInfo info = (BiblioInfo)this.CacheTable[strRecPath]; if (info == null || string.IsNullOrEmpty(info.OldXml) == true) { if (m_loader.Stop != null) { m_loader.Stop.SetMessage("正在获取书目记录 " + strRecPath); } bool bRet = enumerator.MoveNext(); if (bRet == false) { Debug.Assert(false, "还没有到结尾, MoveNext() 不应该返回 false"); // TODO: 这时候也可以采用返回一个带没有找到的错误码的元素 yield break; } BiblioItem biblio = (BiblioItem)enumerator.Current; Debug.Assert(biblio.RecPath == strRecPath, "m_loader 和 items 的元素之间 记录路径存在严格的锁定对应关系"); // 需要放入缓存 if (info == null) { info = new BiblioInfo(); info.RecPath = biblio.RecPath; } info.OldXml = biblio.Content; info.Timestamp = biblio.Timestamp; this.CacheTable[strRecPath] = info; yield return new LoaderItem(info, item); } else yield return new LoaderItem(info, item); } }
void FillList(long lStart, string strLibraryName, IList<DigitalPlatform.MessageClient.Record> Records) { string strError = ""; // lock (_searchParam) { // TODO: 注意来自共享网络的图书馆名不能和 servers.xml 中的名字冲突。另外需要检查,不同的 UID,图书馆名字不能相同,如果发生冲突,则需要给分配 ..1 ..2 这样的编号以示区别 // 需要一直保存一个 UID 到图书馆命的对照表在内存备用 // TODO: 来自共享网络的记录,图标或 @ 后面的名字应该有明显的形态区别 foreach (DigitalPlatform.MessageClient.Record record in Records) { MessageHub.DecodeRecord(record, _searchParam._serverPushEncoding); string strRecPath = record.RecPath + "@" + strLibraryName; // 校验一下 MD5 if (string.IsNullOrEmpty(record.MD5) == false) { string strMD5 = StringUtil.GetMd5(record.Data); if (record.MD5 != strMD5) { strError = "dp2Circulation : 记录 '" + strRecPath + "' Data 的 MD5 校验出现异常"; AddErrorLine(strError); continue; } } string strXml = record.Data; string strMarcSyntax = ""; string strBrowseText = ""; string strColumnTitles = ""; int nRet = BuildBrowseText(strXml, out strBrowseText, out strMarcSyntax, out strColumnTitles, out strError); if (nRet == -1) { AddErrorLine("记录 " + strRecPath + " 创建浏览格式时出: " + strError); continue; } #if NO // string strRecPath = record.RecPath + "@" + (string.IsNullOrEmpty(record.LibraryName) == false ? record.LibraryName : record.LibraryUID); string strRecPath = // "lStart="+lStart.ToString() + " " + i + "/"+ Records.Count + " " + _searchParam.BuildNamePath(record.RecPath); #endif #if NO string strDbName = ListViewProperty.GetDbName(strRecPath); _browseTitleTable[strDbName] = strColumnTitles; #endif _browseTitleTable[strMarcSyntax] = strColumnTitles; // 将书目记录放入 m_biblioTable { BiblioInfo info = new BiblioInfo(); info.OldXml = strXml; info.RecPath = strRecPath; info.Timestamp = ByteArray.GetTimeStampByteArray(record.Timestamp); info.Format = strMarcSyntax; lock (this.m_biblioTable) { this.m_biblioTable[strRecPath] = info; } } List<string> column_list = StringUtil.SplitList(strBrowseText, '\t'); string[] cols = new string[column_list.Count]; column_list.CopyTo(cols); ListViewItem item = null; this.Invoke((Action)(() => { item = Global.AppendNewLine( this.listView_records, strRecPath, cols); } )); if (item != null) item.BackColor = Color.LightGreen; #if NO RegisterBiblioInfo info = new RegisterBiblioInfo(); info.OldXml = strXml; // strMARC; info.Timestamp = ByteArray.GetTimeStampByteArray(record.Timestamp); info.RecPath = record.RecPath + "@" + (string.IsNullOrEmpty(record.LibraryName) == false ? record.LibraryName : record.LibraryUID); info.MarcSyntax = strMarcSyntax; #endif } // Debug.Assert(e.Start == _searchParam._searchCount, ""); return; } return; #if NO ERROR1: AddErrorLine(strError); #endif }
// 保存一条记录 // 保存成功后, info.Timestamp 会被更新 // return: // -2 时间戳不匹配 // -1 出错 // 0 成功 internal virtual int SaveRecord(string strRecPath, BiblioInfo info, out byte [] baNewTimestamp, out string strError) { strError = "尚未实现"; baNewTimestamp = null; return -1; }
void menu_quickMarcQueryRecords_Click(object sender, EventArgs e) { string strError = ""; int nRet = 0; if (this.listView_records.SelectedItems.Count == 0) { strError = "尚未选择要执行 MarcQuery 脚本的事项"; goto ERROR1; } // 书目信息缓存 // 如果已经初始化,则保持 if (this.m_biblioTable == null) this.m_biblioTable = new Hashtable(); OpenFileDialog dlg = new OpenFileDialog(); dlg.Title = "请指定 MarcQuery 脚本文件"; dlg.FileName = this.m_strUsedMarcQueryFilename; dlg.Filter = "MarcQuery 脚本文件 (*.cs)|*.cs|All files (*.*)|*.*"; dlg.RestoreDirectory = true; if (dlg.ShowDialog() != DialogResult.OK) return; this.m_strUsedMarcQueryFilename = dlg.FileName; MarcQueryHost host = null; Assembly assembly = null; nRet = PrepareMarcQuery(this.m_strUsedMarcQueryFilename, out assembly, out host, out strError); if (nRet == -1) goto ERROR1; stop.Style = StopStyle.EnableHalfStop; stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在针对书目记录执行 MarcQuery 脚本 ..."); stop.BeginLoop(); this.EnableControls(false); this.listView_records.Enabled = false; try { if (stop != null) stop.SetProgressRange(0, this.listView_records.SelectedItems.Count); int i = 0; foreach (ListViewItem item in this.listView_records.SelectedItems) { Application.DoEvents(); // 出让界面控制权 if (stop != null && stop.State != 0) { strError = "用户中断"; goto ERROR1; } string strRecPath = item.Text; if (string.IsNullOrEmpty(strRecPath) == true) continue; if (stop != null) { stop.SetMessage("正在获取书目记录 " + strRecPath); stop.SetProgressValue(i); } BiblioInfo info = null; nRet = GetBiblioInfo( false, item, out info, out strError); if (nRet == -1) goto ERROR1; if (info == null) continue; #if NO string[] results = null; byte[] baTimestamp = null; // 获得书目记录 long lRet = Channel.GetBiblioInfos( stop, strRecPath, "", new string[] { "xml" }, // formats out results, out baTimestamp, out strError); if (lRet == 0) goto ERROR1; if (lRet == -1) goto ERROR1; if (results == null || results.Length == 0) { strError = "results error"; goto ERROR1; } string strXml = results[0]; XmlDocument domXmlFragment = null; // 装载书目以外的其它XML片断 nRet = LoadXmlFragment(strXml, out domXmlFragment, out strError); if (nRet == -1) goto ERROR1; string strMARC = ""; string strMarcSyntax = ""; // 将XML格式转换为MARC格式 // 自动从数据记录中获得MARC语法 nRet = MarcUtil.Xml2Marc(strXml, true, null, out strMarcSyntax, out strMARC, out strError); if (nRet == -1) { strError = "XML转换到MARC记录时出错: " + strError; goto ERROR1; } // 存储所获得书目记录 XML BiblioInfo info = null; if (this.m_biblioTable != null) { info = (BiblioInfo)this.m_biblioTable[strRecPath]; if (info == null) { info = new BiblioInfo(); info.RecPath = strRecPath; this.m_biblioTable[strRecPath] = info; } info.OldXml = strXml; info.NewXml = ""; } #endif string strMARC = ""; string strMarcSyntax = ""; // 将XML格式转换为MARC格式 // 自动从数据记录中获得MARC语法 nRet = MarcUtil.Xml2Marc(info.OldXml, true, null, out strMarcSyntax, out strMARC, out strError); if (nRet == -1) { strError = "XML转换到MARC记录时出错: " + strError; goto ERROR1; } host.MainForm = this.MainForm; host.MarcRecord = new MarcRecord(strMARC); host.MarcSyntax = strMarcSyntax; host.Changed = false; host.Main(); if (host.Changed == true) { string strXml = info.OldXml; nRet = MarcUtil.Marc2XmlEx(host.MarcRecord.Text, strMarcSyntax, ref strXml, out strError); if (nRet == -1) goto ERROR1; #if NO // 合成其它XML片断 if (domXmlFragment != null && string.IsNullOrEmpty(domXmlFragment.DocumentElement.InnerXml) == false) { XmlDocumentFragment fragment = domMarc.CreateDocumentFragment(); try { fragment.InnerXml = domXmlFragment.DocumentElement.InnerXml; } catch (Exception ex) { strError = "fragment XML装入XmlDocumentFragment时出错: " + ex.Message; goto ERROR1; } domMarc.DocumentElement.AppendChild(fragment); } strXml = domMarc.OuterXml; #endif if (info != null) { if (string.IsNullOrEmpty(info.NewXml) == true) this.m_nChangedCount++; info.NewXml = strXml; } item.BackColor = SystemColors.Info; item.ForeColor = SystemColors.InfoText; #if NO byte[] baNewTimestamp = null; string strOutputPath = ""; lRet = Channel.SetBiblioInfo( stop, "change", strRecPath, "xml", strXml, baTimestamp, "", out strOutputPath, out baNewTimestamp, out strError); if (lRet == -1) goto ERROR1; #endif } this.MainForm.OperHistory.AppendHtml("<p>" + HttpUtility.HtmlEncode(strRecPath) + "</p>"); // 显示为工作单形式 #if NO if (nRet == -1) { DialogResult result = MessageBox.Show(this, "刷新浏览内容时出错: " + strError + "。\r\n\r\n是否继续刷新? (OK 刷新;Cancel 放弃刷新)", "BiblioSearchForm", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); if (result == System.Windows.Forms.DialogResult.Cancel) break; } #endif i++; } } finally { this.listView_records.Enabled = true; stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); stop.HideProgress(); stop.Style = StopStyle.None; this.EnableControls(true); } DoViewComment(false); return; ERROR1: MessageBox.Show(this, strError); }
/// <summary> /// 装载记录,从 BiblioInfo 对象 /// </summary> /// <param name="info"></param> /// <param name="bSetFocus"></param> /// <param name="strTotalError"></param> /// <param name="bWarningNotSave"></param> /// <returns> /// -1 出错 /// 0 没有装载(例如发现窗口内的记录没有保存,出现警告对话框后,操作者选择了Cancel;或者“到头”“到尾”) /// 1 成功装载 /// 2 通道被占用 /// </returns> public int LoadRecord(BiblioInfo info, bool bSetFocus, out string strTotalError, bool bWarningNotSave = false) { strTotalError = ""; int nRet = 0; if (this.EntitiesChanged == true || this.IssuesChanged == true || this.BiblioChanged == true || this.ObjectChanged == true || this.OrdersChanged == true || this.CommentsChanged == true) { if (this.checkBox_autoSavePrev.Checked == true && bWarningNotSave == false) { nRet = this.DoSaveAll(); if (nRet == -1) { // strTotalError = "当前记录尚未保存"; // 2014/7/8 return -1; } } else { // 警告尚未保存 DialogResult result = MessageBox.Show(this, "当前窗口内有 " + GetCurrentChangedPartName() + " 被修改后尚未保存。若此时装载新内容,现有未保存信息将丢失。\r\n\r\n确实要装入新内容? ", "EntityForm", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2); if (result == DialogResult.No) return 0; } } // 2012/7/25 移动到这里 // 因为 LoadBiblioRecord() 会导致填充AutoGen菜单 this._genData.ClearViewer(); if (this.m_commentViewer != null) this.m_commentViewer.Clear(); // 清空4个下属记录的控件 this.entityControl1.ClearItems(); this.textBox_itemBarcode.Text = ""; this.issueControl1.ClearItems(); this.orderControl1.ClearItems(); this.commentControl1.ClearItems(); this.binaryResControl1.Clear(); this.EnableItemsPage(false); this.EnableIssuesPage(false); this.EnableOrdersPage(false); this.EnableCommentsPage(false); if (this.m_verifyViewer != null) this.m_verifyViewer.Clear(); this.m_webExternalHost_biblio.SetHtmlString("(空白)", "entityform_error"); string strXml = ""; if (string.IsNullOrEmpty(info.NewXml) == false) strXml = info.NewXml; else strXml = info.OldXml; string strError = ""; bool bError = false; // return: // -1 error // 0 空的记录 // 1 成功 nRet = SetBiblioRecordToMarcEditor(strXml, out strError); if (nRet == -1) { if (String.IsNullOrEmpty(strTotalError) == false) strTotalError += "\r\n"; strTotalError += strError; bError = true; } this.BiblioTimestamp = info.Timestamp; this.BiblioRecPath = ""; // info.RecPath; // 显示Ctrl+A菜单 if (this.MainForm.PanelFixedVisible == true) this._genData.AutoGenerate(this.m_marcEditor, new GenerateDataEventArgs(), "format:" + this.MarcSyntax, true); this.BiblioChanged = false; // 装载书目和<dprms:file>以外的其它XML片断 if (string.IsNullOrEmpty(strXml) == false) { nRet = LoadXmlFragment(strXml, out strError); if (nRet == -1) { if (String.IsNullOrEmpty(strTotalError) == false) strTotalError += "\r\n"; strTotalError += strError; bError = true; } } this.DeletedMode = false; if (bError == true) { this.ShowMessage(strTotalError, "red", true); return -1; } this.ShowMessage("书目记录来自\r\n" + info.RecPath, "green", true); if (m_strFocusedPart == "marceditor" && bSetFocus == true) { SwitchFocus(MARC_EDITOR); } DoViewComment(false); return 1; }
// 根据 ListViewItem 对象得到 BiblioInfo 对象 int GetBiblioInfo( bool bCheckSearching, ListViewItem item, out BiblioInfo info, out string strError) { strError = ""; info = null; if (this.m_biblioTable == null) return 0; string strRecPath = item.Text; if (string.IsNullOrEmpty(strRecPath) == true) return 0; // 存储所获得书目记录 XML info = (BiblioInfo)this.m_biblioTable[strRecPath]; if (info == null) { info = new BiblioInfo(); info.RecPath = strRecPath; this.m_biblioTable[strRecPath] = info; } if (string.IsNullOrEmpty(info.OldXml) == true) { if (bCheckSearching == true) { if (this.InSearching == true) return 0; } LibraryChannel channel = this.GetChannel(); try { string[] results = null; byte[] baTimestamp = null; // 获得书目记录 long lRet = channel.GetBiblioInfos( stop, strRecPath, "", new string[] { "xml" }, // formats out results, out baTimestamp, out strError); if (lRet == 0) return -1; // 是否设定为特殊状态? if (lRet == -1) return -1; if (results == null || results.Length == 0) { strError = "results error"; return -1; } string strXml = results[0]; info.OldXml = strXml; info.Timestamp = baTimestamp; info.RecPath = strRecPath; } finally { this.ReturnChannel(channel); } } return 1; }
void FillList(long lStart, string strLibraryName, IList<DigitalPlatform.MessageClient.Record> Records) { string strError = ""; int nRet = 0; // lock (_searchParam) { // TODO: 注意来自共享网络的图书馆名不能和 servers.xml 中的名字冲突。另外需要检查,不同的 UID,图书馆名字不能相同,如果发生冲突,则需要给分配 ..1 ..2 这样的编号以示区别 // 需要一直保存一个 UID 到图书馆命的对照表在内存备用 // TODO: 来自共享网络的记录,图标或 @ 后面的名字应该有明显的形态区别 int i = 0; foreach (DigitalPlatform.MessageClient.Record record in Records) { MessageHub.DecodeRecord(record, _searchParam._serverPushEncoding); string strRecPath = record.RecPath + "@" + strLibraryName; string strXml = record.Data; string strMarcSyntax = ""; string strBrowseText = ""; string strColumnTitles = ""; this.Invoke((Action)(() => { nRet = BuildBrowseText(strXml, out strBrowseText, out strMarcSyntax, out strColumnTitles, out strError); } )); if (nRet == -1) { AddErrorLine("记录 " + strRecPath + " 创建浏览格式时出: " + strError); continue; } _browseTitleTable[strMarcSyntax] = strColumnTitles; // 将书目记录放入 m_biblioTable { BiblioInfo info = new BiblioInfo(); info.OldXml = strXml; info.RecPath = strRecPath; info.Timestamp = ByteArray.GetTimeStampByteArray(record.Timestamp); info.Format = strMarcSyntax; lock (this.browseWindow.BiblioTable) { this.browseWindow.BiblioTable[strRecPath] = info; } } List<string> column_list = StringUtil.SplitList(strBrowseText, '\t'); string[] cols = new string[column_list.Count]; column_list.CopyTo(cols); ListViewItem item = null; this.Invoke((Action)(() => { item = Global.AppendNewLine( this.browseWindow.RecordsList, strRecPath, cols); } )); if (item != null) item.BackColor = Color.LightGreen; } } return; #if NO ERROR1: // 加入一个文本行 AddErrorLine(strError); #endif }
void _doViewComment(bool bOpenWindow) { if (this.m_biblioTable == null) return; if (this._listviewRecords.SelectedItems.Count == 0) return; // 是否要显示一个空画面? ListViewItem item = this._listviewRecords.SelectedItems[0]; this.MainForm.OpenCommentViewer(bOpenWindow); string strRecPath = item.Text; if (string.IsNullOrEmpty(strRecPath) == true) return; // 存储所获得书目记录 XML BiblioInfo info = (BiblioInfo)this.m_biblioTable[strRecPath]; if (info == null) { info = new BiblioInfo(); info.RecPath = strRecPath; this.m_biblioTable[strRecPath] = info; // 后面任务中会填充 info 的内容,如果必要的话 } ItemPropertyTask task = new ItemPropertyTask(); task.BiblioInfo = info; task.Stop = this.stop; task.DbType = this.DbType; this.MainForm.PropertyTaskList.AddTask(task, true); }