Beispiel #1
0
        // 从册条码号(+册记录路径)获得种记录摘要,或者从订购记录路径、期记录路径、评注记录路径获得种记录摘要
        // 权限:   需要具有getbibliosummary权限
        // parameters:
        //      strBiblioRecPathExclude   除开列表中的这些种路径, 才返回摘要内容, 否则仅仅返回种路径即可
        public LibraryServerResult GetBiblioSummary(
            SessionInfo sessioninfo,
            RmsChannel channel,
            string strItemBarcode,
            string strConfirmItemRecPath,
            string strBiblioRecPathExclude,
            out string strBiblioRecPath,
            out string strSummary)
        {
            strBiblioRecPath = "";
            strSummary = "";
            string strError = "";

            LibraryServerResult result = new LibraryServerResult();

            // 权限判断
            // 权限字符串
            if (StringUtil.IsInList("getbibliosummary", sessioninfo.RightsOrigin) == false
                && StringUtil.IsInList("order", sessioninfo.RightsOrigin) == false)
            {
                result.Value = -1;
                result.ErrorInfo = "获取种摘要信息被拒绝。不具备order、getbibliosummary权限。";
                result.ErrorCode = ErrorCode.AccessDenied;
                return result;
            }

            int nRet = 0;
            long lRet = 0;

            if (string.IsNullOrEmpty(strItemBarcode) == true
                && string.IsNullOrEmpty(strConfirmItemRecPath) == true)
            {
                strError = "strItemBarcode和strConfirmItemRecPath参数值不能同时为空";
                goto ERROR1;
            }

            string strItemXml = "";
            string strOutputItemPath = "";
            string strMetaData = "";

            /*
            RmsChannel channel = sessioninfo.Channels.GetChannel(this.WsUrl);
            if (channel == null)
            {
                strError = "channel == null";
                goto ERROR1;
            }
             * */


            // 特殊情况,通过种路径
            string strHead = "@bibliorecpath:";
            if (strItemBarcode.Length > strHead.Length
                && strItemBarcode.Substring(0, strHead.Length) == strHead)
            {
                strBiblioRecPath = strItemBarcode.Substring(strHead.Length);

                // 检查书目库名是否合法
                string strTempBiblioDbName = ResPath.GetDbName(strBiblioRecPath);
                if (this.IsBiblioDbName(strTempBiblioDbName) == false)
                {
                    strError = "strItemBarcode参数中析出的书目库路径 '" + strBiblioRecPath + "' 中,书目库名 '" + strTempBiblioDbName + "' 不是系统定义的书目库名";
                    goto ERROR1;
                }
                goto LOADBIBLIO;
            }


            bool bByRecPath = false;    // 是否经过记录路径来获取的?

            if (string.IsNullOrEmpty(strItemBarcode) == false)
            {
                // 获得册记录
                // return:
                //      -1  error
                //      0   not found
                //      1   命中1条
                //      >1  命中多于1条
                nRet = this.GetItemRecXml(
                    channel,
                    strItemBarcode,
                    out strItemXml,
                    out strOutputItemPath,
                    out strError);
                if (nRet == 0)
                {
                    result.Value = 0;
                    result.ErrorInfo = "册记录没有找到";
                    result.ErrorCode = ErrorCode.NotFound;
                    return result;
                }

                if (nRet == -1)
                    goto ERROR1;
            }

            // 如果命中多于一条(或者没有条码号),并且已经有确定的册记录路径辅助判断
            if (string.IsNullOrEmpty(strItemBarcode) == true
                ||
                (nRet > 1 && String.IsNullOrEmpty(strConfirmItemRecPath) == false))
            {
                // 检查路径中的库名,是不是实体库、订购库、期库、评注库名
                nRet = CheckRecPath(strConfirmItemRecPath,
                    "item,order,issue,comment",
                    out strError);
                if (nRet != 1)
                    goto ERROR1;

                byte[] item_timestamp = null;

                lRet = channel.GetRes(strConfirmItemRecPath,
                    out strItemXml,
                    out strMetaData,
                    out item_timestamp,
                    out strOutputItemPath,
                    out strError);
                if (lRet == -1)
                {
                    strError = "根据strConfirmItemRecPath '" + strConfirmItemRecPath + "' 获得记录失败: " + strError;
                    goto ERROR1;
                }

                bByRecPath = true;
            }

            // 从册记录中获得从属的种id
            string strBiblioRecID = "";

            XmlDocument dom = new XmlDocument();
            try
            {
                dom.LoadXml(strItemXml);
            }
            catch (Exception ex)
            {
                strError = "册记录XML装载到DOM出错:" + ex.Message;
                goto ERROR1;
            }

            if (bByRecPath == true
                && string.IsNullOrEmpty(strItemBarcode) == false)   // 2011/9/6
            {
                // 这种情况需要核实册条码号
                string strTempItemBarcode = DomUtil.GetElementText(dom.DocumentElement,
                    "//barcode");
                if (strTempItemBarcode != strItemBarcode)
                {
                    strError = "通过册条码号 '" + strItemBarcode + "' 获取实体记录发现命中多条,然后自动用记录路径 '" + strConfirmItemRecPath + "' 来获取实体记录,虽然获取成功,但是发现所获取的记录中<barcode>元素中的册条码号 '" + strTempItemBarcode + "' 不符合要求的册条码号 '" + strItemBarcode + "。(后面)这种情况可能是由于实体记录发生过移动造成的。";
                    goto ERROR1;
                }
            }

            strBiblioRecID = DomUtil.GetElementText(dom.DocumentElement, "parent"); //
            if (String.IsNullOrEmpty(strBiblioRecID) == true)
            {
                strError = "种下属记录XML中<parent>元素缺乏或者值为空, 因此无法定位种记录";
                goto ERROR1;
            }

            // 从配置文件中获得和实体库对应的书目库名

            /*
            // 准备工作: 映射数据库名
            nRet = this.GetGlobalCfg(sessioninfo.Channels,
                out strError);
            if (nRet == -1)
                goto ERROR1;
             * */

            string strItemDbName = ResPath.GetDbName(strOutputItemPath);
            string strBiblioDbName = "";

            // 根据书目下属库名, 找到对应的书目库名
            // return:
            //      -1  出错
            //      0   没有找到
            //      1   找到
            nRet = this.GetBiblioDbNameByChildDbName(strItemDbName,
                out strBiblioDbName,
                out strError);
            if (nRet == -1)
                goto ERROR1;
            if (nRet == 0)
            {
                strError = "下属库名 '" + strItemDbName + "' 没有找到所从属的书目库名";
                goto ERROR1;
            }

            string strBiblioXml = "";
            strBiblioRecPath = strBiblioDbName + "/" + strBiblioRecID;

        LOADBIBLIO:

            // 看看是否在排除列表中
            if (String.IsNullOrEmpty(strBiblioRecPathExclude) == false
                && IsInBarcodeList(strBiblioRecPath,
                strBiblioRecPathExclude) == true)
            {
                result.Value = 1;
                return result;
            }

            /*
strSummary = "";
result.Value = 1;
return result;
 * */

            // 获得本地配置文件
            string strLocalPath = "";

            string strRemotePath = BrowseFormat.CanonicalizeScriptFileName(
                ResPath.GetDbName(strBiblioRecPath),
                "./cfgs/summary.fltx");

            nRet = this.CfgsMap.MapFileToLocal(
                // sessioninfo.Channels,
                channel,
                strRemotePath,
                out strLocalPath,
                out strError);
            if (nRet == -1)
                goto ERROR1;
            if (nRet == 0)
            {
                // 配置.fltx文件不存在, 再试探.cs文件
                strRemotePath = BrowseFormat.CanonicalizeScriptFileName(
                ResPath.GetDbName(strBiblioRecPath),
                "./cfgs/summary.cs");

                nRet = this.CfgsMap.MapFileToLocal(
                    // sessioninfo.Channels,
                    channel,
                    strRemotePath,
                    out strLocalPath,
                    out strError);
                if (nRet == -1)
                    goto ERROR1;
                if (nRet == 0)
                {
                    strError = strRemotePath + "不存在...";
                    goto ERROR1;
                }
            }

            bool bFltx = false;
            // 如果是一般.cs文件, 还需要获得.cs.ref配置文件
            if (IsCsFileName(strRemotePath) == true)
            {
                string strTempPath = "";
                nRet = this.CfgsMap.MapFileToLocal(
                    // sessioninfo.Channels,
                    channel,
                    strRemotePath + ".ref",
                    out strTempPath,
                    out strError);
                if (nRet == -1)
                    goto ERROR1;
                bFltx = false;
            }
            else
            {
                bFltx = true;
            }



            // 取得种记录
            byte[] timestamp = null;
            lRet = channel.GetRes(strBiblioRecPath,
                out strBiblioXml,
                out strMetaData,
                out timestamp,
                out strOutputItemPath,
                out strError);
            if (lRet == -1)
            {
                strError = "获得种记录 '" + strBiblioRecPath + "' 时出错: " + strError;
                goto ERROR1;
            }

                string strMarc = "";
                string strMarcSyntax = "";
            {
                // 转换为MARC格式

                // 将MARCXML格式的xml记录转换为marc机内格式字符串
                // parameters:
                //		bWarning	==true, 警告后继续转换,不严格对待错误; = false, 非常严格对待错误,遇到错误后不继续转换
                //		strMarcSyntax	指示marc语法,如果=="",则自动识别
                //		strOutMarcSyntax	out参数,返回marc,如果strMarcSyntax == "",返回找到marc语法,否则返回与输入参数strMarcSyntax相同的值
                nRet = MarcUtil.Xml2Marc(strBiblioXml,
                    true,
                    "", // this.CurMarcSyntax,
                    out strMarcSyntax,
                    out strMarc,
                    out strError);
                if (nRet == -1)
                    goto ERROR1;
            }

            string strFragment = "";
            if (StringUtil.IsInList("coverimage", strBiblioRecPathExclude) == true)
            {
                // 获得封面图像 URL
                string strImageUrl = ScriptUtil.GetCoverImageUrl(strMarc, "SmallImage");
                if (string.IsNullOrEmpty(strImageUrl) == false)
                {
                    if (StringUtil.HasHead(strImageUrl, "uri:") == true)
                    {
                        strImageUrl = "object-path:" + strBiblioRecPath + "/object/" + strImageUrl.Substring(4);
                        strFragment = "<img class='biblio pending' name='" + strImageUrl + "'/>";
                    }
                    else
                    {
                        strFragment = "<img class='biblio' src='" + strImageUrl + "'/>";
                    }
                }
            }

            // 将种记录数据从XML格式转换为HTML格式
            if (string.IsNullOrEmpty(strBiblioXml) == false)
            {
                if (bFltx == true)
                {
                    string strFilterFileName = strLocalPath;
                    nRet = this.ConvertBiblioXmlToHtml(
                        strFilterFileName,
                            strMarc,    // strBiblioXml,
                            strMarcSyntax,
                            strBiblioRecPath,
                            out strSummary,
                            out strError);
                }
                else
                {
                    nRet = this.ConvertRecordXmlToHtml(
                        strLocalPath,
                        strLocalPath + ".ref",
                        strBiblioXml,
                        strBiblioRecPath,   // 2009/10/18 
                        out strSummary,
                        out strError);
                }
                if (nRet == -1)
                    goto ERROR1;

            }
            else
                strSummary = "";

            strSummary = strFragment + strSummary;

            result.Value = 1;
            return result;
        ERROR1:
            result.Value = -1;
            result.ErrorInfo = strError;
            result.ErrorCode = ErrorCode.SystemError;
            return result;
        }
Beispiel #2
0
		// 装载记录
		// 把strRecordPath表示的记录装载到窗口中,并且在窗口第一行
		// 路径内容设置好
		// parameters:
		//		strRecordPath	记录路径。如果==null,表示直接用textBox_recPath中当前的内容作为路径
		//		strExtStyle	如果为null,表示获取strRecordPath或textbox表示的记录。如果为"next"或"prev",
		//					则表示取其后或前一条记录
		// return:
		//		-2	放弃
		//		-1	出错
		//		0	正常
		//		1	到头或者到尾
		public int LoadRecord(string strRecordPath,
			string strExtStyle,
			out string strError)
		{
			strError = "";

			EnableControlsInLoading(true);

			try 
			{

				if (this.Changed == true)
				{

					DialogResult result = MessageBox.Show(this, 
						"装载新内容前, 发现当前窗口中已有内容修改后未来得及保存。是否要继续装载新内容到窗口中(这样将丢失先前修改过的内容)?\r\n\r\n(是)继续装载新内容 (否)不装载新内容",
						"dp2rms",
						MessageBoxButtons.YesNo,
						MessageBoxIcon.Question,
						MessageBoxDefaultButton.Button2);
					if (result != DialogResult.Yes) 
					{
						strError = "装载新内容操作被放弃...";
						return -2;
					}
				}

				if (strRecordPath != null)
					textBox_recPath.Text = strRecordPath;

				ResPath respath = new ResPath(textBox_recPath.Text);

				this.Text = respath.ReverseFullPath;


				string strContent;
				string strMetaData;
				// string strError;
				byte [] baTimeStamp = null;
				string strOutputPath;


				// 使用Channel
				RmsChannel channelSave = channel;

				channel = Channels.GetChannel(respath.Url);
				Debug.Assert(channel != null, "Channels.GetChannel 异常");

				try 
				{

					string strStyle = "content,data,metadata,timestamp,outputpath,withresmetadata";	// 

					if (strExtStyle != null && strExtStyle != "")
					{
						strStyle += "," + strExtStyle;
					}

                    stop.OnStop += new StopEventHandler(this.DoStop);
					stop.Initial("正在装载记录" + respath.FullPath);
					stop.BeginLoop();


            
					long lRet = channel.GetRes(respath.Path,
						strStyle,
						// this.eventClose,
						out strContent,
						out strMetaData,
						out baTimeStamp,
						out strOutputPath,
						out strError);


					stop.EndLoop();
                    stop.OnStop -= new StopEventHandler(this.DoStop);
					stop.Initial("");

					this.TimeStamp = baTimeStamp;	// 设置时间戳很重要。即便xml不合法,也应设置好时间戳,否则窗口无法进行正常删除。

                    this.strDatabaseOriginPath = respath.Url+"?"+strOutputPath; // 保存从数据库中来的原始path

					if (lRet == -1) 
					{
                        if (channel.ErrorCode == ChannelErrorCode.NotFoundSubRes)
                        {
                            // 下级资源不存在, 警告一下就行了
                            MessageBox.Show(this, strError);
                            goto CONTINUELOAD;
                        }
						else if (channel.ErrorCode == ChannelErrorCode.NotFound) 
						{
							if (strExtStyle == "prev")
								strError = "到头";
							else if (strExtStyle == "next")
								strError = "到尾";
							return 1;
						}
						else 
						{
							// this.TimeStamp = null;
							strError = "从路径 '"+respath.Path+"' 获取记录时出错: " + strError;
							return -1;
						}
					}

				}
				finally 
				{
					channel = channelSave;
				}

                CONTINUELOAD:

				respath.Path = strOutputPath;
				textBox_recPath.Text = respath.FullPath;

				//string strTemp = ByteArray.GetHexTimeStampString(baTimeStamp);

				this.m_strMetaData = strMetaData;	// 记忆XML记录的元数据

				int nRet = SetRecordToControls(strContent,
					out strError);
				if (nRet == -1)
					return -1;


				return 0;
			}
			finally
			{
				EnableControlsInLoading(false);
			}
		}
Beispiel #3
0
        // 根据数据库模板的定义,刷新一个已经存在的数据库的定义
        // return:
        //      -1
        //      0   keys定义没有更新
        //      1   keys定义更新了
        int RefreshDatabase(RmsChannel channel,
            string strTemplateDir,
            string strDatabaseName,
            string strIncludeFilenames,
            string strExcludeFilenames,
            out string strError)
        {
            strError = "";
            int nRet = 0;

            strIncludeFilenames = strIncludeFilenames.ToLower();
            strExcludeFilenames = strExcludeFilenames.ToLower();

            bool bKeysChanged = false;

            DirectoryInfo di = new DirectoryInfo(strTemplateDir);
            FileInfo[] fis = di.GetFiles();

            // 创建所有文件对象
            for (int i = 0; i < fis.Length; i++)
            {
                string strName = fis[i].Name;
                if (strName == "." || strName == "..")
                    continue;

                if (FileUtil.IsBackupFile(strName) == true)
                    continue;

                /*
                if (strName.ToLower() == "keys"
                    || strName.ToLower() == "browse")
                    continue;
                 * */

                // 如果Include和exclude里面都有一个文件名,优先依exclude(排除)
                if (StringUtil.IsInList(strName, strExcludeFilenames) == true)
                    continue;

                if (strIncludeFilenames != "*")
                {
                    if (StringUtil.IsInList(strName, strIncludeFilenames) == false)
                        continue;
                }


                string strFullPath = fis[i].FullName;

                nRet = ConvertGb2312TextfileToUtf8(strFullPath,
                    out strError);
                if (nRet == -1)
                    return -1;

                string strExistContent = "";
                string strNewContent = "";

                Stream new_stream = new FileStream(strFullPath, FileMode.Open);

                {
                    StreamReader sr = new StreamReader(new_stream, Encoding.UTF8);
                    strNewContent = ConvertCrLf(sr.ReadToEnd());
                }

                new_stream.Seek(0, SeekOrigin.Begin);


                try
                {
                    string strPath = strDatabaseName + "/cfgs/" + strName;


                    // 获取已有的配置文件对象
                    byte[] timestamp = null;
                    string strOutputPath = "";
                    string strMetaData = "";

                    string strStyle = "content,data,metadata,timestamp,outputpath";
                    MemoryStream exist_stream = new MemoryStream();

                    try
                    {

                        long lRet = channel.GetRes(
                            strPath,
                            exist_stream,
                            null,	// stop,
                            strStyle,
                            null,	// byte [] input_timestamp,
                            out strMetaData,
                            out timestamp,
                            out strOutputPath,
                            out strError);
                        if (lRet == -1)
                        {
                            // 配置文件不存在,怎么返回错误码的?
                            if (channel.ErrorCode == ChannelErrorCode.NotFound)
                            {
                                timestamp = null;
                                goto DO_CREATE;
                            }
                            return -1;
                        }

                        exist_stream.Seek(0, SeekOrigin.Begin);
                        {
                            StreamReader sr = new StreamReader(exist_stream, Encoding.UTF8);
                            strExistContent = ConvertCrLf(sr.ReadToEnd());
                        }
                    }
                    finally
                    {
                        if (exist_stream != null)
                            exist_stream.Close();
                    }

                    // 比较本地的和服务器的有无区别,无区别就不要上载了
                    if (strExistContent == strNewContent)
                    {
                        continue;
                    }

                    DO_CREATE:

                    // 在服务器端创建对象
                    // parameters:
                    //      strStyle    风格。当创建目录的时候,为"createdir",否则为空
                    // return:
                    //		-1	错误
                    //		1	已经存在同名对象
                    //		0	正常返回
                    nRet = NewServerSideObject(
                        channel,
                        strPath,
                        "",
                        new_stream,
                        timestamp,
                        out strError);
                    if (nRet == -1)
                        return -1;
                    if (nRet == 1)
                    {
                        strError = "NewServerSideObject()发现已经存在同名对象: " + strError;
                        return -1;
                    }

                    if (strName.ToLower() == "keys")
                        bKeysChanged = true;

                }
                finally
                {
                    new_stream.Close();
                }
            }

            if (bKeysChanged == true)
            {
                // 对数据库及时调用刷新keys表的API
                long lRet = channel.DoRefreshDB(
                    "begin",
                    strDatabaseName,
                    false,
                    out strError);
                if (lRet == -1)
                {
                    strError = "数据库 '" + strDatabaseName + "' 的定义已经被成功刷新,但在刷新内核Keys表操作时失败: " + strError;
                    return -1;
                }
                return 1;
            }

            return 0;
        }
Beispiel #4
0
		// return:
		//		-1	出错
		//		0	没有找到
		//		1	找到
		int GetMarcDefCfgFile(string strUrl,
			string strDbName,
			out Stream s,
			out string strError)
		{
			strError = "";
			s = null;

            if (String.IsNullOrEmpty(strUrl) == true)
            {
                /*
                strError = "URL为空";
                goto ERROR1;
                 */
                return 0;
            }

			string strPath = strDbName + "/cfgs/marcdef";

			// 使用Channel
			RmsChannel channelSave = channel;

			channel = Channels.GetChannel(strUrl);
			Debug.Assert(channel != null, "Channels.GetChannel 异常");

			try 
			{

				string strContent;
				// string strError;

                stop.OnStop += new StopEventHandler(this.DoStop);
                stop.Initial("正在下载文件" + strPath);
				stop.BeginLoop();

				byte[] baTimeStamp = null;
				string strMetaData;
				string strOutputPath;

				long lRet = channel.GetRes(
					MainForm.cfgCache,
					strPath,
					out strContent,
					out strMetaData,
					out baTimeStamp,
					out strOutputPath,
					out strError);

				stop.EndLoop();
                stop.OnStop -= new StopEventHandler(this.DoStop);
				stop.Initial("");


				if (lRet == -1) 
				{
					if (channel.ErrorCode == ChannelErrorCode.NotFound)
						return 0;

					strError = "获得配置文件 '" +strPath+ "' 时出错:" + strError;
					goto ERROR1;
				}
				else 
				{
					byte [] baContent = StringUtil.GetUtf8Bytes(strContent, true);
					MemoryStream stream = new MemoryStream(baContent);
					s = stream;
				}

			}
			finally 
			{
				channel = channelSave;		
			}

			return 1;
			ERROR1:
			return -1;
		}
