Lucene.Net  3.0.3
Lucene.Net is a .NET port of the Java Lucene Indexing Library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties
CurrentIndex.cs
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 using System;
19 using System.Collections;
20 using System.Collections.Specialized;
21 using System.Configuration;
22 using System.Diagnostics;
23 using System.IO;
24 using System.Xml;
25 using Lucene.Net.Analysis;
26 using Lucene.Net.Analysis.Standard;
27 using Lucene.Net.Documents;
28 using Lucene.Net.Index;
29 using Lucene.Net.Store;
30 using Lucene.Net.Distributed;
31 
32 namespace Lucene.Net.Distributed.Configuration
33 {
34  public enum IndexSetting
35  {
36  NoSetting = 0,
37  IndexA = 1,
38  IndexB = 2
39  }
40 
63  public class CurrentIndex
64  {
65  #region Variables
66  private static readonly string CURRENTINDEX = "currentIndex";
67  private static readonly string INDEX_A = "indexA";
68  private static readonly string INDEX_B = "indexB";
69  private static readonly string TOGGLE = "toggle";
70  private string _strLocalPath;
71  private string _strStatusDir;
72  private string _strIndexAPath;
73  private string _strIndexBPath;
74  private bool _bIndexChanged=false;
75 
76  private int _mergeFactor = (ConfigurationManager.AppSettings["IndexMergeFactor"] != null ? Convert.ToInt32(ConfigurationManager.AppSettings["IndexMergeFactor"]) : 5);
77  private int _maxMergeDocs = (ConfigurationManager.AppSettings["IndexMaxMergeDocs"] != null ? Convert.ToInt32(ConfigurationManager.AppSettings["IndexMaxMergeDocs"]) : 9999999);
78 
79  #endregion
80 
81  #region Constructors
82 
83 
84 
85 
86 
87  public CurrentIndex(XmlNode node, string strLocalPath)
88  {
89  this._strLocalPath=strLocalPath;
90  this.LoadValues(node);
91  }
92 
98  public CurrentIndex(string sStatusDir)
99  {
100  this._strStatusDir=sStatusDir;
101  }
102  #endregion
103 
104  #region Internals
105 
106 
107 
108 
109 
110  internal void LoadValues(XmlNode node)
111  {
112  foreach (XmlNode c in node.ChildNodes)
113  {
114  if (c.Name.ToLower()=="targetpath")
115  {
116  this._strIndexAPath = c.Attributes["indexA"].Value;
117  this._strIndexBPath = c.Attributes["indexB"].Value;
118  }
119  else if (c.Name.ToLower()=="statusdir")
120  {
121  this._strStatusDir = c.Attributes["value"].Value;
122  }
123  }
124  this.CheckValidConfiguration(node);
125  }
126  #endregion
127 
128  #region Public properties
129 
130 
131 
132  public string LocalPath
133  {
134  get {return this._strLocalPath;}
135  }
139  public string StatusDirectory
140  {
141  get {return this._strStatusDir;}
142  }
143 
148  {
149  get
150  {
151  string input=(this.GetCurrentIndex());
152  return (input==CurrentIndex.INDEX_A ? IndexSetting.IndexA : (input==CurrentIndex.INDEX_B ? IndexSetting.IndexB : IndexSetting.IndexA));
153  }
154  }
155 
160  public IndexSetting IndexSettingRefresh
161  {
162  get
163  {
164  if (this.HasChanged)
165  {
166  return (this.IndexSetting==IndexSetting.IndexA ? IndexSetting.IndexB : (this.IndexSetting==IndexSetting.IndexB ? IndexSetting.IndexA : IndexSetting.IndexB ));
167  }
168  else
169  {
170  return this.IndexSetting;
171  }
172  }
173  }
174 
178  public bool CanCopy
179  {
180  get {return (!this.GetToggle() && (this.LocalIndexVersion!=this.TargetIndexVersion));}
181  }
182 
187  public bool HasChanged
188  {
189  get {return this.GetToggle();}
190  }
191 
195  public string CopyTargetPath
196  {
197  get {return (this.IndexSetting==IndexSetting.IndexA ? this._strIndexBPath : (this.IndexSetting==IndexSetting.IndexB ? this._strIndexAPath : ""));}
198  }
199  #endregion
200 
201  #region Public methods
202 
203 
204 
205 
206 
207  public bool Copy()
208  {
209  try
210  {
211  if (this.CanCopy && this.CopyTargetPath!="")
212  {
213  this.DeleteDirectoryFiles(this.CopyTargetPath);
214  this.CopyDirectory(this._strLocalPath, this.CopyTargetPath);
215  return true;
216  }
217  else
218  {
219  return false;
220  }
221  }
222  catch (Exception e)
223  {
224  //Do something with e
225  return false;
226  }
227  }
228 
234  public bool CopyIncremental()
235  {
236  try
237  {
238  if (this.CanCopy && this.CopyTargetPath!="")
239  {
240  this.CopyDirectoryIncremental(this._strLocalPath, this.CopyTargetPath);
241  return true;
242  }
243  else
244  {
245  return false;
246  }
247  }
248  catch (Exception e)
249  {
250  //Do something with e
251  return false;
252  }
253  }
254 
260  public void ProcessLocalIndexDeletes(NameValueCollection nvcDeleteCollection)
261  {
262  if (IndexReader.IndexExists(this._strLocalPath) && nvcDeleteCollection.Count>0)
263  {
264  IndexReader idxDeleter = IndexReader.Open(this._strLocalPath);
265  string[] arKeys = nvcDeleteCollection.AllKeys;
266  int xDelete=0;
267  for (int k=0;k<arKeys.Length;k++)
268  {
269  string[] arKeyValues=nvcDeleteCollection.GetValues(arKeys[k]);
270  for (int v=0;v<arKeyValues.Length;v++)
271  xDelete=idxDeleter.DeleteDocuments(new Term(arKeys[k].ToString(),arKeyValues[v].ToString()));
272  }
273  idxDeleter.Close();
274  }
275  }
276 
283  public void ProcessLocalIndexAdditions(Analyzer oAnalyzer, Hashtable htAddDocuments, bool bCompoundFile)
284  {
285  IndexWriter idxWriter = this.GetIndexWriter(this._strLocalPath, oAnalyzer, bCompoundFile);
286  idxWriter.SetMergeFactor(5);
287  idxWriter.SetMaxMergeDocs(9999999);
288 
289  foreach (DictionaryEntry de in htAddDocuments)
290  {
291  Document d = (Document)de.Key;
292  Analyzer a = (Analyzer)de.Value;
293  idxWriter.AddDocument(d,a);
294  }
295  idxWriter.Close();
296  }
297 
301  public void IndexRefresh()
302  {
303  if (this.HasChanged)
304  {
305  this.SetCurrentIndex(this.IndexSettingRefresh);
306  this.SetToggle(false);
307  }
308  }
309 
313  public void UpdateRefresh()
314  {
315  this.SetToggle(true);
316  }
317  #endregion
318 
319  #region Private properties
320 
321 
322 
323  private string CurrentIndexFile
324  {
325  get {return (this._strStatusDir+(this._strStatusDir.EndsWith(@"\") ? "" : @"\")+CURRENTINDEX);}
326  }
330  private string ToggleFile
331  {
332  get {return (this._strStatusDir+(this._strStatusDir.EndsWith(@"\") ? "" : @"\")+TOGGLE);}
333  }
334 
335  #endregion
336 
337  #region Private methods
338 
344  private void CheckValidConfiguration(XmlNode node)
345  {
346  if (this._strLocalPath == null) throw new ConfigurationErrorsException("CurrentIndex local path invalid: "+Environment.NewLine+node.OuterXml);
347  if (this._strStatusDir == null) throw new ConfigurationErrorsException("CurrentIndex statusDir invalid: " + Environment.NewLine + node.OuterXml);
348  if (this._strIndexAPath == null) throw new ConfigurationErrorsException("CurrentIndex indexA invalid: " + Environment.NewLine + node.OuterXml);
349  if (this._strIndexBPath == null) throw new ConfigurationErrorsException("CurrentIndex indexB invalid: " + Environment.NewLine + node.OuterXml);
350  }
351 
356  private bool GetToggle()
357  {
358  bool bValue=false;
359  string input="";
360  try
361  {
362  if (!File.Exists(this.ToggleFile))
363  {
364  this.SetToggle(false);
365  }
366  else
367  {
368  StreamReader sr = File.OpenText(this.ToggleFile);
369  input = sr.ReadLine();
370  sr.Close();
371  bValue = (input.ToLower()=="true" ? true : false);
372  }
373  }
374  catch (Exception ex)
375  {
376  //Do something with ex
377  }
378  return bValue;
379  }
380 
385  private string GetCurrentIndex()
386  {
387  string input="";
388  try
389  {
390  if (!File.Exists(this.CurrentIndexFile))
391  {
392  this.SetCurrentIndex(IndexSetting.IndexA);
393  input=IndexSetting.IndexA.ToString();
394  }
395  else
396  {
397  StreamReader sr = File.OpenText(this.CurrentIndexFile);
398  input = sr.ReadLine();
399  sr.Close();
400  }
401  }
402  catch (Exception ex)
403  {
404  //Do something with ex
405  }
406  return input;
407  }
408 
413  private void SetCurrentIndex(IndexSetting eIndexSetting)
414  {
415  try
416  {
417  StreamWriter sw = File.CreateText(this.CurrentIndexFile);
418  sw.WriteLine((eIndexSetting==IndexSetting.IndexA ? CurrentIndex.INDEX_A : CurrentIndex.INDEX_B));
419  sw.Close();
420  }
421  catch (Exception ex)
422  {
423  //Do something with ex
424  }
425  }
426 
434  private IndexWriter GetIndexWriter(string indexPath, Analyzer oAnalyzer, bool bCompoundFile)
435  {
436  bool bExists = System.IO.Directory.Exists(indexPath);
437  if (bExists==false)
438  System.IO.Directory.CreateDirectory(indexPath);
439  bExists=IndexReader.IndexExists(FSDirectory.GetDirectory(indexPath, false));
440  IndexWriter idxWriter = new IndexWriter(indexPath, oAnalyzer, !bExists);
441  idxWriter.SetUseCompoundFile(bCompoundFile);
442  return idxWriter;
443  }
444 
449  private void SetToggle(bool bValue)
450  {
451  try
452  {
453  StreamWriter sw = File.CreateText(this.ToggleFile);
454  sw.WriteLine(bValue.ToString());
455  sw.Close();
456  this._bIndexChanged=bValue;
457  }
458  catch (Exception ex)
459  {
460  //Do something with ex
461  }
462  }
463 
467  private long LocalIndexVersion
468  {
469  get {return IndexReader.GetCurrentVersion(this.LocalPath);}
470  }
474  private long TargetIndexVersion
475  {
476  get {return (IndexReader.IndexExists(this.CopyTargetPath) ? IndexReader.GetCurrentVersion(this.CopyTargetPath) : 0);}
477  }
478 
483  private void DeleteDirectoryFiles(string directoryPath)
484  {
485  try
486  {
487  if(!System.IO.Directory.Exists(directoryPath))
488  return;
489  DirectoryInfo di = new DirectoryInfo(directoryPath);
490  FileInfo[] arFi = di.GetFiles();
491  foreach(FileInfo fi in arFi)
492  fi.Delete();
493  }
494  catch(Exception e)
495  {
496  //Do something with e
497  }
498  }
499 
505  private void CopyDirectory(string sourceDirPath, string destDirPath)
506  {
507  string[] Files;
508 
509  if(destDirPath[destDirPath.Length-1]!=Path.DirectorySeparatorChar)
510  destDirPath+=Path.DirectorySeparatorChar;
511  if(!System.IO.Directory.Exists(destDirPath)) System.IO.Directory.CreateDirectory(destDirPath);
512  Files=System.IO.Directory.GetFileSystemEntries(sourceDirPath);
513  foreach(string Element in Files)
514  {
515  // Sub directories
516  if(System.IO.Directory.Exists(Element))
517  CopyDirectory(Element,destDirPath+Path.GetFileName(Element));
518  // Files in directory
519  else
520  File.Copy(Element,destDirPath+Path.GetFileName(Element),true);
521  }
522 
523  }
524 
530  private void CopyDirectoryIncremental(string sourceDirPath, string destDirPath)
531  {
532  string[] Files;
533 
534  if(destDirPath[destDirPath.Length-1]!=Path.DirectorySeparatorChar)
535  destDirPath+=Path.DirectorySeparatorChar;
536  Files=System.IO.Directory.GetFileSystemEntries(sourceDirPath);
537  if(!System.IO.Directory.Exists(destDirPath))
538  {
539  System.IO.Directory.CreateDirectory(destDirPath);
540  foreach(string Element in Files)
541  {
542  // Sub directories
543  if(System.IO.Directory.Exists(Element))
544  CopyDirectory(Element,destDirPath+Path.GetFileName(Element));
545  // Files in directory
546  else
547  File.Copy(Element,destDirPath+Path.GetFileName(Element),true);
548  }
549  }
550  else
551  {
552  foreach(string Element in Files)
553  {
554  if(System.IO.Directory.Exists(Element))
555  {
556  CopyDirectoryIncremental(Element,destDirPath+Path.GetFileName(Element));
557  }
558  else
559  {
560  if (System.IO.File.Exists(destDirPath+Path.GetFileName(Element)))
561  this.CopyFileIncremental(Element, destDirPath+Path.GetFileName(Element));
562  else
563  File.Copy(Element,destDirPath+Path.GetFileName(Element),true);
564  }
565  }
566  }
567  }
568 
575  private void CopyFileIncremental(string filepath1, string filepath2)
576  {
577  FileInfo fi1 = new FileInfo(filepath1);
578  FileInfo fi2 = new FileInfo(filepath2);
579  if ((fi1.LastWriteTime!=fi2.LastWriteTime)||(fi1.Length!=fi2.Length))
580  File.Copy(filepath1,filepath2,true);
581  }
582  #endregion
583 
584  #region Static methods
585 
586 
587 
588 
589 
590  public static Analyzer GetAnalyzer(AnalyzerType oAnalyzerType)
591  {
592  Analyzer oAnalyzer = null;
593  switch (oAnalyzerType)
594  {
595  case AnalyzerType.SimpleAnalyzer:
596  oAnalyzer = new SimpleAnalyzer();
597  break;
598  case AnalyzerType.StopAnalyzer:
599  oAnalyzer = new StopAnalyzer();
600  break;
601  case AnalyzerType.WhitespaceAnalyzer:
602  oAnalyzer = new WhitespaceAnalyzer();
603  break;
604  default:
605  case AnalyzerType.StandardAnalyzer:
606  oAnalyzer = new StandardAnalyzer();
607  break;
608  }
609  return oAnalyzer;
610  }
611  #endregion
612 
613  }
614 }