// 获取指纹信息,追加到结果集文件的尾部 // parameters: // update_table key为读者记录路径 void AppendFingerprintInfo( LibraryChannel channel, DpResultSet resultset, Hashtable update_table, CancellationToken token) { List <string> lines = new List <string>(); foreach (string recpath in update_table.Keys) { lines.Add(recpath); } BrowseLoader loader = new BrowseLoader(); loader.RecPaths = lines; loader.Channel = channel; loader.Format = $"id,cols,format:cfgs/browse_{this.BrowseStyle}"; loader.Prompt += this.Loader_Prompt; foreach (DigitalPlatform.LibraryClient.localhost.Record record in loader) { token.ThrowIfCancellationRequested(); this.ShowMessage("追加 " + record.Path); if (record.Cols == null || record.Cols.Length < 3) { string strError = $"record.Cols error ... 有可能是因为读者库缺乏配置文件 cfgs/browse_{this.BrowseStyle}"; // TODO: 并发操作的情况下,会在中途出现读者记录被别的前端修改的情况,这里似乎可以continue throw new Exception(strError); } // 如果证条码号为空,无法建立对照关系,要跳过 if (string.IsNullOrEmpty(record.Cols[1]) == true) { continue; } DpRecord item = new DpRecord(record.Path); // timestamp | barcode | fingerprint item.BrowseText = record.Cols[0] + "|" + record.Cols[1] + "|" + record.Cols[2]; resultset.Add(item); } }
// 填充列表内容 // return: // -1 error // 0 没有填充任何内容,列表为空 // 1 已经填充了内容 public int LoadObject( LibraryChannel channel, XmlNodeList nodes, string dp2library_version, out string strError) { strError = ""; bool bOldEnabled = this.Enabled; this.Enabled = bOldEnabled; try { this.ListView.Items.Clear(); List<string> recpaths = new List<string>(); List<ListViewItem> items = new List<ListViewItem>(); // 第一阶段,把来自 XML 记录中的 <file> 元素信息填入。 // 这样就保证了至少可以在保存书目记录阶段能还原 XML 记录中的相关部分 foreach (XmlElement node in nodes) { string strID = DomUtil.GetAttr(node, "id"); string strUsage = DomUtil.GetAttr(node, "usage"); string strRights = DomUtil.GetAttr(node, "rights"); ListViewItem item = new ListViewItem(); // state SetLineInfo(item, LineState.Normal); // id ListViewUtil.ChangeItemText(item, COLUMN_ID, strID); // usage ListViewUtil.ChangeItemText(item, COLUMN_USAGE, strUsage); // rights ListViewUtil.ChangeItemText(item, COLUMN_RIGHTS, strRights); this.ListView.Items.Add(item); items.Add(item); string strResPath = this.BiblioRecPath + "/object/" + strID; strResPath = strResPath.Replace(":", "/"); recpaths.Add(strResPath); } if (StringUtil.CompareVersion(dp2library_version, "2.58") >= 0) { // 新方法,速度快 #if NO Stop.OnStop += new StopEventHandler(this.DoStop); Stop.Initial("正在下载对象的元数据"); Stop.BeginLoop(); #endif Stop.Initial("正在下载对象的元数据"); try { BrowseLoader loader = new BrowseLoader(); loader.Channel = channel; loader.Stop = this.Stop; loader.RecPaths = recpaths; loader.Format = "id,metadata,timestamp"; int i = 0; foreach (DigitalPlatform.LibraryClient.localhost.Record record in loader) { Application.DoEvents(); if (this.Stop != null && this.Stop.State != 0) { strError = "用户中断"; return -1; } Debug.Assert(record.Path == recpaths[i], ""); ListViewItem item = items[i]; if (record.RecordBody.Result != null && record.RecordBody.Result.ErrorCode != ErrorCodeValue.NoError) { strError = record.RecordBody.Result.ErrorString; // 2016/5/27 ListViewUtil.ChangeItemText(item, COLUMN_STATE, strError); item.ImageIndex = 1; // error! i++; continue; } string strMetadataXml = record.RecordBody.Metadata; //Debug.Assert(string.IsNullOrEmpty(strMetadataXml) == false, ""); byte[] baMetadataTimestamp = record.RecordBody.Timestamp; //Debug.Assert(baMetadataTimestamp != null, ""); // 取metadata值 Hashtable values = StringUtil.ParseMetaDataXml(strMetadataXml, out strError); if (values == null) { ListViewUtil.ChangeItemText(item, COLUMN_STATE, strError); item.ImageIndex = 1; // error! continue; } // localpath ListViewUtil.ChangeItemText(item, COLUMN_LOCALPATH, (string)values["localpath"]); // size ListViewUtil.ChangeItemText(item, COLUMN_SIZE, (string)values["size"]); // mime ListViewUtil.ChangeItemText(item, COLUMN_MIME, (string)values["mimetype"]); // tiemstamp string strTimestamp = ByteArray.GetHexTimeStampString(baMetadataTimestamp); ListViewUtil.ChangeItemText(item, COLUMN_TIMESTAMP, strTimestamp); i++; } } catch (Exception ex) { // TODO: 出现异常后,是否改为用原来的方法一个一个对象地获取 metadata? strError = ex.Message; return -1; } finally { #if NO Stop.EndLoop(); Stop.OnStop -= new StopEventHandler(this.DoStop); Stop.Initial(""); #endif Stop.Initial(""); } } else { // *** 以前的方法,速度较慢 // 第二阶段,从 dp2library 服务器获取 metadata 信息,填充其他字段内容 foreach (ListViewItem item in items) { string strID = ListViewUtil.GetItemText(item, COLUMN_ID); string strMetadataXml = ""; byte[] baMetadataTimestamp = null; // 获得一个对象资源的元数据 int nRet = GetOneObjectMetadata( channel, this.BiblioRecPath, strID, out strMetadataXml, out baMetadataTimestamp, out strError); if (nRet == -1) { if (channel.ErrorCode == ErrorCode.AccessDenied) { return -1; } // item.SubItems.Add(strError); ListViewUtil.ChangeItemText(item, COLUMN_STATE, strError); item.ImageIndex = 1; // error! continue; } // 取metadata值 Hashtable values = StringUtil.ParseMetaDataXml(strMetadataXml, out strError); if (values == null) { ListViewUtil.ChangeItemText(item, COLUMN_STATE, strError); item.ImageIndex = 1; // error! continue; } // localpath ListViewUtil.ChangeItemText(item, COLUMN_LOCALPATH, (string)values["localpath"]); // size ListViewUtil.ChangeItemText(item, COLUMN_SIZE, (string)values["size"]); // mime ListViewUtil.ChangeItemText(item, COLUMN_MIME, (string)values["mimetype"]); // tiemstamp string strTimestamp = ByteArray.GetHexTimeStampString(baMetadataTimestamp); ListViewUtil.ChangeItemText(item, COLUMN_TIMESTAMP, strTimestamp); } } this.Changed = false; if (this.ListView.Items.Count > 0) return 1; return 0; } finally { this.Enabled = bOldEnabled; } }
// 获取指纹信息,追加到结果集文件的尾部 // parameters: // update_table key为读者记录路径 static void AppendFingerprintInfo( LibraryChannel channel, DpResultSet resultset, Hashtable update_table, CancellationToken token) { List <string> lines = new List <string>(); foreach (string recpath in update_table.Keys) { lines.Add(recpath); } BrowseLoader loader = new BrowseLoader(); loader.RecPaths = lines; loader.Channel = channel; loader.Format = "id,cols,format:cfgs/browse_fingerprint"; loader.Prompt += Loader_Prompt; foreach (DigitalPlatform.LibraryClient.localhost.Record record in loader) { token.ThrowIfCancellationRequested(); ShowMessage("追加 " + record.Path); if (record.Cols == null || record.Cols.Length < 3) { string strError = "record.Cols error ... 有可能是因为读者库缺乏配置文件 cfgs/browse_fingerprint"; // TODO: 并发操作的情况下,会在中途出现读者记录被别的前端修改的情况,这里似乎可以continue throw new Exception(strError); } // 如果证条码号为空,无法建立对照关系,要跳过 if (string.IsNullOrEmpty(record.Cols[1]) == true) { continue; } DpRecord item = new DpRecord(record.Path); // timestamp | barcode | fingerprint item.BrowseText = record.Cols[0] + "|" + record.Cols[1] + "|" + record.Cols[2]; resultset.Add(item); } #if NO // 需要获得更新的事项,然后追加到结果集文件的尾部 // 注意,需要定期彻底重建结果集文件,以便回收多余空间 List <string> lines = new List <string>(); foreach (string recpath in update_table.Keys) { lines.Add(recpath); if (lines.Count >= 100) { List <DigitalPlatform.LibraryClient.localhost.Record> records = null; GetSomeFingerprintData( channel, lines, token, out records); foreach (DigitalPlatform.LibraryClient.localhost.Record record in records) { if (record.Cols == null || record.Cols.Length < 3) { strError = "record.Cols error ... 有可能是因为读者库缺乏配置文件 cfgs/browse_fingerprint"; // TODO: 并发操作的情况下,会在中途出现读者记录被别的前端修改的情况,这里似乎可以continue return(-1); } // 如果证条码号为空,无法建立对照关系,要跳过 if (string.IsNullOrEmpty(record.Cols[1]) == true) { continue; } DpRecord item = new DpRecord(record.Path); // timestamp | barcode | fingerprint item.BrowseText = record.Cols[0] + "|" + record.Cols[1] + "|" + record.Cols[2]; resultset.Add(item); } lines.Clear(); } } if (lines.Count > 0) { List <DigitalPlatform.LibraryClient.localhost.Record> records = null; GetSomeFingerprintData( channel, lines, token, out records); foreach (DigitalPlatform.LibraryClient.localhost.Record record in records) { if (record.Cols == null || record.Cols.Length < 3) { strError = "record.Cols error ... 有可能是因为读者库缺乏配置文件 cfgs/browse_fingerprint"; // TODO: 并发操作的情况下,会在中途出现读者记录被别的前端修改的情况,这里似乎可以continue return(-1); } DpRecord item = new DpRecord(record.Path); // timestamp | barcode | fingerprint item.BrowseText = record.Cols[0] + "|" + record.Cols[1] + "|" + record.Cols[2]; resultset.Add(item); } } return(0); #endif }
// return: // -1 error // 0 没有填充任何内容,列表为空 // 1 已经填充了内容 public int LoadObject( LibraryChannel channel, Stop stop, XmlNodeList nodes, string dp2library_version, out string strError) { strError = ""; this.Clear(); List <string> recpaths = new List <string>(); // 第一阶段,把来自 XML 记录中的 <file> 元素信息填入。 // 这样就保证了至少可以在保存书目记录阶段能还原 XML 记录中的相关部分 foreach (XmlElement node in nodes) { ObjectInfo info = new ObjectInfo(); info.ID = node.GetAttribute("id"); info.Usage = node.GetAttribute("usage"); info.Rights = node.GetAttribute("rights"); this.Add(info); string strResPath = this.HostRecPath + "/object/" + info.ID; strResPath = strResPath.Replace(":", "/"); recpaths.Add(strResPath); } if (recpaths.Count > 0) { if (StringUtil.CompareVersion(dp2library_version, "2.58") >= 0) { // 新方法,速度快 if (stop != null) { stop.Initial("正在下载对象的元数据"); } try { BrowseLoader loader = new BrowseLoader(); loader.Channel = channel; loader.Stop = stop; loader.RecPaths = recpaths; loader.Format = "id,metadata,timestamp"; int i = 0; foreach (DigitalPlatform.LibraryClient.localhost.Record record in loader) { if (stop != null && stop.State != 0) { strError = "用户中断"; return(-1); } Debug.Assert(record.Path == recpaths[i], ""); ObjectInfo info = this[i]; if (record.RecordBody.Result != null && record.RecordBody.Result.ErrorCode != ErrorCodeValue.NoError) { info.ErrorInfo = record.RecordBody.Result.ErrorString; i++; continue; } string strMetadataXml = record.RecordBody.Metadata; info.Metadata = strMetadataXml; byte[] baMetadataTimestamp = record.RecordBody.Timestamp; //Debug.Assert(baMetadataTimestamp != null, ""); #if NO // 取metadata值 Hashtable values = StringUtil.ParseMedaDataXml(strMetadataXml, out strError); if (values == null) { info.ErrorInfo = strError; continue; } // localpath info.FileName = (string)values["localpath"]; // size info.Size = (string)values["size"]; // mime info.Mime = (string)values["mimetype"]; #endif // tiemstamp string strTimestamp = ByteArray.GetHexTimeStampString(baMetadataTimestamp); info.Timestamp = strTimestamp; i++; } } catch (Exception ex) { // TODO: 出现异常后,是否改为用原来的方法一个一个对象地获取 metadata? strError = "LoadObject() 异常: " + ex.Message; return(-1); } finally { stop.Initial(""); } } else { strError = "请升级 dp2library 到 2.58 以上版本"; return(-1); } } this.Changed = false; if (this.Count > 0) { return(1); } return(0); }
void FillBrowseList() { this.listView_browse.Items.Clear(); List <string> recpaths = StringUtil.SplitList(this.DupBiblioRecPathList); LibraryChannel channel = Program.MainForm.GetChannel(); try { // 获得书目记录 BrowseLoader loader = new BrowseLoader(); loader.Channel = channel; // loader.Stop = this.Progress; loader.Format = "id,xml,cols,timestamp"; loader.RecPaths = recpaths; int i = 0; foreach (DigitalPlatform.LibraryClient.localhost.Record biblio_item in loader) { ListViewItem item = null; if (biblio_item.RecordBody != null && biblio_item.RecordBody.Result != null && biblio_item.RecordBody.Result.ErrorCode != DigitalPlatform.LibraryClient.localhost.ErrorCodeValue.NoError) { item = Global.AppendNewLine( this.listView_browse, biblio_item.Path, new string[] { biblio_item.RecordBody.Result.ErrorString }); item.Tag = null; } else { item = Global.AppendNewLine( this.listView_browse, biblio_item.Path, biblio_item.Cols); ItemTag tag = new ItemTag(); tag.RecPath = biblio_item.Path; tag.Xml = biblio_item.RecordBody.Xml; tag.Timestamp = biblio_item.RecordBody.Timestamp; item.Tag = tag; } i++; } if (this.listView_browse.Items.Count > 0) { ListViewUtil.SelectLine(this.listView_browse.Items[0], true); } } finally { Program.MainForm.ReturnChannel(channel); } if (this.AutoSelectMode == true) { SortItems(); if (this.listView_browse.Items.Count > 0) { ListViewUtil.SelectLine(this.listView_browse.Items[0], true); if (this.MergeStyle == dp2Circulation.MergeStyle.None) { // 自动选择保留目标书目记录的方式 this.MergeStyle = MergeStyle.ReserveTargetBiblio; } if ((this.MergeStyle & dp2Circulation.MergeStyle.ReserveTargetBiblio) == dp2Circulation.MergeStyle.ReserveTargetBiblio) { this.Action = "mergeTo"; // useTargetBiblio } else { this.Action = "mergeToUseSourceBiblio"; } this.Close(); } } }