Beispiel #5
0
        private void MarcEditor_GetConfigDom(object sender, GetConfigDomEventArgs e)
        {
            if (String.IsNullOrEmpty(textBox_recPath.Text) == true)
            {
                e.ErrorInfo = "记录路径为空,无法获得配置文件 '" + e.Path + "'";
                return;
            }
            ResPath respath = new ResPath(textBox_recPath.Text);

            // 得到干净的文件名
            string strCfgFileName = e.Path;
            int nRet = strCfgFileName.IndexOf("#");
            if (nRet != -1)
            {
                strCfgFileName = strCfgFileName.Substring(0, nRet);
            }

            string strPath = ResPath.GetDbName(respath.Path) + "/cfgs/" + strCfgFileName;

            // 在cache中寻找
            e.XmlDocument = this.MainForm.DomCache.FindObject(strPath);
            if (e.XmlDocument != null)
                return;

            // 使用Channel

            RmsChannel channelSave = channel;

            channel = Channels.GetChannel(respath.Url);
            Debug.Assert(channel != null, "Channels.GetChannel 异常");

            m_nInGetCfgFile++;

            try
            {
                string strContent;
                string strError;

                stop.OnStop += new StopEventHandler(this.DoStop);
                stop.Initial("正在下载文件" + strPath);
                stop.BeginLoop();

                byte[] baTimeStamp = null;
                string strMetaData;
                string strOutputPath;

                long lRet = channel.GetRes(
                    MainForm.cfgCache,
                    strPath,
                    out strContent,
                    out strMetaData,
                    out baTimeStamp,
                    out strOutputPath,
                    out strError);

                stop.EndLoop();
                stop.OnStop -= new StopEventHandler(this.DoStop);
                stop.Initial("");

                if (lRet == -1)
                {
                    if (channel.ErrorCode == ChannelErrorCode.NotFound)
                    {
                        e.ErrorInfo = "";
                        return;
                    }


                    e.ErrorInfo = "获得配置文件 '" + strPath + "' 时出错:" + strError;
                    return;
                }


                XmlDocument dom = new XmlDocument();
                try
                {
                    dom.LoadXml(strContent);
                }
                catch (Exception ex)
                {
                    e.ErrorInfo = "配置文件 '" + strPath + "' 装入XMLDUM时出错: " + ex.Message;
                    return;
                }
                e.XmlDocument = dom;
                this.MainForm.DomCache.SetObject(strPath, dom);  // 保存到缓存
            }
            finally
            {
                channel = channelSave;

                m_nInGetCfgFile--;
            }
        }
Beispiel #6
0
		int DownloadOneFile(string strID,
			out string strError)
		{

			strError = "";
			ResPath respath = new ResPath(textBox_recPath.Text);
			string strResPath = respath.Path + "/object/" + strID;

			strResPath = strResPath.Replace(":", "/");


			string strLocalPath = this.listView_resFiles.GetLocalFileName(strID);

			SaveFileDialog dlg = new SaveFileDialog();

			dlg.Title = "请指定要保存的本地文件名";
			dlg.CreatePrompt = false;
			dlg.FileName = strLocalPath == "" ? strID + ".res" : strLocalPath;
			dlg.InitialDirectory = Environment.CurrentDirectory;
			// dlg.Filter = "projects files (outer*.xml)|outer*.xml|All files (*.*)|*.*" ;

			dlg.RestoreDirectory = true ;

			if(dlg.ShowDialog() != DialogResult.OK)
			{
				strError = "放弃";
				return -1;
			}


			// 使用Channel
			RmsChannel channelSave = channel;

			channel = Channels.GetChannel(respath.Url);
			Debug.Assert(channel != null, "Channels.GetChannel 异常");

			try 
			{

                stop.OnStop += new StopEventHandler(this.DoStop);
                stop.Initial("正在下载资源文件 " + strResPath);
				stop.BeginLoop();

				byte [] baOutputTimeStamp = null;

				EnableControlsInLoading(true);

				string strMetaData;
				string strOutputPath = "";

				long lRet = channel.GetRes(strResPath,
					dlg.FileName,
					stop,
					out strMetaData,
					out baOutputTimeStamp,
					out strOutputPath,
					out strError);

				EnableControlsInLoading(false);

				stop.EndLoop();
                stop.OnStop -= new StopEventHandler(this.DoStop);
				stop.Initial("");


				if (lRet == -1) 
				{
					MessageBox.Show(this, "下载资源文件失败,原因: "+strError);
					goto ERROR1;
				}

			}
			finally 
			{
				channel = channelSave;
			}
			return 0;

			ERROR1:
			return -1;

		}
Beispiel #7
0
		// 自动加工数据
		public void AutoGenerate()
		{
			// 库名部分路径
			ResPath respath = new ResPath(textBox_recPath.Text);
			respath.MakeDbName();

			string strError;
			string strCode;
			string strRef;

			// 使用Channel
			RmsChannel channelSave = channel;

			channel = Channels.GetChannel(respath.Url);
			Debug.Assert(channel != null, "Channels.GetChannel 异常");

			try 
			{
				string strCfgPath = respath.Path + "/cfgs/autoGenerate.cs";

				string strCfgRefPath = respath.Path + "/cfgs/autoGenerate.cs.ref";

                stop.OnStop += new StopEventHandler(this.DoStop);
                stop.Initial("正在下载文件" + strCfgPath);
				stop.BeginLoop();

				byte[] baTimeStamp = null;
				string strMetaData;
				string strOutputPath;

				long lRet = channel.GetRes(
					MainForm.cfgCache,
					strCfgPath,
					out strCode,
					out strMetaData,
					out baTimeStamp,
					out strOutputPath,
					out strError);

				stop.EndLoop();
                stop.OnStop -= new StopEventHandler(this.DoStop);
				stop.Initial("");

				if (lRet == -1) 
				{
					MessageBox.Show(this, strError);
					return;
				}


                stop.OnStop += new StopEventHandler(this.DoStop);
                stop.Initial("正在下载文件" + strCfgRefPath);
				stop.BeginLoop();

				lRet = channel.GetRes(
					MainForm.cfgCache,
					strCfgRefPath,
					out strRef,
					out strMetaData,
					out baTimeStamp,
					out strOutputPath,
					out strError);

				stop.EndLoop();
                stop.OnStop -= new StopEventHandler(this.DoStop);
				stop.Initial("");


				if (lRet == -1) 
				{
					MessageBox.Show(this, strError);
					return;
				}

			}
			finally 
			{
				channel = channelSave;
			}



			// 执行代码
			int nRet = RunScript(strCode,
                strRef,
                out strError);
			if (nRet == -1) 
			{
				MessageBox.Show(this, strError);
				return;
			}

		}
Beispiel #8
0
        // 下载资源,保存到备份文件
        public static int WriteResToBackupFile(
            IWin32Window owner,
            Stream outputfile,
            string strXmlRecPath,
            string[] res_ids,
            RmsChannel channel,
            DigitalPlatform.Stop stop,
            out string strError)
        {
            strError = "";


            long lRet;

            for (int i = 0; i < res_ids.Length; i++)
            {
                Application.DoEvents();	// 出让界面控制权

                if (stop.State != 0)
                {
                    DialogResult result = MessageBox.Show(owner,
                        "确实要中断当前批处理操作?",
                        "dp2batch",
                        MessageBoxButtons.YesNo,
                        MessageBoxIcon.Question,
                        MessageBoxDefaultButton.Button2);
                    if (result == DialogResult.Yes)
                    {
                        strError = "用户中断";
                        return -1;
                    }
                    else
                    {
                        stop.Continue();
                    }
                }

                string strID = res_ids[i].Trim();

                if (strID == "")
                    continue;

                string strResPath = strXmlRecPath + "/object/" + strID;

                string strMetaData;

                if (stop != null)
                    stop.SetMessage("正在下载 " + strResPath);

                long lResStart = 0;
                // 写res的头。
                // 如果不能预先确知整个res的长度,可以用随便一个lTotalLength值调用本函数,
                // 但是需要记忆下函数所返回的lStart,最后调用EndWriteResToBackupFile()。
                // 如果能预先确知整个res的长度,则最后不必调用EndWriteResToBackupFile()
                lRet = Backup.BeginWriteResToBackupFile(
                    outputfile,
                    0,	// 未知
                    out lResStart);

                byte[] baOutputTimeStamp = null;
                string strOutputPath;

            REDO_GETRES:
                lRet = channel.GetRes(strResPath,
                    (Stream)null,	// 故意不获取资源体
                    stop,
                    "metadata,timestamp,outputpath",
                    null,
                    out strMetaData,	// 但是要获得metadata
                    out baOutputTimeStamp,
                    out strOutputPath,
                    out strError);
                if (lRet == -1)
                {
                    // TODO: 允许重试
                    DialogResult redo_result = MessageBox.Show(owner,
                        "获取记录 '" + strResPath + "' 时出现错误: " + strError + "\r\n\r\n重试,还是中断当前批处理操作?\r\n(Retry 重试;Cancel 中断批处理)",
                        "dp2batch",
                        MessageBoxButtons.RetryCancel,
                        MessageBoxIcon.Question,
                        MessageBoxDefaultButton.Button1);
                    if (redo_result == DialogResult.Cancel)
                        return -1;
                    goto
                        REDO_GETRES;
                }

                byte[] timestamp = baOutputTimeStamp;

                ResPath respath = new ResPath();
                respath.Url = channel.Url;
                respath.Path = strOutputPath;	// strResPath;

                // strMetaData还要加入资源id?
                ExportUtil.ChangeMetaData(ref strMetaData,
                    strID,
                    null,
                    null,
                    null,
                    respath.FullPath,
                    ByteArray.GetHexTimeStampString(baOutputTimeStamp));


                lRet = Backup.WriteResMetadataToBackupFile(outputfile,
                    strMetaData);
                if (lRet == -1)
                    return -1;

                long lBodyStart = 0;
                // 写res body的头。
                // 如果不能预先确知body的长度,可以用随便一个lBodyLength值调用本函数,
                // 但是需要记忆下函数所返回的lBodyStart,最后调用EndWriteResBodyToBackupFile()。
                // 如果能预先确知body的长度,则最后不必调用EndWriteResBodyToBackupFile()
                lRet = Backup.BeginWriteResBodyToBackupFile(
                    outputfile,
                    0, // 未知
                    out lBodyStart);
                if (lRet == -1)
                    return -1;

                if (stop != null)
                    stop.SetMessage("正在下载 " + strResPath + " 的数据体");

            REDO_GETRES_1:
                lRet = channel.GetRes(strResPath,
                    outputfile,
                    stop,
                    "content,data,timestamp", //"content,data,timestamp"
                    timestamp,
                    out strMetaData,
                    out baOutputTimeStamp,
                    out strOutputPath,
                    out strError);
                if (lRet == -1)
                {
                    if (channel.ErrorCode == ChannelErrorCode.EmptyRecord)
                    {
                        // 空记录
                    }
                    else
                    {
                        // TODO: 允许重试
                        DialogResult redo_result = MessageBox.Show(owner,
                            "获取记录 '" + strResPath + "' 时出现错误: " + strError + "\r\n\r\n重试,还是中断当前批处理操作?\r\n(Retry 重试;Cancel 中断批处理)",
                            "dp2batch",
                            MessageBoxButtons.RetryCancel,
                            MessageBoxIcon.Question,
                            MessageBoxDefaultButton.Button1);
                        if (redo_result == DialogResult.Cancel)
                            return -1;
                        goto
                            REDO_GETRES_1;
                    }
                }

                long lBodyLength = outputfile.Position - lBodyStart - 8;
                // res body收尾
                lRet = Backup.EndWriteResBodyToBackupFile(
                    outputfile,
                    lBodyLength,
                    lBodyStart);
                if (lRet == -1)
                    return -1;

                long lTotalLength = outputfile.Position - lResStart - 8;
                lRet = Backup.EndWriteResToBackupFile(
                    outputfile,
                    lTotalLength,
                    lResStart);
                if (lRet == -1)
                    return -1;

            }

            /*
            if (stop != null)
                stop.SetMessage("保存资源到备份文件全部完成");
            */

            return 0;
        }
Beispiel #9
0
		// 校验起止号
        // return:
        //      0   不存在记录
        //      1   存在记录
        int VerifyRange(RmsChannel channel,
			string strDbName,
			out string strError)
		{
            bool bStartNotFound = false;
            bool bEndNotFound = false;

			strError = "";

			// 如果edit中为空,则假定为“全部范围”
			if (textBox_startNo.Text == "")
				textBox_startNo.Text = "1";

			if (textBox_endNo.Text == "")
				textBox_endNo.Text = "9999999999";


			bool bAsc = true;

			Int64 nStart = 0;
			Int64 nEnd = 9999999999;
			
			
			try 
			{
				nStart = Convert.ToInt64(textBox_startNo.Text);
			}
			catch 
			{
			}

				
			try 
			{
				nEnd = Convert.ToInt64(textBox_endNo.Text);
			}
			catch 
			{
			}


			if (nStart > nEnd)
				bAsc = false;
			else
				bAsc = true;

			string strPath = strDbName + "/" + textBox_startNo.Text;
			string strStyle = "outputpath";

			if (bAsc == true)
				strStyle += ",next,myself";
			else 
				strStyle += ",prev,myself";

			string strResult;
			string strMetaData;
			byte [] baOutputTimeStamp;
			string strOutputPath;

			string strError0  = "";

			string strStartID = "";
			string strEndID = "";

			// 获得资源
			// return:
			//		-1	出错。具体出错原因在this.ErrorCode中。this.ErrorInfo中有出错信息。
			//		0	成功
			long lRet = channel.GetRes(strPath,
				strStyle,
				out strResult,
				out strMetaData,
				out baOutputTimeStamp,
				out strOutputPath,
				out strError0);
			if (lRet == -1) 
			{
				if (channel.ErrorCode == ChannelErrorCode.NotFound)
				{
					strStartID = textBox_startNo.Text;
                    bStartNotFound = true;
				}
				else 
					strError += "校验startno时出错: " + strError0 + " ";
				
			}
			else 
			{
				// 取得返回的id
				strStartID = ResPath.GetRecordId(strOutputPath);


			}

			if (strStartID == "")
			{
				strError = "strStartID为空...";
				return -1;
			}

			strPath = strDbName + "/" + textBox_endNo.Text;

			strStyle = "outputpath";
			if (bAsc == true)
				strStyle += ",prev,myself";
			else 
				strStyle += ",next,myself";

			// 获得资源
			// return:
			//		-1	出错。具体出错原因在this.ErrorCode中。this.ErrorInfo中有出错信息。
			//		0	成功
			lRet = channel.GetRes(strPath,
				strStyle,
				out strResult,
				out strMetaData,
				out baOutputTimeStamp,
				out strOutputPath,
				out strError0);
			if (lRet == -1) 
			{

				if (channel.ErrorCode == ChannelErrorCode.NotFound)
				{
					strEndID = textBox_endNo.Text;
                    bEndNotFound = true;
				}
				else
					strError += "校验endno时出错: " + strError0 + " ";

			}
			else 
			{
				// 取得返回的id
				strEndID = ResPath.GetRecordId(strOutputPath);

			}

			if (strEndID == "")
			{
				strError = "strEndID为空...";
				return -1;
			}

			///
			bool bSkip = false;

			Int64 nTemp = 0;
			try 
			{
				nTemp = Convert.ToInt64(strStartID);
			}
			catch
			{
				strError = "strStartID值 '" + strStartID + "' 不是数字...";
				return -1;
			}

			if (bAsc == true) 
			{
				if (nTemp > nEnd)
				{
					bSkip = true;
				}
			}
			else
			{
				if (nTemp < nEnd)
				{
					bSkip = true;
				}
			}

			if (bSkip == false) 
			{
				textBox_startNo.Text = strStartID;
			}


			///

			bSkip = false;

			try 
			{
				nTemp = Convert.ToInt64(strEndID);
			}
			catch
			{
				strError = "strEndID值 '" + strEndID + "' 不是数字...";
				return -1;
			}
			if (bAsc == true) 
			{
				if (nTemp < nStart)
				{
					bSkip = true;
				}
			}
			else
			{
				if (nTemp > nStart)
				{
					bSkip = true;
				}
			}

			if (bSkip == false) 
			{
				textBox_endNo.Text = strEndID;
			}

            if (bStartNotFound == true && bEndNotFound == true)
			    return 0;

            return 1;
		}
