Пример #1
0
        // 按照字段修改权限定义,合并新旧两个 MARC 记录
        // parameters:
        //      strDefaultOperation   insert/replace/delete 之一或者逗号间隔组合
        // return:
        //      -1  出错
        //      0   成功
        //      1   有部分修改要求被拒绝
        public static int MergeOldNew(
            string strDefaultOperation,
            string strFieldNameList,
            string strOldMarc,
            ref string strNewMarc,
            out string strComment,
            out string strError)
        {
            strError = "";
            strComment = "";
            int nRet = 0;

            if (string.IsNullOrEmpty(strOldMarc) == true && string.IsNullOrEmpty(strNewMarc) == true)
                return 0;

#if NO
            bool bNew = false;
            bool bDelete = false;
            bool bChange = false;

            if (string.IsNullOrEmpty(strAction) == true)
            {
                bNew = true;
                bDelete = true;
                bChange = true;
            }
            else
            {
                bNew = StringUtil.IsInList("new", strAction);
                bDelete = StringUtil.IsInList("delete", strAction);
                bChange = StringUtil.IsInList("change", strAction);
            }
#endif

            string strOldHeader = "";
            string strNewHeader = "";
            string strOldBody = "";
            string strNewBody = "";

            SplitMarc(strOldMarc,
                out strOldHeader,
                out strOldBody);
            SplitMarc(strNewMarc,
                out strNewHeader,
                out strNewBody);

            if (strOldHeader.Length < 24)
                strOldHeader = strOldHeader.PadRight(24, '?');
            if (strNewHeader.Length < 24)
                strNewHeader = strNewHeader.PadRight(24, '?');

#if NO
            FieldNameList list = new FieldNameList();
            nRet = list.Build(strFieldNameList, out strError);
            if (nRet == -1)
            {
                strError = "字段权限定义 '" + strFieldNameList + "' 不合法: " + strError;
                return -1;
            }
#endif
            
            OperationRights rights_table = new OperationRights();
            nRet = rights_table.Build(strFieldNameList,
                strDefaultOperation,
                out strError);
            if (nRet == -1)
            {
                strError = "字段权限定义 '" + strFieldNameList + "' 不合法: " + strError;
                return -1;
            }

            var differ = new MarcDiffer();
            var builder = new MarcDiffBuilder(differ);
            var result = builder.BuildDiffModel(strOldBody, strNewBody);

            Debug.Assert(result.OldText.Lines.Count == result.NewText.Lines.Count, "");

            /*
    public enum ChangeType
    {
        Unchanged,
        Deleted,
        Inserted,
        Imaginary,
        Modified
    }
             * */
            // 字段名如果最后增加了一个 ! 字符,表示这是因为 856 权限原因被拒绝操作的字段。如果 856 字段名后面没有 ! 字符,则表示是因为 fieldnamelist 定义缘故被拒绝的
            // 被拒绝插入的字段名
            List<string> denied_insert_fieldnames = new List<string>();
            // 被拒绝删除的字段名
            List<string> denied_delete_fieldnames = new List<string>();
            // 被拒绝修改的字段名
            List<string> denied_change_fieldnames = new List<string>();

            bool bNotAccepted = false;
            List<string> fields = new List<string>();
            for (int index = 0; index < result.NewText.Lines.Count; index ++ )
            {
                var newline = result.NewText.Lines[index];
                var oldline = result.OldText.Lines[index];

                // 2013/11/18
                if (string.IsNullOrEmpty(newline.Text) == true
    && string.IsNullOrEmpty(oldline.Text) == true)
                    continue;

                string strNewFieldName = GetFieldName(newline.Text);
                // string strOldFieldName = GetFieldName(oldline.Text);

                if (newline.Type == ChangeType.Unchanged)
                {
                    fields.Add(RemoveMask(newline.Text));
                }
                else if (newline.Type == ChangeType.Inserted)
                {
                    Debug.Assert(strNewFieldName != null, "");

                    // 注:有标记的字段不允许插入
                    bool bMask = HasMask(newline.Text);

                    if (rights_table.InsertFieldNames.Contains(strNewFieldName) == true
                        && bMask == false)
                        fields.Add(newline.Text);
                    else
                    {
                        denied_insert_fieldnames.Add(strNewFieldName 
                            + (bMask ? "!" : ""));
                        bNotAccepted = true;
                    }
                }
                else if (newline.Type == ChangeType.Modified)
                {
                    Debug.Assert(strNewFieldName != null, "");

                    Debug.Assert(oldline.Type == ChangeType.Modified, "");

                    // 看新旧字段名是否都在可修改范围内
                    string strOldFieldName = GetFieldName(oldline.Text);
                    Debug.Assert(strOldFieldName != null, "");

                    // 注:如果 new 有标记,说明如果替换后,前端看不到这种替换,所以不允许替换
                    //  如果 old 有标记,则替换会超越权限,等于删除了不应删除的 856
                    //  等于前端只能将能管辖的 856 改成新的也能管辖的状态才被允许
                    bool bMaskNew = HasMask(newline.Text);
                    bool bMaskOld = HasMask(oldline.Text);

                    bool bReserveOld = false;

                    if (rights_table.ReplaceFieldNames.Contains(strNewFieldName) == true
                        && rights_table.ReplaceFieldNames.Contains(strOldFieldName) == true
                        )
                    {
                        if (bMaskNew == false && bMaskOld == false)
                            fields.Add(newline.Text);
                        if (bMaskNew == true && bMaskOld == false)
                        {
                            bReserveOld = true;
                        }
                        if (bMaskNew == false && bMaskOld == true)
                        {
                            // 有时候这种情况:
                            //    111 -> 删除
                            //    222 -> 2222 (修改内容)
                            // 会被识别成
                            //    111 -> 2222 (修改内容)
                            //    222 -> 删除
                            // 这样,第一个修改动作应该不接受。循环到后面,第二个修改正好被接受,所以总体上不会造成 222 重复
                            // 所以,第一个修改此时操作办法:old new 都进去
                            fields.Add(RemoveMask(oldline.Text));
                            fields.Add(newline.Text);
                        }
                        if (bMaskNew == true && bMaskOld == true)
                        {
                            bReserveOld = true;
                        }
                    }
                    
                    if (bReserveOld)
                    {
                        fields.Add(RemoveMask(result.OldText.Lines[index].Text));    // 依然采用修改前的值
                        bNotAccepted = true;

                        denied_change_fieldnames.Add(strOldFieldName
                            + (bMaskNew ? "!" : ""));
                    }
                }
                else if (oldline.Type == ChangeType.Deleted)
                {
                    string strOldFieldName = GetFieldName(oldline.Text);
                    Debug.Assert(strOldFieldName != null, "");

                    // 注:有标记的字段不允许用于删除
                    bool bMask = HasMask(oldline.Text);

                    if (rights_table.DeleteFieldNames.Contains(strOldFieldName) == false
                        || bMask == true)
                    {
                        fields.Add(RemoveMask(oldline.Text));   // 不允许删除

                        // 当具有标记的时候,表示这是因为旧记录中的字段权限禁止当前用户获取,造成前端得不到这个字段,然后在提交保存的时候也就没有这个字段,并不是前端故意要删除这个字段,因而也就不要做 partial_denied 提示了
                        if (bMask == false)
                        {
                            bNotAccepted = true;

                            denied_delete_fieldnames.Add(strOldFieldName
                                + (bMask ? "!" : ""));
                        }
                    }
                    else
                    {
                        // bNotAccepted = true; // BUG
                    }
                }
            }

            StringBuilder text = new StringBuilder(4096);
            if (rights_table.ReplaceFieldNames.Contains("###") == true
                || rights_table.InsertFieldNames.Contains("###") == true)
                text.Append(strNewHeader);
            else
            {
                if (strNewHeader != strOldHeader)
                {
                    bNotAccepted = true;
                    denied_change_fieldnames.Add("###");    // ### 表示头标区
                }
                text.Append(strOldHeader);
            }

            foreach (string s in fields)
            {
                if (string.IsNullOrEmpty(s) == true)
                    continue;
                text.Append(s);
                text.Append((char)30);
            }

            if (denied_insert_fieldnames.Count > 0)
                strComment += "字段 " + StringUtil.MakePathList(denied_insert_fieldnames)+ " 被拒绝插入";

            if (denied_delete_fieldnames.Count > 0)
            {
                if (string.IsNullOrEmpty(strComment) == false)
                    strComment += " ; ";
                strComment += "字段 " + StringUtil.MakePathList(denied_delete_fieldnames) + " 被拒绝删除";
            }

            if (denied_change_fieldnames.Count > 0)
            {
                if (string.IsNullOrEmpty(strComment) == false)
                    strComment += " ; ";
                strComment += "字段 " + StringUtil.MakePathList(denied_change_fieldnames) + " 被拒绝修改";
            }

            strNewMarc = text.ToString();
            if (bNotAccepted == true)
                return 1;
            return 0;
        }
