using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Data.SqlClient; using System.Text.RegularExpressions; namespace FindLinx { public partial class frmFindLinx : Form { public frmFindLinx() { InitializeComponent(); } public string MyStatus { get { return tsslStatus.Text; } set { tsslStatus.Text = value; Application.DoEvents(); } } private static string _SelectedDatabase = null; public static string SelectedDatabase { get { return frmFindLinx._SelectedDatabase; } set { frmFindLinx._SelectedDatabase = value; _ConnectionString = _MenuConnectionString.Replace("{MENU}", SelectedDatabase); } } private static string _MenuConnectionString = @"Data Source=VOLIAN-SERVER;User Id=proms2010;password=proms2010;Initial Catalog={MENU}"; private static string _ConnectionString = null; private Dictionary _MyContents = null; private void chooseDBToolStripMenuItem_Click(object sender, EventArgs e) { ChooseDatabase(); findLinxToolStripMenuItem.Enabled = true; LoadContents(); ResetLinks(); FindLinks(); //ShowLinks(SelectedDatabase); } private void ChooseDatabase() { System.Windows.Forms.ContextMenuStrip cms = BuildDatabaseMenu(); SelectedDatabase = null; while (SelectedDatabase == null) { cms.Show(new System.Drawing.Point((System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width - cms.Width) / 2, (System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height - cms.Height) / 2)); System.Windows.Forms.Application.DoEvents(); } } private static System.Windows.Forms.ContextMenuStrip BuildDatabaseMenu() { System.Windows.Forms.ContextMenuStrip cms = new System.Windows.Forms.ContextMenuStrip(); cms.Items.Add("Choose Database"); System.Windows.Forms.ToolStripMenuItem tsmi = cms.Items[0] as System.Windows.Forms.ToolStripMenuItem; tsmi.BackColor = System.Drawing.Color.FromKnownColor(System.Drawing.KnownColor.ActiveCaption);// System.Drawing.Color.Pink; tsmi.ForeColor = System.Drawing.Color.FromKnownColor(System.Drawing.KnownColor.ActiveCaptionText); tsmi.Font = new System.Drawing.Font(tsmi.Font, System.Drawing.FontStyle.Bold); foreach (string name in DBNames) cms.Items.Add(name, null, new EventHandler(Database_Click)); return cms; } private static List _DBNames; public static List DBNames { get { if (_DBNames == null) _DBNames = GetDatabases(); return _DBNames; } } private static List GetDatabases() { List dbNames; dbNames = new List(); SelectedDatabase = "master"; SqlConnection cn = new SqlConnection(_ConnectionString); cn.Open(); // SqlDataAdapter da = new SqlDataAdapter("select name from sysdatabases where name like 'VEP%' order by name", cn); //SqlDataAdapter da = new SqlDataAdapter("select name, case when object_id('[' + name + ']..Items') is null then 'Not PROMS' when object_id('[' + name + ']..Revisions') is not null then 'Approval' when object_id('[' + name + ']..ContentAudits') is not null then 'Change Manager' else 'Original' end functionality from sysdatabases where name not in ('master','model','msdb','tempdb') order by name", cn); SqlDataAdapter da = new SqlDataAdapter("select name from sysdatabases where name not in ('master','model','msdb','tempdb') and name like 'VEPROMS%' order by name", cn); da.SelectCommand.CommandTimeout = 300; // 300 sec timeout DataSet ds = new DataSet(); try { da.Fill(ds); } catch (Exception ex) { System.Windows.Forms.MessageBox.Show(ex.GetType().Name, ex.Message); throw (new Exception("Cannot Load Data List", ex)); } cn.Close(); foreach (DataRow dr in ds.Tables[0].Rows) dbNames.Add(dr["name"].ToString()); return dbNames; } private static void Database_Click(object sender, EventArgs e) { System.Windows.Forms.ToolStripMenuItem tsmi = sender as System.Windows.Forms.ToolStripMenuItem; if (tsmi != null) { SelectedDatabase = tsmi.Text; } } private void findLinxToolStripMenuItem_Click(object sender, EventArgs e) { FindLinks(); } private Dictionary DicPrefix; private Dictionary DicSuffix; private void ResetLinks() { DicPrefix = new Dictionary(); DicSuffix = new Dictionary(); } private void ShowLinks(string selectedDatabase) { tbResults.Clear(); SortedList srtPrefixes = new SortedList(new DegreeComparer()); foreach (string pre in DicPrefix.Keys) { srtPrefixes.Add(-DicPrefix[pre], pre); } tbResults.AppendText(string.Format("{0} Prefixes\r\n", selectedDatabase)); foreach (string pre in srtPrefixes.Values) { tbResults.AppendText(string.Format("{0},'{1}'\r\n", DicPrefix[pre], pre)); } SortedList srtSuffixes = new SortedList(new DegreeComparer()); foreach (string suf in DicSuffix.Keys) { srtSuffixes.Add(-DicSuffix[suf], suf); } tbResults.AppendText(string.Format("\r\n{0} Suffixes\r\n", selectedDatabase)); foreach (string suf in srtSuffixes.Values) { tbResults.AppendText(string.Format("{0},'{1}'\r\n", DicSuffix[suf], suf)); } } private void FindLinks() { // loop through contents foreach (int ic in _MyContents.Keys)// for each content record { string Text = _MyContents[ic]; // find all links //string findLink = @""; // need to only process transitions (no ros) string findLink = @""; // need to only process transitions (no ros) MatchCollection ms = Regex.Matches(Text, findLink); int ii = 0; foreach (Match mlink in ms)// for each link { if (mlink.ToString().Contains("#Link:T")) { string key = string.Format("{0}.{1}.{2}", _SelectedDatabase, ic, ii); if (key == "VEPROMS_BWD.16964.0") Console.WriteLine("Here"); string oldval = OldTransitionValue(mlink.ToString()); string newval = NewTransitionValue(mlink.ToString()); //if (oldval != newval && (!(oldval == "" && newval.Contains("Prerequisite {Prereq")) && !oldval.Contains("{First Step")) && !oldval.Contains("{Page Num")) tbResults.AppendText(string.Format("'{0}','{1}','{2}'\r\n", _SelectedDatabase, oldval, newval)); if (oldval != newval) tbResults.AppendText(string.Format("'{0}','{1}','{2}','{3}'\r\n", _SelectedDatabase, oldval, newval, mlink.ToString())); ii++; // instance of transition } } } } private string OldTransitionValue(string _TextAndLink) { Match m = Regex.Match(_TextAndLink, @""); return m.Groups[3].ToString(); } private string NewTransitionValue(string _TextAndLink) { Match m = Regex.Match(_TextAndLink, @""); // get value string including formatting. string mtxt = m.Groups[1].ToString(); mtxt = Regex.Replace(mtxt, @"^(\\[^v \\]+)*\\v0", ""); // replace the rtf commands that occur prior to the value string if (mtxt.StartsWith(" ")) mtxt = mtxt.Substring(1); mtxt = Regex.Replace(mtxt, @"\\v(\\[^v \\]+)* $", ""); // replace the rtf commands that occur after to the value string mtxt = Regex.Replace(mtxt, @"(\\ulnone|\\b0)+$", ""); return mtxt; } private string GetValuePrefix(string Text, Match mlink, int lastlink) { throw new Exception("The method or operation is not implemented."); } private string SuffixPattern(string suffix) { string firstchar = ""; suffix = suffix.Replace("\r", "{CR}"); suffix = suffix.Replace("\n", "{LF}"); if (Regex.IsMatch(suffix, @"^(\\(b0|b|ulnone|ul))+\\")) { firstchar = "{RTFCommand}"; suffix = Regex.Replace(suffix, @"^(\\(b0|b|ulnone|ul))+", ""); } if (suffix == @"\v0 ") return @"Pattern','" + firstchar + @"\v0{Space}"; if (suffix == @"\v0") return @"Pattern','" + firstchar + @"\v0"; return _SelectedDatabase + "','" + suffix; } private string GetSuffix(string Text, Match mlink, int iEnd) { int iStart = mlink.Index + mlink.Length; //int iEnd = (mlink.NextMatch() == null) ? Text.Length : mlink.NextMatch().Index; string follows = Text.Substring(iStart,iEnd-iStart); int iEndComment = follows.IndexOf("\\v0"); if (follows.Length > 3 + iEndComment) { if (follows.Substring(iEndComment + 3, 1) == " ") return follows.Substring(0, iEndComment + 4); if (follows.Substring(iEndComment + 3, 1) == "\\") return follows.Substring(0, iEndComment + 3); return follows.Substring(0, iEndComment + 3); } return follows; } public class DegreeComparer : IComparer { #region IComparer Members public int Compare(int x, int y) { if (x < y) return -1; else return 1; } #endregion } private string PrefixPattern(string prefix) { string firstchar = ""; if(prefix.StartsWith(" ")) { firstchar = "{Space}"; prefix = prefix.Substring(1); } else if (prefix.StartsWith("\n")) { firstchar = "{Newline}"; prefix = prefix.Substring(1); } else if (prefix.StartsWith("\xa0")) { firstchar = "{HardSpace}"; prefix = prefix.Substring(1); } else if (Regex.IsMatch(prefix, @"^\\u[0-9]{1,4}\?")) { firstchar = "{Unicode}"; prefix=Regex.Replace(prefix, @"^\\u[0-9]{1,4}\?",""); } else if (Regex.IsMatch(prefix, @"^\\'[0-9a-fA-F]{2}")) { firstchar = "{Hexcode}"; prefix = Regex.Replace(prefix, @"^\\'[0-9a-fA-F]{2}", ""); } else if (Regex.IsMatch(prefix, @"^[:.()\[\]""*=<>]")) { firstchar = "{Punctuation}"; prefix = Regex.Replace(prefix, @"^[:.()\[\]""*=<>]", ""); } else if (Regex.IsMatch(prefix, @"^\\[{}~]")) { firstchar = "{Special}"; prefix = Regex.Replace(prefix, @"^\\[{}~]", ""); } else if (Regex.IsMatch(prefix, @"^\\(b0|b|ulnone|ul|line)\\")) { firstchar = "{RTFCommand}"; prefix = Regex.Replace(prefix, @"^\\(b0|b|ulnone|ul|line)", ""); } if (prefix == @"\v ") return @"Pattern','" + firstchar +@"\v "; //if (prefix == @" \v ") // return @"Pattern-{Space}\v "; //if (prefix == "\xA0\\v ") // return @"Pattern-{HardSpace}\v "; //if (Regex.IsMatch(prefix, @"^\\u[0-9]{1,4}\?\\v $")) // return @"Pattern-" + firstchar + @"{Unicode}\v "; //if (Regex.IsMatch(prefix, @"^\\u[0-9]{1,4}\?.*\\v $")) // return @"Pattern-" + firstchar + @"{Unicode}{Text}\v "; // if (Regex.IsMatch(prefix, @"^\\[{}~]\\v $")) // return @"Pattern-" + firstchar + @"{Special}\v "; // if (Regex.IsMatch(prefix, @"^ ?[()""\[\]]\\v $")) // return @"Pattern-" + firstchar + @"{Puctuation}\v "; if (Regex.IsMatch(prefix, @"^ ?[-%A-Za-z0-9.,/()\[\]]+\\v $")) return @"Pattern','" + firstchar + @"{Text}\v "; //if (prefix == "\n\\v ") // return @"Pattern-{Newline}\v "; return SelectedDatabase + "','" + prefix; } private string GetPrefix(string Text, Match mlink, int lastlink) { string precedes = Text.Substring(lastlink, mlink.Index - lastlink); if(mlink.Index - lastlink <= 3) return precedes; if (precedes.EndsWith(@"\v ")) { //int indexSpace = Text.LastIndexOf(' ', mlink.Index - 4); ////if (indexSpace > mlink.Index) indexSpace = 0; //int indexCR = Text.LastIndexOf('\n', mlink.Index - 4); ////if (indexCR > mlink.Index) indexCR = 0; //if (indexCR >= 0 && indexCR > indexSpace) // indexSpace = indexCR; //int indexHS = Text.LastIndexOf('\xA0', mlink.Index - 4); ////if (indexHS > mlink.Index) indexHS = 0; //if (indexHS >= 0 && indexHS > indexSpace) // indexSpace = indexHS; int indexSpace = Text.LastIndexOfAny(" \n\xA0:.()[]\"<>*=".ToCharArray(), mlink.Index - 4); int indexSlash = Text.LastIndexOf('\\', mlink.Index - 4); if (indexSlash >= 0) { if (indexSlash > indexSpace) return Text.Substring(indexSlash, mlink.Index - indexSlash); } if (indexSpace >= 0) { return Text.Substring(indexSpace, mlink.Index - indexSpace); } } return precedes; } private void LoadContents() { SqlConnection cn = new SqlConnection(_ConnectionString); cn.Open(); //SqlDataAdapter da = new SqlDataAdapter("select ContentID,Text from Contents where ContentID in(select fromID from transitions union select contentid from rousages)", cn); SqlDataAdapter da = new SqlDataAdapter("select ContentID,Text from Contents where ContentID in(select fromID from transitions)", cn); da.SelectCommand.CommandTimeout = 300; // 300 sec timeout DataSet ds = new DataSet(); try { da.Fill(ds); _MyContents = new Dictionary(); foreach (DataRow dr in ds.Tables[0].Rows) { _MyContents.Add((int)dr["ContentID"], dr["Text"].ToString()); } //MessageBox.Show(string.Format("{0} Content Records Found", ds.Tables[0].Rows.Count), "Contents Loaded", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (Exception ex) { System.Windows.Forms.MessageBox.Show(ex.Message, ex.GetType().Name, MessageBoxButtons.OK, MessageBoxIcon.Error); throw (new Exception("Cannot Load Data List", ex)); } cn.Close(); } private void allDBsToolStripMenuItem_Click(object sender, EventArgs e) { DateTime tStart = DateTime.Now; ResetLinks(); foreach (string dbName in DBNames) { SelectedDatabase = dbName; LoadContents(); MyStatus = string.Format("{0} - {1} Contents", SelectedDatabase, _MyContents.Count); FindLinks(); } //ShowLinks("All Databases"); DateTime tEnd = DateTime.Now; TimeSpan ts = TimeSpan.FromTicks(tEnd.Ticks - tStart.Ticks); MyStatus = string.Format("{0:0.000} Seconds", ts.TotalSeconds); } private void exitToolStripMenuItem_Click(object sender, EventArgs e) { this.Close(); } } }