Beispiel #10
0
		void DoExportXmlFile(string strOutputFileName)
		{
			string strError = "";

			FileStream outputfile = null;
			XmlTextWriter writer = null;   

			if (textBox_dbPath.Text == "")
			{
				MessageBox.Show(this, "尚未选择源库...");
				return;
			}

			ResPath respath = new ResPath(textBox_dbPath.Text);

			channel = this.Channels.GetChannel(respath.Url);

			string strDbName = respath.Path;

			if (strOutputFileName != null && strOutputFileName != "") 
			{
				// 探测文件是否存在
				FileInfo fi = new FileInfo(strOutputFileName);
				if (fi.Exists == true && fi.Length > 0)
				{
					DialogResult result = MessageBox.Show(this,
						"文件 '" + strOutputFileName + "' 已存在,是否覆盖?\r\n\r\n--------------------\r\n注:(是)覆盖  (否)中断处理",
						"dp2batch",
						MessageBoxButtons.YesNo,
						MessageBoxIcon.Question,
						MessageBoxDefaultButton.Button2);
					if (result != DialogResult.Yes) 
					{
						strError = "放弃处理...";
						goto ERROR1;
					}
				}

				// 打开文件
				outputfile = File.Create(
					strOutputFileName);

				writer = new XmlTextWriter(outputfile, Encoding.UTF8);
				writer.Formatting = Formatting.Indented;
				writer.Indentation = 4;

			}


			try 
			{
				
				Int64 nStart;
				Int64 nEnd;
				Int64 nCur;
				bool bAsc = GetDirection(out nStart,
					out nEnd);

				// 设置进度条范围
				Int64 nMax = nEnd - nStart;
				if (nMax < 0)
					nMax *= -1;
				nMax ++;

				ProgressRatio =  nMax / 10000;
				if (ProgressRatio < 1.0)
					ProgressRatio = 1.0;

				progressBar_main.Minimum = 0;
				progressBar_main.Maximum = (int)(nMax/ProgressRatio);
				progressBar_main.Value = 0;


				bool bFirst = true;	// 是否为第一次取记录

				string strID = this.textBox_startNo.Text;


				stop.Initial(new Delegate_doStop(this.DoStop),
					"正在导出数据");
				stop.BeginLoop();

				EnableControls(false);

				if (writer != null) 
				{
					writer.WriteStartDocument();
					writer.WriteStartElement("dprms","collection",DpNs.dprms);
					//writer.WriteStartElement("collection");
					//writer.WriteAttributeString("xmlns:marc",
					//	"http://www.loc.gov/MARC21/slim");

				}

				// 循环
				for(;;) 
				{
					Application.DoEvents();	// 出让界面控制权

					if (stop.State != 0)
					{
						strError = "用户中断";
						goto ERROR1;
					}

					string strStyle = "";
					if (outputfile != null)
						strStyle = "data,content,timestamp,outputpath";
					else
						strStyle = "timestamp,outputpath";	// 优化

					if (bFirst == true)
						strStyle += "";
					else 
					{
						if (bAsc == true)
							strStyle += ",next";
						else
							strStyle += ",prev";
					}


					string strPath = strDbName + "/" + strID;
					string strXmlBody = "";
					string strMetaData = "";
					byte[] baOutputTimeStamp = null;
					string strOutputPath = "";

					bool bFoundRecord = false;

					// 获得资源
					// return:
					//		-1	出错。具体出错原因在this.ErrorCode中。this.ErrorInfo中有出错信息。
					//		0	成功
					long lRet = channel.GetRes(strPath,
						strStyle,
						out strXmlBody,
						out strMetaData,
						out baOutputTimeStamp,
						out strOutputPath,
						out strError);


					if (lRet == -1) 
					{
						if (channel.ErrorCode == ChannelErrorCode.NotFound) 
						{
							if (checkBox_forceLoop.Checked == true && bFirst == true)
							{
								AutoCloseMessageBox.Show(this, "记录 " + strID + " 不存在。\r\n\r\n按 确认 继续。");

								bFirst = false;
								goto CONTINUE;
							}
							else 
							{
								if (bFirst == true)
								{
									strError = "记录 " + strID + " 不存在。处理结束。";
								}
								else 
								{
									if (bAsc == true)
										strError = "记录 " + strID + " 是最末一条记录。处理结束。";
									else
										strError = "记录 " + strID + " 是最前一条记录。处理结束。";
								}
							}

						}
						else if (channel.ErrorCode == ChannelErrorCode.EmptyRecord) 
						{
							bFirst = false;
							bFoundRecord = false;
							// 把id解析出来
							strID = ResPath.GetRecordId(strOutputPath);
							goto CONTINUE;

						}

						goto ERROR1;
					}

					bFirst = false;

					bFoundRecord = true;

					// 把id解析出来
					strID = ResPath.GetRecordId(strOutputPath);

				CONTINUE:
					stop.SetMessage(strID);

					// 是否超过循环范围
					try 
					{
						nCur = Convert.ToInt64(strID);
					}
					catch
					{
						// ???
						nCur = 0;
					}

					if (bAsc == true && nCur > nEnd)
						break;
					if (bAsc == false && nCur < nEnd)
						break;

					if (bFoundRecord == true 
						&& writer != null) 
					{
						// 写磁盘
						XmlDocument dom = new XmlDocument();

						try 
						{
							dom.LoadXml(strXmlBody);

							ResPath respathtemp = new ResPath();
							respathtemp.Url = channel.Url;
							respathtemp.Path = strOutputPath;



							// DomUtil.SetAttr(dom.DocumentElement, "xmlns:dprms", DpNs.dprms);
							// 给根元素设置几个参数
							DomUtil.SetAttr(dom.DocumentElement, "path", DpNs.dprms, respathtemp.FullPath);
							DomUtil.SetAttr(dom.DocumentElement, "timestamp", DpNs.dprms, ByteArray.GetHexTimeStampString(baOutputTimeStamp));

							// DomUtil.SetAttr(dom.DocumentElement, "xmlns:marc", null);
							dom.DocumentElement.WriteTo(writer);
						}
						catch (Exception ex)
						{
							strError = ex.Message;
							// 询问是否继续
							goto ERROR1;
						}


						/*
						if (nRet == -1) 
						{
							// 询问是否继续
							goto ERROR1;
						}
						*/
					}

					// 删除
					if (checkBox_export_delete.Checked == true)
					{

						byte [] baOutputTimeStamp1 = null;
						strPath = strOutputPath;	// 得到实际的路径

						lRet = channel.DoDeleteRecord(
							strPath,
							baOutputTimeStamp,
							out baOutputTimeStamp1,
							out strError);
						if (lRet == -1) 
						{
							// 询问是否继续
							goto ERROR1;
						}
					}


					if (bAsc == true) 
					{
						progressBar_main.Value = (int)((nCur-nStart + 1)/ProgressRatio);
					}
					else 
					{
						// ?
						progressBar_main.Value = (int)((nStart-nCur + 1)/ProgressRatio);
					}


					// 对已经作过的进行判断
					if (bAsc == true && nCur >= nEnd)
						break;
					if (bAsc == false && nCur <= nEnd)
						break;


				}


				stop.EndLoop();
				stop.Initial(null, "");

				EnableControls(true);

			}

			finally 
			{
				if (writer != null) 
				{
					writer.WriteEndElement();
					writer.WriteEndDocument();
					writer.Close();
					writer = null;
				}

				if (outputfile != null) 
				{
					outputfile.Close();
					outputfile = null;
				}

			}

			END1:
				channel = null;
			if (checkBox_export_delete.Checked == true)
				MessageBox.Show(this, "数据导出和删除完成。");
			else
				MessageBox.Show(this, "数据导出完成。");
			return;

			ERROR1:

				stop.EndLoop();
			stop.Initial(null, "");

			EnableControls(true);


			channel = null;
			MessageBox.Show(this, strError);
			return;
		
		}
Beispiel #11
0
        // return:
        //		-1	error
        //		0	正常结束
        //		1	希望跳过后来的OnEnd()
        int DoExportFile(
            string[] dbpaths,
            string strOutputFileName,
            ExportFileType exportType,
            Encoding targetEncoding,
            out string strError)
        {
            strError = "";
            int nRet = 0;

            string strDeleteStyle = "";
            if (this.checkBox_export_fastMode.Checked == true)
                strDeleteStyle = "fastmode";

            string strInfo = "";    // 汇总信息,在完成后显示

            FileStream outputfile = null;	// Backup和Xml格式输出都需要这个
            XmlTextWriter writer = null;   // Xml格式输出时需要这个

            bool bAppend = true;

            Debug.Assert(dbpaths != null, "");

            if (dbpaths.Length == 0)
            {
                strError = "尚未指定源库...";
                goto ERROR1;
            }

            if (String.IsNullOrEmpty(strOutputFileName) == false)
            {
                // 探测输出文件是否已经存在
                FileInfo fi = new FileInfo(strOutputFileName);
                bAppend = true;
                if (fi.Exists == true && fi.Length > 0)
                {
                    if (exportType == ExportFileType.BackupFile
                        || exportType == ExportFileType.ISO2709File)
                    {
                        DialogResult result = MessageBox.Show(this,
                            "文件 '" + strOutputFileName + "' 已存在,是否追加?\r\n\r\n--------------------\r\n注:(是)追加  (否)覆盖  (取消)中断处理",
                            "dp2batch",
                            MessageBoxButtons.YesNoCancel,
                            MessageBoxIcon.Question,
                            MessageBoxDefaultButton.Button1);
                        if (result == DialogResult.Yes)
                        {
                            bAppend = true;
                        }
                        if (result == DialogResult.No)
                        {
                            bAppend = false;
                        }
                        if (result == DialogResult.Cancel)
                        {
                            strError = "放弃处理...";
                            goto ERROR1;
                        }
                    }
                    else if (exportType == ExportFileType.XmlFile)
                    {
                        DialogResult result = MessageBox.Show(this,
                            "文件 '" + strOutputFileName + "' 已存在,是否覆盖?\r\n\r\n--------------------\r\n注:(是)覆盖  (否)中断处理",
                            "dp2batch",
                            MessageBoxButtons.YesNo,
                            MessageBoxIcon.Question,
                            MessageBoxDefaultButton.Button2);
                        if (result != DialogResult.Yes)
                        {
                            strError = "放弃处理...";
                            goto ERROR1;
                        }
                    }


                }

                // 打开文件
                if (exportType == ExportFileType.BackupFile
                    || exportType == ExportFileType.ISO2709File)
                {
                    outputfile = File.Open(
                        strOutputFileName,
                        FileMode.OpenOrCreate,	// 原来是Open,后来修改为OpenOrCreate。这样对临时文件被系统管理员手动意外删除(但是xml文件中仍然记载了任务)的情况能够适应。否则会抛出FileNotFoundException异常
                        FileAccess.Write,
                        FileShare.ReadWrite);
                }
                else if (exportType == ExportFileType.XmlFile)
                {
                    outputfile = File.Create(
                        strOutputFileName);

                    writer = new XmlTextWriter(outputfile, Encoding.UTF8);
                    writer.Formatting = Formatting.Indented;
                    writer.Indentation = 4;
                }
            }

            if ((exportType == ExportFileType.BackupFile
                || exportType == ExportFileType.ISO2709File)
                && outputfile != null)
            {
                if (bAppend == true)
                    outputfile.Seek(0, SeekOrigin.End);	// 具有追加的能力
                else
                    outputfile.SetLength(0);
            }

            WriteLog("开始输出");

            try
            {

                // string[] dbpaths = textBox_dbPath.Text.Split(new char[] { ';' });

                for (int f = 0; f < dbpaths.Length; f++)
                {
                    string strOneDbPath = dbpaths[f];

                    ResPath respath = new ResPath(strOneDbPath);

                    channel = this.Channels.GetChannel(respath.Url);

                    string strDbName = respath.Path;
                    if (String.IsNullOrEmpty(strInfo) == false)
                        strInfo += "\r\n";
                    strInfo += "" + strDbName;

                    // 实际处理的首尾号
                    string strRealStartNo = "";
                    string strRealEndNo = "";

                    /*
                    DialogResult result;
                    if (checkBox_export_delete.Checked == true)
                    {
                        result = MessageBox.Show(this,
                            "确实要删除 '" + respath.Path + "' 内指定范围的记录?\r\n\r\n---------\r\n(是)删除 (否)放弃批处理",
                            "dp2batch",
                            MessageBoxButtons.YesNo,
                            MessageBoxIcon.Question,
                            MessageBoxDefaultButton.Button2);
                        if (result != DialogResult.Yes)
                            continue;
                    }
                     * 
                     * */


                    //channel = this.Channels.GetChannel(respath.Url);

                    //string strDbName = respath.Path;

                    // 如果为多库输出
                    if (dbpaths.Length > 0)
                    {
                        // 如果为全选
                        if (this.radioButton_all.Checked == true)
                        {
                            // 恢复为最大范围
                            this.textBox_startNo.Text = "1";
                            this.textBox_endNo.Text = "9999999999";
                        }

                        // 校验起止号
                        if (checkBox_verifyNumber.Checked == true)
                        {
                            nRet = VerifyRange(channel,
                                strDbName,
                                out strError);
                            if (nRet == -1)
                                MessageBox.Show(this, strError);

                            if (nRet == 0)
                            {
                                // 库中无记录
                                AutoCloseMessageBox.Show(this, "数据库 " + strDbName + " 中无记录。");
                                strInfo += "(无记录)";
                                WriteLog("发现数据库 " + strDbName + " 中无记录");
                                continue;
                            }
                        }
                        else
                        {
                            if (this.textBox_startNo.Text == "")
                            {
                                strError = "尚未指定起始号";
                                goto ERROR1;
                            }
                            if (this.textBox_endNo.Text == "")
                            {
                                strError = "尚未指定结束号";
                                goto ERROR1;
                            }
                        }
                    }

                    string strOutputStartNo = "";
                    string strOutputEndNo = "";
                    // 虽然界面不让校验起止号,但是也要校验,为了设置好进度条
                    if (checkBox_verifyNumber.Checked == false)
                    {
                        // 校验起止号
                        // return:
                        //      0   不存在记录
                        //      1   存在记录
                        nRet = VerifyRange(channel,
                            strDbName,
                            this.textBox_startNo.Text,
                            this.textBox_endNo.Text,
                            out strOutputStartNo,
                            out strOutputEndNo,
                            out strError);
                    }

                    //try
                    //{

                    Int64 nStart = 0;
                    Int64 nEnd = 0;
                    Int64 nCur = 0;
                    bool bAsc = true;

                    bAsc = GetDirection(
                        this.textBox_startNo.Text,
                        this.textBox_endNo.Text,
                        out nStart,
                        out nEnd);

                    // 探测到的号码
                    long nOutputEnd = 0;
                    long nOutputStart = 0;
                    if (checkBox_verifyNumber.Checked == false)
                    {
                        GetDirection(
                            strOutputStartNo,
                            strOutputEndNo,
                            out nOutputStart,
                            out nOutputEnd);
                    }

                    // 设置进度条范围
                    if (checkBox_verifyNumber.Checked == true)
                    {

                        Int64 nMax = nEnd - nStart;
                        if (nMax < 0)
                            nMax *= -1;
                        nMax++;

                        /*
                        ProgressRatio = nMax / 10000;
                        if (ProgressRatio < 1.0)
                            ProgressRatio = 1.0;

                        progressBar_main.Minimum = 0;
                        progressBar_main.Maximum = (int)(nMax / ProgressRatio);
                        progressBar_main.Value = 0;
                         * */
                        stop.SetProgressRange(0, nMax);
                    }
                    else
                    {
                        Int64 nMax = nOutputEnd - nOutputStart;
                        if (nMax < 0)
                            nMax *= -1;
                        nMax++;
                        stop.SetProgressRange(0, nMax);
                    }


                    bool bFirst = true;	// 是否为第一次取记录

                    string strID = this.textBox_startNo.Text;

                    stop.OnStop += new StopEventHandler(this.DoStop);
                    stop.Initial("正在导出数据");
                    stop.BeginLoop();

                    EnableControls(false);

                    if (exportType == ExportFileType.XmlFile
                        && writer != null)
                    {
                        writer.WriteStartDocument();
                        writer.WriteStartElement("dprms", "collection", DpNs.dprms);
                        //writer.WriteStartElement("collection");
                        //writer.WriteAttributeString("xmlns:marc",
                        //	"http://www.loc.gov/MARC21/slim");

                    }

                    WriteLog("开始输出数据库 '" + strDbName + "' 内的数据记录");

                    m_nRecordCount = 0;
                    // 循环
                    for (; ; )
                    {
                        Application.DoEvents();	// 出让界面控制权

                        if (stop.State != 0)
                        {
                            WriteLog("打开对话框 '确实要中断当前批处理操作?'");
                            DialogResult result = MessageBox.Show(this,
                                "确实要中断当前批处理操作?",
                                "dp2batch",
                                MessageBoxButtons.YesNo,
                                MessageBoxIcon.Question,
                                MessageBoxDefaultButton.Button2);
                            WriteLog("关闭对话框 '确实要中断当前批处理操作?'");
                            if (result == DialogResult.Yes)
                            {
                                strError = "用户中断";
                                goto ERROR1;
                            }
                            else
                            {
                                stop.Continue();
                            }
                        }

                        string strDirectionComment = "";
                        string strStyle = "";
                        if (outputfile != null)
                            strStyle = "data,content,timestamp,outputpath";
                        else
                            strStyle = "timestamp,outputpath";	// 优化

                        if (bFirst == true)
                        {
                            strStyle += "";
                        }
                        else
                        {
                            if (bAsc == true)
                            {
                                strStyle += ",next";
                                strDirectionComment = "的后一条记录";
                            }
                            else
                            {
                                strStyle += ",prev";
                                strDirectionComment = "的前一条记录";
                            }
                        }


                        string strPath = strDbName + "/" + strID;
                        string strXmlBody = "";
                        string strMetaData = "";
                        byte[] baOutputTimeStamp = null;
                        string strOutputPath = "";

                        bool bFoundRecord = false;

                        bool bNeedRetry = true;

                    REDO_GETRES:
                        // 获得资源
                        // return:
                        //		-1	出错。具体出错原因在this.ErrorCode中。this.ErrorInfo中有出错信息。
                        //		0	成功
                        long lRet = channel.GetRes(strPath,
                            strStyle,
                            out strXmlBody,
                            out strMetaData,
                            out baOutputTimeStamp,
                            out strOutputPath,
                            out strError);


                        if (lRet == -1)
                        {
                            if (channel.ErrorCode == ChannelErrorCode.NotFound)
                            {
                                if (bFirst == true)
                                {
                                    if (checkBox_forceLoop.Checked == true)
                                    {
                                        string strText = "记录 " + strID + strDirectionComment + " 不存在。\r\n\r\n按 确认 继续。";
                                        WriteLog("打开对话框 '" + strText.Replace("\r\n", "\\n") + "'");
                                        AutoCloseMessageBox.Show(this, strText);
                                        WriteLog("关闭对话框 '" + strText.Replace("\r\n", "\\n") + "'");

                                        bFirst = false;
                                        goto CONTINUE;
                                    }
                                    else
                                    {
                                        // 如果不要强制循环,此时也不能结束,否则会让用户以为数据库里面根本没有数据
                                        string strText = "您为数据库 " + strDbName + " 指定的首记录 " + strID + strDirectionComment + " 不存在。\r\n\r\n(注:为避免出现此提示,可在操作前勾选“校准首尾ID”)\r\n\r\n按 确认 继续向后找...";
                                        WriteLog("打开对话框 '" + strText.Replace("\r\n", "\\n") + "'");
                                        AutoCloseMessageBox.Show(this, strText);
                                        WriteLog("关闭对话框 '" + strText.Replace("\r\n", "\\n") + "'");

                                        bFirst = false;
                                        goto CONTINUE;
                                    }
                                }
                                else
                                {
                                    Debug.Assert(bFirst == false, "");

                                    if (bFirst == true)
                                    {
                                        strError = "记录 " + strID + strDirectionComment + " 不存在。处理结束。";
                                    }
                                    else
                                    {
                                        if (bAsc == true)
                                            strError = "记录 " + strID + " 是最末一条记录。处理结束。";
                                        else
                                            strError = "记录 " + strID + " 是最前一条记录。处理结束。";
                                    }

                                    if (dbpaths.Length > 1)
                                        break;  // 多库情况,继续其它库循环
                                    else
                                    {
                                        bNeedRetry = false; // 单库情况,也没有必要出现重试对话框

                                        WriteLog("打开对话框 '" + strError.Replace("\r\n", "\\n") + "'");
                                        MessageBox.Show(this, strError);
                                        WriteLog("关闭对话框 '" + strError.Replace("\r\n", "\\n") + "'");
                                        break;
                                    }
                                }

                            }
                            else if (channel.ErrorCode == ChannelErrorCode.EmptyRecord)
                            {
                                bFirst = false;
                                bFoundRecord = false;
                                // 把id解析出来
                                strID = ResPath.GetRecordId(strOutputPath);
                                goto CONTINUE;

                            }

                            // 允许重试
                            if (bNeedRetry == true)
                            {
                                string strText = "获取记录 '" + strPath + "' (style='" + strStyle + "')时出现错误: " + strError + "\r\n\r\n重试,还是中断当前批处理操作?\r\n(Retry 重试;Cancel 中断批处理)";
                                WriteLog("打开对话框 '" + strText.Replace("\r\n", "\\n") + "'");
                                DialogResult redo_result = MessageBox.Show(this,
                                    strText,
                                    "dp2batch",
                                    MessageBoxButtons.RetryCancel,
                                    MessageBoxIcon.Question,
                                    MessageBoxDefaultButton.Button1);
                                WriteLog("关闭对话框 '" + strText.Replace("\r\n", "\\n") + "'");
                                if (redo_result == DialogResult.Cancel)
                                    goto ERROR1;
                                goto
                                    REDO_GETRES;
                            }
                            else
                            {
                                goto ERROR1;
                            }
                        }

                        // 2008/11/9 
                        if (String.IsNullOrEmpty(strXmlBody) == true)
                        {
                            bFirst = false;
                            bFoundRecord = false;
                            // 把id解析出来
                            strID = ResPath.GetRecordId(strOutputPath);
                            goto CONTINUE;
                        }

                        bFirst = false;

                        bFoundRecord = true;

                        // 把id解析出来
                        strID = ResPath.GetRecordId(strOutputPath);
                        stop.SetMessage("已导出记录 " + strOutputPath + "  " + m_nRecordCount.ToString());

                        if (String.IsNullOrEmpty(strRealStartNo) == true)
                        {
                            strRealStartNo = strID;
                        }

                        strRealEndNo = strID;

                    CONTINUE:

                        // 是否超过循环范围
                        try
                        {
                            nCur = Convert.ToInt64(strID);
                        }
                        catch
                        {
                            // ???
                            nCur = 0;
                        }

                        if (checkBox_verifyNumber.Checked == false)
                        {
                            // 如果当前记录号码突破预计的头部和尾部
                            if (nCur > nOutputEnd
                                || nCur < nOutputStart)
                            {
                                if (nCur > nOutputEnd)
                                    nOutputEnd = nCur;

                                if (nCur < nOutputStart)
                                    nOutputStart = nCur;

                                // 重新计算和设置进度条
                                long nMax = nOutputEnd - nOutputStart;
                                if (nMax < 0)
                                    nMax *= -1;
                                nMax++;

                                stop.SetProgressRange(0, nMax);
                            }
                        }

                        if (bAsc == true && nCur > nEnd)
                            break;
                        if (bAsc == false && nCur < nEnd)
                            break;

                        string strMarc = "";

                        // 将Xml转换为MARC
                        if (exportType == ExportFileType.ISO2709File
                            && bFoundRecord == true)    // 2008/11/13 
                        {
                            nRet = GetMarc(strXmlBody,
                                out strMarc,
                                out strError);
                            if (nRet == -1)
                            {
                                strError = "记录 " + strOutputPath + " 在将XML格式转换为MARC时出错: " + strError;
                                goto ERROR1;
                            }
                        }

                        if (this.MarcFilter != null)
                        {
                            // 触发filter中的Record相关动作
                            // TODO: 有可能strMarc为空哟,需要测试一下
                            nRet = MarcFilter.DoRecord(
                                null,
                                strMarc,
                                m_nRecordCount,
                                out strError);
                            if (nRet == -1)
                                goto ERROR1;
                        }

                        // 触发Script的Outputing()代码
                        if (bFoundRecord == true && this.AssemblyMain != null)
                        {
                            // 这些变量要先初始化,因为filter代码可能用到这些Batch成员.
                            batchObj.XmlRecord = strXmlBody;

                            batchObj.MarcSyntax = this.CurMarcSyntax;

                            batchObj.MarcRecord = strMarc;	// MARC记录体
                            batchObj.MarcRecordChanged = false;	// 为本轮Script运行准备初始状态

                            batchObj.SearchPanel.ServerUrl = channel.Url;
                            batchObj.ServerUrl = channel.Url;
                            batchObj.RecPath = strOutputPath;	// 记录路径
                            batchObj.RecIndex = m_nRecordCount;	// 当前记录在一批中的序号
                            batchObj.TimeStamp = baOutputTimeStamp;


                            BatchEventArgs args = new BatchEventArgs();

                            batchObj.Outputing(this, args);
                            /*
                            if (args.Continue == ContinueType.SkipMiddle)
                                goto CONTINUEDBS;
                            if (args.Continue == ContinueType.SkipBeginMiddle)
                                goto CONTINUEDBS;
                            */
                            if (args.Continue == ContinueType.SkipAll)
                                goto CONTINUEDBS;

                            // 观察用于输出的MARC记录是否被改变
                            if (batchObj.MarcRecordChanged == true)
                                strMarc = batchObj.MarcRecord;

                            // 观察XML记录是否被改变
                            if (batchObj.XmlRecordChanged == true)
                                strXmlBody = batchObj.XmlRecord;

                        }


                        if (bFoundRecord == true
                            && outputfile != null)
                        {
                            if (exportType == ExportFileType.BackupFile)
                            {
                                // 写磁盘
                                nRet = WriteRecordToBackupFile(
                                    outputfile,
                                    strDbName,
                                    strID,
                                    strMetaData,
                                    strXmlBody,
                                    baOutputTimeStamp,
                                    out strError);
                                if (nRet == -1)
                                {
                                    // 询问是否继续
                                    goto ERROR1;
                                }
                            }
                            else if (exportType == ExportFileType.ISO2709File)
                            {
                                // 写磁盘
                                nRet = WriteRecordToISO2709File(
                                    outputfile,
                                    strDbName,
                                    strID,
                                    strMarc,
                                    baOutputTimeStamp,
                                    targetEncoding,
                                    this.OutputCrLf,
                                    this.AddG01,
                                    this.Remove998,
                                    out strError);
                                if (nRet == -1)
                                {
                                    // 询问是否继续
                                    goto ERROR1;
                                }
                            }
                            else if (exportType == ExportFileType.XmlFile)
                            {
                                XmlDocument dom = new XmlDocument();

                                try
                                {
                                    dom.LoadXml(strXmlBody);

                                    ResPath respathtemp = new ResPath();
                                    respathtemp.Url = channel.Url;
                                    respathtemp.Path = strOutputPath;


                                    // DomUtil.SetAttr(dom.DocumentElement, "xmlns:dprms", DpNs.dprms);
                                    // 给根元素设置几个参数
                                    DomUtil.SetAttr(dom.DocumentElement, "path", DpNs.dprms, respathtemp.FullPath);
                                    DomUtil.SetAttr(dom.DocumentElement, "timestamp", DpNs.dprms, ByteArray.GetHexTimeStampString(baOutputTimeStamp));

                                    // DomUtil.SetAttr(dom.DocumentElement, "xmlns:marc", null);
                                    dom.DocumentElement.WriteTo(writer);
                                }
                                catch (Exception ex)
                                {
                                    strError = ExceptionUtil.GetAutoText(ex);
                                    // 询问是否继续
                                    goto ERROR1;
                                }

                            }
                        }

                        // 删除
                        if (checkBox_export_delete.Checked == true)
                        {

                            byte[] baOutputTimeStamp1 = null;
                            strPath = strOutputPath;	// 得到实际的路径
                            lRet = channel.DoDeleteRes(
                                strPath,
                                baOutputTimeStamp,
                                strDeleteStyle,
                                out baOutputTimeStamp1,
                                out strError);
                            if (lRet == -1)
                            {
                                // 询问是否继续
                                goto ERROR1;
                            }
                            stop.SetMessage("已删除记录" + strPath + "  " + m_nRecordCount.ToString());
                        }

                        if (bFoundRecord == true)
                            m_nRecordCount++;


                        if (bAsc == true)
                        {
                            //progressBar_main.Value = (int)((nCur - nStart + 1) / ProgressRatio);
                            stop.SetProgressValue(nCur - nStart + 1);
                        }
                        else
                        {
                            // ?
                            // progressBar_main.Value = (int)((nStart - nCur + 1) / ProgressRatio);
                            stop.SetProgressValue(nStart - nCur + 1);
                        }


                        // 对已经作过的进行判断
                        if (bAsc == true && nCur >= nEnd)
                            break;
                        if (bAsc == false && nCur <= nEnd)
                            break;


                    } // end of for one database

                    stop.EndLoop();
                    stop.OnStop -= new StopEventHandler(this.DoStop);
                    stop.Initial("");

                    EnableControls(true);

                //}

            CONTINUEDBS:
                    strInfo += " : " + m_nRecordCount.ToString() + "条 (ID " + strRealStartNo + "-" + strRealEndNo + ")";

                }   // end of dbpaths loop


            }   // end of try
            finally
            {
                if (writer != null)
                {
                    writer.WriteEndElement();
                    writer.WriteEndDocument();
                    writer.Close();
                    writer = null;
                }

                if (outputfile != null)
                {
                    outputfile.Close();
                    outputfile = null;
                }
            }

            // END1:
            channel = null;

            if (checkBox_export_delete.Checked == true)
                strError = "数据导出和删除完成。\r\n---\r\n" + strInfo;
            else
                strError = "数据导出完成。\r\n---\r\n" + strInfo;

            WriteLog("结束输出");

            return 0;
        ERROR1:
            stop.EndLoop();
            stop.OnStop -= new StopEventHandler(this.DoStop);
            stop.Initial("");

            EnableControls(true);
            channel = null;
            return -1;
        }
        // 获得用户记录
        // return:
        //      -1  error
        //      0   not found
        //      >=1   检索命中的条数
        public static int GetUserRecord(
            RmsChannel channel,
            string strUserName,
            out string strRecPath,
            out string strXml,
            out byte[] baTimeStamp,
            out string strError)
        {
            strError = "";

            strXml = "";
            strRecPath = "";
            baTimeStamp = null;

            if (strUserName == "")
            {
                strError = "用户名为空";
                return -1;
            }

            string strQueryXml = "<target list='" + Defs.DefaultUserDb.Name
                + ":" + Defs.DefaultUserDb.SearchPath.UserName + "'><item><word>"
                + strUserName + "</word><match>exact</match><relation>=</relation><dataType>string</dataType><maxCount>10</maxCount></item><lang>chi</lang></target>";

            long nRet = channel.DoSearch(strQueryXml,
                "default",
                "", // strOutputStyle
                out strError);
            if (nRet == -1)
            {
                strError = "检索帐户库时出错: " + strError;
                return -1;
            }

            if (nRet == 0)
                return 0;	// not found

            long nSearchCount = nRet;

            List<string> aPath = null;
            nRet = channel.DoGetSearchResult(
                "default",
                1,
                "zh",
                null,	// stop,
                out aPath,
                out strError);
            if (nRet == -1)
            {
                strError = "检索注册用户库获取检索结果时出错: " + strError;
                return -1;
            }
            if (aPath.Count == 0)
            {
                strError = "检索注册用户库获取的检索结果为空";
                return -1;
            }

            // strRecID = ResPath.GetRecordId((string)aPath[0]);
            strRecPath = (string)aPath[0];

            string strStyle = "content,data,timestamp,withresmetadata";
            string strMetaData;
            string strOutputPath;

            nRet = channel.GetRes((string)aPath[0],
                strStyle,
                out strXml,
                out strMetaData,
                out baTimeStamp,
                out strOutputPath,
                out strError);
            if (nRet == -1)
            {
                strError = "获取注册用户库记录体时出错: " + strError;
                return -1;
            }


            return (int)nSearchCount;
        }
