source: trunk/CrypCore/SearchProvider.cs @ 274

Last change on this file since 274 was 274, checked in by enkler, 13 years ago

continued implementation of local search, quasi finished

File size: 5.7 KB
Line 
1using System.Collections.Generic;
2using System.IO;
3using System.Xml;
4using Lucene.Net.Analysis;
5using Lucene.Net.Analysis.Standard;
6using Lucene.Net.Documents;
7using Lucene.Net.Index;
8using Lucene.Net.QueryParsers;
9using Lucene.Net.Search;
10using Lucene.Net.Store;
11using Directory = System.IO.Directory;
12using System;
13
14namespace Cryptool.Core
15{
16    public class SearchResult
17    {
18        public string Plugin { get; set; }
19        public string Context { get; set; }
20        public float Score { get; set; }
21    }
22
23    public class SearchProvider
24    {
25        private const string ContentField = "content";
26        private const string PluginField = "plugin";
27        //private const string HelpFilePath = "";
28        //private const string IndexPath = "";
29        public string HelpFilePath { get; set; }
30        public string IndexPath { get; set; }
31
32        public List<SearchResult> Search(string SearchString)
33        {
34            var LocalSearch = new LocalSearchTool { IndexPath = IndexPath };
35            LocalSearch.Search(SearchString);
36
37
38
39
40
41            return LocalSearch.SearchResults;
42        }
43
44        public void CreateIndexes()
45        {
46            Lucene.Net.Store.Directory dir = FSDirectory.GetDirectory(IndexPath, true);
47
48            Analyzer analyzer = new StandardAnalyzer();
49
50            var indexWriter = new
51            IndexWriter(dir, analyzer, true);
52
53            indexWriter.SetMaxFieldLength(int.MaxValue);
54
55            foreach (var File in Directory.GetFiles(HelpFilePath))
56            {
57                var text = GetTextFromXaml(File);
58                var doc = new Document();
59
60                var fldContent = new Field(ContentField, text, Field.Store.YES, Field.Index.TOKENIZED,
61                              Field.TermVector.WITH_POSITIONS_OFFSETS);
62                var fldName = new Field(PluginField, Path.GetFileNameWithoutExtension(Path.GetFileName(File)), Field.Store.YES, Field.Index.NO,
63                              Field.TermVector.NO);
64                doc.Add(fldContent);
65                doc.Add(fldName);
66                indexWriter.AddDocument(doc, analyzer);
67            }
68
69            indexWriter.Optimize();
70            indexWriter.Close();
71        }
72
73        private static string GetTextFromXaml(string Xaml)
74        {
75            var XamlDoc = new XmlDocument();
76            XamlDoc.Load(Xaml);
77            string text = ReadXml(XamlDoc.ChildNodes);
78            return text;
79        }
80
81        private static string ReadXml(XmlNodeList Nodes)
82        {
83            string Result = string.Empty;
84            if (Nodes.Count > 0)
85                foreach (XmlNode o in Nodes)
86                {
87                    if (!string.IsNullOrEmpty(o.Value))
88                        Result += o.Value.Trim(new[] { ' ' });
89                    Result += ReadXml(o.ChildNodes);
90                }
91            return Result;
92        }
93    }
94
95    public class SearchTool
96    {
97        public List<SearchResult> SearchResults { get; set; }
98
99        protected const string ContentField = "content";
100        protected const string PluginField = "plugin";
101
102
103        public virtual void Search(string SearchString)
104        {
105            SearchResults = new List<SearchResult>();
106        }
107    }
108
109    public class LocalSearchTool : SearchTool
110    {
111        public string IndexPath { get; set; }
112
113        private const int ContextLeftOffset = 15;
114        private const int ContextRightOffset = 35;
115        private const int ContextLength = ContextLeftOffset + ContextRightOffset;
116
117        public override void Search(string SearchString)
118        {
119            base.Search(SearchString);
120            SearchString = SearchString.ToLower();
121            var dir = FSDirectory.GetDirectory(IndexPath, false);
122
123            var searcher = new IndexSearcher(dir);
124
125            IndexReader Reader = searcher.Reader;
126
127            var parser = new QueryParser(ContentField, new StandardAnalyzer());
128            Query query = parser.Parse(SearchString);
129
130            Lucene.Net.Search.Hits hits = searcher.Search(query);
131
132            for (int i = 0; i < hits.Length(); i++)
133            {
134                Document doc = hits.Doc(i);
135                string text = doc.Get(ContentField);
136                var tpv = (TermPositionVector)Reader.GetTermFreqVector(hits.Id(i), ContentField);
137                String[] DocTerms = tpv.GetTerms();
138                int[] freq = tpv.GetTermFrequencies();
139                for (int t = 0; t < freq.Length; t++)
140                {
141                    if (DocTerms[t].Equals(SearchString))
142                    {
143                        TermVectorOffsetInfo[] offsets = tpv.GetOffsets(t);
144                        int[] pos = tpv.GetTermPositions(t);
145
146                        for (int tp = 0; tp < pos.Length; tp++)
147                        {
148                            int start = offsets[tp].GetStartOffset();
149                            int indexStart = start - ContextLeftOffset < 0 ? 0 : start - ContextLeftOffset;
150                            int contextstart = 0;
151                            if (indexStart > 0)
152                                contextstart = text.IndexOf(' ', indexStart) + 1;
153                            int contextlength = text.IndexOf(' ', contextstart + ContextLength) - contextstart;
154                            string context = contextstart + contextlength > text.Length ? text.Substring(contextstart) : text.Substring(contextstart, contextlength);
155                            SearchResults.Add(new SearchResult { Plugin = doc.Get(PluginField), Context = context, Score = hits.Score(i) });
156                        }
157                    }
158                }
159
160            }
161        }
162    }
163}
164
Note: See TracBrowser for help on using the repository browser.