adapdev-commits Mailing List for Adapdev.NET (Page 7)
Status: Beta
Brought to you by:
intesar66
You can subscribe to this list here.
2005 |
Jan
|
Feb
|
Mar
(26) |
Apr
(59) |
May
(37) |
Jun
(53) |
Jul
(13) |
Aug
(7) |
Sep
(5) |
Oct
(74) |
Nov
(404) |
Dec
(14) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2006 |
Jan
(10) |
Feb
(26) |
Mar
(64) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Sean M. <int...@us...> - 2005-11-26 08:09:33
|
Update of /cvsroot/adapdev/Adapdev/src/Adapdev.UnitTest.Core In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18792/src/Adapdev.UnitTest.Core Modified Files: LocalSeparateTestEngine.cs RunTestCommand.cs TestSuiteBuilder.cs Log Message: Cleaned up several warnings Restored some lingering files Index: TestSuiteBuilder.cs =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev.UnitTest.Core/TestSuiteBuilder.cs,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** TestSuiteBuilder.cs 23 Nov 2005 03:00:42 -0000 1.14 --- TestSuiteBuilder.cs 26 Nov 2005 08:09:23 -0000 1.15 *************** *** 49,54 **** public class TestSuiteBuilder : MarshalByRefObject { - // unique id for the specified test - private int id = 0; // list of assembly dependencies for the current assembly private Hashtable dependencyList = new Hashtable(); --- 49,52 ---- Index: LocalSeparateTestEngine.cs =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev.UnitTest.Core/LocalSeparateTestEngine.cs,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** LocalSeparateTestEngine.cs 16 Nov 2005 07:01:53 -0000 1.5 --- LocalSeparateTestEngine.cs 26 Nov 2005 08:09:23 -0000 1.6 *************** *** 10,14 **** public class LocalSeparateTestEngine : ITestEngine { ! private TestSuite suite; private AppDomainManager manager; private string assembly; --- 10,14 ---- public class LocalSeparateTestEngine : ITestEngine { ! private TestSuite suite = null; private AppDomainManager manager; private string assembly; Index: RunTestCommand.cs =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev.UnitTest.Core/RunTestCommand.cs,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** RunTestCommand.cs 23 Nov 2005 03:00:42 -0000 1.5 --- RunTestCommand.cs 26 Nov 2005 08:09:23 -0000 1.6 *************** *** 8,12 **** using Adapdev.Diagnostics; using Adapdev.Threading; - using Adapdev.Threading; using log4net; --- 8,11 ---- |
From: Sean M. <int...@us...> - 2005-11-26 08:09:33
|
Update of /cvsroot/adapdev/Adapdev/src/Adapdev.Windows.Forms/Progress In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18792/src/Adapdev.Windows.Forms/Progress Modified Files: ProgressWindow.cs Log Message: Cleaned up several warnings Restored some lingering files Index: ProgressWindow.cs =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev.Windows.Forms/Progress/ProgressWindow.cs,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** ProgressWindow.cs 16 Nov 2005 07:02:01 -0000 1.4 --- ProgressWindow.cs 26 Nov 2005 08:09:23 -0000 1.5 *************** *** 259,263 **** } listView.Items.Add(li); ! if (firstMsg = true) { firstMsg = false; this.morelessButton.Enabled = !(this.listView.Items.Count == 0); --- 259,263 ---- } listView.Items.Add(li); ! if (firstMsg == true) { firstMsg = false; this.morelessButton.Enabled = !(this.listView.Items.Count == 0); |
From: Sean M. <int...@us...> - 2005-11-26 08:09:33
|
Update of /cvsroot/adapdev/Adapdev/src/Adapdev.NVelocity/Util In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18792/src/Adapdev.NVelocity/Util Modified Files: StringUtils.cs Log Message: Cleaned up several warnings Restored some lingering files Index: StringUtils.cs =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev.NVelocity/Util/StringUtils.cs,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** StringUtils.cs 16 Nov 2005 07:01:52 -0000 1.5 --- StringUtils.cs 26 Nov 2005 08:09:23 -0000 1.6 *************** *** 576,580 **** foo = new String(tmpChar); } ! catch (Exception f) { // Do nothing. --- 576,580 ---- foo = new String(tmpChar); } ! catch (Exception) { // Do nothing. |
From: Sean M. <int...@us...> - 2005-11-26 08:09:33
|
Update of /cvsroot/adapdev/Adapdev/src/Adapdev In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18792/src/Adapdev Modified Files: Util.cs Log Message: Cleaned up several warnings Restored some lingering files Index: Util.cs =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev/Util.cs,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** Util.cs 16 Nov 2005 07:02:01 -0000 1.5 --- Util.cs 26 Nov 2005 08:09:23 -0000 1.6 *************** *** 65,69 **** } } ! catch (Exception e) { throw; --- 65,69 ---- } } ! catch (Exception) { throw; *************** *** 89,93 **** } } ! catch (Exception e) { throw; --- 89,93 ---- } } ! catch (Exception) { throw; |
From: Sean M. <int...@us...> - 2005-11-26 08:09:33
|
Update of /cvsroot/adapdev/Adapdev/src/Adapdev.Tests/XPath In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18792/src/Adapdev.Tests/XPath Modified Files: XPathObjectNavigatorTest.cs Log Message: Cleaned up several warnings Restored some lingering files Index: XPathObjectNavigatorTest.cs =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev.Tests/XPath/XPathObjectNavigatorTest.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** XPathObjectNavigatorTest.cs 16 Nov 2005 07:01:53 -0000 1.3 --- XPathObjectNavigatorTest.cs 26 Nov 2005 08:09:23 -0000 1.4 *************** *** 219,223 **** /// </summary> [TestFixture] ! public class XPathObjectNavigatorTest : Assertion { [Test] --- 219,223 ---- /// </summary> [TestFixture] ! public class XPathObjectNavigatorTest : Assert { [Test] *************** *** 229,245 **** XPathObjectNavigator context = new XPathObjectNavigator(customer); XPathNodeIterator i = context.Select("/Customer/Address/Street"); ! AssertEquals(1, i.Count); ! AssertEquals(true, i.MoveNext()); ! AssertEquals(customer.Address.Street, i.Current.Value); ! AssertEquals(customer.Address.Street, ((XPathObjectNavigator)i.Current).Node); i = context.Select("FirstName"); ! AssertEquals(1, i.Count); ! AssertEquals(true, i.MoveNext()); ! AssertEquals(customer.FirstName, i.Current.Value); i = context.Select("/Customer/LastName"); ! AssertEquals(true, i.MoveNext()); ! AssertEquals(customer.LastName, i.Current.Value); } --- 229,245 ---- XPathObjectNavigator context = new XPathObjectNavigator(customer); XPathNodeIterator i = context.Select("/Customer/Address/Street"); ! Assert.AreEqual(1, i.Count); ! Assert.AreEqual(true, i.MoveNext()); ! Assert.AreEqual(customer.Address.Street, i.Current.Value); ! Assert.AreEqual(customer.Address.Street, ((XPathObjectNavigator)i.Current).Node); i = context.Select("FirstName"); ! Assert.AreEqual(1, i.Count); ! Assert.AreEqual(true, i.MoveNext()); ! Assert.AreEqual(customer.FirstName, i.Current.Value); i = context.Select("/Customer/LastName"); ! Assert.AreEqual(true, i.MoveNext()); ! Assert.AreEqual(customer.LastName, i.Current.Value); } *************** *** 264,282 **** Order[] orders = new Order[] { o1, o2 }; XPathObjectNavigator navigator = new XPathObjectNavigator(orders, "Orders"); ! AssertEquals(2, navigator.Select("//Order").Count); ! AssertEquals(2, navigator.Select("Order").Count); ! AssertEquals(o1, navigator.SelectObject("Order[1]")); ! AssertEquals(o2, navigator.SelectObject("Order[2]")); ! AssertEquals(o1, navigator.SelectObject("//Order[Customer/FirstName='Rodrigo']")); ! AssertEquals(o2, navigator.SelectObject("//Order[Customer/LastName='Longo']")); XPathNodeIterator i = navigator.Select("//Product[Name='egg']"); ! AssertEquals(2, i.Count); ! AssertEquals(true, i.MoveNext()); ! AssertEquals(p1, ((XPathObjectNavigator)i.Current).Node); ! AssertEquals(o2.Items[0], navigator.SelectObject("//OrderItem[Quantity>10]")); ! AssertEquals(p2, navigator.SelectObject("//Product[Categories/String='Silly Stuff']")); } --- 264,282 ---- Order[] orders = new Order[] { o1, o2 }; XPathObjectNavigator navigator = new XPathObjectNavigator(orders, "Orders"); ! Assert.AreEqual(2, navigator.Select("//Order").Count); ! Assert.AreEqual(2, navigator.Select("Order").Count); ! Assert.AreEqual(o1, navigator.SelectObject("Order[1]")); ! Assert.AreEqual(o2, navigator.SelectObject("Order[2]")); ! Assert.AreEqual(o1, navigator.SelectObject("//Order[Customer/FirstName='Rodrigo']")); ! Assert.AreEqual(o2, navigator.SelectObject("//Order[Customer/LastName='Longo']")); XPathNodeIterator i = navigator.Select("//Product[Name='egg']"); ! Assert.AreEqual(2, i.Count); ! Assert.AreEqual(true, i.MoveNext()); ! Assert.AreEqual(p1, ((XPathObjectNavigator)i.Current).Node); ! Assert.AreEqual(o2.Items[0], navigator.SelectObject("//OrderItem[Quantity>10]")); ! Assert.AreEqual(p2, navigator.SelectObject("//Product[Categories/String='Silly Stuff']")); } *************** *** 288,292 **** XPathObjectNavigator navigator = new XPathObjectNavigator(customer); ! AssertEquals(customer.Properties["email"], navigator.SelectObject("Properties/email")); } --- 288,292 ---- XPathObjectNavigator navigator = new XPathObjectNavigator(customer); ! Assert.AreEqual(customer.Properties["email"], navigator.SelectObject("Properties/email")); } *************** *** 301,307 **** XPathObjectNavigator navigator = new XPathObjectNavigator(customers); object[] actual = navigator.SelectObjects("Customer[Address/Number = 45]"); ! AssertEquals(2, actual.Length); ! AssertEquals(customer1, actual[0]); ! AssertEquals(customer2, actual[1]); } --- 301,307 ---- XPathObjectNavigator navigator = new XPathObjectNavigator(customers); object[] actual = navigator.SelectObjects("Customer[Address/Number = 45]"); ! Assert.AreEqual(2, actual.Length); ! Assert.AreEqual(customer1, actual[0]); ! Assert.AreEqual(customer2, actual[1]); } *************** *** 313,319 **** XPathObjectNavigator navigator = new XPathObjectNavigator(customer1); ! AssertSame(customer1.Email, navigator.SelectObject("Email")); ! AssertSame(customer1, navigator.SelectObject("/Customer[Email='rb...@ac...']")); } } --- 313,319 ---- XPathObjectNavigator navigator = new XPathObjectNavigator(customer1); ! Assert.AreSame(customer1.Email, navigator.SelectObject("Email")); ! Assert.AreSame(customer1, navigator.SelectObject("/Customer[Email='rb...@ac...']")); } } |
From: Sean M. <int...@us...> - 2005-11-26 08:09:33
|
Update of /cvsroot/adapdev/Adapdev/src/Adapdev.Tests/Text/Indexing In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18792/src/Adapdev.Tests/Text/Indexing Modified Files: FullTextSearchTests.cs SearchResultTest.cs StringTokenizerTest.cs TokenAssertions.cs WordFilterTest.cs Log Message: Cleaned up several warnings Restored some lingering files Index: FullTextSearchTests.cs =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev.Tests/Text/Indexing/FullTextSearchTests.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** FullTextSearchTests.cs 16 Nov 2005 07:01:53 -0000 1.3 --- FullTextSearchTests.cs 26 Nov 2005 08:09:23 -0000 1.4 *************** *** 43,47 **** /// </summary> [TestFixture] ! public class FullTextSearchTests : Assertion { IIndex _index; --- 43,47 ---- /// </summary> [TestFixture] ! public class FullTextSearchTests : Assert { IIndex _index; *************** *** 98,103 **** _index.Clear(); ! AssertEquals(0, ((FullTextSearchIndex)_index).Records.Length); ! AssertEquals(0, ((FullTextSearchIndex)_index).Postings.Length); AssertSearchContains(_index.Search(new FullTextSearchExpression("chocolate"))); --- 98,103 ---- _index.Clear(); ! Equals(0, ((FullTextSearchIndex)_index).Records.Length); ! Equals(0, ((FullTextSearchIndex)_index).Postings.Length); AssertSearchContains(_index.Search(new FullTextSearchExpression("chocolate"))); *************** *** 216,220 **** FullTextSearchIndex index = _index as FullTextSearchIndex; IRecord[] records = index.Records; ! AssertEquals(3, records.Length); _record1 = FindByTitle(records, (string)_record1["Title"]); _record2 = FindByTitle(records, (string)_record2["Title"]); --- 216,220 ---- FullTextSearchIndex index = _index as FullTextSearchIndex; IRecord[] records = index.Records; ! Equals(3, records.Length); _record1 = FindByTitle(records, (string)_record1["Title"]); _record2 = FindByTitle(records, (string)_record2["Title"]); *************** *** 245,249 **** } } ! AssertEquals("result.Count", expected.Length, result.Count); } --- 245,249 ---- } } ! Assert.AreEqual(expected.Length, result.Count, "result.Count"); } Index: StringTokenizerTest.cs =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev.Tests/Text/Indexing/StringTokenizerTest.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** StringTokenizerTest.cs 16 Nov 2005 07:01:53 -0000 1.3 --- StringTokenizerTest.cs 26 Nov 2005 08:09:23 -0000 1.4 *************** *** 42,46 **** /// </summary> [TestFixture] ! public class StringTokenizerTest : Assertion { [Test] --- 42,46 ---- /// </summary> [TestFixture] ! public class StringTokenizerTest : Assert { [Test] Index: SearchResultTest.cs =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev.Tests/Text/Indexing/SearchResultTest.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** SearchResultTest.cs 16 Nov 2005 07:01:53 -0000 1.3 --- SearchResultTest.cs 26 Nov 2005 08:09:23 -0000 1.4 *************** *** 70,74 **** /// </summary> [TestFixture] ! public class SearchResultTest : Assertion { HashtableRecord _record1; --- 70,74 ---- /// </summary> [TestFixture] ! public class SearchResultTest : Assert { HashtableRecord _record1; *************** *** 97,104 **** { HashtableRecord[] records = (HashtableRecord[])_result.ToRecordArray(typeof(HashtableRecord)); ! AssertEquals(3, records.Length); ! AssertSame(_record1, records[0]); ! AssertSame(_record2, records[1]); ! AssertSame(_record3, records[2]); } --- 97,104 ---- { HashtableRecord[] records = (HashtableRecord[])_result.ToRecordArray(typeof(HashtableRecord)); ! Assert.AreEqual(3, records.Length); ! Assert.AreSame(_record1, records[0]); ! Assert.AreSame(_record2, records[1]); ! Assert.AreSame(_record3, records[2]); } *************** *** 141,145 **** AssertSearchHits(_result.Intersect(other), _record2); ! AssertEquals(0, _result.Intersect(new SearchResult()).Count); AssertSearchHits(_result.Intersect(_result), _record1, _record2, _record3); } --- 141,145 ---- AssertSearchHits(_result.Intersect(other), _record2); ! Assert.AreEqual(0, _result.Intersect(new SearchResult()).Count); AssertSearchHits(_result.Intersect(_result), _record1, _record2, _record3); } *************** *** 152,156 **** foreach (SearchHit hit in _result) { ! AssertEquals(expected[i++], hit.Record); } } --- 152,156 ---- foreach (SearchHit hit in _result) { ! Assert.AreEqual(expected[i++], hit.Record); } } *************** *** 158,167 **** void AssertSearchHits(SearchResult result, params IRecord[] expectedRecords) { ! AssertEquals(expectedRecords.Length, result.Count); for (int i=0; i<expectedRecords.Length; ++i) { IRecord expected = expectedRecords[i]; IRecord actual = result[i].Record; ! AssertEquals(string.Format("{0} != {1}", expected["Name"], actual["Name"]), expected, actual); } } --- 158,167 ---- void AssertSearchHits(SearchResult result, params IRecord[] expectedRecords) { ! Assert.AreEqual(expectedRecords.Length, result.Count); for (int i=0; i<expectedRecords.Length; ++i) { IRecord expected = expectedRecords[i]; IRecord actual = result[i].Record; ! //Assert.AreEqual(string.Format("{0} != {1}", expected["Name"], actual["Name"]), expected, actual); } } Index: TokenAssertions.cs =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev.Tests/Text/Indexing/TokenAssertions.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** TokenAssertions.cs 16 Nov 2005 07:01:53 -0000 1.3 --- TokenAssertions.cs 26 Nov 2005 08:09:23 -0000 1.4 *************** *** 55,59 **** foreach (Token expected in tokens) { ! Assertion.AssertEquals(expected, actual.NextToken()); } } --- 55,59 ---- foreach (Token expected in tokens) { ! Assert.AreEqual(expected, actual.NextToken()); } } *************** *** 63,67 **** foreach (Token expected in tokens) { ! Assertion.AssertEquals(expected, tokenizer.NextToken()); } } --- 63,67 ---- foreach (Token expected in tokens) { ! Assert.AreEqual(expected, tokenizer.NextToken()); } } *************** *** 71,77 **** foreach (string value in expectedValues) { ! Assertion.AssertEquals(value, tokenizer.NextToken().Value); } ! Assertion.AssertNull(tokenizer.NextToken()); } --- 71,77 ---- foreach (string value in expectedValues) { ! Assert.AreEqual(value, tokenizer.NextToken().Value); } ! Assert.IsNull(tokenizer.NextToken()); } Index: WordFilterTest.cs =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev.Tests/Text/Indexing/WordFilterTest.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** WordFilterTest.cs 16 Nov 2005 07:01:53 -0000 1.3 --- WordFilterTest.cs 26 Nov 2005 08:09:23 -0000 1.4 *************** *** 42,46 **** /// </summary> [TestFixture] ! public class WordFilterTest : Assertion { [Test] --- 42,46 ---- /// </summary> [TestFixture] ! public class WordFilterTest : Assert { [Test] |
From: Sean M. <int...@us...> - 2005-11-26 08:09:32
|
Update of /cvsroot/adapdev/Adapdev/src/Adapdev.NVelocity/Runtime In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18792/src/Adapdev.NVelocity/Runtime Modified Files: RuntimeInstance.cs Log Message: Cleaned up several warnings Restored some lingering files Index: RuntimeInstance.cs =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev.NVelocity/Runtime/RuntimeInstance.cs,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** RuntimeInstance.cs 16 Nov 2005 07:01:51 -0000 1.5 --- RuntimeInstance.cs 26 Nov 2005 08:09:23 -0000 1.6 *************** *** 425,429 **** o = Activator.CreateInstance(rmType); } ! catch (System.Exception cnfe) { String err = "The specified class for Resourcemanager (" + rm + ") does not exist (or is not accessible to the current classlaoder."; --- 425,429 ---- o = Activator.CreateInstance(rmType); } ! catch (System.Exception) { String err = "The specified class for Resourcemanager (" + rm + ") does not exist (or is not accessible to the current classlaoder."; |
From: Sean M. <int...@us...> - 2005-11-26 08:09:32
|
Update of /cvsroot/adapdev/Adapdev/src/Adapdev.Data.Tests/Schema In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18792/src/Adapdev.Data.Tests/Schema Added Files: SaveDatabaseSchemaTest.cs Log Message: Cleaned up several warnings Restored some lingering files --- NEW FILE: SaveDatabaseSchemaTest.cs --- using System; using Adapdev.Data.Schema; using Adapdev.Serialization; using NUnit.Framework; namespace Adapdev.Data.Tests.Schema { /// <summary> /// Summary description for SaveDatabaseSchemaTest. /// </summary> /// [TestFixture] public class SaveDatabaseSchemaTest { private string _oledbConnectionString = "Provider=sqloledb;Data Source=localhost;Initial Catalog=northwind;User Id=sa;Password=;"; [Test] public void SaveSchema() { DatabaseSchema ds = SchemaBuilder.CreateDatabaseSchema(this._oledbConnectionString, Adapdev.Data.DbType.SQLSERVER, Adapdev.Data.DbProviderType.OLEDB); Serializer.SerializeToXmlFile(ds, "schema.xml"); } } } |
From: Sean M. <int...@us...> - 2005-11-26 08:09:32
|
Update of /cvsroot/adapdev/Adapdev/src/Adapdev.Tests/Reflection In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18792/src/Adapdev.Tests/Reflection Modified Files: ClassAccessorCacheTest.cs Log Message: Cleaned up several warnings Restored some lingering files Index: ClassAccessorCacheTest.cs =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev.Tests/Reflection/ClassAccessorCacheTest.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** ClassAccessorCacheTest.cs 16 Nov 2005 07:01:52 -0000 1.3 --- ClassAccessorCacheTest.cs 26 Nov 2005 08:09:23 -0000 1.4 *************** *** 59,63 **** ClassAccessor c = ClassAccessorCache.Get(o); c.LoadAllProperties(); ! Console.WriteLine(ClassAccessorCache.ToString()); } } --- 59,63 ---- ClassAccessor c = ClassAccessorCache.Get(o); c.LoadAllProperties(); ! Console.WriteLine(ClassAccessorCache.Properties()); } } |
From: Sean M. <int...@us...> - 2005-11-26 08:09:32
|
Update of /cvsroot/adapdev/Adapdev/src/Adapdev.Data In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18792/src/Adapdev.Data Modified Files: AbstractDAO.cs Log Message: Cleaned up several warnings Restored some lingering files Index: AbstractDAO.cs =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev.Data/AbstractDAO.cs,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** AbstractDAO.cs 16 Nov 2005 07:01:47 -0000 1.7 --- AbstractDAO.cs 26 Nov 2005 08:09:22 -0000 1.8 *************** *** 326,330 **** public object SelectById(object id) { ! return this.SelectOne(id); } --- 326,336 ---- public object SelectById(object id) { ! object o; ! using (IDbConnection conn = this.CreateConnection()) ! { ! conn.Open(); ! o = this.SelectById(id, conn); ! } ! return o; } *************** *** 337,342 **** public object SelectById(object id, IDbConnection connection) { ! return this.SelectOne(id, connection); ! } /// <summary> --- 343,356 ---- public object SelectById(object id, IDbConnection connection) { ! object o = null; ! IDataReader dr = DbProviderFactory.CreateDataReader(connection, this.CreateSelectOneCommand(id), this.provider); ! while (dr.Read()) ! { ! o = this.MapObject(dr); ! break; ! } ! dr.Close(); ! ! return o; } /// <summary> *************** *** 349,359 **** public object SelectOne(object id) { ! object o; ! using (IDbConnection conn = this.CreateConnection()) ! { ! conn.Open(); ! o = this.SelectOne(id, conn); ! } ! return o; } --- 363,367 ---- public object SelectOne(object id) { ! return this.SelectById(id); } *************** *** 367,380 **** public object SelectOne(object id, IDbConnection conn) { ! object o = null; ! IDataReader dr = DbProviderFactory.CreateDataReader(conn, this.CreateSelectOneCommand(id), this.provider); ! while (dr.Read()) ! { ! o = this.MapObject(dr); ! break; ! } ! dr.Close(); ! ! return o; } --- 375,379 ---- public object SelectOne(object id, IDbConnection conn) { ! return this.SelectById(id, conn); } *************** *** 592,596 **** public DataSet SelectDatasetById(object id) { ! return this.SelectOneDS(id); } --- 591,595 ---- public DataSet SelectDatasetById(object id) { ! return this.CreateDataSet(this.CreateSelectOneCommand(id)); } *************** *** 603,607 **** public DataSet SelectDatasetById(object id, IDbConnection conn) { ! return this.SelectOneDS(id, conn); } --- 602,606 ---- public DataSet SelectDatasetById(object id, IDbConnection conn) { ! return this.GetDataSet(this.CreateSelectOneCommand(id), conn); } *************** *** 615,619 **** public DataSet SelectOneDS(object id) { ! return this.CreateDataSet(this.CreateSelectOneCommand(id)); } --- 614,618 ---- public DataSet SelectOneDS(object id) { ! return this.SelectDatasetById(id); } *************** *** 627,631 **** public DataSet SelectOneDS(object id, IDbConnection conn) { ! return this.GetDataSet(this.CreateSelectOneCommand(id), conn); } --- 626,630 ---- public DataSet SelectOneDS(object id, IDbConnection conn) { ! return this.SelectDatasetById(id, conn); } |
From: Sean M. <int...@us...> - 2005-11-26 08:09:32
|
Update of /cvsroot/adapdev/Adapdev/src/Adapdev.Data.Tests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18792/src/Adapdev.Data.Tests Modified Files: Adapdev.Data.Tests.csproj SchemaBuilderTest.cs Log Message: Cleaned up several warnings Restored some lingering files Index: SchemaBuilderTest.cs =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev.Data.Tests/SchemaBuilderTest.cs,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** SchemaBuilderTest.cs 16 Nov 2005 07:01:47 -0000 1.9 --- SchemaBuilderTest.cs 26 Nov 2005 08:09:22 -0000 1.10 *************** *** 16,20 **** private string _oledbConnectionString = "Provider=sqloledb;Data Source=localhost;Initial Catalog=northwind;User Id=sa;Password=;"; - private string _sqlserverConnectionString = "Data Source=localhost; Initial Catalog=northwind; User ID=sa; Password=; Trusted_Connection=false;"; private string _mysqlConnectionString = "Data Source=localhost;Database=codus_test;User ID=;Password=;"; --- 16,19 ---- Index: Adapdev.Data.Tests.csproj =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev.Data.Tests/Adapdev.Data.Tests.csproj,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** Adapdev.Data.Tests.csproj 16 Nov 2005 07:01:47 -0000 1.12 --- Adapdev.Data.Tests.csproj 26 Nov 2005 08:09:22 -0000 1.13 *************** *** 170,173 **** --- 170,178 ---- BuildAction = "Compile" /> + <File + RelPath = "Schema\SaveDatabaseSchemaTest.cs" + SubType = "Code" + BuildAction = "Compile" + /> </Include> </Files> |
From: Sean M. <int...@us...> - 2005-11-23 03:09:15
|
Update of /cvsroot/adapdev/Adapdev/src/Adapdev/Threading In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25980/src/Adapdev/Threading Added Files: CallerThreadContext.cs Exceptions.cs STPStartInfo.cs SmartThreadPool.cs WorkItem.cs WorkItemsQueue.cs Log Message: --- NEW FILE: WorkItem.cs --- // Ami Bar // am...@gm... using System; using System.Threading; using System.Diagnostics; namespace Adapdev.Threading { #region WorkItem Delegate /// <summary> /// A delegate that represents the method to run as the work item /// </summary> /// <param name="state">A state object for the method to run</param> public delegate object WorkItemCallback(object state); /// <summary> /// A delegate to call after the WorkItemCallback completed /// </summary> /// <param name="wir">The work item result object</param> public delegate void PostExecuteWorkItemCallback(IWorkItemResult wir); #endregion #region IWorkItemResult interface /// <summary> /// IWorkItemResult interface /// </summary> public interface IWorkItemResult { /// <summary> /// Get the result of the work item. /// If the work item didn't run yet then the caller waits. /// </summary> /// <returns>The result of the work item</returns> object GetResult(); /// <summary> /// Get the result of the work item. /// If the work item didn't run yet then the caller waits until timeout. /// </summary> /// <returns>The result of the work item</returns> /// On timeout throws WorkItemTimeoutException object GetResult( int millisecondsTimeout, bool exitContext); /// <summary> /// Get the result of the work item. /// If the work item didn't run yet then the caller waits until timeout. /// </summary> /// <returns>The result of the work item</returns> /// On timeout throws WorkItemTimeoutException object GetResult( TimeSpan timeout, bool exitContext); /// <summary> /// Get the result of the work item. /// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled. /// </summary> /// <param name="millisecondsTimeout">Timeout in milliseconds, or -1 for infinite</param> /// <param name="exitContext"> /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. /// </param> /// <param name="cancelWaitHandle">A cancel wait handle to interrupt the blocking if needed</param> /// <returns>The result of the work item</returns> /// On timeout throws WorkItemTimeoutException /// On cancel throws WorkItemCancelException object GetResult( int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle); /// <summary> /// Get the result of the work item. /// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled. /// </summary> /// <returns>The result of the work item</returns> /// On timeout throws WorkItemTimeoutException /// On cancel throws WorkItemCancelException object GetResult( TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle); /// <summary> /// Get the result of the work item. /// If the work item didn't run yet then the caller waits. /// </summary> /// <param name="e">Filled with the exception if one was thrown</param> /// <returns>The result of the work item</returns> object GetResult(out Exception e); /// <summary> /// Get the result of the work item. /// If the work item didn't run yet then the caller waits until timeout. /// </summary> /// <param name="e">Filled with the exception if one was thrown</param> /// <returns>The result of the work item</returns> /// On timeout throws WorkItemTimeoutException object GetResult( int millisecondsTimeout, bool exitContext, out Exception e); /// <summary> /// Get the result of the work item. /// If the work item didn't run yet then the caller waits until timeout. /// </summary> /// <param name="e">Filled with the exception if one was thrown</param> /// <returns>The result of the work item</returns> /// On timeout throws WorkItemTimeoutException object GetResult( TimeSpan timeout, bool exitContext, out Exception e); /// <summary> /// Get the result of the work item. /// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled. /// </summary> /// <param name="millisecondsTimeout">Timeout in milliseconds, or -1 for infinite</param> /// <param name="exitContext"> /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. /// </param> /// <param name="cancelWaitHandle">A cancel wait handle to interrupt the blocking if needed</param> /// <param name="e">Filled with the exception if one was thrown</param> /// <returns>The result of the work item</returns> /// On timeout throws WorkItemTimeoutException /// On cancel throws WorkItemCancelException object GetResult( int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e); /// <summary> /// Get the result of the work item. /// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled. /// </summary> /// <returns>The result of the work item</returns> /// <param name="e">Filled with the exception if one was thrown</param> /// On timeout throws WorkItemTimeoutException /// On cancel throws WorkItemCancelException object GetResult( TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e); /// <summary> /// Gets an indication whether the asynchronous operation has completed. /// </summary> bool IsCompleted { get; } /// <summary> /// Gets an indication whether the asynchronous operation has been canceled. /// </summary> bool IsCanceled { get; } /// <summary> /// Gets a user-defined object that qualifies or contains information about an asynchronous operation. /// </summary> object State { get; } /// <summary> /// Cancel the work item if it didn't start running yet. /// </summary> /// <returns>Returns true on success or false if the work item is in progress or already completed</returns> bool Cancel(); } #endregion #region WorkItem class /// <summary> /// Holds a callback delegate and the state for that delegate. /// </summary> internal class WorkItem : IDisposable { #region WorkItemState enum /// <summary> /// Indicates the state of the work item in the thread pool /// </summary> private enum WorkItemState { InQueue, InProgress, Completed, Canceled, } #endregion #region Member Variables /// <summary> /// Callback delegate for the callback. /// </summary> private WorkItemCallback _callback; /// <summary> /// Callback delegate for the the post execute. /// </summary> private PostExecuteWorkItemCallback _postExecuteWorkItemCallback; /// <summary> /// State with which to call the callback delegate. /// </summary> private object _state; /// <summary> /// Stores the caller's context /// </summary> private CallerThreadContext _callerContext; /// <summary> /// Holds the result of the mehtod /// </summary> private object _result; /// <summary> /// Hold the exception if the method threw it /// </summary> private Exception _exception; /// <summary> /// Hold the state of the work item /// </summary> private WorkItemState _workItemState; /// <summary> /// A ManualResetEvent to indicate that the result is ready /// </summary> private ManualResetEvent _workItemCompleted; /// <summary> /// A reference count to the _workItemCompleted. /// When it reaches to zero _workItemCompleted is Closed /// </summary> private int _workItemCompletedRefCount; /// <summary> /// Represents the result state of the work item /// </summary> private WorkItemResult _workItemResult; /// <summary> /// Indicates when to call to the post execute /// </summary> private CallToPostExecute _callToPostExecute; #endregion #region Construction /// <summary> /// Initialize the callback holding object. /// </summary> /// <param name="callback">Callback delegate for the callback.</param> /// <param name="state">State with which to call the callback delegate.</param> /// /// We assume that the WorkItem object is created within the thread /// that meant to run the callback public WorkItem( WorkItemCallback callback, object state, bool useCallerContext, PostExecuteWorkItemCallback postExecuteWorkItemCallback, CallToPostExecute callToPostExecute) { if (useCallerContext) { _callerContext = CallerThreadContext.Capture(); } _postExecuteWorkItemCallback = postExecuteWorkItemCallback; _callToPostExecute = callToPostExecute; _callback = callback; _state = state; _workItemState = WorkItemState.InQueue; _workItemCompleted = null; _workItemCompletedRefCount = 0; _workItemResult = new WorkItemResult(this); } #endregion #region Methods /// <summary> /// Change the state of the work item to in progress if it wasn't canceled. /// </summary> /// <returns> /// Return true on success or false in case the work item was canceled. /// If the work item needs to run a post execute then the method will return true. /// </returns> public bool StartingWorkItem() { lock(this) { if (WorkItemState.Canceled == _workItemState) { bool result = false; if ((_postExecuteWorkItemCallback != null) && ((_callToPostExecute & CallToPostExecute.WhenWorkItemCanceled) == CallToPostExecute.WhenWorkItemCanceled)) { result = true; } return result; } Debug.Assert(WorkItemState.InQueue == _workItemState); SetWorkItemState(WorkItemState.InProgress); } return true; } /// <summary> /// Execute the work item and the post execute /// </summary> public void Execute() { CallToPostExecute currentCallToPostExecute = 0; // Execute the work item if we are in the correct state switch(_workItemState) { case WorkItemState.InProgress: currentCallToPostExecute |= CallToPostExecute.WhenWorkItemNotCanceled; ExecuteWorkItem(); break; case WorkItemState.Canceled: currentCallToPostExecute |= CallToPostExecute.WhenWorkItemCanceled; break; default: Debug.Assert(false); throw new NotSupportedException(); } // Run the post execute as needed if ((currentCallToPostExecute & _callToPostExecute) != 0) { PostExecute(); } } /// <summary> /// Execute the work item /// </summary> private void ExecuteWorkItem() { CallerThreadContext ctc = null; if (null != _callerContext) { ctc = CallerThreadContext.Capture(); CallerThreadContext.Apply(_callerContext); } Exception exception = null; object result = null; try { result = _callback(_state); } catch (Exception e) { // Save the exception so we can rethrow it later exception = e; } if (null != _callerContext) { CallerThreadContext.Apply(ctc); } SetResult(result, exception); } /// <summary> /// Runs the post execute callback /// </summary> private void PostExecute() { if (null != _postExecuteWorkItemCallback) { try { _postExecuteWorkItemCallback(this._workItemResult); } catch (Exception e) { Debug.Assert(null != e); } } } /// <summary> /// Set the result of the work item to return /// </summary> /// <param name="result">The result of the work item</param> internal void SetResult(object result, Exception exception) { _result = result; _exception = exception; SignalComplete(false); } /// <summary> /// Returns the work item result /// </summary> /// <returns>The work item result</returns> internal IWorkItemResult GetWorkItemResult() { return _workItemResult; } /// <summary> /// Wait for all work items to complete /// </summary> /// <param name="workItemResults">Array of work item result objects</param> /// <param name="millisecondsTimeout">The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.</param> /// <param name="exitContext"> /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. /// </param> /// <param name="cancelWaitHandle">A cancel wait handle to interrupt the wait if needed</param> /// <returns> /// true when every work item in workItemResults has completed; otherwise false. /// </returns> internal static bool WaitAll( IWorkItemResult [] workItemResults, int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle) { bool success; WaitHandle [] waitHandles = new WaitHandle[workItemResults.Length];; GetWaitHandles(workItemResults, waitHandles); if ((null == cancelWaitHandle) && (waitHandles.Length <= 64)) { success = WaitHandle.WaitAll(waitHandles, millisecondsTimeout, exitContext); } else { success = true; int millisecondsLeft = millisecondsTimeout; DateTime start = DateTime.Now; WaitHandle [] whs; if (null != cancelWaitHandle) { whs = new WaitHandle [] { null, cancelWaitHandle }; } else { whs = new WaitHandle [] { null }; } bool waitInfinitely = (Timeout.Infinite == millisecondsTimeout); // Iterate over the wait handles and wait for each one to complete. // We cannot use WaitHandle.WaitAll directly, because the cancelWaitHandle // won't affect it. // Each iteration we update the time left for the timeout. for(int i = 0; i < workItemResults.Length; ++i) { // WaitAny don't work with negative numbers if (!waitInfinitely && (millisecondsLeft < 0)) { success = false; break; } whs[0] = waitHandles[i]; int result = WaitHandle.WaitAny(whs, millisecondsLeft, exitContext); if((result > 0) || (WaitHandle.WaitTimeout == result)) { success = false; break; } if(!waitInfinitely) { // Update the time left to wait TimeSpan ts = DateTime.Now - start; millisecondsLeft = millisecondsTimeout - (int)ts.TotalMilliseconds; } } } // Release the wait handles ReleaseWaitHandles(workItemResults); return success; } /// <summary> /// Waits for any of the work items in the specified array to complete, cancel, or timeout /// </summary> /// <param name="workItemResults">Array of work item result objects</param> /// <param name="millisecondsTimeout">The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.</param> /// <param name="exitContext"> /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. /// </param> /// <param name="cancelWaitHandle">A cancel wait handle to interrupt the wait if needed</param> /// <returns> /// The array index of the work item result that satisfied the wait, or WaitTimeout if no work item result satisfied the wait and a time interval equivalent to millisecondsTimeout has passed or the work item has been canceled. /// </returns> internal static int WaitAny( IWorkItemResult [] workItemResults, int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle) { WaitHandle [] waitHandles = null; if (null != cancelWaitHandle) { waitHandles = new WaitHandle[workItemResults.Length+1]; GetWaitHandles(workItemResults, waitHandles); waitHandles[workItemResults.Length] = cancelWaitHandle; } else { waitHandles = new WaitHandle[workItemResults.Length]; GetWaitHandles(workItemResults, waitHandles); } int result = WaitHandle.WaitAny(waitHandles, millisecondsTimeout, exitContext); // Treat cancel as timeout if (null != cancelWaitHandle) { if (result == workItemResults.Length) { result = WaitHandle.WaitTimeout; } } ReleaseWaitHandles(workItemResults); return result; } /// <summary> /// Fill an array of wait handles with the work items wait handles. /// </summary> /// <param name="workItemResults">An array of work item results</param> /// <param name="waitHandles">An array of wait handles to fill</param> private static void GetWaitHandles( IWorkItemResult [] workItemResults, WaitHandle [] waitHandles) { for(int i = 0; i < workItemResults.Length; ++i) { WorkItemResult wir = workItemResults[i] as WorkItemResult; Debug.Assert(null != wir, "All workItemResults must be WorkItemResult objects"); waitHandles[i] = wir.GetWorkItem().GetWaitHandle(); } } /// <summary> /// Release the work items' wait handles /// </summary> /// <param name="workItemResults">An array of work item results</param> private static void ReleaseWaitHandles(IWorkItemResult [] workItemResults) { for(int i = 0; i < workItemResults.Length; ++i) { WorkItemResult wir = workItemResults[i] as WorkItemResult; wir.GetWorkItem().ReleaseWaitHandle(); } } #endregion #region Private Members /// <summary> /// Sets the work item's state /// </summary> /// <param name="workItemState">The state to set the work item to</param> private void SetWorkItemState(WorkItemState workItemState) { lock(this) { _workItemState = workItemState; } } /// <summary> /// Signals that work item has been completed or canceled /// </summary> /// <param name="canceled">Indicates that the work item has been canceled</param> private void SignalComplete(bool canceled) { SetWorkItemState(canceled ? WorkItemState.Canceled : WorkItemState.Completed); lock(this) { // If someone is waiting then signal. if (null != _workItemCompleted) { _workItemCompleted.Set(); } } } #endregion #region Members exposed by WorkItemResult /// <summary> /// Cancel the work item if it didn't start running yet. /// </summary> /// <returns>Returns true on success or false if the work item is in progress or already completed</returns> private bool Cancel() { lock(this) { switch(_workItemState) { case WorkItemState.Canceled: //Debug.WriteLine("Work item already canceled"); return true; case WorkItemState.Completed: case WorkItemState.InProgress: //Debug.WriteLine("Work item cannot be canceled"); return false; case WorkItemState.InQueue: // Signal to the wait for completion that the work // item has been completed (canceled). There is no // reason to wait for it to get out of the queue SignalComplete(true); //Debug.WriteLine("Work item canceled"); return true; } } return false; } /// <summary> /// Get the result of the work item. /// If the work item didn't run yet then the caller waits for the result, timeout, or cancel. /// In case of error the method throws and exception /// </summary> /// <returns>The result of the work item</returns> private object GetResult( int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle) { Exception e = null; object result = GetResult(millisecondsTimeout, exitContext, cancelWaitHandle, out e); if (null != e) { throw e; } return result; } /// <summary> /// Get the result of the work item. /// If the work item didn't run yet then the caller waits for the result, timeout, or cancel. /// In case of error the e argument is filled with the exception /// </summary> /// <returns>The result of the work item</returns> private object GetResult( int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e) { e = null; // Check for cancel if (WorkItemState.Canceled == _workItemState) { throw new WorkItemCancelException("Work item canceled"); } // Check for completion if (IsCompleted) { e = _exception; return _result; } // If no cancelWaitHandle is provided if (null == cancelWaitHandle) { WaitHandle wh = GetWaitHandle(); bool timeout = !wh.WaitOne(millisecondsTimeout, exitContext); ReleaseWaitHandle(); if (timeout) { throw new WorkItemTimeoutException("Work item timeout"); } } else { WaitHandle wh = GetWaitHandle(); int result = WaitHandle.WaitAny(new WaitHandle[] { wh, cancelWaitHandle }); ReleaseWaitHandle(); switch(result) { case 0: // The work item signaled // Note that the signal could be also as a result of canceling the // work item (not the get result) break; case 1: case WaitHandle.WaitTimeout: throw new WorkItemTimeoutException("Work item timeout"); default: Debug.Assert(false); break; } } // Check for cancel if (WorkItemState.Canceled == _workItemState) { throw new WorkItemCancelException("Work item canceled"); } Debug.Assert(IsCompleted); e = _exception; // Return the result return _result; } /// <summary> /// A wait handle to wait for completion, cancel, or timeout /// </summary> private WaitHandle GetWaitHandle() { lock(this) { if (null == _workItemCompleted) { _workItemCompleted = new ManualResetEvent(IsCompleted); } ++_workItemCompletedRefCount; } return _workItemCompleted; } private void ReleaseWaitHandle() { lock(this) { if (null != _workItemCompleted) { --_workItemCompletedRefCount; if (0 == _workItemCompletedRefCount) { _workItemCompleted.Close(); _workItemCompleted = null; } } } } /// <summary> /// Returns true when the work item has completed or canceled /// </summary> private bool IsCompleted { get { lock(this) { return ((_workItemState == WorkItemState.Completed) || (_workItemState == WorkItemState.Canceled)); } } } /// <summary> /// Returns true when the work item has canceled /// </summary> public bool IsCanceled { get { lock(this) { return (_workItemState == WorkItemState.Canceled); } } } #endregion #region WorkItemResult class private class WorkItemResult : IWorkItemResult { /// <summary> /// A back reference to the work item /// </summary> private WorkItem _workItem; public WorkItemResult(WorkItem workItem) { _workItem = workItem; } internal WorkItem GetWorkItem() { return _workItem; } #region IWorkItemResult Members public bool IsCompleted { get { return _workItem.IsCompleted; } } public bool IsCanceled { get { return _workItem.IsCanceled; } } public object GetResult() { return _workItem.GetResult(Timeout.Infinite, true, null); } public object GetResult(int millisecondsTimeout, bool exitContext) { return _workItem.GetResult(millisecondsTimeout, exitContext, null); } public object GetResult(TimeSpan timeout, bool exitContext) { return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, null); } public object GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle) { return _workItem.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle); } public object GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle) { return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle); } public object GetResult(out Exception e) { return _workItem.GetResult(Timeout.Infinite, true, null, out e); } public object GetResult(int millisecondsTimeout, bool exitContext, out Exception e) { return _workItem.GetResult(millisecondsTimeout, exitContext, null, out e); } public object GetResult(TimeSpan timeout, bool exitContext, out Exception e) { return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, null, out e); } public object GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e) { return _workItem.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle, out e); } public object GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e) { return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle, out e); } public bool Cancel() { return _workItem.Cancel(); } public object State { get { return _workItem._state; } } #endregion } #endregion #region IDisposable Members public void Dispose() { IDisposable disp = _state as IDisposable; if (null != disp) { disp.Dispose(); _state = null; } } #endregion } #endregion } --- NEW FILE: WorkItemsQueue.cs --- // Ami Bar // am...@gm... using System; using System.Collections; using System.Threading; namespace Adapdev.Threading { #region WorkItemsQueue class /// <summary> /// WorkItemsQueue class. /// </summary> internal class WorkItemsQueue : IDisposable { #region Member variables /// /// Waiters queue (implemented as stack). /// The head is a dummy and is not used. /// private WaiterEntry _headWaiterEntry = new WaiterEntry(); /// <summary> /// Waiters count /// </summary> private int _waitersCount = 0; /// <summary> /// Work items queue /// </summary> private Queue _workItems = new Queue(); /// <summary> /// Indicate that work items are allowed to be queued /// </summary> private bool _isWorkItemsQueueActive = true; /// <summary> /// A slot in the thread local storage to save some data /// </summary> private static readonly LocalDataStoreSlot _slot = Thread.AllocateDataSlot(); private bool _isDisposed = false; #endregion #region Public properties /// <summary> /// Returns the current number of work items in the queue /// </summary> public int Count { get { lock(this) { ValidateNotDisposed(); return _workItems.Count; } } } #endregion #region Public methods /// <summary> /// Enqueue a work item to the queue. /// </summary> public bool EnqueueWorkItem(WorkItem workItem) { // A work item cannot be null, since null is used in the // WaitForWorkItem() method to indicate timeout or cancel if (null == workItem) { throw new ArgumentNullException("workItem" , "workItem cannot be null"); } bool enqueue = true; // First check if there is a waiter waiting for work item. During // the check, timed out waiters are ignored. If there is no // waiter then the work item is queued. lock(this) { ValidateNotDisposed(); if (!_isWorkItemsQueueActive) { return false; } while(_waitersCount > 0) { // Dequeue a waiter. WaiterEntry waiterEntry = PopWaiter(); // Signal the waiter. On success break the loop if (waiterEntry.Signal(workItem)) { enqueue = false; break; } } if (enqueue) { // Enqueue the work item _workItems.Enqueue(workItem); } } return true; } /// <summary> /// Waits for a work item or exits on timeout or cancel /// </summary> /// <param name="millisecondsTimeout">Timeout in milliseconds</param> /// <param name="cancelEvent">Cancel wait handle</param> /// <returns>Returns true if the resource was granted</returns> public WorkItem DequeueWorkItem( int millisecondsTimeout, WaitHandle cancelEvent) { /// This method cause the caller to wait for a work item. /// If there is at least one waiting work item then the /// method returns immidiately with true. /// /// If there are no waiting work items then the caller /// is queued between other waiters for a work item to arrive. /// /// If a work item didn't come within millisecondsTimeout or /// the user canceled the wait by signaling the cancelEvent /// then the method returns false to indicate that the caller /// didn't get a work item. WaiterEntry waiterEntry = null; WorkItem workItem = null; lock(this) { ValidateNotDisposed(); // If there are waiting work items then take one and return. if (_workItems.Count > 0) { workItem = _workItems.Dequeue() as WorkItem; return workItem; } // No waiting work items ... else { // Get the wait entry for the waiters queue waiterEntry = GetThreadWaiterEntry(); // Put the waiter with the other waiters PushWaiter(waiterEntry); } } // Prepare array of wait handle for the WaitHandle.WaitAny() WaitHandle [] waitHandles = new WaitHandle [] { waiterEntry.WaitHandle, cancelEvent }; // Wait for an available resource, cancel event, or timeout. // During the wait we are supposes to exit the synchronization // domain. (Placing true as the third argument of the WaitAny()) // It just doesn't work, I don't know why, so I have lock(this) // statments insted of one. int index = WaitHandle.WaitAny( waitHandles, millisecondsTimeout, true); lock(this) { // success is true if it got a work item. bool success = (0 == index); // The timeout variable is used only for readability. // (We treat cancel as timeout) bool timeout = !success; // On timeout update the waiterEntry that it is timed out if (timeout) { // The Timeout() fails if the waiter has already been signaled timeout = waiterEntry.Timeout(); // On timeout remove the waiter from the queue. // Note that the complexity is O(1). if(timeout) { RemoveWaiter(waiterEntry, false); } // Again readability success = !timeout; } // On success return the work item if (success) { workItem = waiterEntry.WorkItem; if (null == workItem) { workItem = _workItems.Dequeue() as WorkItem; } } } // On failure return null. return workItem; } /// <summary> /// Cleanup the work items queue, hence no more work /// items are allowed to be queue /// </summary> protected virtual void Cleanup() { lock(this) { // Deactivate only once if (!_isWorkItemsQueueActive) { return; } // Don't queue more work items _isWorkItemsQueueActive = false; foreach(WorkItem workItem in _workItems) { workItem.Dispose(); } // Clear the work items that are already queued _workItems.Clear(); // Note: // I don't iterate over the queue and dispose of work items's states, // since if a work item has a state object that is still in use in the // application then I must not dispose it. // Tell the waiters that they were timed out. // It won't signal them to exit, but to ignore their // next work item. while(_waitersCount > 0) { WaiterEntry waiterEntry = PopWaiter(); waiterEntry.Timeout(); } } } #endregion #region Private methods /// <summary> /// Returns the WaiterEntry of the current thread /// </summary> /// <returns></returns> /// In order to avoid creation and destuction of WaiterEntry /// objects each thread stores its own WaiterEntry. private WaiterEntry GetThreadWaiterEntry() { WaiterEntry waiterEntry = Thread.GetData(_slot) as WaiterEntry; if (null == waiterEntry) { waiterEntry = new WaiterEntry(); Thread.SetData(_slot, waiterEntry); } waiterEntry.Reset(); return waiterEntry; } #region Waiters stack methods /// /// Push a new waiter into the waiter's stack /// /// A waiter to put in the stack private void PushWaiter(WaiterEntry newWaiterEntry) { // Remove the waiter if it is already in the stack and // update waiter's count as needed RemoveWaiter(newWaiterEntry, false); // If the stack is empty then newWaiterEntry is the new head of the stack if (null == _headWaiterEntry._nextWaiterEntry) { _headWaiterEntry._nextWaiterEntry = newWaiterEntry; newWaiterEntry._prevWaiterEntry = _headWaiterEntry; } // If the stack is not empty then put newWaiterEntry as the new head // of the stack. else { // Save the old first waiter entry WaiterEntry oldFirstWaiterEntry = _headWaiterEntry._nextWaiterEntry; // Update the links _headWaiterEntry._nextWaiterEntry = newWaiterEntry; newWaiterEntry._nextWaiterEntry = oldFirstWaiterEntry; newWaiterEntry._prevWaiterEntry = _headWaiterEntry; oldFirstWaiterEntry._prevWaiterEntry = newWaiterEntry; } // Increment the number of waiters ++_waitersCount; } /// /// Pop a waiter from the waiter's stack /// /// Returns the first waiter in the stack private WaiterEntry PopWaiter() { // Store the current stack head WaiterEntry oldFirstWaiterEntry = _headWaiterEntry._nextWaiterEntry; // Store the new stack head WaiterEntry newHeadWaiterEntry = oldFirstWaiterEntry._nextWaiterEntry; // Update the old stack head list links and decrement the number // waiters. RemoveWaiter(oldFirstWaiterEntry, true); // Update the new stack head _headWaiterEntry._nextWaiterEntry = newHeadWaiterEntry; if (null != newHeadWaiterEntry) { newHeadWaiterEntry._prevWaiterEntry = _headWaiterEntry; } // Return the old stack head return oldFirstWaiterEntry; } /// <summary> /// Remove a waiter from the stack /// </summary> /// <param name="waiterEntry">A waiter entry to remove</param> /// <param name="popDecrement">If true the waiter count is always decremented</param> private void RemoveWaiter(WaiterEntry waiterEntry, bool popDecrement) { // Store the prev entry in the list WaiterEntry prevWaiterEntry = waiterEntry._prevWaiterEntry; // Store the next entry in the list WaiterEntry nextWaiterEntry = waiterEntry._nextWaiterEntry; // A flag to indicate if we need to decrement the waiters count. // If we got here from PopWaiter then we must decrement. // If we got here from PushWaiter then we decrement only if // the waiter was already in the stack. bool decrementCounter = popDecrement; // Null the waiter's entry links waiterEntry._prevWaiterEntry = null; waiterEntry._nextWaiterEntry = null; // If the waiter entry had a prev link then update it. // It also means that the waiter is already in the list and we // need to decrement the waiters count. if (null != prevWaiterEntry) { prevWaiterEntry._nextWaiterEntry = nextWaiterEntry; decrementCounter = true; } // If the waiter entry had a next link then update it. // It also means that the waiter is already in the list and we // need to decrement the waiters count. if (null != nextWaiterEntry) { nextWaiterEntry._prevWaiterEntry = prevWaiterEntry; decrementCounter = true; } // Decrement the waiters count if needed if (decrementCounter) { --_waitersCount; } } #endregion #endregion #region WaiterEntry class // A waiter entry in the _waiters queue. private class WaiterEntry : IDisposable { #region Member variables /// <summary> /// Event to signal the waiter that it got the work item. /// </summary> private AutoResetEvent _waitHandle = new AutoResetEvent(false); /// <summary> /// Flag to know if this waiter already quited from the queue /// because of a timeout. /// </summary> private bool _isTimedout = false; /// <summary> /// Flag to know if the waiter was signaled and got a work item. /// </summary> private bool _isSignaled = false; /// <summary> /// A work item that passed directly to the waiter withou going /// through the queue /// </summary> private WorkItem _workItem = null; private bool _isDisposed = false; // Linked list members internal WaiterEntry _nextWaiterEntry = null; internal WaiterEntry _prevWaiterEntry = null; #endregion #region Construction public WaiterEntry() { Reset(); } #endregion #region Public methods public WaitHandle WaitHandle { get { return _waitHandle; } } public WorkItem WorkItem { get { lock(this) { return _workItem; } } } /// <summary> /// Signal the waiter that it got a work item. /// </summary> /// <returns>Return true on success</returns> /// The method fails if Timeout() preceded its call public bool Signal(WorkItem workItem) { lock(this) { if (!_isTimedout) { _workItem = workItem; _isSignaled = true; _waitHandle.Set(); return true; } } return false; } /// <summary> /// Mark the wait entry that it has been timed out /// </summary> /// <returns>Return true on success</returns> /// The method fails if Signal() preceded its call public bool Timeout() { lock(this) { // Time out can happen only if the waiter wasn't marked as // signaled if (!_isSignaled) { // We don't remove the waiter from the queue, the DequeueWorkItem // method skips _waiters that were timed out. _isTimedout = true; return true; } } return false; } /// <summary> /// Reset the wait entry so it can be used again /// </summary> public void Reset() { _workItem = null; _isTimedout = false; _isSignaled = false; _waitHandle.Reset(); } /// <summary> /// Free resources /// </summary> public void Close() { if (null != _waitHandle) { _waitHandle.Close(); _waitHandle = null; } } #endregion #region IDisposable Members public void Dispose() { if (!_isDisposed) { Close(); _isDisposed = true; } } ~WaiterEntry() { Dispose(); } #endregion } #endregion #region IDisposable Members public void Dispose() { if (!_isDisposed) { Cleanup(); _isDisposed = true; GC.SuppressFinalize(this); } } ~WorkItemsQueue() { Cleanup(); } private void ValidateNotDisposed() { if(_isDisposed) { throw new ObjectDisposedException(GetType().ToString(), "The SmartThreadPool has been shutdown"); } } #endregion } #endregion } --- NEW FILE: CallerThreadContext.cs --- // Ami Bar // am...@gm... using System; using System.Threading; using System.Globalization; using System.Security.Principal; using System.Reflection; using System.Runtime.Remoting.Contexts; namespace Adapdev.Threading { #region CallerThreadContext class /// <summary> /// This class stores the caller thread context in order to restore /// it when the work item is executed in the context of the thread /// from the pool. /// Note that we can't store the thread's CompressedStack, because /// it throws a security exception /// </summary> internal class CallerThreadContext { private CultureInfo _culture = null; private CultureInfo _cultureUI = null; private IPrincipal _principal; private System.Runtime.Remoting.Contexts.Context _context; private static FieldInfo _fieldInfo = GetFieldInfo(); private static FieldInfo GetFieldInfo() { Type threadType = typeof(Thread); return threadType.GetField( "m_Context", BindingFlags.Instance | BindingFlags.NonPublic); } /// <summary> /// Constructor /// </summary> private CallerThreadContext() { } /// <summary> /// Captures the current thread context /// </summary> /// <returns></returns> public static CallerThreadContext Capture() { CallerThreadContext callerThreadContext = new CallerThreadContext(); Thread thread = Thread.CurrentThread; callerThreadContext._culture = thread.CurrentCulture; callerThreadContext._cultureUI = thread.CurrentUICulture; callerThreadContext._principal = Thread.CurrentPrincipal; callerThreadContext._context = Thread.CurrentContext; return callerThreadContext; } /// <summary> /// Applies the thread context stored earlier /// </summary> /// <param name="callerThreadContext"></param> public static void Apply(CallerThreadContext callerThreadContext) { Thread thread = Thread.CurrentThread; thread.CurrentCulture = callerThreadContext._culture; thread.CurrentUICulture = callerThreadContext._cultureUI; Thread.CurrentPrincipal = callerThreadContext._principal; // Uncomment the following block to enable the Thread.CurrentThread /* if (null != _fieldInfo) { _fieldInfo.SetValue( Thread.CurrentThread, callerThreadContext._context); } */ } } #endregion } --- NEW FILE: STPStartInfo.cs --- // Ami Bar // am...@gm... using System; namespace Adapdev.Threading { /// <summary> /// Summary description for STPStartInfo. /// </summary> public class STPStartInfo { /// <summary> /// Idle timeout in milliseconds. /// If a thread is idle for _idleTimeout milliseconds then /// it may quit. /// </summary> private int _idleTimeout; /// <summary> /// The lower limit of threads in the pool. /// </summary> private int _minWorkerThreads; /// <summary> /// The upper limit of threads in the pool. /// </summary> private int _maxWorkerThreads; /// <summary> /// Use the caller's security context /// </summary> private bool _useCallerContext; /// <summary> /// Dispose of the state object of a work item /// </summary> private bool _disposeOfStateObjects; /// <summary> /// The option to run the post execute /// </summary> private CallToPostExecute _callToPostExecute; /// <summary> /// A post execute callback to call when none is provided in /// the QueueWorkItem method. /// </summary> private PostExecuteWorkItemCallback _postExecuteWorkItemCallback; public STPStartInfo() { _idleTimeout = SmartThreadPool.DefaultIdleTimeout; _minWorkerThreads = SmartThreadPool.DefaultMinWorkerThreads; _maxWorkerThreads = SmartThreadPool.DefaultMaxWorkerThreads; _useCallerContext = SmartThreadPool.DefaultUseCallerContext; _disposeOfStateObjects = SmartThreadPool.DefaultDisposeOfStateObjects; _callToPostExecute = SmartThreadPool.DefaultCallToPostExecute; _postExecuteWorkItemCallback = SmartThreadPool.DefaultPostExecuteWorkItemCallback; } public STPStartInfo(STPStartInfo stpStartInfo) { _idleTimeout = stpStartInfo._idleTimeout; _minWorkerThreads = stpStartInfo._minWorkerThreads; _maxWorkerThreads = stpStartInfo._maxWorkerThreads; _useCallerContext = stpStartInfo._useCallerContext; _disposeOfStateObjects = stpStartInfo._disposeOfStateObjects; _callToPostExecute = stpStartInfo._callToPostExecute; _postExecuteWorkItemCallback = stpStartInfo._postExecuteWorkItemCallback; } public int IdleTimeout { get { return _idleTimeout; } set { _idleTimeout = value; } } public int MinWorkerThreads { get { return _minWorkerThreads; } set { _minWorkerThreads = value; } } public int MaxWorkerThreads { get { return _maxWorkerThreads; } set { _maxWorkerThreads = value; } } public bool UseCallerContext { get { return _useCallerContext; } set { _useCallerContext = value; } } public bool DisposeOfStateObjects { get { return _disposeOfStateObjects; } set { _disposeOfStateObjects = value; } } public CallToPostExecute CallToPostExecute { get { return _callToPostExecute; } set { _callToPostExecute = value; } } public PostExecuteWorkItemCallback PostExecuteWorkItemCallback { get { return _postExecuteWorkItemCallback; } set { _postExecuteWorkItemCallback = value; } } } } --- NEW FILE: SmartThreadPool.cs --- // Ami Bar // am...@gm... // // Smart Thread Pool in C#. // 7 Aug 2004 - Initial release // 14 Sep 2004 - Bug fixes // 15 Oct 2004 - Added new features // - Work items return result. // - Support waiting synchronization for multiple work items. // - Work items can be cancelled. // - Passage of the caller threads context to the thread in the pool. // - Minimal usage of WIN32 handles. // - Minor bug fixes. // 26 Dec 2004 - Changes: // - Removed static constructors. // - Added finalizers. // - Changed Exceptions so they are serializable. // - Fixed the bug in one of the SmartThreadPool constructors. // - Changed the SmartThreadPool.WaitAll() so it will support any number of waiters. // The SmartThreadPool.WaitAny() is still limited by the .NET Framework. // - Added PostExecute with options on which cases to call it. // - Added option to dispose of the state objects. // - Added a WaitForIdle() method that waits until the work items queue is empty. // - Added an STPStartInfo class for the initialization of the thread pool. // - Changed exception handling so if a work item throws an exception it // is rethrown at GetResult(), rather then firing an UnhandledException event. // Note that PostExecute exception are always ignored. // 25 Mar 2005 - Fixed bug: // - Fixed bug where work items got lost. It could happen sometimes, but especially // when the idle timeout is small. // 3 Jul 2005 - Fixed bug: // - Fixed bug where Enqueue() throws an exception because PopWaiter() returned null, // hardly reconstructed // 16 Aug 2005 - Fixed bug: // - Fixed bug where the InUseThreads becomes negative when cancelling work items using System; using System.Security; using System.Threading; using System.Collections; using System.Diagnostics; namespace Adapdev.Threading { #region CallToPostExecute enumerator [Flags] public enum CallToPostExecute { Never = 0x00, WhenWorkItemCanceled = 0x01, WhenWorkItemNotCanceled = 0x02, Always = WhenWorkItemCanceled | WhenWorkItemNotCanceled, } #endregion #region SmartThreadPool class /// <summary> /// Smart thread pool class. /// </summary> public class SmartThreadPool : IDisposable { #region Default Constants /// <summary> /// Default minimum number of threads the thread pool contains. (0) /// </summary> public const int DefaultMinWorkerThreads = 0; /// <summary> /// Default maximum number of threads the thread pool contains. (25) /// </summary> public const int DefaultMaxWorkerThreads = 25; /// <summary> /// Default idle timeout in milliseconds. (One minute) /// </summary> public const int DefaultIdleTimeout = 60*1000; // One minute /// <summary> /// Indicate to copy the security context of the caller and then use it in the call. (false) /// </summary> public const bool DefaultUseCallerContext = false; /// <summary> /// Indicate to dispose of the state objects if they support the IDispose interface. (false) /// </summary> public const bool DefaultDisposeOfStateObjects = false; /// <summary> /// The default option to run the post execute /// </summary> public const CallToPostExecute DefaultCallToPostExecute = CallToPostExecute.Always; /// <summary> /// The default post execute method to run. /// When null it means not to call it. /// </summary> public static readonly PostExecuteWorkItemCallback DefaultPostExecuteWorkItemCallback = null; #endregion #region Member Variables /// <summary> /// Hashtable of all the threads in the thread pool. /// </summary> private Hashtable _workerThreads = Hashtable.Synchronized(new Hashtable()); /// <summary> /// Queue of work items. /// </summary> private WorkItemsQueue _workItemsQueue = new WorkItemsQueue(); /// <summary> /// Number of threads that currently work (not idle). /// </summary> private int _inUseWorkerThreads = 0; /// <summary> /// Start information to use. /// It is simpler than providing many constructors. /// </summary> private STPStartInfo _stpStartInfo = new STPStartInfo(); /// <summary> /// Total number of work items that are stored in the work items queue /// plus the work items that the threads in the pool are working on. /// </summary> private int _currentWorkItemsCount = 0; /// <summary> /// Signaled when the thread pool is idle, i.e. no thread is busy /// and the work items queue is empty /// </summary> private ManualResetEvent _isIdleWaitHandle = new ManualResetEvent(true); /// <summary> /// An event to signal all the threads to quit immediately. /// </summary> private ManualResetEvent _shuttingDownEvent = new ManualResetEvent(false); /// <summary> /// A flag to indicate the threads to quit. /// </summary> private bool _shutdown = false; /// <summary> /// Counts the threads created in the pool. /// It is used to name the threads. /// </summary> private int _threadCounter = 0; /// <summary> /// Indicate that the SmartThreadPool has been disposed /// </summary> private bool _isDisposed = false; #endregion #region Construction and Finalization /// <summary> /// Constructor /// </summary> public SmartThreadPool() { Start(); } /// <summary> /// Constructor /// </summary> /// <param name="idleTimeout">Idle timeout in milliseconds</param> public SmartThreadPool(int idleTimeout) { _stpStartInfo.IdleTimeout = idleTimeout; Start(); } /// <summary> /// Constructor /// </summary> /// <param name="idleTimeout">Idle timeout in milliseconds</param> /// <param name="maxWorkerThreads">Upper limit of threads in the pool</param> public SmartThreadPool( int idleTimeout, int maxWorkerThreads) { _stpStartInfo.IdleTimeout = idleTimeout; _stpStartInfo.MaxWorkerThreads = maxWorkerThreads; Start(); } /// <summary> /// Constructor /// </summary> /// <param name="idleTimeout">Idle timeout in milliseconds</param> /// <param name="maxWorkerThreads">Upper limit of threads in the pool</param> /// <param name="minWorkerThreads">Lower limit of threads in the pool</param> public SmartThreadPool( int idleTimeout, int maxWorkerThreads, int minWorkerThreads) { _stpStartInfo.IdleTimeout = idleTimeout; _stpStartInfo.MaxWorkerThreads = maxWorkerThreads; _stpStartInfo.MinWorkerThreads = minWorkerThreads; Start(); } /// <summary> /// Constructor /// </summary> /// <param name="idleTimeout">Idle timeout in milliseconds</param> /// <param name="maxWorkerThreads">Upper limit of threads in the pool</param> /// <param name="minWorkerThreads">Lower limit of threads in the pool</param> /// <param name="useCallerContext">Indicate to copy the security context of the caller and then use it in the call</param> /// <param name="disposeOfStateObjects">Indicate to dispose of the state objects if they support the IDispose interface</param> public SmartThreadPool(STPStartInfo stpStartInfo) { _stpStartInfo = new STPStartInfo(stpStartInfo); Start(); } private void Start() { ValidateSTPStartInfo(); StartThreads(_stpStartInfo.MinWorkerThreads); } private void ValidateSTPStartInfo() { if (_stpStartInfo.MinWorkerThreads < 0) { throw new ArgumentOutOfRangeException( "MinWorkerThreads", "MinWorkerThreads cannot be negative"); } if (_stpStartInfo.MaxWorkerThreads <= 0) { throw new ArgumentOutOfRangeException( "MaxWorkerThreads", "MaxWorkerThreads must be greater than zero"); } if (_stpStartInfo.MinWorkerThreads > _stpStartInfo.MaxWorkerThreads) { throw new ArgumentOutOfRangeException( "MinWorkerThreads, maxWorkerThreads", "MaxWorkerThreads must be greater or equal to MinWorkerThreads"); } } #endregion #region Thread Processing /// <summary> /// Waits on the queue for a work item, shutdown, or timeout. /// </summary> /// <returns> /// Returns the WaitingCallback or null in case of timeout or shutdown. /// </returns> private WorkItem Dequeue() { WorkItem workItem = _workItemsQueue.DequeueWorkItem(_stpStartInfo.IdleTimeout, _shuttingDownEvent); return workItem; } /// <summary> /// Put a new work item in the queue /// </summary> /// <param name="workItem">A work item to queue</param> private void Enqueue(WorkItem workItem) { // Make sure the workItem is not null Debug.Assert(null != workItem); IncrementWorkItemsCount(); _workItemsQueue.EnqueueWorkItem(workItem); // If all the threads are busy then try to create a new one if ((InUseThreads + WaitingCallbacks) > _workerThreads.Count) { StartThreads(1); } } private void IncrementWorkItemsCount() { int count = Interlocked.Increment(ref _currentWorkItemsCount); if (count == 1) { _isIdleWaitHandle.Reset(); } } private void DecrementWorkItemsCount() { int count = Interlocked.Decrement(ref _currentWorkItemsCount); if (count == 0) { _isIdleWaitHandle.Set(); } } /// <summary> /// Inform that the current thread is about to quit or quiting. /// The same thread may call this method more than once. /// </summary> private void InformCompleted() { // There is no need to lock the two methods together // since only the current thread removes itself // and the _workerThreads is a synchronized hashtable if (_workerThreads.Contains(Thread.CurrentThread)) { _workerThreads.Remove(Thread.CurrentThread); } } /// <summary> /// Starts new threads /// </summary> /// <param name="threadsCount">The number of threads to start</param> private void StartThreads(int threadsCount) { lock(_workerThreads.SyncRoot) { // Don't start threads on shut down if (_shutdown) { return; } for(int i = 0; i < threadsCount; ++i) { // Don't create more threads then the upper limit if (_workerThreads.Count >= _stpStartInfo.MaxWorkerThreads) { return; } // Create a new thread Thread workerThread = new Thread(new ThreadStart(ProcessQueuedItems)); // Configure the new thread and start it workerThread.Name = "STP Thread #" + _threadCounter; workerThread.IsBackground = true; workerThread.Start(); ++_threadCounter; // Add the new thread to the hashtable and update its creation // time. _workerThreads[workerThread] = DateTime.Now; } } } /// <summary> /// A worker thread method that processes work items from the work items queue. /// </summary> private void ProcessQueuedItems() { try { bool bInUseWorkerThreadsWasIncremented = false; // Process until shutdown. while(!_shutdown) { // Update the last time this thread was seen alive. // It's good for debugging. _workerThreads[Thread.CurrentThread] = DateTime.Now; // Wait for a work item, shutdown, or timeout WorkItem workItem = Dequeue(); // Update the last time this thread was seen alive. // It's good for debugging. _workerThreads[Thread.CurrentThread] = DateTime.Now; // On timeout or shut down. if (null == workItem) { // Double lock for quit. if (_workerThreads.Count > _stpStartInfo.MinWorkerThreads) { lock(_workerThreads.SyncRoot) { if (_workerThreads.Count > _stpStartInfo.MinWorkerThreads) { // Inform that the thread is quiting and then quit. ... [truncated message content] |
From: Sean M. <int...@us...> - 2005-11-23 03:00:54
|
Update of /cvsroot/adapdev/Adapdev/src/Adapdev.Data In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24316/src/Adapdev.Data Modified Files: DbProviderFactory.cs Log Message: Index: DbProviderFactory.cs =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev.Data/DbProviderFactory.cs,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** DbProviderFactory.cs 16 Nov 2005 07:01:47 -0000 1.7 --- DbProviderFactory.cs 23 Nov 2005 03:00:41 -0000 1.8 *************** *** 97,115 **** public static IDataReader CreateDataReader(string connectionString, IDbCommand command, DbProviderType DbProviderType) { ! IDbConnection connection = DbProviderFactory.CreateConnection(DbProviderType); ! connection.ConnectionString = connectionString; ! return CreateDataReader(connection, command, DbProviderType); } public static IDataReader CreateDataReader(string connectionString, string command, DbProviderType DbProviderType) { ! IDbConnection connection = DbProviderFactory.CreateConnection(DbProviderType); ! connection.ConnectionString = connectionString; ! IDbCommand cmd = DbProviderFactory.CreateCommand(DbProviderType); ! cmd.CommandText = command; ! return CreateDataReader(connection, cmd, DbProviderType); } --- 97,121 ---- public static IDataReader CreateDataReader(string connectionString, IDbCommand command, DbProviderType DbProviderType) { ! using(IDbConnection connection = DbProviderFactory.CreateConnection(DbProviderType)) ! { ! connection.ConnectionString = connectionString; ! connection.Open(); ! return CreateDataReader(connection, command, DbProviderType); ! } } public static IDataReader CreateDataReader(string connectionString, string command, DbProviderType DbProviderType) { ! using(IDbConnection connection = DbProviderFactory.CreateConnection(DbProviderType)) ! { ! connection.ConnectionString = connectionString; ! connection.Open(); ! IDbCommand cmd = DbProviderFactory.CreateCommand(DbProviderType); ! cmd.CommandText = command; ! return CreateDataReader(connection, cmd, DbProviderType); ! } } *************** *** 163,167 **** public static DataTable CreateDataTable(string connection, IDbCommand command, DbProviderType DbProviderType) { ! throw new NotImplementedException(); } --- 169,173 ---- public static DataTable CreateDataTable(string connection, IDbCommand command, DbProviderType DbProviderType) { ! return CreateDataSet(connection, command, DbProviderType).Tables[0]; } |
From: Sean M. <int...@us...> - 2005-11-23 03:00:54
|
Update of /cvsroot/adapdev/Adapdev/src/Adapdev.UnitTest.Core In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24316/src/Adapdev.UnitTest.Core Modified Files: Adapdev.UnitTest.Core.csproj RunTestCommand.cs RunTestFixtureCommand.cs RunTestIterationCommand.cs TestRunner.cs TestSuiteBuilder.cs TestUnit.cs TextFormatter.cs Log Message: Index: TestSuiteBuilder.cs =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev.UnitTest.Core/TestSuiteBuilder.cs,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** TestSuiteBuilder.cs 16 Nov 2005 07:01:53 -0000 1.13 --- TestSuiteBuilder.cs 23 Nov 2005 03:00:42 -0000 1.14 *************** *** 213,216 **** --- 213,217 ---- this.ProcessMaxKAttribute(m, t); this.ProcessMinOperationsPerSecondAttribute(m, t); + this.ProcessTransactionAttribute(m, t); if(log.IsDebugEnabled) log.Debug("Test built: " + t.ToString()); *************** *** 347,350 **** --- 348,363 ---- } + public void ProcessTransactionAttribute(ICustomAttributeProvider m, Test t) + { + if (TypeHelper.HasCustomAttribute(m, typeof(Adapdev.UnitTest.TransactionAttribute))) + { + t.TransactionType = TransactionType.AutoCommit; + } + else if (TypeHelper.HasCustomAttribute(m, typeof(Adapdev.UnitTest.RollbackTransactionAttribute))) + { + t.TransactionType = TransactionType.AutoRollback; + } + } + public void ProcessTestSetUpAttribute(ICustomAttributeProvider mi, TestHelper t) { Index: TestUnit.cs =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev.UnitTest.Core/TestUnit.cs,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** TestUnit.cs 16 Nov 2005 07:01:53 -0000 1.4 --- TestUnit.cs 23 Nov 2005 03:00:42 -0000 1.5 *************** *** 48,51 **** --- 48,52 ---- protected int _maxK = 0; protected ArrayList _attributes = new ArrayList(); + protected TransactionType _transaction = TransactionType.None; public TestUnit() *************** *** 65,68 **** --- 66,75 ---- } + public TransactionType TransactionType + { + get{return this._transaction;} + set{this._transaction = value;} + } + public void AddAttribute(Attribute a) { Index: RunTestCommand.cs =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev.UnitTest.Core/RunTestCommand.cs,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** RunTestCommand.cs 16 Nov 2005 07:01:53 -0000 1.4 --- RunTestCommand.cs 23 Nov 2005 03:00:42 -0000 1.5 *************** *** 1,3 **** --- 1,4 ---- using System; + using System.Collections; using System.Diagnostics; using System.IO; *************** *** 7,10 **** --- 8,12 ---- using Adapdev.Diagnostics; using Adapdev.Threading; + using Adapdev.Threading; using log4net; *************** *** 29,32 **** --- 31,35 ---- private object o = null; private TestFixtureIteration _testFixtureIteration = null; + private readonly SmartThreadPool pool; public RunTestCommand(TestEventDispatcher dispatcher, Test test, TestFixture tf, Type type, object o, TestFixtureIteration tfi) *************** *** 40,43 **** --- 43,57 ---- } + public RunTestCommand(TestEventDispatcher dispatcher, Test test, TestFixture tf, Type type, object o, TestFixtureIteration tfi, SmartThreadPool pool) + { + this._dispatcher = dispatcher; + this._test = test; + this._testFixture = tf; + this.o = o; + this._testFixtureIteration = tfi; + this.pool = pool; + this._type = type; + } + public void Execute() { *************** *** 81,96 **** private void RunTestIteration(TestResult testResult, MethodInfo method) { ! if(this._testFixture.IsMultiThreaded) { ! using(ThreadPoolWait threadPool = new ThreadPoolWait()) ! { ! for (int i = 1; i <= _test.RepeatCount; i++) ! { ! RunTestIterationCommand command = new RunTestIterationCommand(this._dispatcher, this._test, this._testFixture, this._type, this.o, this._testFixtureIteration, method, i, testResult); ! threadPool.QueueUserWorkItem(new WaitCallback(command.Execute)); ! } ! threadPool.WaitOne(); } } else --- 95,131 ---- private void RunTestIteration(TestResult testResult, MethodInfo method) { ! if(this._testFixture.IsMultiThreaded && this.pool != null) { ! ArrayList threads = new ArrayList(); ! for (int i = 1; i <= _test.RepeatCount; i++) ! { ! RunTestIterationCommand command = new RunTestIterationCommand(this._dispatcher, this._test, this._testFixture, this._type, this.o, this._testFixtureIteration, method, i, testResult); ! Thread t = new Thread(new ThreadStart(command.Execute)); ! threads.Add(t); ! t.Start(); } + foreach(Thread t in threads) t.Join(); + + // try + // { + // ArrayList workitems = new ArrayList(); + // + // for (int i = 1; i <= _test.RepeatCount; i++) + // { + // RunTestIterationCommand command = new RunTestIterationCommand(this._dispatcher, this._test, this._testFixture, this._type, this.o, this._testFixtureIteration, method, i, testResult); + // workitems.Add(pool.QueueWorkItem(new WorkItemCallback(command.Execute))); + // } + // + // workitems.TrimToSize(); + // IWorkItemResult[] results = workitems.ToArray(typeof(IWorkItemResult)) as IWorkItemResult[]; + // + // SmartThreadPool.WaitAll(results, 15000, true); + // } + // catch(Exception ex) + // { + // Console.WriteLine(ex.Message); + // Console.WriteLine(ex.StackTrace); + // } } else Index: TestRunner.cs =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev.UnitTest.Core/TestRunner.cs,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** TestRunner.cs 16 Nov 2005 07:01:53 -0000 1.12 --- TestRunner.cs 23 Nov 2005 03:00:42 -0000 1.13 *************** *** 100,103 **** --- 100,104 ---- public TestAssemblyResult[] Run(TestSuite ts) { + Thread.CurrentThread.ApartmentState = ApartmentState.MTA; this._mode = RunMode.Running; ArrayList al = new ArrayList(); Index: TextFormatter.cs =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev.UnitTest.Core/TextFormatter.cs,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** TextFormatter.cs 16 Nov 2005 07:01:53 -0000 1.10 --- TextFormatter.cs 23 Nov 2005 03:00:42 -0000 1.11 *************** *** 83,89 **** if(!(tar.State == TestState.Ignore)) { foreach(AbstractTestIteration ati in tar.Iterations) { ! if(tar.Iterations.Count > 1) sb.Append(this.GetNesting(nesting) + "Iteration: " + ati.Iteration + "\r\n"); sb.AppendFormat(this.GetNesting(nesting + 1) + this.GetMarker(tar) + "{0} - {1}\r\n", tar.Name, tar.State); //sb.AppendFormat(this.GetNesting(nesting + 1) + this.GetMarker(tar) + "Time: {0}s\r\n", tar.GetTotalDuration()); --- 83,93 ---- if(!(tar.State == TestState.Ignore)) { + if(tar.Iterations.Count > 1) nesting += 1; foreach(AbstractTestIteration ati in tar.Iterations) { ! if(tar.Iterations.Count > 1) ! { ! sb.Append(this.GetNesting(nesting) + "Iteration: " + ati.Iteration + "\r\n"); ! } sb.AppendFormat(this.GetNesting(nesting + 1) + this.GetMarker(tar) + "{0} - {1}\r\n", tar.Name, tar.State); //sb.AppendFormat(this.GetNesting(nesting + 1) + this.GetMarker(tar) + "Time: {0}s\r\n", tar.GetTotalDuration()); *************** *** 93,96 **** --- 97,106 ---- } + if(ati is TestIteration) + { + sb.Append(this.GetNesting(nesting + 2) + "Thread Id: " + (ati as TestIteration).Thread + Environment.NewLine); + sb.Append(this.GetNesting(nesting + 2) + "Time: " + (ati as TestIteration).Duration + Environment.NewLine); + } + if(showFailure && (ati is TestIteration)) { *************** *** 100,108 **** } - if(ati is TestIteration) - { - sb.Append(this.GetNesting(nesting + 2) + "Thread Id: " + (ati as TestIteration).Thread + Environment.NewLine); - sb.Append(this.GetNesting(nesting + 2) + "Time: " + (ati as TestIteration).Duration + Environment.NewLine); - } if(showOutput && ati.ConsoleOutput.Length > 0) --- 110,113 ---- Index: RunTestIterationCommand.cs =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev.UnitTest.Core/RunTestIterationCommand.cs,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** RunTestIterationCommand.cs 16 Nov 2005 07:01:53 -0000 1.5 --- RunTestIterationCommand.cs 23 Nov 2005 03:00:42 -0000 1.6 *************** *** 4,7 **** --- 4,8 ---- using System.Reflection; using System.Threading; + using Adapdev.Commands; using Adapdev.Diagnostics; *************** *** 11,15 **** /// Summary description for RunTestIterationCommand. /// </summary> ! public class RunTestIterationCommand { private TestEventDispatcher _dispatcher = null; --- 12,16 ---- /// Summary description for RunTestIterationCommand. /// </summary> ! public class RunTestIterationCommand : IThreadWorkItemCommand { private TestEventDispatcher _dispatcher = null; *************** *** 72,77 **** kStart = Process.GetCurrentProcess().WorkingSet; timer.Start(); ! ! new RunMethodCommand(this._method, o).Execute(); timer.Stop(); --- 73,83 ---- kStart = Process.GetCurrentProcess().WorkingSet; timer.Start(); ! ! // Check for transactions and run ! ICommand command = new RunMethodCommand(this._method, o); ! if(this._test.TransactionType == TransactionType.AutoCommit) command = new AutoCommitCommand(command); ! else if(this._test.TransactionType == TransactionType.AutoRollback) command = new AutoRollbackCommand(command); ! command.Execute(); ! timer.Stop(); *************** *** 230,234 **** ! public void Execute(object o){this.Execute();} } } --- 236,240 ---- ! public object Execute(object o){this.Execute();return 1;} } } Index: RunTestFixtureCommand.cs =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev.UnitTest.Core/RunTestFixtureCommand.cs,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** RunTestFixtureCommand.cs 16 Nov 2005 07:01:53 -0000 1.4 --- RunTestFixtureCommand.cs 23 Nov 2005 03:00:42 -0000 1.5 *************** *** 11,15 **** /// Summary description for TestFixtureCommand. /// </summary> ! public class RunTestFixtureCommand : ICommand { private TestEventDispatcher _dispatcher = null; --- 11,15 ---- /// Summary description for TestFixtureCommand. /// </summary> ! public class RunTestFixtureCommand : IThreadWorkItemCommand { private TestEventDispatcher _dispatcher = null; *************** *** 96,108 **** if(this._testFixture.IsMultiThreaded) { ! using(ThreadPoolWait threadPool = new ThreadPoolWait()) { ! foreach (Test test in this._testFixture.GetTests()) ! { ! RunTestCommand command = new RunTestCommand(this._dispatcher, test, this._testFixture, this._type, this._o, this._testFixtureIteration); ! threadPool.QueueUserWorkItem(new WaitCallback(command.Execute)); ! } ! threadPool.WaitOne(); } } else --- 96,146 ---- if(this._testFixture.IsMultiThreaded) { ! ArrayList threads = new ArrayList(); ! ! foreach (Test test in this._testFixture.GetTests()) { ! RunTestCommand command = new RunTestCommand(this._dispatcher, test, this._testFixture, this._type, this._o, this._testFixtureIteration); ! Thread t = new Thread(new ThreadStart(command.Execute)); ! threads.Add(t); ! t.Start(); } + foreach(Thread t in threads) t.Join(); + + + // using(ThreadPoolWait threadPool = new ThreadPoolWait()) + // { + // foreach (Test test in this._testFixture.GetTests()) + // { + // RunTestCommand command = new RunTestCommand(this._dispatcher, test, this._testFixture, this._type, this._o, this._testFixtureIteration); + // threadPool.QueueUserWorkItem(new WaitCallback(command.Execute)); + // } + // threadPool.WaitOne(); + // } + + // SmartThreadPool smartThreadPool = new SmartThreadPool(); + // + // try + // { + // ArrayList workitems = new ArrayList(); + // + // foreach(Test test in this._testFixture.GetTests()) + // { + // RunTestCommand command = new RunTestCommand(this._dispatcher, test, this._testFixture, this._type, this._o, this._testFixtureIteration); + // workitems.Add(smartThreadPool.QueueWorkItem(new WorkItemCallback(command.Execute))); + // } + // + // workitems.TrimToSize(); + // IWorkItemResult[] results = workitems.ToArray(typeof(IWorkItemResult)) as IWorkItemResult[]; + // SmartThreadPool.WaitAll(results, 15000, true); + // } + // catch(Exception ex) + // { + // Console.WriteLine(ex.Message); + // Console.WriteLine(ex.StackTrace); + // } + // finally + // { + // smartThreadPool.Shutdown(); + // } } else *************** *** 115,118 **** --- 153,161 ---- } + public object Execute(object o) + { + this.Execute(); + return 1; + } } } Index: Adapdev.UnitTest.Core.csproj =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev.UnitTest.Core/Adapdev.UnitTest.Core.csproj,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** Adapdev.UnitTest.Core.csproj 16 Nov 2005 07:01:53 -0000 1.9 --- Adapdev.UnitTest.Core.csproj 23 Nov 2005 03:00:42 -0000 1.10 *************** *** 142,145 **** --- 142,155 ---- /> <File + RelPath = "AutoCommitCommand.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "AutoRollbackCommand.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "BaseTestHelper.cs" SubType = "Code" *************** *** 167,170 **** --- 177,185 ---- /> <File + RelPath = "IThreadWorkItemCommand.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "LocalSeparateTestEngine.cs" SubType = "Code" |
From: Sean M. <int...@us...> - 2005-11-23 03:00:51
|
Update of /cvsroot/adapdev/Adapdev/src/Adapdev In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24316/src/Adapdev Modified Files: Adapdev.csproj Log Message: Index: Adapdev.csproj =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev/Adapdev.csproj,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** Adapdev.csproj 16 Nov 2005 07:02:01 -0000 1.16 --- Adapdev.csproj 23 Nov 2005 03:00:42 -0000 1.17 *************** *** 566,569 **** --- 566,574 ---- /> <File + RelPath = "Threading\CallerThreadContext.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "Threading\DelegateAdapter.cs" SubType = "Code" *************** *** 571,574 **** --- 576,594 ---- /> <File + RelPath = "Threading\Exceptions.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "Threading\SmartThreadPool.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "Threading\STPStartInfo.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "Threading\ThreadPoolWait.cs" SubType = "Code" *************** *** 576,579 **** --- 596,609 ---- /> <File + RelPath = "Threading\WorkItem.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "Threading\WorkItemsQueue.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "Transactions\TransactionScope.cs" SubType = "Code" |
From: Sean M. <int...@us...> - 2005-11-23 03:00:51
|
Update of /cvsroot/adapdev/Adapdev/src/Adapdev.UnitTest.Core.AdapdevTests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24316/src/Adapdev.UnitTest.Core.AdapdevTests Modified Files: Adapdev.UnitTest.Core.AdapdevTests.csproj Log Message: Index: Adapdev.UnitTest.Core.AdapdevTests.csproj =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev.UnitTest.Core.AdapdevTests/Adapdev.UnitTest.Core.AdapdevTests.csproj,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** Adapdev.UnitTest.Core.AdapdevTests.csproj 16 Nov 2005 07:01:53 -0000 1.6 --- Adapdev.UnitTest.Core.AdapdevTests.csproj 23 Nov 2005 03:00:41 -0000 1.7 *************** *** 85,88 **** --- 85,93 ---- Package = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}" /> + <Reference + Name = "System.EnterpriseServices" + AssemblyName = "System.EnterpriseServices" + HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.EnterpriseServices.dll" + /> </References> </Build> *************** *** 109,112 **** --- 114,132 ---- BuildAction = "Compile" /> + <File + RelPath = "RollbackTransactionTest.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "SomeTest.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "TransactionTest.cs" + SubType = "Code" + BuildAction = "Compile" + /> </Include> </Files> |
From: Sean M. <int...@us...> - 2005-11-23 03:00:51
|
Update of /cvsroot/adapdev/Adapdev/src/Adapdev.UnitTest In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24316/src/Adapdev.UnitTest Modified Files: Adapdev.UnitTest.csproj TestAttribute.cs Added Files: TransactionType.cs Log Message: --- NEW FILE: TransactionType.cs --- using System; namespace Adapdev.UnitTest { /// <summary> /// Summary description for TransactionType. /// </summary> public enum TransactionType { None, AutoCommit, AutoRollback } } Index: Adapdev.UnitTest.csproj =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev.UnitTest/Adapdev.UnitTest.csproj,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** Adapdev.UnitTest.csproj 16 Nov 2005 07:02:00 -0000 1.8 --- Adapdev.UnitTest.csproj 23 Nov 2005 03:00:42 -0000 1.9 *************** *** 146,150 **** /> <File ! RelPath = "RollbackTransaction.cs" SubType = "Code" BuildAction = "Compile" --- 146,150 ---- /> <File ! RelPath = "RollbackTransactionAttribute.cs" SubType = "Code" BuildAction = "Compile" *************** *** 201,205 **** /> <File ! RelPath = "Transaction.cs" SubType = "Code" BuildAction = "Compile" --- 201,210 ---- /> <File ! RelPath = "TransactionAttribute.cs" ! SubType = "Code" ! BuildAction = "Compile" ! /> ! <File ! RelPath = "TransactionType.cs" SubType = "Code" BuildAction = "Compile" Index: TestAttribute.cs =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev.UnitTest/TestAttribute.cs,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** TestAttribute.cs 16 Nov 2005 07:02:00 -0000 1.5 --- TestAttribute.cs 23 Nov 2005 03:00:42 -0000 1.6 *************** *** 45,48 **** --- 45,49 ---- private string _description = ""; private TestType _testType = TestType.Unit; + private TransactionType _transactionType = TransactionType.None; /// <summary> *************** *** 74,77 **** --- 75,84 ---- } + public TransactionType TransactionType + { + get { return _transactionType; } + set { _transactionType = value; } + } + } } \ No newline at end of file |
From: Sean M. <int...@us...> - 2005-11-23 03:00:49
|
Update of /cvsroot/adapdev/Adapdev/src/Adapdev.UnitTest.Core.Tests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24316/src/Adapdev.UnitTest.Core.Tests Modified Files: Adapdev.UnitTest.Core.Tests.csproj AdapdevLocalTestEngineTest.cs Log Message: Index: AdapdevLocalTestEngineTest.cs =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev.UnitTest.Core.Tests/AdapdevLocalTestEngineTest.cs,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** AdapdevLocalTestEngineTest.cs 16 Nov 2005 07:01:53 -0000 1.7 --- AdapdevLocalTestEngineTest.cs 23 Nov 2005 03:00:41 -0000 1.8 *************** *** 1,3 **** --- 1,4 ---- using System; + using System.Threading; using NUnit.Framework; *************** *** 27,31 **** public void RunAdapdev() { ! using(ITestEngine engine = TestEngineFactory.CreateLocal(basedir + @"\Adapdev.UnitTest.Core.AdapdevTests.dll")) { Assert.IsTrue(engine.GetLoadedAssemblies().Count > 0, "No assemblies loaded."); --- 28,32 ---- public void RunAdapdev() { ! using(ITestEngine engine = TestEngineFactory.CreateLocalSeparate(basedir + @"\Adapdev.UnitTest.Core.AdapdevTests.dll")) { Assert.IsTrue(engine.GetLoadedAssemblies().Count > 0, "No assemblies loaded."); *************** *** 37,41 **** Console.WriteLine(new Adapdev.UnitTest.Core.TextFormatter(new TestAssemblyResult[]{result}, true, true, true).GetText()); ! Assert.AreEqual(20, result.Passed); Assert.AreEqual(2, result.Failed); --- 38,42 ---- Console.WriteLine(new Adapdev.UnitTest.Core.TextFormatter(new TestAssemblyResult[]{result}, true, true, true).GetText()); ! Assert.AreEqual(25, result.Passed); Assert.AreEqual(2, result.Failed); Index: Adapdev.UnitTest.Core.Tests.csproj =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev.UnitTest.Core.Tests/Adapdev.UnitTest.Core.Tests.csproj,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** Adapdev.UnitTest.Core.Tests.csproj 21 Nov 2005 06:16:04 -0000 1.6 --- Adapdev.UnitTest.Core.Tests.csproj 23 Nov 2005 03:00:41 -0000 1.7 *************** *** 18,22 **** OutputType = "Library" PreBuildEvent = "" ! PostBuildEvent = "" RootNamespace = "Adapdev.UnitTest.Core.Tests" RunPostBuildEvent = "OnBuildSuccess" --- 18,22 ---- OutputType = "Library" PreBuildEvent = "" ! PostBuildEvent = "xcopy ..\..\..\..\lib\nunit $(TargetDir)\nunit /s /e /y /i
copy ..\..\..\Adapdev.UnitTest.Core.AdapdevTests\$(OutDir)Adapdev.UnitTest.Core.AdapdevTests.dll $(TargetDir)\Adapdev.UnitTest.Core.AdapdevTests.dll
" RootNamespace = "Adapdev.UnitTest.Core.Tests" RunPostBuildEvent = "OnBuildSuccess" |
From: Sean M. <int...@us...> - 2005-11-21 06:16:13
|
Update of /cvsroot/adapdev/Adapdev/src/Adapdev.UnitTest.Core.Tests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23258/src/Adapdev.UnitTest.Core.Tests Modified Files: Adapdev.UnitTest.Core.Tests.csproj Log Message: Index: Adapdev.UnitTest.Core.Tests.csproj =================================================================== RCS file: /cvsroot/adapdev/Adapdev/src/Adapdev.UnitTest.Core.Tests/Adapdev.UnitTest.Core.Tests.csproj,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** Adapdev.UnitTest.Core.Tests.csproj 16 Nov 2005 07:01:53 -0000 1.5 --- Adapdev.UnitTest.Core.Tests.csproj 21 Nov 2005 06:16:04 -0000 1.6 *************** *** 18,22 **** OutputType = "Library" PreBuildEvent = "" ! PostBuildEvent = "xcopy ..\..\..\..\lib\nunit $(TargetDir)\nunit /s /e /y /i
copy ..\..\..\Adapdev.UnitTest.Core.AdapdevTests\bin\Debug\Adapdev.UnitTest.Core.AdapdevTests.dll $(TargetDir)\Adapdev.UnitTest.Core.AdapdevTests.dll" RootNamespace = "Adapdev.UnitTest.Core.Tests" RunPostBuildEvent = "OnBuildSuccess" --- 18,22 ---- OutputType = "Library" PreBuildEvent = "" ! PostBuildEvent = "" RootNamespace = "Adapdev.UnitTest.Core.Tests" RunPostBuildEvent = "OnBuildSuccess" |
From: Sean M. <int...@us...> - 2005-11-17 02:55:29
|
Update of /cvsroot/adapdev/Adapdev/src/Adapdev/Text/Indexing/FullText/Tokenizers In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13039/src/Adapdev/Text/Indexing/FullText/Tokenizers Added Files: NullTokenizer.cs StringTokenizer.cs Log Message: --- NEW FILE: StringTokenizer.cs --- #region license // Bamboo.Prevalence - a .NET object prevalence engine // Copyright (C) 2004 Rodrigo B. de Oliveira // // Based on the original concept and implementation of Prevayler (TM) // by Klaus Wuestefeld. Visit http://www.prevayler.org for details. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE // OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // Contact Information // // http://bbooprevalence.sourceforge.net // mailto:rod...@us... #endregion using System; using Adapdev.Text.Indexing.FullText; namespace Adapdev.Text.Indexing.FullText.Tokenizers { /// <summary> /// Splits a string into tokens by considering any /// whitespace and punctuation characters as separators. /// </summary> /// <remarks> /// This tokenizer must always be the last in a /// tokenizer chain. /// </remarks> [Serializable] public class StringTokenizer : ITokenizer { string _text; int _current; /// <summary> /// Creates a new tokenizer for the string /// in the text argument. /// </summary> /// <param name="text">token source</param> public StringTokenizer(string text) : this(text, 0) { } /// <summary> /// Creates a new tokenizer for the string /// in the text argument starting from /// the position indicated by the current /// argument. /// </summary> /// <param name="text">token source</param> /// <param name="current">starting position</param> protected StringTokenizer(string text, int current) { if (null == text) { throw new ArgumentNullException("text", "text can't be null"); } _text = text; _current = current; } #region Implementation of ITokenizer /// <summary> /// Always returns null since this tokenizer /// must be the last in the chain. /// </summary> public ITokenizer Previous { get { return null; } set { throw new NotSupportedException("ITokenizer chaining not supported by StringTokenizer!"); } } /// <summary> /// See <see cref="Adapdev.Text.Indexing.FullText.ITokenizer.NextToken"/> for /// details. /// </summary> /// <returns></returns> public Adapdev.Text.Indexing.FullText.Token NextToken() { SkipSeparators(); int begin = _current; for (; _current<_text.Length; ++_current) { if (IsSeparator(_text, _current)) { break; } } if (_current > begin) { return new Token(_text.Substring(begin, _current-begin), begin); } return null; } /// <summary> /// Returns a clone. /// </summary> /// <param name="tail">must always be null</param> /// <returns>a clone</returns> public ITokenizer Clone(ITokenizer tail) { if (null != tail) { throw new NotSupportedException("ITokenizer chaining not supported by StringTokenizer!"); } return new StringTokenizer(_text, _current); } #endregion void SkipSeparators() { for (; _current<_text.Length; ++_current) { if (!IsSeparator(_text, _current)) { break; } } } bool IsSeparator(string text, int index) { char current = text[index]; return Char.IsWhiteSpace(current) || Char.IsPunctuation(current); } } } --- NEW FILE: NullTokenizer.cs --- #region license // Bamboo.Prevalence - a .NET object prevalence engine // Copyright (C) 2004 Rodrigo B. de Oliveira // // Based on the original concept and implementation of Prevayler (TM) // by Klaus Wuestefeld. Visit http://www.prevayler.org for details. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE // OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // Contact Information // // http://bbooprevalence.sourceforge.net // mailto:rod...@us... #endregion using System; using Adapdev.Text.Indexing.FullText; namespace Adapdev.Text.Indexing.FullText.Tokenizers { /// <summary> /// Summary description for NullTokenizer. /// </summary> public class NullTokenizer : ITokenizer { /// <summary> /// The one and only NullTokenizer instance. /// </summary> public static ITokenizer Instance = new NullTokenizer(); private NullTokenizer() { } #region Implementation of ITokenizer /// <summary> /// Always returns null since this tokenizer /// must be the last in the chain. /// </summary> public ITokenizer Previous { get { return null; } set { throw new NotSupportedException("ITokenizer chaining not supported by NullTokenizer!"); } } /// <summary> /// See <see cref="Adapdev.Text.Indexing.FullText.ITokenizer.NextToken"/> for /// details. /// </summary> /// <returns></returns> public Adapdev.Text.Indexing.FullText.Token NextToken() { return null; } /// <summary> /// Returns this. /// </summary> /// <param name="tail">must always be null</param> /// <returns>a clone</returns> public ITokenizer Clone(ITokenizer tail) { return this; } #endregion } } |
Update of /cvsroot/adapdev/Adapdev/src/Adapdev/Text/Indexing/FullText/Filters In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13039/src/Adapdev/Text/Indexing/FullText/Filters Added Files: AbstractFilter.cs ConditionalFilter.cs RegexTokenFilter.cs SpecialCharactersFilter.cs TokenLengthFilter.cs WordFilter.cs Log Message: --- NEW FILE: RegexTokenFilter.cs --- #region license // Bamboo.Prevalence - a .NET object prevalence engine // Copyright (C) 2004 Rodrigo B. de Oliveira // // Based on the original concept and implementation of Prevayler (TM) // by Klaus Wuestefeld. Visit http://www.prevayler.org for details. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE // OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // Contact Information // // http://bbooprevalence.sourceforge.net // mailto:rod...@us... #endregion using System; using System.Text.RegularExpressions; using Adapdev.Text.Indexing.FullText; namespace Adapdev.Text.Indexing.FullText.Filters { /// <summary> /// Filters off tokens based on a regular expression. /// </summary> /// <remarks>This filter will filter off /// any tokens that <b>match</b> the regular /// expression (and not the ones that don't)</remarks> [Serializable] public class RegexTokenFilter : ConditionalFilter { Regex _regex; /// <summary> /// Creates a new filter that will filter off any /// tokens that match the regular expression passed /// as argument. /// </summary> /// <param name="regex">the regular expression</param> public RegexTokenFilter(string regex) : this(null, regex) { } /// <summary> /// Creates a new filter that will filter off any /// tokens that match the regular expression passed /// as argument. /// </summary> /// <param name="previous">the previous tokenizer in the chain</param> /// <param name="regex">the regular expression</param> public RegexTokenFilter(ITokenizer previous, string regex) : base(previous) { if (null == regex) { throw new ArgumentNullException("regex", "regex can't be null!"); } _regex = new Regex(regex); } /// <summary> /// Creates a new filter that will filter off any /// tokens that match the regular expression passed /// as argument. /// </summary> /// <param name="regex">the regular expression</param> public RegexTokenFilter(Regex regex) : this(null, regex) { } /// <summary> /// Creates a new filter that will filter off any /// tokens that match the regular expression passed /// as argument. /// </summary> /// <param name="previous">the previous tokenizer in the chain</param> /// <param name="regex">the regular expression</param> public RegexTokenFilter(ITokenizer previous, Regex regex) : base(previous) { if (null == regex) { throw new ArgumentNullException("regex", "regex can't be null!"); } _regex = regex; } /// <summary> /// See <see cref="ConditionalFilter.IsValidToken"/> for details. /// </summary> /// <param name="token"></param> /// <returns></returns> protected override bool IsValidToken(Token token) { return !_regex.IsMatch(token.Value); } } } --- NEW FILE: AbstractFilter.cs --- #region license // Bamboo.Prevalence - a .NET object prevalence engine // Copyright (C) 2004 Rodrigo B. de Oliveira // // Based on the original concept and implementation of Prevayler (TM) // by Klaus Wuestefeld. Visit http://www.prevayler.org for details. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE // OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // Contact Information // // http://bbooprevalence.sourceforge.net // mailto:rod...@us... #endregion using System; using Adapdev.Text.Indexing.FullText; namespace Adapdev.Text.Indexing.FullText.Filters { /// <summary> /// Basic implementation for ITokenFilter with /// support for tokenizer chaining. /// </summary> [Serializable] public abstract class AbstractFilter : ITokenFilter { /// <summary> /// the previous tokenizer in the chain /// </summary> protected ITokenizer _previous; /// <summary> /// Creates a new filter with no previous /// tokenizer. /// </summary> protected AbstractFilter() { _previous = null; } /// <summary> /// Creates a new filter with a previous /// tokenizer in a tokenizer chain. /// </summary> /// <param name="previous">the previous tokenizer /// in the chain</param> protected AbstractFilter(ITokenizer previous) { _previous = previous; } /// <summary> /// Gets/sets the previous tokenizer /// in the chain. /// </summary> public ITokenizer Previous { get { return _previous; } set { _previous = value; } } /// <summary> /// Returns a MemberwiseClone of this object /// with the guarantee that the tail argument /// will be the last tokenizer in the new /// tokenizer chain. /// </summary> /// <param name="tail">the last tokenizer for the /// new chain</param> /// <returns>cloned chain with tail as the /// last tokenizer in the chain</returns> public ITokenizer Clone(ITokenizer tail) { AbstractFilter clone = MemberwiseClone() as AbstractFilter; if (null == _previous) { clone._previous = tail; } else { clone._previous = _previous.Clone(tail); } return clone; } /// <summary> /// Must be supplied by derived classes. /// </summary> /// <returns></returns> public abstract Token NextToken(); } } --- NEW FILE: WordFilter.cs --- #region license // Bamboo.Prevalence - a .NET object prevalence engine // Copyright (C) 2004 Rodrigo B. de Oliveira // // Based on the original concept and implementation of Prevayler (TM) // by Klaus Wuestefeld. Visit http://www.prevayler.org for details. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE // OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // Contact Information // // http://bbooprevalence.sourceforge.net // mailto:rod...@us... #endregion using System; using System.Collections; using Adapdev.Text.Indexing.FullText; namespace Adapdev.Text.Indexing.FullText.Filters { /// <summary> /// Filters off tokens by word. /// </summary> [Serializable] public class WordFilter : ConditionalFilter { Hashtable _words; /// <summary> /// See <see cref="WordFilter(string[])"/>. /// </summary> /// <param name="previous">the previous tokenizer in the chain</param> /// <param name="words">list of words that should be filtered /// off the chain</param> public WordFilter(ITokenizer previous, params string[] words) : base(previous) { if (null == words) { throw new ArgumentNullException("words"); } _words = new Hashtable(words.Length); foreach (string word in words) { _words[word] = null; } } /// <summary> /// Creates a new filter that will not allow /// any words in the list represented by the words /// argument to pass through the chain. /// </summary> /// <param name="words">list of words that should be filtered /// off the chain</param> public WordFilter(params string[] words) : this(null, words) { } /// <summary> /// See <see cref="ConditionalFilter.IsValidToken"/> for details. /// </summary> /// <param name="token"></param> /// <returns></returns> protected override bool IsValidToken(Token token) { return !_words.ContainsKey(token.Value); } } } --- NEW FILE: SpecialCharactersFilter.cs --- #region license // Bamboo.Prevalence - a .NET object prevalence engine // Copyright (C) 2004 Rodrigo B. de Oliveira // // Based on the original concept and implementation of Prevayler (TM) // by Klaus Wuestefeld. Visit http://www.prevayler.org for details. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE // OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // Contact Information // // http://bbooprevalence.sourceforge.net // mailto:rod...@us... #endregion using System; using System.Globalization; using System.Text; using Adapdev.Text.Indexing.FullText; namespace Adapdev.Text.Indexing.FullText.Filters { /// <summary> /// A filter that replaces special characters by /// their simpler ASCII counterparts. /// </summary> [Serializable] public class SpecialCharactersFilter : AbstractFilter { /// <summary> /// Creates a new filter. /// </summary> public SpecialCharactersFilter() { } /// <summary> /// Creates a new filter in a tokenizer chain. /// </summary> /// <param name="previous">previous tokenizer in the chain</param> public SpecialCharactersFilter(ITokenizer previous) : base(previous) { } /// <summary> /// Gets the token from the previous tokenizer in the /// chain and replaces every "complex" character /// in the token by its simpler counterpart. /// </summary> /// <returns>the new token or null</returns> public override Token NextToken() { Token token = _previous.NextToken(); if (null != token) { token.Value = Filter(token.Value); } return token; } public static string Filter(string value) { char[] mapped = new char[value.Length]; for (int i=0; i<value.Length; ++i) { char c = char.ToLower(value[i]); switch (c) { case 'á': c = 'a'; break; case 'ã': c = 'a'; break; case 'â': c = 'a'; break; case 'à ': c = 'a'; break; case 'é': c = 'e'; break; case 'ê': c = 'e'; break; case 'Ã': c = 'i'; break; case 'ó': c = 'o'; break; case 'õ': c = 'o'; break; case 'ô': c = 'o'; break; case 'ú': c = 'u'; break; case 'ü': c = 'u'; break; case 'ç': c = 'c'; break; } mapped[i] = c; } return new string(mapped); } } } --- NEW FILE: ConditionalFilter.cs --- #region license // Bamboo.Prevalence - a .NET object prevalence engine // Copyright (C) 2004 Rodrigo B. de Oliveira // // Based on the original concept and implementation of Prevayler (TM) // by Klaus Wuestefeld. Visit http://www.prevayler.org for details. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE // OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // Contact Information // // http://bbooprevalence.sourceforge.net // mailto:rod...@us... #endregion using System; using Adapdev.Text.Indexing.FullText; namespace Adapdev.Text.Indexing.FullText.Filters { /// <summary> /// Base class for filter implementations that /// exclude tokens from the stream based on /// a condition. /// </summary> [Serializable] public abstract class ConditionalFilter : AbstractFilter { /// <summary> /// Creates a standalone filter (with no previous /// tokenizer). /// </summary> protected ConditionalFilter() { } /// <summary> /// Creates a filter in a filter chain. /// </summary> /// <param name="previous">the previous token in the chain</param> protected ConditionalFilter(ITokenizer previous) : base(previous) { } /// <summary> /// Gets a token from the previous tokenizer in the chain /// and checks the condition implemented by IsValidToken, /// when IsValidToken returns false the token is discarded /// and a new one is tried. This process is repeated until /// IsValidToken returns true or the previous tokenizer /// returns null. /// </summary> /// <returns>the next token for which IsValidToken returns true or /// null when the previous tokenizer runs out of tokens</returns> public override Adapdev.Text.Indexing.FullText.Token NextToken() { Token token = _previous.NextToken(); while (null != token) { if (IsValidToken(token)) { break; } token = _previous.NextToken(); } return token; } /// <summary> /// Test if the token is a valid token and /// as such should be returned to the /// caller of <see cref="NextToken" />. /// </summary> /// <param name="token">token to be tested</param> /// <returns>true if the token is valid, false otherwise</returns> protected abstract bool IsValidToken(Token token); } } --- NEW FILE: TokenLengthFilter.cs --- #region license // Bamboo.Prevalence - a .NET object prevalence engine // Copyright (C) 2004 Rodrigo B. de Oliveira // // Based on the original concept and implementation of Prevayler (TM) // by Klaus Wuestefeld. Visit http://www.prevayler.org for details. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE // OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // Contact Information // // http://bbooprevalence.sourceforge.net // mailto:rod...@us... #endregion using System; using Adapdev.Text.Indexing.FullText; namespace Adapdev.Text.Indexing.FullText.Filters { /// <summary> /// Filters off tokens by length. /// </summary> [Serializable] public class TokenLengthFilter : ConditionalFilter { int _minTokenLength; /// <summary> /// Creates a new filter that will only allow /// tokens with at least minTokenLength /// characters to pass. /// </summary> /// <param name="minTokenLength">minimum token length</param> public TokenLengthFilter(int minTokenLength) { _minTokenLength = minTokenLength; } /// <summary> /// See <see cref="TokenLengthFilter(int)"/>. /// </summary> /// <param name="previous">previous tokenizer in the chain</param> /// <param name="minTokenLength">minimum token length</param> public TokenLengthFilter(ITokenizer previous, int minTokenLength) : base(previous) { _minTokenLength = minTokenLength; } /// <summary> /// See <see cref="ConditionalFilter.IsValidToken"/> for details. /// </summary> /// <param name="token"></param> /// <returns></returns> protected override bool IsValidToken(Token token) { return (token.Value.Length >= _minTokenLength); } } } |
From: Sean M. <int...@us...> - 2005-11-17 02:48:40
|
Update of /cvsroot/adapdev/Adapdev/src/Adapdev.NVelocity In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11770/src/Adapdev.NVelocity Added Files: Template.cs Log Message: --- NEW FILE: Template.cs --- namespace NVelocity { using System; using System.IO; using NVelocity.Context; using NVelocity.Exception; using NVelocity.Runtime.Parser; using NVelocity.Runtime.Parser.Node; using NVelocity.Runtime.Resource; /// <summary> This class is used for controlling all template /// operations. This class uses a parser created /// by JavaCC to create an AST that is subsequently /// traversed by a Visitor. /// * /// <pre> /// Template template = Velocity.getTemplate("test.wm"); /// Context context = new VelocityContext(); /// * /// context.put("foo", "bar"); /// context.put("customer", new Customer()); /// * /// template.merge(context, writer); /// </pre> /// * /// </summary> /// <author> <a href="mailto:jv...@ap...">Jason van Zyl</a> /// </author> /// <author> <a href="mailto:ge...@op...">Geir Magnusson Jr.</a> /// </author> /// <version> $Id: Template.cs,v 1.3 2005/11/17 02:48:31 intesar66 Exp $ /// /// </version> public class Template : Resource { /// <summary> To keep track of whether this template has been /// initialized. We use the document.init(context) /// to perform this. /// </summary> private bool initialized = false; private System.Exception errorCondition = null; /// <summary>Default constructor /// </summary> public Template() { } /// <summary> gets the named resource as a stream, parses and inits /// * /// </summary> /// <returns>true if successful /// @throws ResourceNotFoundException if template not found /// from any available source. /// @throws ParseErrorException if template cannot be parsed due /// to syntax (or other) error. /// @throws Exception some other problem, should only be from /// initialization of the template AST. /// /// </returns> public override bool Process() { data = null; Stream is_Renamed = null; errorCondition = null; /* * first, try to get the stream from the loader */ try { is_Renamed = resourceLoader.getResourceStream(name); } catch (ResourceNotFoundException rnfe) { /* * remember and re-throw */ errorCondition = rnfe; throw rnfe; } /* * if that worked, lets protect in case a loader impl * forgets to throw a proper exception */ if (is_Renamed != null) { /* * now parse the template */ try { //UPGRADE_ISSUE: The equivalent of constructor 'java.io.BufferedReader.BufferedReader' is incompatible with the expected type in C#. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1109"' StreamReader br = new StreamReader(new StreamReader(is_Renamed, System.Text.Encoding.GetEncoding(encoding)).BaseStream); data = rsvc.parse(br, name); InitDocument(); return true; } catch (IOException uce) { String msg = "Template.process : Unsupported input encoding : " + encoding + " for template " + name; errorCondition = new ParseErrorException(msg); throw errorCondition; } catch (ParseException pex) { /* * remember the error and convert */ errorCondition = new ParseErrorException(pex.Message); throw errorCondition; } catch (System.Exception e) { /* * who knows? Something from initDocument() */ errorCondition = e; throw e; } finally { /* * Make sure to close the inputstream when we are done. */ is_Renamed.Close(); } } else { /* * is == null, therefore we have some kind of file issue */ errorCondition = new ResourceNotFoundException("Unknown resource error for resource " + name); throw errorCondition; } } /// <summary> initializes the document. init() is not longer /// dependant upon context, but we need to let the /// init() carry the template name down throught for VM /// namespace features /// </summary> public virtual void InitDocument() { /* * send an empty InternalContextAdapter down into the AST to initialize it */ InternalContextAdapterImpl ica = new InternalContextAdapterImpl(new VelocityContext()); try { /* * put the current template name on the stack */ ica.PushCurrentTemplateName(name); /* * init the AST */ ((SimpleNode) data).init(ica, rsvc); } finally { /* * in case something blows up... * pull it off for completeness */ ica.PopCurrentTemplateName(); } } /// <summary> The AST node structure is merged with the /// context to produce the final output. /// * /// Throws IOException if failure is due to a file related /// issue, and Exception otherwise /// * /// </summary> /// <param name="context">Conext with data elements accessed by template /// </param> /// <param name="writer">output writer for rendered template /// @throws ResourceNotFoundException if template not found /// from any available source. /// @throws ParseErrorException if template cannot be parsed due /// to syntax (or other) error. /// @throws Exception anything else. /// /// </param> public virtual void Merge(IContext context, TextWriter writer) { /* * we shouldn't have to do this, as if there is an error condition, * the application code should never get a reference to the * Template */ if (errorCondition != null) { throw errorCondition; } if (data != null) { /* * create an InternalContextAdapter to carry the user Context down * into the rendering engine. Set the template name and render() */ InternalContextAdapterImpl ica = new InternalContextAdapterImpl(context); try { ica.PushCurrentTemplateName(name); ica.CurrentResource = this; ((SimpleNode) data).render(ica, writer); } finally { /* * lets make sure that we always clean up the context */ ica.PopCurrentTemplateName(); ica.CurrentResource = null; } } else { /* * this shouldn't happen either, but just in case. */ String msg = "Template.merge() failure. The document is null, " + "most likely due to parsing error."; rsvc.error(msg); throw new System.Exception(msg); } } } } |
From: Sean M. <int...@us...> - 2005-11-17 02:48:06
|
Update of /cvsroot/adapdev/Adapdev/src/Adapdev.NVelocity/Dvsl In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11652/src/Adapdev.NVelocity/Dvsl Added Files: TemplateHandler.cs Log Message: --- NEW FILE: TemplateHandler.cs --- namespace NVelocity.Dvsl { using System; using System.Collections; using System.IO; using System.Xml; using System.Xml.XPath; using NVelocity.Context; using NVelocity.Runtime.Parser.Node; /// <summary> /// Currently provides the match rule accumulation /// as well as the AST storage and rendering /// /// Rule stuff might be replaced with the dom4j RuleManager /// </summary> /// <author> <a href="mailto:ge...@ap...?">Geir Magnusson Jr.</a></author> public class TemplateHandler { public TemplateHandler() { } private Hashtable astmap = new Hashtable(); private IList xpathList = new ArrayList(); public virtual void RegisterMatch(String xpath, SimpleNode node) { Hashtable foo = new Hashtable(); foo["xpath"] = xpath; foo["ast"] = node; xpathList.Add(foo); } internal virtual bool Render(DvslNode node, IContext context, TextWriter writer) { /* * find if we have an AST where the xpath expression mathes * for this node */ XmlNode dom4jnode = (XmlNode) node.NodeImpl; XPathNavigator nav = dom4jnode.CreateNavigator(); SimpleNode sn = null; for (int i = 0; i < xpathList.Count; i++) { Hashtable m = (Hashtable) xpathList[i]; XPathExpression expr = nav.Compile((String) m["xpath"]); if (nav.Matches((String) m["xpath"])) { sn = (SimpleNode) m["ast"]; break; } } // if we found something, render if (sn != null) { InternalContextAdapterImpl ica = new InternalContextAdapterImpl(context); ica.PushCurrentTemplateName(node.Name); try { sn.render(ica, writer); } finally { ica.PopCurrentTemplateName(); } return true; } return false; } } } |
From: Sean M. <int...@us...> - 2005-11-17 02:47:00
|
Update of /cvsroot/adapdev/Adapdev/src/Adapdev/Text/Indexing/Records In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11442/src/Adapdev/Text/Indexing/Records Added Files: HashtableRecord.cs Log Message: --- NEW FILE: HashtableRecord.cs --- #region license // Bamboo.Prevalence - a .NET object prevalence engine // Copyright (C) 2004 Rodrigo B. de Oliveira // // Based on the original concept and implementation of Prevayler (TM) // by Klaus Wuestefeld. Visit http://www.prevayler.org for details. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE // OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // Contact Information // // http://bbooprevalence.sourceforge.net // mailto:rod...@us... #endregion using System; using System.Collections; namespace Adapdev.Text.Indexing.Records { /// <summary> /// An IRecord implementation over a Hashtable. /// </summary> [Serializable] public class HashtableRecord : Adapdev.Text.Indexing.IRecord { /// <summary> /// The hashtable. /// </summary> protected Hashtable _hashtable; /// <summary> /// Creates an empty record. /// </summary> public HashtableRecord() { _hashtable = new Hashtable(); } /// <summary> /// Sets/Gets a hashtable field. /// </summary> public object this[string name] { get { return _hashtable[name]; } set { _hashtable[name] = value; } } /// <summary> /// Delegates to the internal hashtable. /// </summary> /// <returns></returns> public override int GetHashCode() { return _hashtable.GetHashCode(); } /// <summary> /// Delegates to the internal hashtable. /// </summary> /// <param name="rhs"></param> /// <returns></returns> public override bool Equals(object rhs) { HashtableRecord other = rhs as HashtableRecord; if (null == other) { return false; } return other._hashtable.Equals(_hashtable); } } } |
From: Sean M. <int...@us...> - 2005-11-17 02:46:58
|
Update of /cvsroot/adapdev/Adapdev/src/Adapdev/Text/Indexing/FullText In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11442/src/Adapdev/Text/Indexing/FullText Added Files: FullTextSearchExpression.cs FullTextSearchIndex.cs FullTextSearchMode.cs ITokenFilter.cs ITokenizer.cs IndexedField.cs IndexedFieldCollection.cs Posting.cs Postings.cs TermOccurenceCollection.cs TermOccurrence.cs Token.cs Log Message: --- NEW FILE: FullTextSearchMode.cs --- #region license // Bamboo.Prevalence - a .NET object prevalence engine // Copyright (C) 2004 Rodrigo B. de Oliveira // // Based on the original concept and implementation of Prevayler (TM) // by Klaus Wuestefeld. Visit http://www.prevayler.org for details. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE // OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // Contact Information // // http://bbooprevalence.sourceforge.net // mailto:rod...@us... #endregion using System; namespace Adapdev.Text.Indexing.FullText { /// <summary> /// Search mode. /// </summary> public enum FullTextSearchMode { /// <summary> /// Include a record in the result if /// any of the words in the search expression /// occurs in the record /// </summary> IncludeAny, /// <summary> /// Include a record in the result only /// if all of the words in the search expression /// occurs in the record /// </summary> IncludeAll } } --- NEW FILE: ITokenFilter.cs --- #region license // Bamboo.Prevalence - a .NET object prevalence engine // Copyright (C) 2004 Rodrigo B. de Oliveira // // Based on the original concept and implementation of Prevayler (TM) // by Klaus Wuestefeld. Visit http://www.prevayler.org for details. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE // OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // Contact Information // // http://bbooprevalence.sourceforge.net // mailto:rod...@us... #endregion using System; namespace Adapdev.Text.Indexing.FullText { /// <summary> /// Marker interface for token filters. /// </summary> public interface ITokenFilter : ITokenizer { } } --- NEW FILE: FullTextSearchIndex.cs --- #region license // Bamboo.Prevalence - a .NET object prevalence engine // Copyright (C) 2004 Rodrigo B. de Oliveira // // Based on the original concept and implementation of Prevayler (TM) // by Klaus Wuestefeld. Visit http://www.prevayler.org for details. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE // OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // Contact Information // // http://bbooprevalence.sourceforge.net // mailto:rod...@us... #endregion using System; using System.Collections; using Adapdev.Text.Indexing; using Adapdev.Text.Indexing.FullText.Filters; using Adapdev.Text.Indexing.FullText.Tokenizers; namespace Adapdev.Text.Indexing.FullText { /// <summary> /// An index for full text searches over record objects. /// </summary> /// <remarks> /// <b>The mutating methods of this class (such as /// <see cref="Add" />, <see cref="Remove" /> and /// <see cref="Update" />) /// are not thread-safe, all the /// synchronization work must be done by the /// application.</b><br /><br /> /// Non mutating methods such as the various <see cref="Search" /> /// implementations <b>can be safely called from multiple threads</b> /// simultaneously. /// </remarks> /// <example> /// <code> /// FullTextSearchIndex index = new FullTextSearchIndex(); /// index.Fields.Add("title"); /// index.Fields.Add("author"); /// /// HashtableRecord book1 = new HashtableRecord(); /// book1["title"] = "A Midsummer Night's Dream"; /// book1["author"] = "Shakespeare, William" /// /// HashtableRecord book2 = new HashtableRecord(); /// book2["title"] = "Much Ado About Nothing"; /// book2["author"] = "Shakespeare, William"; /// /// index.Add(book1); /// index.Add(book2); /// /// SearchResult result1 = index.Search("midsummer dream"); /// AssertEquals(1, result1.Count); /// Assert(result1.Contains(book1)); /// /// SearchResult result2 = index.Search("shakespeare"); /// result2.SortByField("title"); /// /// AssertEquals(2, result2.Count); /// AssertEquals(book1, result2[0].Record); /// AssertEquals(book2, result2[1].Record); /// </code> /// </example> [Serializable] public class FullTextSearchIndex : IIndex { /// <summary> /// A filter that considers only tokens with more than 2 characters /// and replaces special characters (like '', '') by their /// simpler counterparts ('c', 'a'). /// </summary> public static ITokenFilter DefaultFilter = new SpecialCharactersFilter(new TokenLengthFilter(3)); IndexedFieldCollection _fields; Hashtable _postings; ITokenFilter _filter = FullTextSearchIndex.DefaultFilter; /// <summary> /// Creates an empty index. /// </summary> public FullTextSearchIndex() { _fields = new IndexedFieldCollection(); _postings = new Hashtable(); } /// <summary> /// Creates an empty index with a specific filter /// chain for token filtering. /// </summary> /// <param name="filter">the filter chain that /// should be used by the index to filter /// tokens</param> public FullTextSearchIndex(ITokenFilter filter) : this() { Filter = filter; } /// <summary> /// Gets/sets the filter chain that will be used /// for all text preprocessing /// </summary> public ITokenFilter Filter { get { return _filter; } set { if (null == value) { throw new ArgumentNullException("value", "Filter cannot be null!"); } _filter = value; } } /// <summary> /// Returns a snapshot of all the Postings held /// by this index. Each Postings instance represents /// a currently indexed term and all its occurrences. /// </summary> public Postings[] Postings { get { Postings[] postings = new Postings[_postings.Count]; _postings.Values.CopyTo(postings, 0); return postings; } } /// <summary> /// Returns a snapshot of all the records currently /// held by this index. /// </summary> public IRecord[] Records { get { Hashtable records = new Hashtable(); foreach (Postings postings in _postings.Values) { foreach (IRecord record in postings.Records) { records[record] = null; } } IRecord[] returnValue = new IRecord[records.Count]; records.Keys.CopyTo(returnValue, 0); return returnValue; } } /// <summary> /// Collection of fields that compose the index. /// </summary> public IndexedFieldCollection Fields { get { return _fields; } } #region Implementation of IIndex /// <summary> /// See <see cref="Adapdev.Text.Indexing.IIndex.Add"/> for details. /// </summary> /// <param name="record">record that should be indexed</param> /// <remarks> /// Indexes all the fields included in the /// <see cref="Fields"/> collection. Notice /// however that the record is never automatically /// reindexed should its fields change or should /// the collection of indexed fields (<see cref="Fields"/>) /// change.<br /> /// The application is always responsible for calling /// <see cref="Update"/> in such cases. /// </remarks> public void Add(Adapdev.Text.Indexing.IRecord record) { foreach (IndexedField field in _fields) { IndexByField(record, field); } } public void Clear() { _postings.Clear(); } /// <summary> /// See <see cref="Adapdev.Text.Indexing.IIndex.Remove"/> for details. /// </summary> /// <param name="record">record that should be removed from the index</param> /// <remarks>reference comparison is always used</remarks> public void Remove(Adapdev.Text.Indexing.IRecord record) { foreach (Postings postings in _postings.Values) { postings.Remove(record); } } /// <summary> /// See <see cref="Adapdev.Text.Indexing.IIndex.Update"/> for details. /// </summary> /// <param name="record">existing record that should have its index information updated</param> /// <remarks>reference comparison is always used</remarks> public void Update(Adapdev.Text.Indexing.IRecord record) { Remove(record); Add(record); } /// <summary> /// When the expression passed as argument is an instance /// of FullTextSearchExpression this method behaves exactly /// as <see cref="Search(FullTextSearchExpression)" />, otherwise /// it behaves as expression.Evaluate(this). /// </summary> /// <param name="expression">search expression</param> /// <returns>the result of applying the search against this index</returns> public Adapdev.Text.Indexing.SearchResult Search(Adapdev.Text.Indexing.ISearchExpression expression) { FullTextSearchExpression ftexpression = expression as FullTextSearchExpression; if (null != ftexpression) { return Search(ftexpression); } return expression.Evaluate(this); } #endregion /// <summary> /// Convenience method that creates a new <see cref="FullTextSearchExpression"/> /// for the expression passed as argument and calls /// <see cref="Search(FullTextSearchExpression)"/>. /// </summary> /// <param name="expression">search expression</param> /// <returns><see cref="Search(FullTextSearchExpression)"/></returns> public Adapdev.Text.Indexing.SearchResult Search(string expression) { return Search(new FullTextSearchExpression(expression)); } /// <summary> /// Searches the index for the words included in /// the expression passed as argument. <br /> /// All the fields are searched for every word /// in the expression.<br /> /// </summary> /// <param name="expression">search expression</param> /// <returns> /// When expression.SearchMode is /// <see cref="FullTextSearchMode.IncludeAny"/> every /// record for which at least one word in the expression /// implies a match will be returned.<br /> /// When expression.SearchMode is /// <see cref="FullTextSearchMode.IncludeAll" /> only /// those records for which all of the words in the expression /// imply a match will be returned. /// </returns> public Adapdev.Text.Indexing.SearchResult Search(FullTextSearchExpression expression) { ITokenizer tokenizer = CreateTokenizer(expression.Expression); Token token = tokenizer.NextToken(); if (null == token) { throw new ArgumentException("Invalid search expression. The expression must contain at least one valid token!", "expression"); } long begin = System.Environment.TickCount; SearchResult result = null; if (expression.SearchMode == FullTextSearchMode.IncludeAny) { result = IncludeAny(tokenizer, token); } else { result = IncludeAll(tokenizer, token); } result.ElapsedTime = System.Environment.TickCount - begin; return result; } SearchResult IncludeAny(ITokenizer tokenizer, Token token) { SearchResult result = new SearchResult(); while (null != token) { SearchToken(result, token); token = tokenizer.NextToken(); } return result; } SearchResult IncludeAll(ITokenizer tokenizer, Token token) { ArrayList results = new ArrayList(); while (null != token) { SearchResult tokenResult = new SearchResult(); SearchToken(tokenResult, token); results.Add(tokenResult); token = tokenizer.NextToken(); } SearchResult result = (SearchResult)results[0]; for (int i=1; i<results.Count && result.Count > 0; ++i) { result = result.Intersect((SearchResult)results[i]); } return result; } void IndexByField(IRecord record, IndexedField field) { string value = (string)record[field.Name]; ITokenizer tokenizer = CreateTokenizer(value); Token token = tokenizer.NextToken(); while (null != token) { IndexByToken(token, record, field); token = tokenizer.NextToken(); } } void IndexByToken(Token token, IRecord record, IndexedField field) { Postings postings = (Postings)_postings[token.Value]; if (null == postings) { postings = new Postings(token.Value); _postings[token.Value] = postings; } postings.Add(record, field, token.Position); } void SearchToken(SearchResult result, Token token) { Postings postings = (Postings)_postings[token.Value]; if (null != postings) { AddToResult(result, postings); } } void AddToResult(SearchResult result, Postings found) { foreach (Posting posting in found) { result.Add(new SearchHit(posting.Record)); } } ITokenizer CreateTokenizer(string value) { if (null == value || 0 == value.Length) { return NullTokenizer.Instance; } return _filter.Clone(new StringTokenizer(value)); } } } --- NEW FILE: Postings.cs --- #region license // Bamboo.Prevalence - a .NET object prevalence engine // Copyright (C) 2004 Rodrigo B. de Oliveira // // Based on the original concept and implementation of Prevayler (TM) // by Klaus Wuestefeld. Visit http://www.prevayler.org for details. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE // OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // Contact Information // // http://bbooprevalence.sourceforge.net // mailto:rod...@us... #endregion using System; using System.Collections; using System.Text; namespace Adapdev.Text.Indexing.FullText { /// <summary> /// A collection of Posting objects for a /// specific term.<br /> /// Posting objects are indexed by record for /// fast Add and Remove operations. /// </summary> [Serializable] public class Postings : System.Collections.IEnumerable { Hashtable _postings; string _term; /// <summary> /// Creates a new Postings object for /// a term. /// </summary> /// <param name="term">the term</param> public Postings(string term) { _term = term; _postings = new Hashtable(); } /// <summary> /// the term /// </summary> public string Term { get { return _term; } } /// <summary> /// Returns a snapshot of all the /// records currently indexed by the term /// </summary> public IRecord[] Records { get { IRecord[] records = new IRecord[_postings.Count]; _postings.Keys.CopyTo(records, 0); return records; } } /// <summary> /// Adds a new occurrence of the term. The occurrence /// information (field and position) will be added /// to an existing Posting object whenever possible. /// </summary> /// <param name="record">the record where the term was found</param> /// <param name="field">the field where the term was found</param> /// <param name="position">the position in the field where the term was found</param> public void Add(IRecord record, IndexedField field, int position) { Posting posting = _postings[record] as Posting; if (null == posting) { posting = new Posting(record); _postings[record] = posting; } posting.Occurrences.Add(field, position); } /// <summary> /// Removes all information related to a /// specific record from this object. /// </summary> /// <param name="record">the record to be removed</param> public void Remove(IRecord record) { _postings.Remove(record); } /// <summary> /// Enumerates through all the Posting objects. /// </summary> /// <returns></returns> public System.Collections.IEnumerator GetEnumerator() { return _postings.Values.GetEnumerator(); } /// <summary> /// Builds a readable representation of this object. /// </summary> /// <returns></returns> public override string ToString() { StringBuilder builder = new StringBuilder(); builder.Append(_term); builder.Append(" => ["); foreach (Posting posting in _postings.Values) { builder.Append(posting.ToString()); builder.Append(", "); } if (builder.Length > 1) { builder.Remove(builder.Length-2, 2); } builder.Append("]"); return builder.ToString(); } } } --- NEW FILE: ITokenizer.cs --- #region license // Bamboo.Prevalence - a .NET object prevalence engine // Copyright (C) 2004 Rodrigo B. de Oliveira // // Based on the original concept and implementation of Prevayler (TM) // by Klaus Wuestefeld. Visit http://www.prevayler.org for details. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE // OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // Contact Information // // http://bbooprevalence.sourceforge.net // mailto:rod...@us... #endregion using System; namespace Adapdev.Text.Indexing.FullText { /// <summary> /// A tokenizer is a source of or a filter for <see cref="Token"/> objects. /// </summary> public interface ITokenizer { /// <summary> /// For chaining tokenizers together. /// </summary> ITokenizer Previous { get; set; } /// <summary> /// Clone the tokenizer. If the tokenizer /// supports chaining it should also clone /// the Previous tokenizer in the chain. If /// Previous is null the value of the tail /// parameter should be used instead (but without cloning /// the tail). /// </summary> /// <param name="tail">the last tokenizer in the chain</param> /// <example> /// <code> /// public ITokenizer Clone(ITokenizer tail) /// { /// ITokenizer clone = this.MemberwiseClone() as ITokenizer; /// if (null == this.Previous) /// { /// clone.Previous = tail; /// } /// else /// { /// clone.Previous = this.Previous.Clone(tail); /// } /// return clone; /// } /// </code> /// </example> ITokenizer Clone(ITokenizer tail); /// <summary> /// Retrieves the next token. /// </summary> /// <returns> /// next token or null if no more tokens /// are available. /// </returns> Token NextToken(); } } --- NEW FILE: Posting.cs --- #region license // Bamboo.Prevalence - a .NET object prevalence engine // Copyright (C) 2004 Rodrigo B. de Oliveira // // Based on the original concept and implementation of Prevayler (TM) // by Klaus Wuestefeld. Visit http://www.prevayler.org for details. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE // OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // Contact Information // // http://bbooprevalence.sourceforge.net // mailto:rod...@us... #endregion using System; using System.Collections; namespace Adapdev.Text.Indexing.FullText { /// <summary> /// A Posting object represents the occurrence /// of a term in a record and stores all /// the information associated to this occurrence /// (in which fields does the term occur? how many /// times?).<br /> /// The term itself is not stored in the posting but /// should be used to index the posting in a /// dictionary. /// </summary> [Serializable] public class Posting { IRecord _record; TermOccurrenceCollection _occurrences; /// <summary> /// Creates a new posting for a record. /// </summary> /// <param name="record">the record</param> public Posting(IRecord record) { _record = record; _occurrences = new TermOccurrenceCollection(); } /// <summary> /// Occurrences of the term in the record. /// </summary> internal TermOccurrenceCollection Occurrences { get { return _occurrences; } } /// <summary> /// The record. /// </summary> public IRecord Record { get { return _record; } } /// <summary> /// Builds a more friendly representation of this object. /// </summary> /// <returns></returns> public override string ToString() { return "<" + _record + " => " + _occurrences + ">"; } } } --- NEW FILE: TermOccurrence.cs --- #region license // Bamboo.Prevalence - a .NET object prevalence engine // Copyright (C) 2004 Rodrigo B. de Oliveira // // Based on the original concept and implementation of Prevayler (TM) // by Klaus Wuestefeld. Visit http://www.prevayler.org for details. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE // OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // Contact Information // // http://bbooprevalence.sourceforge.net // mailto:rod...@us... #endregion using System; using System.Text; namespace Adapdev.Text.Indexing.FullText { /// <summary> /// Answers the questions: /// <list type="bullet"> /// <item>in which field does the term occur?</item> /// <item>how many times does the term occur in that specific field?</item> /// <item>in which positions?</item> /// </list> /// This information can be used for ranking the search and /// for specific search types such as proximity search, /// searching for terms only in specific fields, etc. /// </summary> [Serializable] public class TermOccurrence { IndexedField _field; int[] _positions; /// <summary> /// Creates a new TermOccurrence for the /// field and position passed as arguments. /// </summary> /// <param name="field">the field where the term was found</param> /// <param name="position">the position where the term was found</param> public TermOccurrence(IndexedField field, int position) { _field = field; _positions = new int[] { position }; } /// <summary> /// Field where the term was found /// </summary> public IndexedField Field { get { return _field; } } /// <summary> /// Positions in the field where /// the term was found. /// </summary> public int[] Positions { get { return _positions; } } internal void Add(int position) { int[] newPositions = new int[_positions.Length + 1]; Array.Copy(_positions, newPositions, _positions.Length); newPositions[_positions.Length] = position; } /// <summary> /// More readable representation of the object. /// </summary> /// <returns></returns> public override string ToString() { StringBuilder builder = new StringBuilder(); builder.Append("<"); builder.Append(_field.ToString()); builder.Append(" => "); builder.Append("["); for (int i=0; i<_positions.Length; ++i) { builder.Append(_positions[i]); builder.Append(", "); } builder.Append("]"); return builder.ToString(); } } } --- NEW FILE: FullTextSearchExpression.cs --- #region license // Bamboo.Prevalence - a .NET object prevalence engine // Copyright (C) 2004 Rodrigo B. de Oliveira // // Based on the original concept and implementation of Prevayler (TM) // by Klaus Wuestefeld. Visit http://www.prevayler.org for details. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE // OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // Contact Information // // http://bbooprevalence.sourceforge.net // mailto:rod...@us... #endregion using System; using Adapdev.Text.Indexing; namespace Adapdev.Text.Indexing.FullText { /// <summary> /// Search expression class for searches over /// a <see cref="FullTextSearchIndex"/>. /// </summary> [Serializable] public class FullTextSearchExpression : ISearchExpression { string _expression; FullTextSearchMode _mode; /// <summary> /// Creates a new search expression that will /// return all the records that include any of /// the words (<see cref="FullTextSearchMode.IncludeAny"/>) /// in the expression passed as argument. /// </summary> /// <param name="expression">words to search for</param> public FullTextSearchExpression(string expression) { _expression = expression; _mode = FullTextSearchMode.IncludeAny; } /// <summary> /// Creates a new search expression for /// the words in the expression argument /// with the specific behavior indicated by the mode /// argument. /// </summary> /// <param name="expression">words to search for</param> /// <param name="mode">search mode</param> public FullTextSearchExpression(string expression, FullTextSearchMode mode) { _expression = expression; _mode = mode; } /// <summary> /// Search expression /// </summary> public string Expression { get { return _expression; } } /// <summary> /// Search mode /// </summary> public FullTextSearchMode SearchMode { get { return _mode; } } #region Implementation of ISearchExpression /// <summary> /// Delegates to <see cref="Adapdev.Text.Indexing.FullText.FullTextSearchIndex.Search"/>. /// </summary> /// <param name="index">index</param> /// <returns></returns> /// <exception cref="ArgumentException">if the /// index argument is not of the correct type</exception> public Adapdev.Text.Indexing.SearchResult Evaluate(Adapdev.Text.Indexing.IIndex index) { FullTextSearchIndex ftindex = index as FullTextSearchIndex; if (null == ftindex) { throw new ArgumentException("FullTextSearchExpression objects can be evaluated against FullTextSearchIndex objects only!"); } return ftindex.Search(this); } #endregion } } --- NEW FILE: IndexedFieldCollection.cs --- #region license // Bamboo.Prevalence - a .NET object prevalence engine // Copyright (C) 2004 Rodrigo B. de Oliveira // // Based on the original concept and implementation of Prevayler (TM) // by Klaus Wuestefeld. Visit http://www.prevayler.org for details. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE // OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // Contact Information // // http://bbooprevalence.sourceforge.net // mailto:rod...@us... #endregion using System; using System.Collections; namespace Adapdev.Text.Indexing.FullText { /// <summary> /// Definition of the fields that will be used /// to compose a <see cref="FullTextSearchIndex"/>. /// </summary> [Serializable] public class IndexedFieldCollection : CollectionBase { /// <summary> /// Creates an empty collection. /// </summary> public IndexedFieldCollection() { } /// <summary> /// Adds a new IndexedField to the collection /// for the field with name passed as argument. /// </summary> /// <param name="field">name of the /// record field to be indexed</param> public void Add(string field) { InnerList.Add(new IndexedField(field)); } } } --- NEW FILE: TermOccurenceCollection.cs --- #region license // Bamboo.Prevalence - a .NET object prevalence engine // Copyright (C) 2004 Rodrigo B. de Oliveira // // Based on the original concept and implementation of Prevayler (TM) // by Klaus Wuestefeld. Visit http://www.prevayler.org for details. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE // OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // Contact Information // // http://bbooprevalence.sourceforge.net // mailto:rod...@us... #endregion using System; using System.Collections; using System.Text; namespace Adapdev.Text.Indexing.FullText { /// <summary> /// A collection of TermOccurrence objects. /// </summary> [Serializable] public class TermOccurrenceCollection : CollectionBase { /// <summary> /// Creates an empty collection. /// </summary> public TermOccurrenceCollection() { } /// <summary> /// Adds the information related to the new /// occurrence of the term in the field and /// position passed as argument. If a TermOccurrence /// object for the specified field /// is already in the collection, the new position /// information is simply added to the existing /// TermOccurrence object. Otherwise a new TermOccurrence /// object will be created and added to the /// collection. /// </summary> /// <param name="field">field where the term /// was found</param> /// <param name="position"> /// position in the field where the term was found</param> public void Add(IndexedField field, int position) { foreach (TermOccurrence to in InnerList) { if (to.Field == field) { to.Add(position); return; } } InnerList.Add(new TermOccurrence(field, position)); } /// <summary> /// Builds a readable representation of this object. /// </summary> /// <returns></returns> public override string ToString() { StringBuilder builder = new StringBuilder(); builder.Append("["); foreach (TermOccurrence to in InnerList) { builder.Append(to.ToString()); builder.Append(", "); } builder.Append("]"); return builder.ToString(); } } } --- NEW FILE: IndexedField.cs --- #region license // Bamboo.Prevalence - a .NET object prevalence engine // Copyright (C) 2004 Rodrigo B. de Oliveira // // Based on the original concept and implementation of Prevayler (TM) // by Klaus Wuestefeld. Visit http://www.prevayler.org for details. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE // OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // Contact Information // // http://bbooprevalence.sourceforge.net // mailto:rod...@us... #endregion using System; namespace Adapdev.Text.Indexing.FullText { /// <summary> /// Metadata for a field that should be indexed /// for full text searching. /// </summary> [Serializable] public class IndexedField { string _name; /// <summary> /// Creates a new IndexedField. /// </summary> /// <param name="name">name of the record field /// to be indexed</param> public IndexedField(string name) { _name = name; } /// <summary> /// Record's field name /// </summary> public string Name { get { return _name; } } /// <summary> /// Builds a more friendly representation of this object. /// </summary> /// <returns></returns> public override string ToString() { return "<IndexedField \"" + _name + "\">"; } } } --- NEW FILE: Token.cs --- #region license // Bamboo.Prevalence - a .NET object prevalence engine // Copyright (C) 2004 Rodrigo B. de Oliveira // // Based on the original concept and implementation of Prevayler (TM) // by Klaus Wuestefeld. Visit http://www.prevayler.org for details. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE // OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // Contact Information // // http://bbooprevalence.sourceforge.net // mailto:rod...@us... #endregion using System; namespace Adapdev.Text.Indexing.FullText { /// <summary> /// A token. /// </summary> [Serializable] public class Token { int _position; string _value; /// <summary> /// Creates a new token. /// </summary> /// <param name="value">token image</param> /// <param name="position">absolute position of the /// image in the original text</param> public Token(string value, int position) { if (null == value) { throw new ArgumentNullException("value"); } if (position < 0) { throw new ArgumentOutOfRangeException("occurrences", "position must be a positive number"); } _value = value; _position = position; } /// <summary> /// Token image /// </summary> public string Value { get { return _value; } set { if (null == value) { throw new ArgumentNullException("value"); } _value = value; } } /// <summary> /// Absolute position in the original text from /// which this token was extracted. /// </summary> public int Position { get { return _position; } } /// <summary> /// Tokens are equal if both properties, /// Value and Position, are considered /// equal. /// </summary> /// <param name="other">object to test equality for</param> /// <returns>true if the objects are considered equal</returns> public override bool Equals(object other) { Token token = other as Token; if (null == token) { return false; } return _position == token._position && _value == token._value; } /// <summary> /// Calculates a hashcode based on the properties /// Value and Position. /// </summary> /// <returns>the combined hashcode of both properties</returns> public override int GetHashCode() { return _position.GetHashCode() ^ _value.GetHashCode(); } /// <summary> /// Builds a more human friendly representation of the token. /// </summary> /// <returns>a readable representation of the token</returns> public override string ToString() { return "<\"" + _value + "\" at " + _position + ">"; } } } |