Beispiel #13
0
        // 将内核网络配置文件映射到本地
        // return:
        //      -1  出错
        //      0   不存在
        //      1   找到
        public int MapFileToLocal(
            // RmsChannelCollection Channels,
            RmsChannel channel,
            string strPath,
            out string strLocalPath,
            out string strError)
        {
            strLocalPath = "";
            strError = "";

            strLocalPath = this.RootDir + "/" + strPath;

            // 确保目录存在
            PathUtil.CreateDirIfNeed(Path.GetDirectoryName(strLocalPath));

            this.locks.LockForRead(strLocalPath);
            try {
                // 看看物理文件是否存在
                FileInfo fi = new FileInfo(strLocalPath);
                if (fi.Exists == true) {
                    if (fi.Length == 0)
                        return 0;   // not exist
                    return 1;
                }
            }
            finally
            {
                this.locks.UnlockForRead(strLocalPath);
            }

            // 确保目录存在
            PathUtil.CreateDirIfNeed(Path.GetDirectoryName(strLocalPath));

            this.locks.LockForWrite(strLocalPath);
            try
            {
#if NO
                RmsChannel channel = Channels.GetChannel(this.ServerUrl);
                if (channel == null)
                {
                    strError = "GetChannel error";
                    return -1;
                }
#endif

                string strMetaData = "";
                byte[] baOutputTimestamp = null;
                string strOutputPath = "";

                long lRet = channel.GetRes(strPath,
                    strLocalPath,
                    (Stop)null,
                    out strMetaData,
                    out baOutputTimestamp,
                    out strOutputPath,
                    out strError);
                if (lRet == -1)
                {
                    if (channel.ErrorCode == ChannelErrorCode.NotFound)
                    {
                        // 为了避免以后再次从网络获取耗费时间, 需要在本地写一个0字节的文件
                        FileStream fs = File.Create(strLocalPath);
                        fs.Close();
                        return 0;
                    }
                    return -1;
                }

                return 1;
            }
            finally
            {
                this.locks.UnlockForWrite(strLocalPath);
            }
        }
Beispiel #14
0
        // 移动或者复制书目记录
        // strExistingXml和请求中传来的old xml的时间戳比较,在本函数外、调用前进行
        // parameters:
        //      strAction   动作。为"onlycopybiblio" "onlymovebiblio"之一。增加 copy / move
        //      strNewBiblio    需要在目标记录中更新的内容。如果 == null,表示不特意更新
        //      strMergeStyle   如何合并两条记录的元数据部分? reserve_source / reserve_target。 空表示 reserve_source
        int DoBiblioOperMove(
            string strAction,
            SessionInfo sessioninfo,
            RmsChannel channel,
            string strOldRecPath,
            string strExistingSourceXml,
            // byte[] baExistingSourceTimestamp, // 请求中提交过来的时间戳
            string strNewRecPath,
            string strNewBiblio,    // 已经经过Merge预处理的新记录XML
            string strMergeStyle,
            out string strOutputTargetXml,
            out byte[] baOutputTimestamp,
            out string strOutputRecPath,
            out string strError)
        {
            strError = "";
            long lRet = 0;
            baOutputTimestamp = null;
            strOutputRecPath = "";

            strOutputTargetXml = ""; // 最后保存成功的记录

            // 检查路径
            if (strOldRecPath == strNewRecPath)
            {
                strError = "当action为\"" + strAction + "\"时,strNewRecordPath路径 '" + strNewRecPath + "' 和strOldRecPath '" + strOldRecPath + "' 必须不相同";
                goto ERROR1;
            }

            if (String.IsNullOrEmpty(strNewRecPath) == true)
            {
                strError = "DoBiblioOperMove() strNewRecPath参数值不能为空";
                goto ERROR1;
            }

            // 检查即将覆盖的目标位置是不是有记录,如果有,则不允许进行move操作。
            bool bAppendStyle = false;  // 目标路径是否为追加形态?
            string strTargetRecId = ResPath.GetRecordId(strNewRecPath);
            string strExistTargetXml = "";

            if (strTargetRecId == "?" || String.IsNullOrEmpty(strTargetRecId) == true)
            {
                // 2009/11/1 
                if (String.IsNullOrEmpty(strTargetRecId) == true)
                    strNewRecPath += "/?";

                bAppendStyle = true;
            }


            string strOutputPath = "";
            string strMetaData = "";

            if (bAppendStyle == false)
            {
                byte[] exist_target_timestamp = null;

                // 获取覆盖目标位置的现有记录
                lRet = channel.GetRes(strNewRecPath,
                    out strExistTargetXml,
                    out strMetaData,
                    out exist_target_timestamp,
                    out strOutputPath,
                    out strError);
                if (lRet == -1)
                {
                    if (channel.ErrorCode == ChannelErrorCode.NotFound)
                    {
                        // 如果记录不存在, 说明不会造成覆盖态势
                        /*
                        strExistSourceXml = "<root />";
                        exist_source_timestamp = null;
                        strOutputPath = info.NewRecPath;
                         * */
                    }
                    else
                    {
                        strError = "移动操作发生错误, 在读入即将覆盖的目标位置 '" + strNewRecPath + "' 原有记录阶段:" + strError;
                        goto ERROR1;
                    }
                }
                else
                {
#if NO
                    // 如果记录存在,则目前不允许这样的操作
                    strError = "移动(move)操作被拒绝。因为在即将覆盖的目标位置 '" + strNewRecPath + "' 已经存在书目记录。请先删除(delete)这条记录,再进行移动(move)操作";
                    goto ERROR1;
#endif
                }
            }

            /*
            // 把两个记录装入DOM

            XmlDocument domSourceExist = new XmlDocument();
            XmlDocument domNew = new XmlDocument();

            try
            {
                domSourceExist.LoadXml(strExistingSourceXml);
            }
            catch (Exception ex)
            {
                strError = "strExistXml装载进入DOM时发生错误: " + ex.Message;
                goto ERROR1;
            }

            try
            {
                domNew.LoadXml(strNewBiblio);
            }
            catch (Exception ex)
            {
                strError = "strNewBiblio装载进入DOM时发生错误: " + ex.Message;
                goto ERROR1;
            }
             * */

            // 只有order权限的情况
            if (StringUtil.IsInList("setbiblioinfo", sessioninfo.RightsOrigin) == false
                && StringUtil.IsInList("order", sessioninfo.RightsOrigin) == true)
            {
                if (strAction == "onlymovebiblio"
                    || strAction == "move")
                {
                    string strSourceDbName = ResPath.GetDbName(strOldRecPath);
                    // 源头书目库为 非工作库 情况
                    if (IsOrderWorkBiblioDb(strSourceDbName) == false)
                    {
                        // 非工作库不能删除记录
                        if (IsOrderWorkBiblioDb(strSourceDbName) == false)
                        {
                            // 非工作库。要求原来记录不存在
                            strError = "当前帐户只有order权限而没有setbiblioinfo权限,不能用" + strAction + "功能删除源书目记录 '" + strOldRecPath + "'";
                            goto ERROR1;
                        }
                    }
                }
            }

            // 移动记录
            byte[] output_timestamp = null;
            string strIdChangeList = "";

            // TODO: Copy后还要写一次?因为Copy并不写入新记录。
            // 其实Copy的意义在于带走资源。否则还不如用Save+Delete
            lRet = channel.DoCopyRecord(strOldRecPath,
                 strNewRecPath,
                 strAction == "onlymovebiblio" || strAction == "move" ? true : false,   // bDeleteSourceRecord
                 strMergeStyle,
                 out strIdChangeList,
                 out output_timestamp,
                 out strOutputRecPath,
                 out strError);
            if (lRet == -1)
            {
                strError = "DoCopyRecord() error :" + strError;
                goto ERROR1;
            }

            // TODO: 兑现对 856 字段的合并,和来自源的 856 字段的 $u 修改

            if (String.IsNullOrEmpty(strNewBiblio) == false)
            {
                this.BiblioLocks.LockForWrite(strOutputRecPath);

                try
                {
                    // TODO: 如果新的、已存在的xml没有不同,或者新的xml为空,则这步保存可以省略
                    string strOutputBiblioRecPath = "";
                    lRet = channel.DoSaveTextRes(strOutputRecPath,
                        strNewBiblio,
                        false,
                        "content", // ,ignorechecktimestamp
                        output_timestamp,
                        out baOutputTimestamp,
                        out strOutputBiblioRecPath,
                        out strError);
                    if (lRet == -1)
                        goto ERROR1;
                }
                finally
                {
                    this.BiblioLocks.UnlockForWrite(strOutputRecPath);
                }
            }

            {
                // TODO: 是否和前面一起锁定?
                byte[] exist_target_timestamp = null;

                // 获取最后的记录
                lRet = channel.GetRes(strOutputRecPath,
                    out strOutputTargetXml,
                    out strMetaData,
                    out exist_target_timestamp,
                    out strOutputPath,
                    out strError);
            }

            return 0;
        ERROR1:
            return -1;
        }
Beispiel #15
0
		// 保存记录到模板配置文件
		// parameters:
		public void SaveToTemplate()
		{
			// 选择目标数据库
			OpenResDlg dlg = new OpenResDlg();
            dlg.Font = GuiUtil.GetDefaultFont();

			dlg.Text = "请选择目标数据库";
			dlg.EnabledIndices = new int[] { ResTree.RESTYPE_DB };
			dlg.ap = this.MainForm.AppInfo;
			dlg.ApCfgTitle = "detailform_openresdlg";
			dlg.Path = textBox_recPath.Text;
			dlg.Initial( MainForm.Servers,
				this.Channels);	
			// dlg.StartPosition = FormStartPosition.CenterScreen;
			dlg.ShowDialog(this);

			if (dlg.DialogResult != DialogResult.OK)
				return;


			// 下载模板配置文件
			ResPath respath = new ResPath(dlg.Path);

			string strError;
			string strContent;
			byte[] baTimeStamp = null;
			string strMetaData;
			string strOutputPath;

			string strCfgFilePath = respath.Path + "/cfgs/template";

			long lRet = 0;

			// 使用Channel
			RmsChannel channelSave = channel;

			channel = Channels.GetChannel(respath.Url);
			Debug.Assert(channel != null, "Channels.GetChannel 异常");

			try 
			{

                stop.OnStop += new StopEventHandler(this.DoStop);
				stop.Initial("正在下载文件" + strCfgFilePath);
				stop.BeginLoop();



				lRet = channel.GetRes(
					MainForm.cfgCache,
					strCfgFilePath,
					out strContent,
					out strMetaData,
					out baTimeStamp,
					out strOutputPath,
					out strError);

				stop.EndLoop();
                stop.OnStop -= new StopEventHandler(this.DoStop);
				stop.Initial("");

				if (lRet == -1) 
				{
					this.TimeStamp = null;
					MessageBox.Show(this, strError);
					return;
				}

			}
			finally 
			{
				channel = channelSave;
			}

			SelectRecordTemplateDlg tempdlg = new SelectRecordTemplateDlg();
            tempdlg.Font = GuiUtil.GetDefaultFont();

            int nRet = tempdlg.Initial(strContent, out strError);
			if (nRet == -1) 
				goto ERROR1;


			tempdlg.Text = "请选择要修改的模板记录";
			tempdlg.CheckNameExist = false;	// 按OK按钮时不警告"名字不存在",这样允许新建一个模板
			tempdlg.ap = this.MainForm.AppInfo;
			tempdlg.ApCfgTitle = "detailform_selecttemplatedlg";
			tempdlg.ShowDialog(this);

			if (tempdlg.DialogResult != DialogResult.OK)
				return;

			string strXmlBody = "";
            bool bHasUploadedFile = false;


			nRet = GetXmlRecord(out strXmlBody,
                out bHasUploadedFile,
                out strError);
			if (nRet == -1)
				goto ERROR1;



			// 修改配置文件内容
			if (tempdlg.textBox_name.Text != "")
			{
				// 替换或者追加一个记录
				nRet = tempdlg.ReplaceRecord(tempdlg.textBox_name.Text,
					strXmlBody,
					out strError);
				if (nRet == -1) 
				{
					goto ERROR1;
				}
			}

			if (tempdlg.Changed == false)	// 没有必要保存回去
				return;

			string strOutputXml = tempdlg.OutputXml;


			// 使用Channel
			channelSave = channel;

			// 重新获得一次channel, 是因为前面GetXmlRecord()函数有可能摧毁这个变量
			channel = Channels.GetChannel(respath.Url);
			Debug.Assert(channel != null, "Channels.GetChannel 异常");

			try 
			{


				// 存回配置文件
                stop.OnStop += new StopEventHandler(this.DoStop);
				stop.Initial("正在保存配置文件 " + strCfgFilePath);
				stop.BeginLoop();

				byte [] baOutputTimeStamp = null;
				// string strOutputPath = "";

				EnableControlsInLoading(true);

				lRet = channel.DoSaveTextRes(strCfgFilePath,
					strOutputXml,
					true,	// bInlucdePreamble
					"",	// style
					baTimeStamp,
					out baOutputTimeStamp,
					out strOutputPath,
					out strError);

				EnableControlsInLoading(false);

				stop.EndLoop();
                stop.OnStop -= new StopEventHandler(this.DoStop);
				stop.Initial("");


				if (lRet == -1) 
				{
					strError = "保存配置文件"+ strCfgFilePath +"失败,原因: "+strError;
					goto ERROR1;
				}
			}
			finally 
			{
				channel = channelSave;
			}

			MessageBox.Show(this, "修改模板配置文件成功。");

			return;

			ERROR1:
				MessageBox.Show(this, strError);

		}