Пример #2
-2
        // 创建展示两个 MARC 记录差异的 HTML 字符串
        // return:
        //      -1  出错
        //      0   成功
        public static int DiffHtml(
            string strOldTitle,
            string strOldMarc,
            string strOldFragmentXml,
            string strOldImageFragment,
            string strNewTitle,
            string strNewMarc,
            string strNewFragmentXml,
            string strNewImageFragment,
            out string strHtml,
            out string strError)
        {
            strError = "";
            strHtml = "";
            // int nRet = 0;

            if (string.IsNullOrEmpty(strOldMarc) == true && string.IsNullOrEmpty(strNewMarc) == true)
                return 0;

            string strOldHeader = "";
            string strNewHeader = "";
            string strOldBody = "";
            string strNewBody = "";

            SplitMarc(strOldMarc,
                out strOldHeader,
                out strOldBody);
            SplitMarc(strNewMarc,
                out strNewHeader,
                out strNewBody);

            if (strOldHeader.Length < 24)
                strOldHeader = strOldHeader.PadRight(24, '?');
            if (strNewHeader.Length < 24)
                strNewHeader = strNewHeader.PadRight(24, '?');

            var marc_differ = new MarcDiffer();
            var marc_builder = new MarcDiffBuilder(marc_differ);
            var marc_diff_result = marc_builder.BuildDiffModel(strOldBody, strNewBody);

            Debug.Assert(marc_diff_result.OldText.Lines.Count == marc_diff_result.NewText.Lines.Count, "");

            /*
    public enum ChangeType
    {
        Unchanged,
        Deleted,
        Inserted,
        Imaginary,
        Modified
    }
             * */

            StringBuilder strResult = new StringBuilder("\r\n<table class='marc'>", 4096);

            if (string.IsNullOrEmpty(strOldTitle) == false
                || string.IsNullOrEmpty(strNewTitle) == false)
            {
                string strLineClass = "header";
                strResult.Append("\r\n<tr class='" + strLineClass + "'>");

                strResult.Append(BuildHeaderHtml(false, strOldTitle));
                strResult.Append(SEP);
                strResult.Append(BuildHeaderHtml(false, strNewTitle));
                strResult.Append("\r\n</tr>");
            }


            {
                string strLineClass = "header";
                bool bModified = strOldHeader != strNewHeader;
                strResult.Append("\r\n<tr class='" + strLineClass + "'>");

                strResult.Append(BuildHeaderHtml(bModified, strOldHeader));
                strResult.Append(SEP);
                strResult.Append(BuildHeaderHtml(bModified, strNewHeader));
                strResult.Append("\r\n</tr>");
            }

            if (string.IsNullOrEmpty(strOldImageFragment) == false
|| string.IsNullOrEmpty(strNewImageFragment) == false)
            {
                string strLineClass = "header";
                strResult.Append("\r\n<tr class='" + strLineClass + "'>");

                strResult.Append(GetImageHtml(strOldImageFragment));
                strResult.Append(SEP);
                strResult.Append(GetImageHtml(strNewImageFragment));
                strResult.Append("\r\n</tr>");
            }


            for (int index = 0; index < marc_diff_result.NewText.Lines.Count; index++)
            {
                var newline = marc_diff_result.NewText.Lines[index];
                var oldline = marc_diff_result.OldText.Lines[index];

                if (string.IsNullOrEmpty(newline.Text) == true
                    && string.IsNullOrEmpty(oldline.Text) == true)
                    continue;

                string strLineClass = "datafield";
                strResult.Append("\r\n<tr class='" + strLineClass + "'>");
                // 创建一个字段的 HTML 局部 三个 <td>
                strResult.Append(BuildFieldHtml( oldline.Type, oldline.Text));
                strResult.Append(SEP);
                strResult.Append(BuildFieldHtml(newline.Type, newline.Text));
                strResult.Append("\r\n</tr>");

#if NO
                if (newline.Type == ChangeType.Unchanged)
                {

                }
                else if (newline.Type == ChangeType.Inserted)
                {

                }
                else if (newline.Type == ChangeType.Modified)
                {

                }
                else if (oldline.Type == ChangeType.Deleted)
                {

                }
#endif
            }

#if NO
            if (string.IsNullOrEmpty(strOldFragmentXml) == false || string.IsNullOrEmpty(strNewFragmentXml) == false)
            {
                var xml_differ = new Differ();
                var xml_builder = new SideBySideDiffBuilder(xml_differ);
                var xml_diff_result = xml_builder.BuildDiffModel(GetComparableXmlString(strOldFragmentXml), GetComparableXmlString(strNewFragmentXml));

                Debug.Assert(xml_diff_result.OldText.Lines.Count == xml_diff_result.NewText.Lines.Count, "");

                for (int index = 0; index < xml_diff_result.NewText.Lines.Count; index++)
                {
                    var newline = xml_diff_result.NewText.Lines[index];
                    var oldline = xml_diff_result.OldText.Lines[index];

                    string strLineClass = "datafield";

                    if (newline.Type == ChangeType.Modified)
                    {

                    }

                    strResult.Append("\r\n<tr class='" + strLineClass + "'>");
                    // 创建一个 XML 字段的 HTML 局部 三个 <td>
                    strResult.Append(BuildFragmentFieldHtml(oldline.Type, oldline.Text));
                strResult.Append(SEP);
                    strResult.Append(BuildFragmentFieldHtml(newline.Type, newline.Text));
                    strResult.Append("\r\n</tr>");
                }

            }
#endif

            if (string.IsNullOrEmpty(strOldFragmentXml) == false || string.IsNullOrEmpty(strNewFragmentXml) == false)
            {
                string strLineClass = "sepline";
                strResult.Append("\r\n<tr class='" + strLineClass + "'>");
                strResult.Append("<td class='sepline' colspan='3'>&nbsp;</td>");
                strResult.Append("<td class='cross'>&nbsp;</td>");
                strResult.Append("<td class='sepline' colspan='3'>&nbsp;</td>");
                strResult.Append("\r\n</tr>");
            }

            strResult.Append(DiffXml(
                0,
                strOldFragmentXml,
                XmlNodeType.Element,
                strNewFragmentXml,
                XmlNodeType.Element));

            strResult.Append("</table>");
            strHtml = strResult.ToString();

            return 0;
        }