378 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			378 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| 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<int, string> _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<string> _DBNames;
 | |
| 		public static List<string> DBNames
 | |
| 		{
 | |
| 			get 
 | |
| 			{
 | |
| 				if (_DBNames == null)
 | |
| 					_DBNames = GetDatabases();
 | |
| 				return _DBNames; 
 | |
| 			}
 | |
| 		}
 | |
| 		private static List<string> GetDatabases()
 | |
| 		{
 | |
| 			List<string> dbNames;
 | |
| 			dbNames = new List<string>();
 | |
| 			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<string, int> DicPrefix;
 | |
| 		private Dictionary<string, int> DicSuffix;
 | |
| 		private void ResetLinks()
 | |
| 		{
 | |
| 			DicPrefix = new Dictionary<string, int>();
 | |
| 			DicSuffix = new Dictionary<string, int>();
 | |
| 		}
 | |
| 		private void ShowLinks(string selectedDatabase)
 | |
| 		{
 | |
| 			tbResults.Clear();
 | |
| 			SortedList<int, string> srtPrefixes = new SortedList<int, string>(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<int, string> srtSuffixes = new SortedList<int, string>(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 = @"<START\](.*?)#Link:T(.*?)\[END>";  // need to only process transitions (no ros)
 | |
| 				string findLink = @"<START\](.*?)\[END>";  // 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, @"<START\](\\[^v \\]+)*\\v0(\\[^v \{\\]+)* (.*?)(\\[^v'? \\]+)*\\v(\\[^v \\]+)* #Link:(.*?)\[END>");
 | |
| 			return m.Groups[3].ToString();
 | |
| 		}
 | |
| 		private string NewTransitionValue(string _TextAndLink)
 | |
| 		{
 | |
| 			Match m = Regex.Match(_TextAndLink, @"<START\](.*?)#Link:(.*?)\[END>");  // 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<int>
 | |
| 		{
 | |
| 			#region IComparer<int> 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<int, string>();
 | |
| 				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();
 | |
| 		}
 | |
| 	}
 | |
| } |