Beispiel #16
0
        // 执行API中的"change"操作
        // 1) 操作成功后, NewRecord中有实际保存的新记录,NewTimeStamp为新的时间戳
        // 2) 如果返回TimeStampMismatch错,则OldRecord中有库中发生变化后的“原记录”,OldTimeStamp是其时间戳
        // return:
        //      -1  出错
        //      0   成功
        public int DoOperChange(
            bool bForce,
            // string strUserID,
            SessionInfo sessioninfo,
            RmsChannel channel,
            EntityInfo info,
            ref XmlDocument domOperLog,
            ref List<EntityInfo> ErrorInfos)
        {
            int nRedoCount = 0;
            EntityInfo error = null;
            bool bExist = true;    // info.RecPath所指的记录是否存在?

            int nRet = 0;
            long lRet = 0;

            string strError = "";

            // 检查一下路径
            if (String.IsNullOrEmpty(info.NewRecPath) == true)
            {
                strError = "info.NewRecPath中的路径不能为空";
                goto ERROR1;
            }

            string strTargetRecId = ResPath.GetRecordId(info.NewRecPath);

            if (strTargetRecId == "?")
            {
                strError = "info.NewRecPath路径 '" + strTargetRecId + "' 中记录ID部分不能为'?'";
                goto ERROR1;
            }
            if (String.IsNullOrEmpty(strTargetRecId) == true)
            {
                strError = "info.NewRecPath路径 '" + strTargetRecId + "' 中记录ID部分不能为空";
                goto ERROR1;
            }

            if (info.OldRecPath != info.NewRecPath)
            {
                strError = "当action为\"change\"时,info.NewRecordPath路径 '" + info.NewRecPath + "' 和info.OldRecPath '" + info.OldRecPath + "' 必须相同";
                goto ERROR1;
            }

            string strExistXml = "";
            byte[] exist_timestamp = null;
            string strOutputPath = "";
            string strMetaData = "";


            // 先读出数据库中即将覆盖位置的已有记录
        REDOLOAD:

            lRet = channel.GetRes(info.NewRecPath,
                out strExistXml,
                out strMetaData,
                out exist_timestamp,
                out strOutputPath,
                out strError);
            if (lRet == -1)
            {
                if (channel.ErrorCode == ChannelErrorCode.NotFound)
                {
                    // 如果记录不存在, 则构造一条空的记录
                    bExist = false;
                    strExistXml = "<root />";
                    exist_timestamp = null;
                    strOutputPath = info.NewRecPath;
                }
                else
                {
                    error = new EntityInfo(info);
                    error.ErrorInfo = "保存操作发生错误, 在读入原有记录阶段:" + strError;
                    error.ErrorCode = channel.OriginErrorCode;
                    ErrorInfos.Add(error);
                    return -1;
                }
            }


            // 把两个记录装入DOM

            XmlDocument domExist = new XmlDocument();
            XmlDocument domNew = new XmlDocument();

            try
            {
                domExist.LoadXml(strExistXml);
            }
            catch (Exception ex)
            {
                strError = "strExistXml装载进入DOM时发生错误: " + ex.Message;
                goto ERROR1;
            }

            try
            {
                domNew.LoadXml(info.NewRecord);
            }
            catch (Exception ex)
            {
                strError = "info.NewRecord装载进入DOM时发生错误: " + ex.Message;
                goto ERROR1;
            }


            // 观察时间戳是否发生变化
            nRet = ByteArray.Compare(info.OldTimestamp, exist_timestamp);
            if (nRet != 0)
            {
                // 时间戳不相等了
                // 需要把info.OldRecord和strExistXml进行比较,看看和业务有关的元素(要害元素)值是否发生了变化。
                // 如果这些要害元素并未发生变化,就继续进行合并、覆盖保存操作

                XmlDocument domOld = new XmlDocument();

                try
                {
                    domOld.LoadXml(info.OldRecord);
                }
                catch (Exception ex)
                {
                    strError = "info.OldRecord装载进入DOM时发生错误: " + ex.Message;
                    goto ERROR1;
                }

                if (bForce == false)
                {
                    // 比较两个记录, 看看和事项有关的字段是否发生了变化
                    // return:
                    //      0   没有变化
                    //      1   有变化
                    nRet = IsItemInfoChanged(domOld,
                        domExist);
                }

                if (nRet == 1 || bForce == true)    // 2008/10/19
                {
                    error = new EntityInfo(info);
                    // 错误信息中, 返回了修改过的原记录和新时间戳
                    error.OldRecord = strExistXml;
                    error.OldTimestamp = exist_timestamp;

                    if (bExist == false)
                        error.ErrorInfo = "保存操作发生错误: 数据库中的原记录 (路径为'" + info.OldRecPath + "') 已被删除。";
                    else
                        error.ErrorInfo = "保存操作发生错误: 数据库中的原记录 (路径为'" + info.OldRecPath + "') 已发生过修改";
                    error.ErrorCode = ErrorCodeValue.TimestampMismatch;
                    ErrorInfos.Add(error);
                    return -1;
                }

                // exist_timestamp此时已经反映了库中被修改后的记录的时间戳
            }


            // 合并新旧记录
            string strWarning = "";
            string strNewXml = "";
            if (bForce == false)
            {
                // 2011/2/11
                nRet = CanChange(
    sessioninfo,
    "change",
    domExist,
    domNew,
    out strError);
                if (nRet == -1)
                    goto ERROR1;
                if (nRet == 0)
                {
                    error = new EntityInfo(info);
                    error.ErrorInfo = strError;
                    error.ErrorCode = ErrorCodeValue.AccessDenied;
                    ErrorInfos.Add(error);
                    return -1;
                }

                // 2010/4/8
                nRet = this.App.SetOperation(
                    ref domNew,
                    "lastModified",
                    sessioninfo.UserID,
                    "",
                    out strError);
                if (nRet == -1)
                    goto ERROR1;

                // return:
                //      -1  出错
                //      0   正确
                //      1   有部分修改没有兑现。说明在strError中
                nRet = MergeTwoItemXml(
                    sessioninfo,
                    domExist,
                    domNew,
                    out strNewXml,
                    out strError);
                if (nRet == -1)
                    goto ERROR1;
                if (nRet == 1)
                    strWarning = strError;
            }
            else
            {
                // 2008/10/19
                strNewXml = domNew.OuterXml;
            }


            // 保存新记录
            byte[] output_timestamp = null;
            lRet = channel.DoSaveTextRes(info.NewRecPath,
                strNewXml,
                false,   // include preamble?
                "content",
                exist_timestamp,
                out output_timestamp,
                out strOutputPath,
                out strError);
            if (lRet == -1)
            {

                if (channel.ErrorCode == ChannelErrorCode.TimestampMismatch)
                {
                    if (nRedoCount > 10)
                    {
                        strError = "反复保存均遇到时间戳冲突, 超过10次重试仍然失败";
                        goto ERROR1;
                    }
                    // 发现时间戳不匹配
                    // 重复进行提取已存在记录\比较的过程
                    nRedoCount++;
                    goto REDOLOAD;
                }

                error = new EntityInfo(info);
                error.ErrorInfo = "保存操作发生错误:" + strError;
                error.ErrorCode = channel.OriginErrorCode;
                ErrorInfos.Add(error);
                return -1;
            }
            else // 成功
            {
                DomUtil.SetElementText(domOperLog.DocumentElement, "action", "change");

                // 新记录
                XmlNode node = DomUtil.SetElementText(domOperLog.DocumentElement,
                    "record", strNewXml);
                DomUtil.SetAttr(node, "recPath", info.NewRecPath);

                // 旧记录
                node = DomUtil.SetElementText(domOperLog.DocumentElement,
                    "oldRecord", strExistXml);
                DomUtil.SetAttr(node, "recPath", info.OldRecPath);

                // 保存成功,需要返回信息元素。因为需要返回新的时间戳
                error = new EntityInfo(info);
                error.NewTimestamp = output_timestamp;
                error.NewRecord = strNewXml;

                error.ErrorInfo = "保存操作成功。NewTimeStamp中返回了新的时间戳,NewRecord中返回了实际保存的新记录(可能和提交的新记录稍有差异)。";
                if (string.IsNullOrEmpty(strWarning) == false)
                {
                    error.ErrorInfo = "保存操作成功。但" + strWarning;
                    error.ErrorCode = ErrorCodeValue.PartialDenied;
                }
                else
                    error.ErrorCode = ErrorCodeValue.NoError;
                ErrorInfos.Add(error);
            }

            return 0;

        ERROR1:
            error = new EntityInfo(info);
            error.ErrorInfo = strError;
            error.ErrorCode = ErrorCodeValue.CommonError;
            ErrorInfos.Add(error);
            return -1;
        }
Beispiel #17
0
		// 保存记录
		// parameters:
		//		strRecordPath	记录路径。如果==null,表示直接用textBox_recPath中当前的内容作为路径
		public void SaveRecord(string strRecordPath)
		{
			if (strRecordPath != null)
				textBox_recPath.Text = strRecordPath;

			if (textBox_recPath.Text == "")
			{
				MessageBox.Show(this, "路径不能为空");
				return;
			}

			ResPath respath = new ResPath(textBox_recPath.Text);

			Uri uri = null;
			try 
			{
				uri = new Uri(respath.Url);
			}
			catch (Exception ex)
			{
				MessageBox.Show(this, "路径错误: " + ex.Message);
				return;
			}
			// 保存到文件
			if (uri.IsFile)
			{
				MessageBox.Show(this, "暂时不支持保存到文件");
				return;
			}


			string strError;

			string strXml = "";
            bool bHasUploadedFile = false;

			int nRet = GetXmlRecord(out strXml,
                out bHasUploadedFile,
                out strError);
			if (nRet == -1)
			{
				MessageBox.Show(this, strError);
				return;
			}


			byte [] baOutputTimeStamp = null;
			string strOutputPath = "";
			long lRet = 0;

            int nUploadCount = 0;

			// 使用Channel
			RmsChannel channelSave = channel;

			channel = Channels.GetChannel(respath.Url);
			Debug.Assert(channel != null, "Channels.GetChannel 异常");

			try 
			{

                stop.OnStop += new StopEventHandler(this.DoStop);
				stop.Initial("正在保存记录 " + respath.FullPath);
				stop.BeginLoop();


				EnableControlsInLoading(true);

				//string strTemp = ByteArray.GetHexTimeStampString(this.TimeStamp);

                if (String.IsNullOrEmpty(this.strDatabaseOriginPath) == false
                    && bHasUploadedFile == true
                    && respath.FullPath != this.strDatabaseOriginPath)
                {
                    ResPath respath_old = new ResPath(this.strDatabaseOriginPath);

                    if (respath_old.Url != respath.Url)
                    {
                        MessageBox.Show(this, "目前暂不支持跨服务器情况下的资源复制。本记录中原有的已上载资源,在另存到目标库的时丢失(为空),请注意保存完后手动上载。");
                        goto SKIPCOPYRECORD;
                    }
                    // 复制记录
                    // return:
                    //		-1	出错。错误信息在strError中
                    //		0或者其他		成功
                    nRet = channel.DoCopyRecord(respath_old.Path,
                        respath.Path,
                        false,  // bool bDeleteOriginRecord,
                        out baOutputTimeStamp,
                        out strOutputPath,
                        out strError);
                    if (nRet == -1)
                    {
                        MessageBox.Show(this, "复制资源时发生错误: " + strError);
                    }
                    else
                    {
                        // 为继续保存最新XML记录作准备
                        respath.Path = strOutputPath;   // ?形式路径其实已经确定
                        this.TimeStamp = baOutputTimeStamp;
                    }
                }
                SKIPCOPYRECORD:

				lRet = channel.DoSaveTextRes(respath.Path,
					strXml,
					false,	// bInlucdePreamble
					"",	// style
					this.TimeStamp,
					out baOutputTimeStamp,
					out strOutputPath,
					out strError);


				EnableControlsInLoading(false);

				stop.EndLoop();
                stop.OnStop -= new StopEventHandler(this.DoStop);
				stop.Initial("");


				if (lRet == -1) 
				{
					MessageBox.Show(this, "保存记录失败,原因: "+strError);
					return;
                }

                //


                this.TimeStamp = baOutputTimeStamp;
                respath.Path = strOutputPath;
                textBox_recPath.Text = respath.FullPath;

                ////
                this.strDatabaseOriginPath = respath.Url + "?" + strOutputPath; // 保存从数据库中来的原始path

                stop.OnStop += new StopEventHandler(this.DoStop);
                stop.Initial("正在保存资源 " + respath.FullPath);
                stop.BeginLoop();

                EnableControlsInLoading(true);
                Debug.Assert(channel != null, "");
                // 保存对象资源,循环对象列表就可以了
                nUploadCount = this.listView_resFiles.DoUpload(
                    respath.Path,
                    channel,
                    stop,
                    out strError);
                EnableControlsInLoading(false);

                stop.EndLoop();
                stop.OnStop -= new StopEventHandler(this.DoStop);
                stop.Initial("");

            }
            finally
            {
                channel = channelSave;
            }

			if (nUploadCount == -1) 
			{
				MessageBox.Show(this, "XML记录保存成功, 但保存资源失败,原因: "+strError);
				return;
			}

			if (nUploadCount > 0)
			{
				// 使用Channel
				channelSave = channel;

				channel = Channels.GetChannel(respath.Url);
				Debug.Assert(channel != null, "Channels.GetChannel 异常");


				// 需要重新获得时间戳
				string strStyle = "timestamp,metadata";	// withresmetadata
				string strMetaData = "";
				string strContent = "";

				try 
				{
					lRet = channel.GetRes(respath.Path,
						strStyle,
						out strContent,
						out strMetaData,
						out baOutputTimeStamp,
						out strOutputPath,
						out strError);
					if (lRet == -1)
					{
						MessageBox.Show(this, "重新获得时间戳 '" + respath.FullPath + "' 失败。原因 : " + strError);
						return;
					}
				}
				finally 
				{
					channel = channelSave;
				}
				this.TimeStamp = baOutputTimeStamp;	// 设置时间戳很重要。即便xml不合法,也应设置好时间戳,否则窗口无法进行正常删除。
				this.m_strMetaData = strMetaData;	// 记忆XML记录的元数据



			}

			this.Changed = false;

			MessageBox.Show(this, "保存记录 '" + respath.FullPath + "' 成功。");
		}
Beispiel #18
0
        // TODO: 是否检查流通信息,需要可以通过参数控制
        // 检索书目记录下属的事项记录,返回少量必要的信息,可以提供后面实做删除时使用
        // parameters:
        //      strStyle    return_record_xml 要在DeleteEntityInfo结构中返回OldRecord内容
        //                  check_circulation_info 检查是否具有流通信息。如果具有则会报错 2012/12/19 把缺省行为变为此参数
        // return:
        //      -1  error
        //      0   not exist item dbname
        //      1   exist item dbname
        public int SearchChildItems(RmsChannel channel,
            string strBiblioRecPath,
            string strStyle,
            out long lHitCount,
            out List<DeleteEntityInfo> entityinfos,
            out string strError)
        {
            strError = "";
            lHitCount = 0;
            entityinfos = new List<DeleteEntityInfo>();

            int nRet = 0;

            bool bReturnRecordXml = StringUtil.IsInList("return_record_xml", strStyle);
            bool bCheckCirculationInfo = StringUtil.IsInList("check_circulation_info", strStyle);
            bool bOnlyGetCount = StringUtil.IsInList("only_getcount", strStyle);

            string strBiblioDbName = ResPath.GetDbName(strBiblioRecPath);
            string strBiblioRecId = ResPath.GetRecordId(strBiblioRecPath);

            // 获得书目库对应的事项库名
            string strItemDbName = "";
            nRet = this.GetItemDbName(strBiblioDbName,
                 out strItemDbName,
                 out strError);
            if (nRet == -1)
                goto ERROR1;

            if (String.IsNullOrEmpty(strItemDbName) == true)
                return 0;


            // 检索实体库中全部从属于特定id的记录

            string strQueryXml = "<target list='"
                + StringUtil.GetXmlStringSimple(strItemDbName + ":" + "父记录") 
                + "'><item><word>"
                + strBiblioRecId
                + "</word><match>exact</match><relation>=</relation><dataType>string</dataType><maxCount>-1</maxCount></item><lang>" + "zh" + "</lang></target>";

            long lRet = channel.DoSearch(strQueryXml,
                "entities",
                "", // strOuputStyle
                out strError);
            if (lRet == -1)
                goto ERROR1;

            if (lRet == 0)
            {
                strError = "没有找到属于书目记录 '" + strBiblioRecPath + "' 的任何"+this.ItemName+"记录";
                return 0;
            }

            lHitCount = lRet;

            // 仅返回命中条数
            if (bOnlyGetCount == true)
                return 0;

            int nResultCount = (int)lRet;
            int nMaxCount = 10000;
            if (nResultCount > nMaxCount)
            {
                strError = "命中"+this.ItemName+"记录数 " + nResultCount.ToString() + " 超过 "+nMaxCount.ToString()+", 暂时不支持针对它们的删除操作";
                goto ERROR1;
            }

            int nStart = 0;
            int nPerCount = 100;
            for (; ; )
            {
                List<string> aPath = null;
                lRet = channel.DoGetSearchResult(
                    "entities",
                    nStart,
                    nPerCount,
                    "zh",
                    null,
                    out aPath,
                    out strError);
                if (lRet == -1)
                    goto ERROR1;

                if (aPath.Count == 0)
                {
                    strError = "aPath.Count == 0";
                    goto ERROR1;
                }

                // 获得每条记录
                for (int i = 0; i < aPath.Count; i++)
                {
                    string strMetaData = "";
                    string strXml = "";
                    byte[] timestamp = null;
                    string strOutputPath = "";

                    lRet = channel.GetRes(aPath[i],
                        out strXml,
                        out strMetaData,
                        out timestamp,
                        out strOutputPath,
                        out strError);
                    DeleteEntityInfo entityinfo = new DeleteEntityInfo();

                    if (lRet == -1)
                    {
                        /*
                        entityinfo.RecPath = aPath[i];
                        entityinfo.ErrorCode = channel.OriginErrorCode;
                        entityinfo.ErrorInfo = channel.ErrorInfo;

                        entityinfo.OldRecord = "";
                        entityinfo.OldTimestamp = null;
                        entityinfo.NewRecord = "";
                        entityinfo.NewTimestamp = null;
                        entityinfo.Action = "";
                         * */
                        if (channel.ErrorCode == ChannelErrorCode.NotFound)
                            continue;

                        strError = "获取"+this.ItemName+"记录 '" + aPath[i] + "' 时发生错误: " + strError;
                        goto ERROR1;
                        // goto CONTINUE;
                    }

                    entityinfo.RecPath = strOutputPath;
                    entityinfo.OldTimestamp = timestamp;
                    if (bReturnRecordXml == true)
                        entityinfo.OldRecord = strXml;

                    if (bCheckCirculationInfo == true)
                    {
                        // 检查是否有借阅信息
                        // 把记录装入DOM
                        XmlDocument domExist = new XmlDocument();

                        try
                        {
                            domExist.LoadXml(strXml);
                        }
                        catch (Exception ex)
                        {
                            strError = this.ItemName + "记录 '" + aPath[i] + "' 装载进入DOM时发生错误: " + ex.Message;
                            goto ERROR1;
                        }

                        /*
                        entityinfo.ItemBarcode = DomUtil.GetElementText(domExist.DocumentElement,
                            "barcode");
                         * */

                        // TODO: 在日志恢复阶段调用本函数时,是否还有必要检查是否具有流通信息?似乎这时应强制删除为好

                        // 观察已经存在的记录是否有流通信息
                        // return:
                        //      -1  出错
                        //      0   没有
                        //      1   有。报错信息在strError中
                        nRet = this.HasCirculationInfo(domExist, out strError);
                        if (nRet == -1)
                            goto ERROR1;
                        if (nRet == 1)
                        {
                            strError = "拟删除的" + this.ItemName + "记录 '" + entityinfo.RecPath + "' 中" + strError + "(此种情况可能不限于这一条),不能删除。因此全部删除操作均被放弃。";
                            goto ERROR1;
                        }

                    }

                    // CONTINUE:
                    entityinfos.Add(entityinfo);
                }

                nStart += aPath.Count;
                if (nStart >= nResultCount)
                    break;
            }

            return 1;
        ERROR1:
            return -1;
        }
Beispiel #19
0
		// 回调函数
		int DownloadOneFileMetaData(string strID,
			out string strResultXml,
			out byte[] timestamp,
			out string strError)
		{
			timestamp = null;
			strError = "";
			ResPath respath = new ResPath(textBox_recPath.Text);
			string strResPath = respath.Path + "/object/" + strID;

			strResPath = strResPath.Replace(":", "/");

			// 使用Channel

			RmsChannel channelSave = channel;

			channel = Channels.GetChannel(respath.Url);
			Debug.Assert(channel != null, "Channels.GetChannel 异常");

			try 
			{

                stop.OnStop += new StopEventHandler(this.DoStop);
                stop.Initial("正在下载资源文件的元数据 " + strResPath);
				stop.BeginLoop();

				byte [] baOutputTimeStamp = null;
				string strOutputPath = "";

				EnableControlsInLoading(true);

				// 只得到metadata
				long lRet = channel.GetRes(strResPath,
					(Stream)null,
					stop,
					"metadata,timestamp,outputpath",
					null,
					out strResultXml,
					out baOutputTimeStamp,
					out strOutputPath,
					out strError);

				EnableControlsInLoading(false);

				stop.EndLoop();
                stop.OnStop -= new StopEventHandler(this.DoStop);
				stop.Initial("");


				if (lRet == -1) 
				{
					MessageBox.Show(this, "下载资源文件元数据失败,原因: "+strError);
					goto ERROR1;
				}

				timestamp = baOutputTimeStamp;

			}
			finally 
			{
				channel = channelSave;
			}
			return 0;

			ERROR1:
			return -1;
		}
Beispiel #20
0
        // 删除属于同一书目记录的全部实体记录
        // 这是需要提供EntityInfo数组的版本
        // return:
        //      -1  error
        //      0   没有找到属于书目记录的任何实体记录,因此也就无从删除
        //      >0  实际删除的实体记录数
        public int DeleteBiblioChildItems(
            // RmsChannelCollection Channels,
            RmsChannel channel,
            List<DeleteEntityInfo> entityinfos,
            XmlDocument domOperLog,
            out string strError)
        {
            strError = "";

            if (entityinfos == null || entityinfos.Count == 0)
                return 0;

            int nDeletedCount = 0;

            XmlNode root = null;

            if (domOperLog != null)
            {
                root = domOperLog.CreateElement("deleted"+this.ItemNameInternal+"Records");
                domOperLog.DocumentElement.AppendChild(root);
            }

#if NO
            RmsChannel channel = Channels.GetChannel(this.App.WsUrl);
            if (channel == null)
            {
                strError = "get channel error";
                goto ERROR1;
            }
#endif

            // 真正实行删除
            for (int i = 0; i < entityinfos.Count; i++)
            {
                DeleteEntityInfo info = entityinfos[i];

                byte[] output_timestamp = null;
                int nRedoCount = 0;

            REDO_DELETE:

                // this.EntityLocks.LockForWrite(info.ItemBarcode);
                try
                {

                    long lRet = channel.DoDeleteRes(info.RecPath,
                        info.OldTimestamp,
                        out output_timestamp,
                        out strError);
                    if (lRet == -1)
                    {
                        if (channel.ErrorCode == ChannelErrorCode.NotFound)
                            continue;

                        // 如果不重试,让时间戳出错暴露出来。
                        // 如果要重试,也得加上重新读入册记录并判断重新判断无借还信息才能删除

                        if (channel.ErrorCode == ChannelErrorCode.TimestampMismatch)
                        {
                            if (nRedoCount > 10)
                            {
                                strError = "重试了10次还不行。删除"+this.ItemName+"记录 '" + info.RecPath + "' 时发生错误: " + strError;
                                goto ERROR1;
                            }
                            nRedoCount++;

                            // 重新读入记录
                            string strMetaData = "";
                            string strXml = "";
                            string strOutputPath = "";
                            string strError_1 = "";

                            lRet = channel.GetRes(info.RecPath,
                                out strXml,
                                out strMetaData,
                                out output_timestamp,
                                out strOutputPath,
                                out strError_1);
                            if (lRet == -1)
                            {
                                if (channel.ErrorCode == ChannelErrorCode.NotFound)
                                    continue;

                                strError = "在删除"+this.ItemName+"记录 '" + info.RecPath + "' 时发生时间戳冲突,于是自动重新获取记录,但又发生错误: " + strError_1;
                                goto ERROR1;
                                // goto CONTINUE;
                            }

                            // 检查是否有借阅信息
                            // 把记录装入DOM
                            XmlDocument domExist = new XmlDocument();

                            try
                            {
                                if (String.IsNullOrEmpty(strXml) == false)
                                    domExist.LoadXml(strXml);
                                else
                                    domExist.LoadXml("<root />");
                            }
                            catch (Exception ex)
                            {
                                strError = this.ItemName+"记录 '" + info.RecPath + "' XML装载进入DOM时发生错误: " + ex.Message;
                                goto ERROR1;
                            }

                            /*
                            info.ItemBarcode = DomUtil.GetElementText(domExist.DocumentElement,
                                "barcode");
                             * */

                            // 观察已经存在的记录是否有流通信息
                            // return:
                            //      -1  出错
                            //      0   没有
                            //      1   有。报错信息在strError中
                            int nRet = this.HasCirculationInfo(domExist, out strError);
                            if (nRet == -1)
                                goto ERROR1;
                            if (nRet == 1)
                            {
                                strError = "拟删除的"+this.ItemName+"记录 '" + info.RecPath + "' 中"+strError+"(此种情况可能不限于这一条),不能删除。";
                                goto ERROR1;
                            }

                            info.OldTimestamp = output_timestamp;
                            goto REDO_DELETE;
                        }

                        strError = "删除"+this.ItemName+"记录 '" + info.RecPath + "' 时发生错误: " + strError;
                        goto ERROR1;
                    }
                }
                finally
                {
                    // this.EntityLocks.UnlockForWrite(info.ItemBarcode);
                }

                // 增补到日志DOM中
                if (domOperLog != null)
                {
                    Debug.Assert(root != null, "");

                    XmlNode node = domOperLog.CreateElement("record");
                    root.AppendChild(node);

                    DomUtil.SetAttr(node, "recPath", info.RecPath);
                }

                nDeletedCount++;
            }


            return nDeletedCount;
        ERROR1:
            return -1;
        }
Beispiel #21
0
		// 获得一个汉字的拼音
		// 所获得的拼音, 是一个分号间隔的字符串, 表示对应于这个汉字的多音
		// return:
		//		-1	error
		//		1	found
		//		0	not found
		int GetOnePinyin(string strOneHanzi,
			out string strPinyin,
			out string strError)
		{
			strPinyin = "";
			strError = "";

			// 拼音库路径
			string strPinyinDbPath = MainForm.AppInfo.GetString("pinyin",
				"pinyin_db_path",
				"");

            if (String.IsNullOrEmpty(strPinyinDbPath) == true)
            {
                strError = "拼音库路径尚未配置。请先用菜单“帮助/系统参数设置”功能配置适当的拼音库路径。";
                return -1;
            }

			ResPath respath = new ResPath(strPinyinDbPath);

			string strDbName = respath.Path;

            // 2007/4/5 改造 加上了 GetXmlStringSimple()
			string strQueryXml = "<target list='" + strDbName + ":" + "汉字'><item><word>"
				+ StringUtil.GetXmlStringSimple(strOneHanzi)
                + "</word><match>exact</match><relation>=</relation><dataType>string</dataType><maxCount>10</maxCount></item><lang>chi</lang></target>";

			// 使用Channel
			RmsChannel channelSave = channel;

			channel = Channels.GetChannel(respath.Url);
			Debug.Assert(channel != null, "Channels.GetChannel 异常");

			try 
			{

                stop.OnStop += new StopEventHandler(this.DoStop);
                stop.Initial("正在检索拼音 '" + strOneHanzi + "'");
				stop.BeginLoop();

				try 
				{

					long nRet = channel.DoSearch(strQueryXml,
                        "default",
                        out strError);
					if (nRet == -1) 
					{
						strError = "检索拼音库时出错: " + strError;
						return -1;
					}
					if (nRet == 0)
						return 0;	// not found

					List<string> aPath = null;
					nRet = channel.DoGetSearchResult(
                        "default",
						1,
						this.Lang,
						stop,
						out aPath,
						out strError);
					if (nRet == -1) 
					{
						strError = "检索拼音库获取检索结果时出错: " + strError;
						return -1;
					}

					if (aPath.Count == 0)
					{
						strError = "检索拼音库获取的检索结果为空";
						return -1;
					}

					string strStyle = "content,data";

					string strContent;
					string strMetaData;
					byte[] baTimeStamp;
					string strOutputPath;

					nRet = channel.GetRes((string)aPath[0],
						strStyle,
						// this.eventClose,
						out strContent,
						out strMetaData,
						out baTimeStamp,
						out strOutputPath,
						out strError);
					if (nRet == -1) 
					{
						strError = "获取拼音记录体时出错: " + strError;
						return -1;
					}

					// 取出拼音字符串
					XmlDocument dom = new XmlDocument();


					try
					{
						dom.LoadXml(strContent);
					}
					catch (Exception ex)
					{
						strError  = "汉字 '" + strOneHanzi + "' 所获取的拼音记录 " + strContent + " XML数据装载出错: " + ex.Message;
						return -1;
					}

					strPinyin = DomUtil.GetAttr(dom.DocumentElement, "p");

					return 1;

				}
				finally 
				{
					stop.EndLoop();
                    stop.OnStop -= new StopEventHandler(this.DoStop);
					stop.Initial("");
				}

			}
			finally 
			{
				channel = channelSave;
			}

		}
Beispiel #22
0
        // 获得事项记录
        // 本函数可获得超过1条以上的路径
        // parameters:
        //      timestamp   返回命中的第一条的timestamp
        //      strStyle    如果包含 withresmetadata ,表示要在XML记录中返回<dprms:file>元素内的 __xxx 属性
        // return:
        //      -1  error
        //      0   not found
        //      1   命中1条
        //      >1  命中多于1条
        public int GetItemRecXml(
            // RmsChannelCollection channels,
            RmsChannel channel,
            List<string> locateParams,
            string strStyle,
            out string strXml,
            int nMax,
            out List<string> aPath,
            out byte[] timestamp,
            out string strError)
        {
            aPath = null;

            strXml = "";
            strError = "";
            timestamp = null;
            // 构造检索式

            /*
            string strQueryXml = "<target list='"
                    + StringUtil.GetXmlStringSimple(strIssueDbName + ":" + "出版时间")
                    + "'><item><word>"
                    + StringUtil.GetXmlStringSimple(strPublishTime)
                    + "</word><match>exact</match><relation>=</relation><dataType>string</dataType><maxCount>-1</maxCount></item><lang>zh</lang></target>";

            strQueryXml += "<operator value='AND'/>";


            strQueryXml += "<target list='"
                    + StringUtil.GetXmlStringSimple(strIssueDbName + ":" + "父记录")
                    + "'><item><word>"
                    + StringUtil.GetXmlStringSimple(strParentID)
                    + "</word><match>exact</match><relation>=</relation><dataType>string</dataType><maxCount>-1</maxCount></item><lang>zh</lang></target>";

            strQueryXml = "<group>" + strQueryXml + "</group>";
             * */
            // 构造用于获取事项记录的XML检索式
            string strQueryXml = "";
            int nRet = MakeGetItemRecXmlSearchQuery(
                locateParams,
                nMax,
                out strQueryXml,
                out strError);
            if (nRet == -1)
                goto ERROR1;

#if NO
            RmsChannel channel = channels.GetChannel(this.App.WsUrl);
            if (channel == null)
            {
                strError = "get channel error";
                return -1;
            }
#endif

            long lRet = channel.DoSearch(strQueryXml,
                "default",
                "", // strOuputStyle
                out strError);
            if (lRet == -1)
                goto ERROR1;

            // not found
            if (lRet == 0)
            {
                string strText = "";
                // 构造定位提示信息。用于报错。
                nRet = GetLocateText(
                    locateParams,
                    out strText,
                    out strError);
                if (nRet == -1)
                {
                    strError = "定位信息没有找到。并且GetLocateText()函数报错: " + strError;
                    return 0;
                }


                strError = strText + " 的事项没有找到";
                return 0;
            }

            long lHitCount = lRet;

            // List<string> aPath = null;
            lRet = channel.DoGetSearchResult(
                "default",
                0,
                Math.Min(nMax, lHitCount),
                "zh",
                null,
                out aPath,
                out strError);
            if (lRet == -1)
                goto ERROR1;

            Debug.Assert(aPath != null, "");

            if (aPath.Count == 0)
            {
                strError = "DoGetSearchResult aPath error";
                goto ERROR1;
            }

            string strMetaData = "";
            string strOutputPath = "";
            string strGetStyle = "content,data,metadata,timestamp,outputpath";

            if (StringUtil.IsInList("withresmetadata", strStyle) == true)
                strGetStyle += ",withresmetadata";

            lRet = channel.GetRes(aPath[0],
                strGetStyle,
                out strXml,
                out strMetaData,
                out timestamp,
                out strOutputPath,
                out strError);
            if (lRet == -1)
                goto ERROR1;

            return (int)lHitCount;
        ERROR1:
            return -1;
        }
Beispiel #23
0
        int m_nInGetCfgFile = 0;    // 防止GetCfgFile()函数重入 2008/3/6

        // marc编辑窗要从外部获得配置文件内容
        private void MarcEditor_GetConfigFile(object sender,
            DigitalPlatform.Marc.GetConfigFileEventArgs e)
        {

            if (m_nInGetCfgFile > 0)
            {
                e.ErrorInfo = "MarcEditor_GetConfigFile() 重入了";
                return;
            }

            if (String.IsNullOrEmpty(textBox_recPath.Text))
            {
                e.ErrorInfo = "URL为空";
                return;
            }

            // 下载配置文件
            ResPath respath = new ResPath(textBox_recPath.Text);

            string strCfgFileName = e.Path;
            int nRet = strCfgFileName.IndexOf("#");
            if (nRet != -1)
            {
                strCfgFileName = strCfgFileName.Substring(0, nRet);
            }

            string strPath = ResPath.GetDbName(respath.Path) + "/cfgs/" + strCfgFileName;

            // 使用Channel

            RmsChannel channelSave = channel;

            channel = Channels.GetChannel(respath.Url);
            Debug.Assert(channel != null, "Channels.GetChannel 异常");

            m_nInGetCfgFile++;

            try
            {

                string strContent;
                string strError;

                stop.OnStop += new StopEventHandler(this.DoStop);
                stop.Initial("正在下载文件" + strPath);
                stop.BeginLoop();

                byte[] baTimeStamp = null;
                string strMetaData;
                string strOutputPath;

                long lRet = channel.GetRes(
                    MainForm.cfgCache,
                    strPath,
                    out strContent,
                    out strMetaData,
                    out baTimeStamp,
                    out strOutputPath,
                    out strError);

                stop.EndLoop();
                stop.OnStop -= new StopEventHandler(this.DoStop);
                stop.Initial("");


                if (lRet == -1)
                {
                    if (channel.ErrorCode == ChannelErrorCode.NotFound)
                    {
                        e.ErrorInfo = "";
                        return;
                    }


                    e.ErrorInfo = "获得配置文件 '" + strPath + "' 时出错:" + strError;
                    return;
                }
                else
                {
                    byte[] baContent = StringUtil.GetUtf8Bytes(strContent, true);
                    MemoryStream stream = new MemoryStream(baContent);
                    e.Stream = stream;
                }


            }
            finally
            {
                channel = channelSave;

                m_nInGetCfgFile--;
            }
        }
Beispiel #24
0
        // 删除事项记录的操作
        int DoOperDelete(
            SessionInfo sessioninfo,
            bool bForce,
            RmsChannel channel,
            EntityInfo info,
            List<string> oldLocateParams,
            /*
            string strIssueDbName,
            string strParentID,
            string strOldPublishTime,
             * */
            XmlDocument domOldRec,
            ref XmlDocument domOperLog,
            ref List<EntityInfo> ErrorInfos)
        {
            int nRedoCount = 0;
            EntityInfo error = null;
            int nRet = 0;
            long lRet = 0;
            string strError = "";

            /*
            // 如果newrecpath为空但是oldrecpath有值,就用oldrecpath的值
            // 2007/10/23
            if (String.IsNullOrEmpty(info.NewRecPath) == true)
            {
                if (String.IsNullOrEmpty(info.OldRecPath) == false)
                    info.NewRecPath = info.OldRecPath;
            }*/

            // 2008/6/24
            if (String.IsNullOrEmpty(info.NewRecPath) == false)
            {
                if (info.NewRecPath != info.OldRecPath)
                {
                    strError = "action为delete时, 如果info.NewRecPath不空,则其内容必须和info.OldRecPath一致。(info.NewRecPath='" + info.NewRecPath + "' info.OldRecPath='" + info.OldRecPath + "')";
                    return -1;
                }
            }
            else
            {
                info.NewRecPath = info.OldRecPath;
            }


            string strText = "";
            // 构造定位提示信息。用于报错。
            nRet = GetLocateText(
                oldLocateParams,
                out strText,
                out strError);
            if (nRet == -1)
            {
                strError = "GetLocateText()函数报错: " + strError;
                goto ERROR1;
            }

            // 如果记录路径为空, 则先获得记录路径
            if (String.IsNullOrEmpty(info.NewRecPath) == true)
            {
                List<string> aPath = null;

                nRet = IsLocateParamNullOrEmpty(
                    oldLocateParams,
                    out strError);
                if (nRet == -1)
                    goto ERROR1;
                if (nRet == 1)
                {
                    strError += "info.OldRecord中的" + strError + " 和 info.RecPath参数值为空,同时出现,这是不允许的";
                    goto ERROR1;
                }

                /*
                RmsChannel channel = sessioninfo.Channels.GetChannel(this.App.WsUrl);
                if (channel == null)
                {
                    strError = "get channel error";
                    goto ERROR1;
                }
                 * */

                // 本函数只负责查重, 并不获得记录体
                // return:
                //      -1  error
                //      其他    命中记录条数(不超过nMax规定的极限)
                nRet = this.SearchItemRecDup(
                    //  sessioninfo.Channels,
                    channel,
                    oldLocateParams,
                    100,
                    out aPath,
                    out strError);
                if (nRet == -1)
                {
                    strError = "删除操作中事项查重阶段发生错误:" + strError;
                    goto ERROR1;
                }


                if (nRet == 0)
                {
                    error = new EntityInfo(info);
                    error.ErrorInfo = strText + " 的记录已不存在";
                    error.ErrorCode = ErrorCodeValue.NotFound;
                    ErrorInfos.Add(error);
                    return -1;
                }

                if (nRet > 1)
                {
                    /*
                    string[] pathlist = new string[aPath.Count];
                    aPath.CopyTo(pathlist);
                     * */

                    strError = strText + " 已经被下列多条事项记录使用了: " + StringUtil.MakePathList(aPath)/*String.Join(",", pathlist)*/ + "',这是一个严重的系统故障,请尽快通知系统管理员处理。";
                    goto ERROR1;
                }

                info.NewRecPath = aPath[0];
            }

            Debug.Assert(String.IsNullOrEmpty(info.NewRecPath) == false, "");
            // Debug.Assert(strEntityDbName != "", "");

            byte[] exist_timestamp = null;
            string strOutputPath = "";
            string strMetaData = "";
            string strExistingXml = "";

        REDOLOAD:

            // 先读出数据库中此位置的已有记录
            lRet = channel.GetRes(info.NewRecPath,
                out strExistingXml,
                out strMetaData,
                out exist_timestamp,
                out strOutputPath,
                out strError);
            if (lRet == -1)
            {
                if (channel.ErrorCode == ChannelErrorCode.NotFound)
                {
                    error = new EntityInfo(info);
                    error.ErrorInfo = strText + " 的事项记录 '" + info.NewRecPath + "' 已不存在";
                    error.ErrorCode = channel.OriginErrorCode;
                    ErrorInfos.Add(error);
                    return -1;
                }
                else
                {
                    error = new EntityInfo(info);
                    error.ErrorInfo = "删除操作发生错误, 在读入原有记录 '" + info.NewRecPath + "' 阶段:" + strError;
                    error.ErrorCode = channel.OriginErrorCode;
                    ErrorInfos.Add(error);
                    return -1;
                }
            }

            // 把记录装入DOM
            XmlDocument domExist = new XmlDocument();

            try
            {
                domExist.LoadXml(strExistingXml);
            }
            catch (Exception ex)
            {
                strError = "strExistXml装载进入DOM时发生错误: " + ex.Message;
                goto ERROR1;
            }

            // 观察已存在的记录中,唯一性字段是否和要求的一致
        // return:
        //      -1  出错
        //      0   一致
        //      1   不一致。报错信息在strError中
            nRet = IsLocateInfoCorrect(
                oldLocateParams,
                domExist,
                out strError);
            if (nRet != 0)
                goto ERROR1;

            if (bForce == false)
            {
                // 观察已经存在的记录是否有流通信息
                // return:
                //      -1  出错
                //      0   没有
                //      1   有。报错信息在strError中
                nRet = HasCirculationInfo(domExist,
                    out strError);
                if (nRet != 0)
                    goto ERROR1;
            }

            if (bForce == false)
            {
                // 记录是否允许删除?
                // return:
                //      -1  出错。不允许删除。
                //      0   不允许删除,因为权限不够等原因。原因在strError中
                //      1   可以删除
                nRet = CanDelete(
                    sessioninfo,
                    domExist,
                    out strError);
                if (nRet != 1)
                    goto ERROR1;
            }


            // 比较时间戳
            // 观察时间戳是否发生变化
            nRet = ByteArray.Compare(info.OldTimestamp, exist_timestamp);
            if (nRet != 0)
            {
                // 2008/10/19
                if (bForce == true)
                {
                    error = new EntityInfo(info);
                    error.NewTimestamp = exist_timestamp;   // 让前端知道库中记录实际上发生过变化
                    error.ErrorInfo = "数据库中即将删除的册记录已经发生了变化,请重新装载、仔细核对后再行删除。";
                    error.ErrorCode = ErrorCodeValue.TimestampMismatch;
                    ErrorInfos.Add(error);
                    return -1;
                }

                // 如果前端给出了旧记录,就有和库中记录进行比较的基础
                if (String.IsNullOrEmpty(info.OldRecord) == false)
                {
                    // 比较两个记录, 看看和事项要害信息有关的字段是否发生了变化
                    // return:
                    //      0   没有变化
                    //      1   有变化
                    nRet = IsItemInfoChanged(domExist,
                        domOldRec);
                    if (nRet == 1)
                    {

                        error = new EntityInfo(info);
                        error.NewTimestamp = exist_timestamp;   // 让前端知道库中记录实际上发生过变化
                        error.ErrorInfo = "数据库中即将删除的" + this.ItemName + "记录已经发生了变化,请重新装载、仔细核对后再行删除。";
                        error.ErrorCode = ErrorCodeValue.TimestampMismatch;
                        ErrorInfos.Add(error);
                        return -1;
                    }
                }

                info.OldTimestamp = exist_timestamp;
                info.NewTimestamp = exist_timestamp;
            }

            byte[] output_timestamp = null;

            lRet = channel.DoDeleteRes(info.NewRecPath,
                info.OldTimestamp,
                out output_timestamp,
                out strError);
            if (lRet == -1)
            {
                if (channel.ErrorCode == ChannelErrorCode.TimestampMismatch)
                {
                    if (nRedoCount > 10)
                    {
                        strError = "反复删除均遇到时间戳冲突, 超过10次重试仍然失败";
                        goto ERROR1;
                    }
                    // 发现时间戳不匹配
                    // 重复进行提取已存在记录\比较的过程
                    nRedoCount++;
                    goto REDOLOAD;
                }

                error = new EntityInfo(info);
                error.NewTimestamp = output_timestamp;
                error.ErrorInfo = "删除操作发生错误:" + strError;
                error.ErrorCode = channel.OriginErrorCode;
                ErrorInfos.Add(error);
                return -1;
            }
            else
            {
                // 成功
                DomUtil.SetElementText(domOperLog.DocumentElement, "action", "delete");

                // 不创建<record>元素

                // 创建<oldRecord>元素
                XmlNode node = DomUtil.SetElementText(domOperLog.DocumentElement,
                    "oldRecord", strExistingXml);
                DomUtil.SetAttr(node, "recPath", info.NewRecPath);


                // 如果删除成功,则不必要在数组中返回表示成功的信息元素了
            }

            return 0;
        ERROR1:
            error = new EntityInfo(info);
            error.ErrorInfo = strError;
            error.ErrorCode = ErrorCodeValue.CommonError;
            ErrorInfos.Add(error);
            return -1;
        }
Beispiel #25
0
		public void LoadTemplate()
		{
			if (this.Changed == true)
			{

				DialogResult result = MessageBox.Show(this, 
					"装载模板前,发现当前窗口中已有内容修改后未来得及保存。是否要继续装载模板到窗口中(这样将丢失先前修改的内容)?\r\n\r\n(是)继续装载模板 (否)不装载模板",
					"dp2rms",
					MessageBoxButtons.YesNo,
					MessageBoxIcon.Question,
					MessageBoxDefaultButton.Button2);
				if (result != DialogResult.Yes) 
				{
					MessageBox.Show(this, "装载模板操作被放弃...");
					return;
				}
			}

			OpenResDlg dlg = new OpenResDlg();
            dlg.Font = GuiUtil.GetDefaultFont();

			dlg.Text = "请选择目标数据库";
			dlg.EnabledIndices = new int[] { ResTree.RESTYPE_DB };
			dlg.ap = this.MainForm.AppInfo;
			dlg.ApCfgTitle = "detailform_openresdlg";
			dlg.Path = textBox_recPath.Text;
			dlg.Initial( MainForm.Servers,
				this.Channels);	
			// dlg.StartPosition = FormStartPosition.CenterScreen;
			dlg.ShowDialog(this);

			if (dlg.DialogResult != DialogResult.OK)
				return;

			textBox_recPath.Text = dlg.Path + "/?";	// 为了追加保存

			// 下载配置文件
			ResPath respath = new ResPath(dlg.Path);


			// 使用Channel

			RmsChannel channelSave = channel;

			channel = Channels.GetChannel(respath.Url);
			Debug.Assert(channel != null, "Channels.GetChannel 异常");

			try 
			{

				string strContent;
				string strError;

				string strCfgFilePath = respath.Path + "/cfgs/template";

                stop.OnStop += new StopEventHandler(this.DoStop);
				stop.Initial("正在下载文件" + strCfgFilePath);
				stop.BeginLoop();

				byte[] baTimeStamp = null;
				string strMetaData;
				string strOutputPath;

				long lRet = channel.GetRes(
					MainForm.cfgCache,
					strCfgFilePath,
					// this.eventClose,
					out strContent,
					out strMetaData,
					out baTimeStamp,
					out strOutputPath,
					out strError);

				stop.EndLoop();
                stop.OnStop -= new StopEventHandler(this.DoStop);
				stop.Initial("");


				if (lRet == -1) 
				{
					this.TimeStamp = null;
					MessageBox.Show(this, strError);
					return;
				}
				else 
				{
					// MessageBox.Show(this, strContent);
					SelectRecordTemplateDlg tempdlg = new SelectRecordTemplateDlg();
                    tempdlg.Font = GuiUtil.GetDefaultFont();

                    int nRet = tempdlg.Initial(strContent, out strError);
					if (nRet == -1) 
					{
						MessageBox.Show(this, "装载配置文件 '" + strCfgFilePath + "' 发生错误: " + strError);
						return;
					}

					tempdlg.ap = this.MainForm.AppInfo;
					tempdlg.ApCfgTitle = "detailform_selecttemplatedlg";
					tempdlg.ShowDialog(this);

					if (tempdlg.DialogResult != DialogResult.OK)
						return;


					this.TimeStamp = null;
					this.m_strMetaData = "";	// 记忆XML记录的元数据

                    this.strDatabaseOriginPath = ""; // 保存从数据库中来的原始path

					nRet = this.SetRecordToControls(tempdlg.SelectedRecordXml,
						out strError);
					if (nRet == -1)
					{
						MessageBox.Show(this, strError);
						return;
					}


					this.TimeStamp = baTimeStamp;

					this.Text = respath.ReverseFullPath;

				}

			}
			finally 
			{
				channel = channelSave;
			}

		}
Beispiel #26
0
        // 执行API中的"move"操作
        // 1) 操作成功后, NewRecord中有实际保存的新记录,NewTimeStamp为新的时间戳
        // 2) 如果返回TimeStampMismatch错,则OldRecord中有库中发生变化后的“原记录”,OldTimeStamp是其时间戳
        // return:
        //      -1  出错
        //      0   成功
        int DoOperMove(
            SessionInfo sessioninfo,
            // string strUserID,
            RmsChannel channel,
            EntityInfo info,
            ref XmlDocument domOperLog,
            ref List<EntityInfo> ErrorInfos)
        {
            EntityInfo error = null;
            bool bExist = true;    // info.RecPath所指的记录是否存在?

            int nRet = 0;
            long lRet = 0;

            string strError = "";

            // 检查路径
            if (info.OldRecPath == info.NewRecPath)
            {
                strError = "当action为\"move\"时,info.NewRecordPath路径 '" + info.NewRecPath + "' 和info.OldRecPath '" + info.OldRecPath + "' 必须不相同";
                goto ERROR1;
            }

            // 检查即将覆盖的目标位置是不是有记录,如果有,则不允许进行move操作。
            // 如果要进行带覆盖目标位置记录功能的move操作,前端可以先执行一个delete操作,然后再执行move操作。
            // 这样规定,是为了避免过于复杂的判断逻辑,也便于前端操作者清楚操作的后果。
            // 因为如果允许move带有覆盖目标记录功能,则被覆盖的记录的预删除操作,等于进行了一次事项注销,但这个效用不明显,对前端操作人员准确判断事态并对后果负责(而且可能这种注销需要额外的操作权限),不利
            bool bAppendStyle = false;  // 目标路径是否为追加形态?
            string strTargetRecId = ResPath.GetRecordId(info.NewRecPath);

            if (strTargetRecId == "?" || String.IsNullOrEmpty(strTargetRecId) == true)
                bAppendStyle = true;

            string strOutputPath = "";
            string strMetaData = "";

            if (bAppendStyle == false)
            {
                string strExistTargetXml = "";
                byte[] exist_target_timestamp = null;

                // 获取覆盖目标位置的现有记录
                lRet = channel.GetRes(info.NewRecPath,
                    out strExistTargetXml,
                    out strMetaData,
                    out exist_target_timestamp,
                    out strOutputPath,
                    out strError);
                if (lRet == -1)
                {
                    if (channel.ErrorCode == ChannelErrorCode.NotFound)
                    {
                        // 如果记录不存在, 说明不会造成覆盖态势
                        /*
                        strExistSourceXml = "<root />";
                        exist_source_timestamp = null;
                        strOutputPath = info.NewRecPath;
                         * */
                    }
                    else
                    {
                        error = new EntityInfo(info);
                        error.ErrorInfo = "move操作发生错误, 发生在读入即将覆盖的目标位置 '" + info.NewRecPath + "' 原有记录阶段:" + strError;
                        error.ErrorCode = channel.OriginErrorCode;
                        ErrorInfos.Add(error);
                        return -1;
                    }
                }
                else
                {
                    // 如果记录存在,则目前不允许这样的操作
                    strError = "移动(move)操作被拒绝。因为在即将覆盖的目标位置 '" + info.NewRecPath + "' 已经存在" + this.ItemName + "记录。请先删除(delete)这条记录,再进行移动(move)操作";
                    goto ERROR1;
                }
            }


            string strExistSourceXml = "";
            byte[] exist_source_timestamp = null;

            // 先读出数据库中源位置的已有记录
            // REDOLOAD:

            lRet = channel.GetRes(info.OldRecPath,
                out strExistSourceXml,
                out strMetaData,
                out exist_source_timestamp,
                out strOutputPath,
                out strError);
            if (lRet == -1)
            {
                if (channel.ErrorCode == ChannelErrorCode.NotFound)
                {
                    /*
                    // 如果记录不存在, 则构造一条空的记录
                    bExist = false;
                    strExistSourceXml = "<root />";
                    exist_source_timestamp = null;
                    strOutputPath = info.NewRecPath;
                     * */
                    // 这种情况如果放宽,会有严重的副作用,所以不让放宽
                    strError = "move操作的源记录 '" + info.OldRecPath + "' 在数据库中不存在,所以无法进行移动操作。";
                    goto ERROR1;
                }
                else
                {
                    error = new EntityInfo(info);
                    error.ErrorInfo = "移动操作发生错误, 在读入库中原有源记录(路径在info.OldRecPath) '" + info.OldRecPath + "' 阶段:" + strError;
                    error.ErrorCode = channel.OriginErrorCode;
                    ErrorInfos.Add(error);
                    return -1;
                }
            }

            // 把两个记录装入DOM

            XmlDocument domSourceExist = new XmlDocument();
            XmlDocument domNew = new XmlDocument();

            try
            {
                domSourceExist.LoadXml(strExistSourceXml);
            }
            catch (Exception ex)
            {
                strError = "strExistXml装载进入DOM时发生错误: " + ex.Message;
                goto ERROR1;
            }

            try
            {
                domNew.LoadXml(info.NewRecord);
            }
            catch (Exception ex)
            {
                strError = "info.NewRecord装载进入DOM时发生错误: " + ex.Message;
                goto ERROR1;
            }


            // 观察时间戳是否发生变化
            nRet = ByteArray.Compare(info.OldTimestamp, exist_source_timestamp);
            if (nRet != 0)
            {
                // 时间戳不相等了
                // 需要把info.OldRecord和strExistXml进行比较,看看和事项有关的元素(要害元素)值是否发生了变化。
                // 如果这些要害元素并未发生变化,就继续进行合并、覆盖保存操作

                XmlDocument domOld = new XmlDocument();

                try
                {
                    domOld.LoadXml(info.OldRecord);
                }
                catch (Exception ex)
                {
                    strError = "info.OldRecord装载进入DOM时发生错误: " + ex.Message;
                    goto ERROR1;
                }

                // 比较两个记录, 看看和事项有关的要害字段是否发生了变化
                // return:
                //      0   没有变化
                //      1   有变化
                nRet = IsItemInfoChanged(domOld,
                    domSourceExist);
                if (nRet == 1)
                {
                    error = new EntityInfo(info);
                    // 错误信息中, 返回了修改过的原记录和新时间戳
                    error.OldRecord = strExistSourceXml;
                    error.OldTimestamp = exist_source_timestamp;

                    if (bExist == false)
                        error.ErrorInfo = "移动操作发生错误: 数据库中的原记录 (路径为'" + info.OldRecPath + "') 已被删除。";
                    else
                        error.ErrorInfo = "移动操作发生错误: 数据库中的原记录 (路径为'" + info.OldRecPath + "') 已发生过修改";
                    error.ErrorCode = ErrorCodeValue.TimestampMismatch;
                    ErrorInfos.Add(error);
                    return -1;
                }

                // exist_source_timestamp此时已经反映了库中被修改后的记录的时间戳
            }

            // 2011/2/11
            nRet = CanChange(
sessioninfo,
"move",
domSourceExist,
domNew,
out strError);
            if (nRet == -1)
                goto ERROR1;
            if (nRet == 0)
            {
                error = new EntityInfo(info);
                error.ErrorInfo = strError;
                error.ErrorCode = ErrorCodeValue.AccessDenied;
                ErrorInfos.Add(error);
                return -1;
            }

            // 2010/4/8
            // 
            nRet = this.App.SetOperation(
                ref domNew,
                "moved",
                sessioninfo.UserID, // strUserID,
                "",
                out strError);
            if (nRet == -1)
                goto ERROR1;

            string strWarning = "";
            // 合并新旧记录
            // return:
            //      -1  出错
            //      0   正确
            //      1   有部分修改没有兑现。说明在strError中
            string strNewXml = "";
            nRet = MergeTwoItemXml(
                sessioninfo,
                domSourceExist,
                domNew,
                out strNewXml,
                out strError);
            if (nRet == -1)
                goto ERROR1;
            if (nRet == 1)
                strWarning = strError;


            // 移动记录
            byte[] output_timestamp = null;

            // TODO: Copy后还要写一次?因为Copy并不写入新记录。
            // 其实Copy的意义在于带走资源。否则还不如用Save+Delete
            lRet = channel.DoCopyRecord(info.OldRecPath,
                info.NewRecPath,
                true,   // bDeleteSourceRecord
                out output_timestamp,
                out strOutputPath,
                out strError);
            if (lRet == -1)
            {
                strError = "DoCopyRecord() error :" + strError;
                goto ERROR1;
            }

            // Debug.Assert(strOutputPath == info.NewRecPath);
            string strTargetPath = strOutputPath;

            lRet = channel.DoSaveTextRes(strTargetPath,
                strNewXml,
                false,   // include preamble?
                "content",
                output_timestamp,
                out output_timestamp,
                out strOutputPath,
                out strError);
            if (lRet == -1)
            {
                strError = "移动操作中," + this.ItemName + "记录 '" + info.OldRecPath + "' 已经被成功移动到 '" + strTargetPath + "' ,但在写入新内容时发生错误: " + strError;

                if (channel.ErrorCode == ChannelErrorCode.TimestampMismatch)
                {
                    // 不进行反复处理。
                    // 因为源已经移动,情况很复杂
                }

                // 仅仅写入错误日志即可。没有Undo
                this.App.WriteErrorLog(strError);

                error = new EntityInfo(info);
                error.ErrorInfo = "移动操作发生错误:" + strError;
                error.ErrorCode = channel.OriginErrorCode;
                ErrorInfos.Add(error);
                return -1;
            }
            else // 成功
            {
                info.NewRecPath = strOutputPath;    // 兑现保存的位置,因为可能有追加形式的路径

                DomUtil.SetElementText(domOperLog.DocumentElement, "action", "move");

                // 新记录
                XmlNode node = DomUtil.SetElementText(domOperLog.DocumentElement,
                    "record", strNewXml);
                DomUtil.SetAttr(node, "recPath", info.NewRecPath);

                // 旧记录
                node = DomUtil.SetElementText(domOperLog.DocumentElement,
                    "oldRecord", strExistSourceXml);
                DomUtil.SetAttr(node, "recPath", info.OldRecPath);

                // 保存成功,需要返回信息元素。因为需要返回新的时间戳
                error = new EntityInfo(info);
                error.NewTimestamp = output_timestamp;
                error.NewRecord = strNewXml;

                error.ErrorInfo = "移动操作成功。NewRecPath中返回了实际保存的路径, NewTimeStamp中返回了新的时间戳,NewRecord中返回了实际保存的新记录(可能和提交的源记录稍有差异)。";
                if (string.IsNullOrEmpty(strWarning) == false)
                {
                    error.ErrorInfo = "移动操作成功。但" + strWarning;
                    error.ErrorCode = ErrorCodeValue.PartialDenied;
                }
                else
                    error.ErrorCode = ErrorCodeValue.NoError;
                ErrorInfos.Add(error);
            }

            return 0;

        ERROR1:
            error = new EntityInfo(info);
            error.ErrorInfo = strError;
            error.ErrorCode = ErrorCodeValue.CommonError;
            ErrorInfos.Add(error);
            return -1;
        }
Beispiel #27
0
        private void CfgFileEditDlg_Load(object sender, System.EventArgs e)
        {
            button_export.Enabled = false;

            MemoryStream stream = null;
            string strMetaData;
            string strError = "";
            string strMime = "";

            Hashtable values = null;

            if (Obj != null)
            {
                if (this.Obj.Content != null)
                {
                    stream = new MemoryStream(this.Obj.Content);
                    this.Stream = stream;
                    this.Stream.Seek(0, SeekOrigin.Begin);

                    button_export.Enabled = true;
                }

                this.TimeStamp = this.Obj.TimeStamp;

                strMetaData = this.Obj.Metadata;

                // 观察mime
                // 取metadata
                values = StringUtil.ParseMetaDataXml(strMetaData,
                    out strError);
                if (values == null)
                {
                    MessageBox.Show(this, strError);
                    return;
                }
                strMime = (string)values["mimetype"];
                if (strMime == null || strMime == "")
                    strMime = "text";
                this.Mime = strMime;

                this.LocalPath = (string)values["localpath"];
                if (this.LocalPath == null)
                    this.LocalPath = "";

                this.textBox_content.Text = "";

                // string strFirstPart = StringUtil.GetFirstPartPath(ref strMime);
                if (this.IsText == true)
                {
                    if (this.Stream != null)
                    {
                        this.Stream.Seek(0, SeekOrigin.Begin);
                        using (StreamReader sr = new StreamReader(this.Stream, Encoding.UTF8))
                        {
                            this.textBox_content.Text = ConvertCrLf(sr.ReadToEnd());
                        }
                    }
                }
                else
                {
                }

                //////

                button_OK.Enabled = false;

                this.textBox_content.SelectionStart = 0;
                this.textBox_content.SelectionLength = 0;
                return;
            }

            this.channel = Channels.GetChannel(this.ServerUrl);
            Debug.Assert(channel != null, "Channels.GetChannel() 异常");

            DigitalPlatform.Stop stop = null;

            if (stopManager != null)
            {
                stop = new DigitalPlatform.Stop();

                stop.Register(this.stopManager, true);	// 和容器关联

                stop.OnStop += new StopEventHandler(this.DoStop);
                stop.Initial("正在下载配置文件: " + this.Path);

                stop.BeginLoop();

            }

            // string strContent = "";
            byte[] baTimeStamp = null;
            string strOutputPath;

            string strStyle = "content,data,metadata,timestamp,outputpath";
            //			string strStyle = "attachment,data,metadata,timestamp,outputpath";

            stream = new MemoryStream();

            long lRet = channel.GetRes(
                this.Path,
                stream,
                stop,	// stop,
                strStyle,
                null,	// byte [] input_timestamp,
                out strMetaData,
                out baTimeStamp,
                out strOutputPath,
                out strError);

            /*
            long lRet = channel.GetRes((
                this.Path,
                out strContent,
                out strMetaData,
                out baTimeStamp,
                out strOutputPath,
                out strError);
            */

            if (stopManager != null)
            {
                stop.EndLoop();
                stop.OnStop -= new StopEventHandler(this.DoStop);
                stop.Initial("");

            }

            if (lRet == -1)
            {
                MessageBox.Show(this, strError);
                goto FINISH;
            }

            this.Stream = stream;
            this.Stream.Seek(0, SeekOrigin.Begin);

            button_export.Enabled = true;


            this.TimeStamp = baTimeStamp;

            // 观察mime
            // 取metadata
            values = StringUtil.ParseMetaDataXml(strMetaData,
                out strError);
            if (values == null)
            {
                MessageBox.Show(this, strError);
                goto FINISH;
            }
            strMime = (string)values["mimetype"];
            if (strMime == null || strMime == "")
                strMime = "text";
            this.Mime = strMime;

            this.LocalPath = (string)values["localpath"];
            if (this.LocalPath == null)
                this.LocalPath = "";

            // string strFirstPart = StringUtil.GetFirstPartPath(ref strMime);
            if (this.IsText == true)
            {
                this.Stream.Seek(0, SeekOrigin.Begin);
                using (StreamReader sr = new StreamReader(this.Stream, Encoding.UTF8))
                {
                    this.textBox_content.Text = ConvertCrLf(sr.ReadToEnd());
                }
                // 注意,此后 this.Stream 被关闭
            }
            else
            {
                //this.textBox_content.Text = "<二进制内容无法直接编辑>";
                //this.textBox_content.ReadOnly = true;
                //this.button_format.Enabled = false;
            }

            //////

            button_OK.Enabled = false;
        FINISH:
            if (stopManager != null && stop != null)
            {
                stop.Unregister();	// 和容器关联
                stop = null;
            }

            this.channel = null;

            this.textBox_content.SelectionStart = 0;
            this.textBox_content.SelectionLength = 0;
        }
Beispiel #28
0
        // 把实体记录借阅信息详细化
        // parameters:
        //      strEntityRecPath    册记录路径。如果本参数值为空,则表示希望通过strItemBarcode参数来找到册记录
        // return:
        //      -1  error
        //      0   册条码号没有找到对应的册记录
        //      1   成功
        int ModifyEntityRecord(
            // RmsChannelCollection Channels,
            RmsChannel channel,
            string strEntityRecPath,
            string strItemBarcode,
            string strReaderBarcode,
            string strBorrowDate,
            string strBorrowPeriod,
            out string strError)
        {
            strError = "";
            int nRet = 0;
            long lRet = 0;
            int nRedoCount = 0;

            if (String.IsNullOrEmpty(strItemBarcode) == true)
            {
                strError = "strItemBarcode参数不能为空";
                return -1;
            }

            // RmsChannel channel = null;

            REDO_CHANGE:

            string strOutputItemRecPath = "";
            byte[] item_timestamp = null;

            string strItemXml = "";
            List<string> aPath = null;

#if NO
            if (channel == null)
            {
                channel = Channels.GetChannel(this.WsUrl);
                if (channel == null)
                {
                    strError = "get channel error";
                    return -1;
                }
            }
#endif

            if (String.IsNullOrEmpty(strEntityRecPath) == false)
            {
                string strStyle = "content,data,metadata,timestamp,outputpath";
                string strMetaData = "";
                lRet = channel.GetRes(strEntityRecPath,
                    strStyle,
                    out strItemXml,
                    out strMetaData,
                    out item_timestamp,
                    out strOutputItemRecPath,
                    out strError);
                if (lRet == -1)
                {
                    if (channel.ErrorCode == ChannelErrorCode.NotFound)
                    {
                        return 0;
                    }
                    strError = "ModifyEntityRecord()通过册记录路径 '"+strEntityRecPath+"' 读入册记录时发生错误: " + strError;
                    return -1;
                }
            }
            else
            {
                // 从册条码号获得册记录
                // return:
                //      -1  error
                //      0   not found
                //      1   命中1条
                //      >1  命中多于1条
                nRet = this.GetItemRecXml(
                    // Channels,
                    channel,
                    strItemBarcode,
                    out strItemXml,
                    100,
                    out aPath,
                    out item_timestamp,
                    out strError);
                if (nRet == 0)
                {
                    // 册条码号不存在也是需要修复的情况之一。
                    return 0;
                }
                if (nRet == -1)
                {
                    strError = "ModifyEntityRecord()读入册记录时发生错误: " + strError;
                    return -1;
                }

                if (aPath.Count > 1)
                {
                    // TODO: 需要将入围的记录全部提取出来,然后看borrower符合读者证条码号的那一条(或者多条?)
                    // 可以参考UpgradeDt1000Loan中的SearchEntityRecord()函数
                    /*
                    strError = "因册条码号 '" + strItemBarcode + "' 检索命中多条册记录: " + StringUtil.MakePathList(aPath) + ",修改册记录的操作ModifyEntityRecord()无法进行";
                    return -1;
                     * */

                    int nSuccessCount = 0;
                    string strTempError = "";
                    // 递归
                    for (int i = 0; i < aPath.Count; i++)
                    {
                        string strTempPath = aPath[i];

                        if (String.IsNullOrEmpty(strTempPath) == true)
                        {
                            Debug.Assert(false, "");
                            continue;
                        }

                        // return:
                        //      -1  error
                        //      0   册条码号没有找到对应的册记录
                        //      1   成功
                        nRet = ModifyEntityRecord(
                            // Channels,
                            channel,
                            strTempPath,
                            strItemBarcode,
                            strReaderBarcode,
                            strBorrowDate,
                            strBorrowPeriod,
                            out strError);
                        if (nRet == -1 && nSuccessCount == 0)
                        {
                            if (String.IsNullOrEmpty(strTempError) == false)
                                strTempError += "; ";
                            strTempError += "试探册记录 '" + strTempPath + "' 时发生错误: " + strError;
                        }

                        if (nRet == 1)
                        {
                            // 改为存储成功信息
                            if (nSuccessCount == 0)
                                strTempError = "";

                            if (String.IsNullOrEmpty(strTempError) == false)
                                strTempError += "; ";
                            strTempError += strTempPath;

                            nSuccessCount++;
                        }
                    }

                    if (nSuccessCount > 0)
                    {
                        strError = "册条码号 '" + strItemBarcode + "' 检索命中" + aPath.Count.ToString() + "条册记录: " + StringUtil.MakePathList(aPath) + ",后面对它们进行了逐条试探,有 " + nSuccessCount.ToString() + " 条记录符合预期的要求,册中借阅信息得到增强。借阅信息得到增强的册记录路径如下: " + strTempError;
                        return 1;
                    }
                    else
                    {
                        strError = "册条码号 '" + strItemBarcode + "' 检索命中" + aPath.Count.ToString() + "条册记录: " + StringUtil.MakePathList(aPath) + ",后面对它们进行了逐条试探,但是没有一条记录符合预期的要求。试探过程报错如下: " + strTempError;
                        return -1;
                    }

                    /*
                    result.Value = -1;
                    result.ErrorInfo = "册条码号为 '" + strItemBarcode + "' 的册记录有 " + aPath.Count.ToString() + " 条,无法进行修复操作。请在附加册记录路径后重新提交修复操作。";
                    result.ErrorCode = ErrorCode.ItemBarcodeDup;

                    aDupPath = new string[aPath.Count];
                    aPath.CopyTo(aDupPath);
                    return result;
                     * */

                }
                else
                {
                    Debug.Assert(nRet == 1, "");
                    Debug.Assert(aPath.Count == 1, "");

                    if (nRet == 1)
                    {
                        strOutputItemRecPath = aPath[0];
                    }
                }
            }

            XmlDocument itemdom = null;
            nRet = LibraryApplication.LoadToDom(strItemXml,
                out itemdom,
                out strError);
            if (nRet == -1)
            {
                strError = "装载册记录进入XML DOM时发生错误: " + strError;
                return -1;
            }

            // 校验册条码号参数是否和XML记录中完全一致
            string strTempItemBarcode = DomUtil.GetElementText(itemdom.DocumentElement,
                "barcode");
            if (strItemBarcode != strTempItemBarcode)
            {
                strError = "修改册记录ModifyEntityRecord()操作被拒绝。因册条码号参数 '" + strItemBarcode + "' 和册记录中<barcode>元素内的册条码号值 '" + strTempItemBarcode + "' 不一致。";
                return -1;
            }

            // 看看册记录中是否有指回读者记录的链
            string strBorrower = DomUtil.GetElementText(itemdom.DocumentElement,
                "borrower");
            if (strBorrower != strReaderBarcode)
            {
                // strError = "ModifyEntityRecord()操作被拒绝。您所请求要修复的链,本是一条完整正确的链。可直接进行普通还书操作。";
                strError = "修改册记录ModifyEntityRecord()操作被拒绝。因册记录 " + strOutputItemRecPath + " 中的[borrower]值 '" + strBorrower + "' 和发源(来找册条码号 '" + strItemBarcode + "')的读者证条码号 '" + strReaderBarcode + "' 不一致,不能构成一条完整正确的链。请及时排除此故障。";
                return -1;
            }

            // 2007/1/1注:应当看看记录中<borrower>元素是否有内容才改写<borrowDate>和<borrowPeriod>元素。

            DomUtil.SetElementText(itemdom.DocumentElement, "borrowDate", strBorrowDate);
            DomUtil.SetElementText(itemdom.DocumentElement, "borrowPeriod", strBorrowPeriod);

#if NO
            if (channel == null)
            {
                channel = Channels.GetChannel(this.WsUrl);
                if (channel == null)
                {
                    strError = "get channel error";
                    return -1;
                }
            }
#endif
            byte[] output_timestamp = null;
            string strOutputPath = "";

            // 写回册记录
            lRet = channel.DoSaveTextRes(strOutputItemRecPath,
                itemdom.OuterXml,
                false,
                "content",  // ,ignorechecktimestamp
                item_timestamp,
                out output_timestamp,
                out strOutputPath,
                out strError);
            if (lRet == -1)
            {
                if (channel.ErrorCode == ChannelErrorCode.TimestampMismatch)
                {
                    nRedoCount++;
                    if (nRedoCount > 10)
                    {
                        strError = "ModifyEntityRecord()写回册记录的时候,遇到时间戳冲突,并因此重试10次,仍失败...";
                        return -1;
                    }
                    goto REDO_CHANGE;
                }
                return -1;
            } // end of 写回册记录失败

            return 1;
        }
Beispiel #29
0
        // 获得一行信息
        int GetLineInfo(
            RmsChannel channel,
            string strPath,
            out string strSender,
            out string strRecipient,
            out string strSubject,
            out string strDate,
            out string strSize,
            out bool bTouched,
            out string strError)
        {
            strSender = "";
            strRecipient = "";
            strSubject = "";
            strDate = "";
            strSize = "";
            bTouched = false;
            strError = "";


            // 将种记录数据从XML格式转换为HTML格式
            string strMetaData = "";
            byte[] timestamp = null;
            string strXml = "";
            string strOutputPath = "";
            long lRet = channel.GetRes(strPath,
                out strXml,
                out strMetaData,
                out timestamp,
                out strOutputPath,
                out strError);
            if (lRet == -1)
            {
                // text-level: 内部错误
                strError = "获得消息记录 '" + strPath + "' 时出错: " + strError;
                return -1;
            }

            XmlDocument dom = new XmlDocument();
            try
            {
                dom.LoadXml(strXml);
            }
            catch (Exception ex)
            {
                // text-level: 内部错误
                strError = "装载XML记录进入DOM时出错: " + ex.Message;
                return -1;
            }

            strSender = DomUtil.GetElementText(dom.DocumentElement,
                "sender");
            strRecipient = DomUtil.GetElementText(dom.DocumentElement,
                "recipient");
            strSubject = DomUtil.GetElementText(dom.DocumentElement,
                "subject");
            strDate = DomUtil.GetElementText(dom.DocumentElement,
                "date");
            strDate = DateTimeUtil.LocalTime(strDate);

            strSize = DomUtil.GetElementText(dom.DocumentElement,
                "size");
            string strTouched = DomUtil.GetElementText(dom.DocumentElement,
                "touched");
            if (strTouched == "1")
                bTouched = true;
            else
                bTouched = false;

            return 0;
        }
Beispiel #30
0
        // TODO: 是否检查流通信息,需要可以通过参数控制
        // 检索书目记录下属的事项记录,返回少量必要的信息,可以提供后面实做删除时使用
        // parameters:
        //      strStyle    return_record_xml 要在DeleteEntityInfo结构中返回OldRecord内容
        //                  check_circulation_info 检查是否具有流通信息。如果具有则会报错 2012/12/19 把缺省行为变为此参数
        //                  当包含 limit: 时,定义最多取得记录的个数。例如希望最多取得 10 条,可以定义 limit:10
        // return:
        //      -1  error
        //      0   not exist item dbname
        //      1   exist item dbname
        public int SearchChildItems(RmsChannel channel,
            string strBiblioRecPath,
            string strStyle,
            DigitalPlatform.LibraryServer.LibraryApplication.Delegate_checkRecord procCheckRecord,
            object param,
            out long lHitCount,
            out List<DeleteEntityInfo> entityinfos,
            out string strError)
        {
            strError = "";
            lHitCount = 0;
            entityinfos = new List<DeleteEntityInfo>();

            int nRet = 0;

            bool bReturnRecordXml = StringUtil.IsInList("return_record_xml", strStyle);
            bool bCheckCirculationInfo = StringUtil.IsInList("check_circulation_info", strStyle);
            bool bOnlyGetCount = StringUtil.IsInList("only_getcount", strStyle);

            string strLimit = StringUtil.GetParameterByPrefix(strStyle, "limit", ":");

            string strBiblioDbName = ResPath.GetDbName(strBiblioRecPath);
            string strBiblioRecId = ResPath.GetRecordId(strBiblioRecPath);

            // 获得书目库对应的事项库名
            string strItemDbName = "";
            nRet = this.GetItemDbName(strBiblioDbName,
                 out strItemDbName,
                 out strError);
            if (nRet == -1)
                goto ERROR1;

            if (String.IsNullOrEmpty(strItemDbName) == true)
                return 0;

            // 检索实体库中全部从属于特定id的记录

            string strQueryXml = "<target list='"
                + StringUtil.GetXmlStringSimple(strItemDbName + ":" + "父记录")
                + "'><item><word>"
                + strBiblioRecId
                + "</word><match>exact</match><relation>=</relation><dataType>string</dataType><maxCount>-1</maxCount></item><lang>" + "zh" + "</lang></target>";

            long lRet = channel.DoSearch(strQueryXml,
                "entities",
                "", // strOuputStyle
                out strError);
            if (lRet == -1)
                goto ERROR1;

            if (lRet == 0)
            {
                strError = "没有找到属于书目记录 '" + strBiblioRecPath + "' 的任何" + this.ItemName + "记录";
                return 0;
            }

            lHitCount = lRet;

            // 仅返回命中条数
            if (bOnlyGetCount == true)
                return 0;

            int nResultCount = (int)lRet;
            int nMaxCount = 10000;
            if (nResultCount > nMaxCount)
            {
                strError = "命中" + this.ItemName + "记录数 " + nResultCount.ToString() + " 超过 " + nMaxCount.ToString() + ", 暂时不支持针对它们的删除操作";
                goto ERROR1;
            }

            string strColumnStyle = "id,xml,timestamp";

            int nLimit = -1;
            if (string.IsNullOrEmpty(strLimit) == false)
                Int32.TryParse(strLimit, out nLimit);

            int nStart = 0;
            int nPerCount = 100;

            if (nLimit != -1 && nPerCount > nLimit)
                nPerCount = nLimit;

            for (; ; )
            {
#if NO
                List<string> aPath = null;
                lRet = channel.DoGetSearchResult(
                    "entities",
                    nStart,
                    nPerCount,
                    "zh",
                    null,
                    out aPath,
                    out strError);
                if (lRet == -1)
                    goto ERROR1;

                if (aPath.Count == 0)
                {
                    strError = "aPath.Count == 0";
                    goto ERROR1;
                }
#endif
                Record[] searchresults = null;
                lRet = channel.DoGetSearchResult(
    "entities",
    nStart,
    nPerCount,
    strColumnStyle,
    "zh",
    null,
    out searchresults,
    out strError);
                if (lRet == -1)
                    goto ERROR1;
                if (searchresults == null)
                {
                    strError = "searchresults == null";
                    goto ERROR1;
                }
                if (searchresults.Length == 0)
                {
                    strError = "searchresults.Length == 0";
                    goto ERROR1;
                }

                // 获得每条记录
                // for (int i = 0; i < aPath.Count; i++)
                int i = 0;
                foreach (Record record in searchresults)
                {
                    string strMetaData = "";
                    string strXml = "";
                    byte[] timestamp = null;
                    string strOutputPath = "";

                    DeleteEntityInfo entityinfo = new DeleteEntityInfo();

                    if (record.RecordBody == null || string.IsNullOrEmpty(record.RecordBody.Xml) == true)
                    {
                        // TODO: 这里需要改造为直接从结果集中获取 xml,timestamp
                        lRet = channel.GetRes(record.Path,
                            out strXml,
                            out strMetaData,
                            out timestamp,
                            out strOutputPath,
                            out strError);

                        if (lRet == -1)
                        {
                            if (channel.ErrorCode == ChannelErrorCode.NotFound)
                                continue;

                            strError = "获取" + this.ItemName + "记录 '" + record.Path + "' 时发生错误: " + strError;
                            goto ERROR1;
                            // goto CONTINUE;
                        }
                    }
                    else
                    {
                        strXml = record.RecordBody.Xml;
                        strOutputPath = record.Path;
                        timestamp = record.RecordBody.Timestamp;
                    }

                    entityinfo.RecPath = strOutputPath;
                    entityinfo.OldTimestamp = timestamp;
                    if (bReturnRecordXml == true)
                        entityinfo.OldRecord = strXml;

                    if (bCheckCirculationInfo == true
                        || procCheckRecord != null)
                    {
                        // 检查是否有借阅信息
                        // 把记录装入DOM
                        XmlDocument domExist = new XmlDocument();

                        try
                        {
                            domExist.LoadXml(strXml);
                        }
                        catch (Exception ex)
                        {
                            strError = this.ItemName + "记录 '" + record.Path + "' 装载进入DOM时发生错误: " + ex.Message;
                            goto ERROR1;
                        }

                        // 2016/11/15
                        if (procCheckRecord != null)
                        {
                            nRet = procCheckRecord(
                                nStart + i,
                                strOutputPath,
                                domExist,
                                timestamp,
                                param,
                                out strError);
                            if (nRet != 0)
                                return nRet;
                        }

                        /*
                        entityinfo.ItemBarcode = DomUtil.GetElementText(domExist.DocumentElement,
                            "barcode");
                         * */

                        // TODO: 在日志恢复阶段调用本函数时,是否还有必要检查是否具有流通信息?似乎这时应强制删除为好

                        // 观察已经存在的记录是否有流通信息
                        // return:
                        //      -1  出错
                        //      0   没有
                        //      1   有。报错信息在strError中
                        nRet = this.HasCirculationInfo(domExist, out strError);
                        if (nRet == -1)
                            goto ERROR1;
                        if (nRet == 1)
                        {
                            strError = "拟删除的" + this.ItemName + "记录 '" + entityinfo.RecPath + "' 中" + strError + "(此种情况可能不限于这一条),不能删除。因此全部删除操作均被放弃。";
                            goto ERROR1;
                        }
                    }

                    // CONTINUE:
                    entityinfos.Add(entityinfo);

                    i++;
                }

                nStart += searchresults.Length;
                if (nStart >= nResultCount)
                    break;
                if (nLimit != -1 && nStart >= nLimit)
                    break;
            }

            return 1;
        ERROR1:
            return -1;
        }