/// <summary> /// Renames a file in the index. /// </summary> /// <param name="oldName">The old attachment name.</param> /// <param name="newName">The new attachment name.</param> public static bool RenameFile(string oldName, string newName) { IIndexDirectoryProviderV30 indexDirectoryProvider = Collectors.IndexDirectoryProvider; Analyzer analyzer = new SimpleAnalyzer(); Term term = new Term(SearchField.Key.AsString(), (DocumentTypeToString(DocumentType.File) + "|" + oldName).Replace(" ", "")); Query query = new TermQuery(term); using (IndexWriter writer = new IndexWriter(indexDirectoryProvider.GetDirectory(), analyzer, IndexWriter.MaxFieldLength.UNLIMITED)) using (IndexSearcher searcher = new IndexSearcher(indexDirectoryProvider.GetDirectory(), false)) { TopDocs topDocs = searcher.Search(query, 100); if (topDocs.ScoreDocs.Length == 0) { return(true); } Document doc = searcher.Doc(topDocs.ScoreDocs[0].Doc); Document newDoc = new Document(); newDoc.Add(new Field(SearchField.Key.AsString(), (DocumentTypeToString(DocumentType.File) + "|" + newName).Replace(" ", ""), Field.Store.NO, Field.Index.NOT_ANALYZED_NO_NORMS)); newDoc.Add(new Field(SearchField.DocumentType.AsString(), DocumentTypeToString(DocumentType.File), Field.Store.YES, Field.Index.ANALYZED)); newDoc.Add(new Field(SearchField.FileName.AsString(), newName, Field.Store.YES, Field.Index.ANALYZED)); newDoc.Add(new Field(SearchField.FileContent.AsString(), doc.GetField(SearchField.FileContent.AsString()).StringValue, Field.Store.YES, Field.Index.ANALYZED)); writer.UpdateDocument(term, newDoc); writer.Commit(); } return(true); }
/// <summary> /// Indexes a file. /// </summary> /// <param name="fileName">The name of the file to be indexed.</param> /// <param name="filePath">The path of the file to be indexed.</param> /// <returns><c>true</c> if the message has been indexed succesfully, <c>false</c> otherwise.</returns> public static bool IndexFile(string fileName, string filePath) { IIndexDirectoryProviderV30 indexDirectoryProvider = Collectors.IndexDirectoryProvider; Analyzer analyzer = new SimpleAnalyzer(); using (IndexWriter writer = new IndexWriter(indexDirectoryProvider.GetDirectory(), analyzer, IndexWriter.MaxFieldLength.UNLIMITED)) { try { Document doc = new Document(); doc.Add(new Field(SearchField.Key.AsString(), (DocumentTypeToString(DocumentType.File) + "|" + fileName).Replace(" ", ""), Field.Store.NO, Field.Index.NOT_ANALYZED_NO_NORMS)); doc.Add(new Field(SearchField.DocumentType.AsString(), DocumentTypeToString(DocumentType.File), Field.Store.YES, Field.Index.ANALYZED)); doc.Add(new Field(SearchField.FileName.AsString(), fileName, Field.Store.YES, Field.Index.ANALYZED)); string fileContent = SearchEngine.Parser.Parse(filePath); doc.Add(new Field(SearchField.FileContent.AsString(), fileContent, Field.Store.YES, Field.Index.ANALYZED)); writer.AddDocument(doc); writer.Commit(); } catch (System.Runtime.InteropServices.COMException ex) { Log.LogEntry(ex.Message, EntryType.Warning, Log.SystemUsername); } } return(true); }
/// <summary> /// Unindexes the file. /// </summary> /// <param name="fileName">The name of the attachment.</param> /// <returns><c>true</c> if the file has been unindexed succesfully, <c>false</c> otherwise.</returns> public static bool UnindexFile(string fileName) { IIndexDirectoryProviderV30 indexDirectoryProvider = Collectors.IndexDirectoryProvider; using (IndexWriter writer = new IndexWriter(indexDirectoryProvider.GetDirectory(), new SimpleAnalyzer(), IndexWriter.MaxFieldLength.UNLIMITED)) { writer.DeleteDocuments(new Term(SearchField.Key.AsString(), (DocumentTypeToString(DocumentType.File) + "|" + fileName).Replace(" ", ""))); writer.Commit(); } return(true); }
protected void rptIndex_ItemCommand(object sender, CommandEventArgs e) { Log.LogEntry("Index rebuild requested for " + e.CommandArgument as string, EntryType.General, SessionFacade.GetCurrentUsername()); IIndexDirectoryProviderV30 provider = Collectors.IndexDirectoryProvider; //TODO provider.RebuildIndex(); Log.LogEntry("Index rebuild completed for " + e.CommandArgument as string, EntryType.General, Log.SystemUsername); rptIndex.DataBind(); }
/// <summary> /// Clears the files index. /// </summary> public static void ClearFilesIndex() { IIndexDirectoryProviderV30 indexDirectoryProvider = Collectors.IndexDirectoryProvider; Analyzer analyzer = new SimpleAnalyzer(); using (IndexWriter writer = new IndexWriter(indexDirectoryProvider.GetDirectory(), analyzer, IndexWriter.MaxFieldLength.UNLIMITED)) { ClearFilesIndex(writer); ClearAttachmentsIndex(writer); writer.Commit(); } }
/// <summary> /// Unindexes the message. /// </summary> /// <param name="messageId">The id of the message to be unindexed.</param> /// <param name="page">The page the message belongs to.</param> /// <returns><c>true</c> if the message has been unindexed succesfully, <c>false</c> otherwise.</returns> public static bool UnindexMessage(int messageId, PageContent page) { IIndexDirectoryProviderV30 indexDirectoryProvider = Collectors.IndexDirectoryProvider; using (IndexWriter writer = new IndexWriter(indexDirectoryProvider.GetDirectory(), new KeywordAnalyzer(), IndexWriter.MaxFieldLength.UNLIMITED)) { Query query = MultiFieldQueryParser.Parse(Lucene.Net.Util.Version.LUCENE_30 , new string[] { DocumentTypeToString(DocumentType.Message), page.PageInfo.FullName, messageId.ToString() } , new string[] { SearchField.DocumentType.AsString(), SearchField.PageFullName.AsString(), SearchField.MessageId.AsString() } , new Occur[] { Occur.MUST, Occur.MUST, Occur.MUST }, new KeywordAnalyzer()); writer.DeleteDocuments(query); writer.Commit(); } return(true); }
/// <summary> /// Indexes the page. /// </summary> /// <param name="page">The page page to be intexed.</param> /// <returns><c>true</c> if the page has been indexed succesfully, <c>false</c> otherwise.</returns> public static bool IndexPage(PageContent page) { IIndexDirectoryProviderV30 indexDirectoryProvider = Collectors.IndexDirectoryProvider; Analyzer analyzer = new SimpleAnalyzer(); using (IndexWriter writer = new IndexWriter(indexDirectoryProvider.GetDirectory(), analyzer, IndexWriter.MaxFieldLength.UNLIMITED)) { Document doc = new Document(); doc.Add(new Field(SearchField.Key.AsString(), (DocumentTypeToString(DocumentType.Page) + "|" + page.FullName).Replace(" ", ""), Field.Store.NO, Field.Index.NOT_ANALYZED_NO_NORMS)); doc.Add(new Field(SearchField.DocumentType.AsString(), DocumentTypeToString(DocumentType.Page), Field.Store.YES, Field.Index.NOT_ANALYZED)); doc.Add(new Field(SearchField.PageFullName.AsString(), page.FullName, Field.Store.YES, Field.Index.ANALYZED)); doc.Add(new Field(SearchField.Title.AsString(), page.Title, Field.Store.YES, Field.Index.ANALYZED)); doc.Add(new Field(SearchField.Content.AsString(), page.Content, Field.Store.YES, Field.Index.ANALYZED)); writer.AddDocument(doc); writer.Commit(); } return(true); }
/// <summary> /// Indexes the message. /// </summary> /// <param name="message">The message to be indexed.</param> /// <param name="page">The page the message belongs to.</param> /// <returns><c>true</c> if the message has been indexed succesfully, <c>false</c> otherwise.</returns> public static bool IndexMessage(Message message, PageContent page) { IIndexDirectoryProviderV30 indexDirectoryProvider = Collectors.IndexDirectoryProvider; Analyzer analyzer = new SimpleAnalyzer(); using (IndexWriter writer = new IndexWriter(indexDirectoryProvider.GetDirectory(), analyzer, IndexWriter.MaxFieldLength.UNLIMITED)) { Document doc = new Document(); doc.Add(new Field(SearchField.DocumentType.AsString(), DocumentTypeToString(DocumentType.Message), Field.Store.YES, Field.Index.NOT_ANALYZED)); doc.Add(new Field(SearchField.PageFullName.AsString(), page.PageInfo.FullName, Field.Store.YES, Field.Index.NOT_ANALYZED)); doc.Add(new Field(SearchField.MessageId.AsString(), message.ID.ToString(), Field.Store.NO, Field.Index.NOT_ANALYZED)); doc.Add(new Field(SearchField.Title.AsString(), message.Subject, Field.Store.YES, Field.Index.ANALYZED)); doc.Add(new Field(SearchField.Content.AsString(), message.Body, Field.Store.YES, Field.Index.ANALYZED)); doc.Add(new Field(SearchField.MessageDateTime.AsString(), message.DateTime.ToString("yyyy/MM/dd HH:mm:ss"), Field.Store.YES, Field.Index.NO)); writer.AddDocument(doc); writer.Commit(); } return(true); }
/// <summary> /// Performs all needed startup operations. /// </summary> public static void Startup() { // Load Host Host.Instance = new Host(); // Load config ISettingsStorageProviderV30 ssp = ProviderLoader.LoadSettingsStorageProvider(WebConfigurationManager.AppSettings["SettingsStorageProvider"]); ssp.Init(Host.Instance, GetSettingsStorageProviderConfiguration()); Collectors.SettingsProvider = ssp; if (!(ssp is SettingsStorageProvider)) { // Update DLLs from public\Plugins UpdateDllsIntoSettingsProvider(ssp, ProviderLoader.SettingsStorageProviderAssemblyName); } if (ssp.IsFirstApplicationStart()) { if (ssp.GetMetaDataItem(MetaDataItem.AccountActivationMessage, null) == "") { ssp.SetMetaDataItem(MetaDataItem.AccountActivationMessage, null, Defaults.AccountActivationMessageContent); } if (ssp.GetMetaDataItem(MetaDataItem.EditNotice, null) == "") { ssp.SetMetaDataItem(MetaDataItem.EditNotice, null, Defaults.EditNoticeContent); } if (ssp.GetMetaDataItem(MetaDataItem.Footer, null) == "") { ssp.SetMetaDataItem(MetaDataItem.Footer, null, Defaults.FooterContent); } if (ssp.GetMetaDataItem(MetaDataItem.Header, null) == "") { ssp.SetMetaDataItem(MetaDataItem.Header, null, Defaults.HeaderContent); } if (ssp.GetMetaDataItem(MetaDataItem.PasswordResetProcedureMessage, null) == "") { ssp.SetMetaDataItem(MetaDataItem.PasswordResetProcedureMessage, null, Defaults.PasswordResetProcedureMessageContent); } if (ssp.GetMetaDataItem(MetaDataItem.Sidebar, null) == "") { ssp.SetMetaDataItem(MetaDataItem.Sidebar, null, Defaults.SidebarContent); } if (ssp.GetMetaDataItem(MetaDataItem.PageChangeMessage, null) == "") { ssp.SetMetaDataItem(MetaDataItem.PageChangeMessage, null, Defaults.PageChangeMessage); } if (ssp.GetMetaDataItem(MetaDataItem.DiscussionChangeMessage, null) == "") { ssp.SetMetaDataItem(MetaDataItem.DiscussionChangeMessage, null, Defaults.DiscussionChangeMessage); } if (ssp.GetMetaDataItem(MetaDataItem.ApproveDraftMessage, null) == "") { ssp.SetMetaDataItem(MetaDataItem.ApproveDraftMessage, null, Defaults.ApproveDraftMessage); } } // Load config IIndexDirectoryProviderV30 idp = ProviderLoader.LoadIndexDirectoryProvider(WebConfigurationManager.AppSettings["IndexDirectoryProvider"]); idp.Init(Host.Instance, GetSettingsStorageProviderConfiguration()); Collectors.IndexDirectoryProvider = idp; MimeTypes.Init(); // Load Providers Collectors.FileNames = new System.Collections.Generic.Dictionary <string, string>(10); Collectors.UsersProviderCollector = new ProviderCollector <IUsersStorageProviderV30>(); Collectors.PagesProviderCollector = new ProviderCollector <IPagesStorageProviderV30>(); Collectors.FilesProviderCollector = new ProviderCollector <IFilesStorageProviderV30>(); Collectors.FormatterProviderCollector = new ProviderCollector <IFormatterProviderV30>(); Collectors.CacheProviderCollector = new ProviderCollector <ICacheProviderV30>(); Collectors.DisabledUsersProviderCollector = new ProviderCollector <IUsersStorageProviderV30>(); Collectors.DisabledPagesProviderCollector = new ProviderCollector <IPagesStorageProviderV30>(); Collectors.DisabledFilesProviderCollector = new ProviderCollector <IFilesStorageProviderV30>(); Collectors.DisabledFormatterProviderCollector = new ProviderCollector <IFormatterProviderV30>(); Collectors.DisabledCacheProviderCollector = new ProviderCollector <ICacheProviderV30>(); // Load built-in providers // Files storage providers have to be loaded BEFORE users storage providers in order to properly set permissions FilesStorageProvider f = new FilesStorageProvider(); if (!ProviderLoader.IsDisabled(f.GetType().FullName)) { f.Init(Host.Instance, ""); Collectors.FilesProviderCollector.AddProvider(f); Log.LogEntry("Provider " + f.Information.Name + " loaded (Enabled)", EntryType.General, Log.SystemUsername); } else { Collectors.DisabledFilesProviderCollector.AddProvider(f); Log.LogEntry("Provider " + f.Information.Name + " loaded (Disabled)", EntryType.General, Log.SystemUsername); } UsersStorageProvider u = new UsersStorageProvider(); if (!ProviderLoader.IsDisabled(u.GetType().FullName)) { u.Init(Host.Instance, ""); Collectors.UsersProviderCollector.AddProvider(u); Log.LogEntry("Provider " + u.Information.Name + " loaded (Enabled)", EntryType.General, Log.SystemUsername); } else { Collectors.DisabledUsersProviderCollector.AddProvider(u); Log.LogEntry("Provider " + u.Information.Name + " loaded (Disabled)", EntryType.General, Log.SystemUsername); } // Load Users (pages storage providers might need access to users/groups data for upgrading from 2.0 to 3.0) ProviderLoader.FullLoad(true, false, false, false, false); //Users.Instance = new Users(); bool groupsCreated = VerifyAndCreateDefaultGroups(); PagesStorageProvider p = new PagesStorageProvider(); if (!ProviderLoader.IsDisabled(p.GetType().FullName)) { p.Init(Host.Instance, ""); Collectors.PagesProviderCollector.AddProvider(p); Log.LogEntry("Provider " + p.Information.Name + " loaded (Enabled)", EntryType.General, Log.SystemUsername); } else { Collectors.DisabledPagesProviderCollector.AddProvider(p); Log.LogEntry("Provider " + p.Information.Name + " loaded (Disabled)", EntryType.General, Log.SystemUsername); } CacheProvider c = new CacheProvider(); if (!ProviderLoader.IsDisabled(c.GetType().FullName)) { c.Init(Host.Instance, ""); Collectors.CacheProviderCollector.AddProvider(c); Log.LogEntry("Provider " + c.Information.Name + " loaded (Enabled)", EntryType.General, Log.SystemUsername); } else { Collectors.DisabledCacheProviderCollector.AddProvider(c); Log.LogEntry("Provider " + c.Information.Name + " loaded (Disabled)", EntryType.General, Log.SystemUsername); } // Load all other providers ProviderLoader.FullLoad(false, true, true, true, true); if (groupsCreated) { // It is necessary to set default permissions for file management UserGroup administratorsGroup = Users.FindUserGroup(Settings.AdministratorsGroup); UserGroup anonymousGroup = Users.FindUserGroup(Settings.AnonymousGroup); UserGroup usersGroup = Users.FindUserGroup(Settings.UsersGroup); SetAdministratorsGroupDefaultPermissions(administratorsGroup); SetUsersGroupDefaultPermissions(usersGroup); SetAnonymousGroupDefaultPermissions(anonymousGroup); } // Init cache //Cache.Instance = new Cache(Collectors.CacheProviderCollector.GetProvider(Settings.DefaultCacheProvider)); if (Collectors.CacheProviderCollector.GetProvider(Settings.DefaultCacheProvider) == null) { Log.LogEntry("Default Cache Provider was not loaded, backing to integrated provider", EntryType.Error, Log.SystemUsername); Settings.DefaultCacheProvider = typeof(CacheProvider).FullName; Collectors.TryEnable(Settings.DefaultCacheProvider); } // Create the Main Page, if needed if (Pages.FindPage(Settings.DefaultPage) == null) { CreateMainPage(); } Log.LogEntry("ScrewTurn Wiki is ready", EntryType.General, Log.SystemUsername); System.Threading.ThreadPool.QueueUserWorkItem(ignored => { SearchClass.RebuildIndex(); }); }
/// <summary> /// Searches the specified phrase in the specified search fields. /// </summary> /// <param name="searchFields">The search fields.</param> /// <param name="phrase">The phrase to search.</param> /// <param name="searchOption">The search options.</param> /// <returns>A list of <see cref="SearchResult"/> items.</returns> public static List <SearchResult> Search(SearchField[] searchFields, string phrase, SearchOptions searchOption) { IIndexDirectoryProviderV30 indexDirectoryProvider = Collectors.IndexDirectoryProvider; Analyzer analyzer = new SimpleAnalyzer(); using (IndexSearcher searcher = new IndexSearcher(indexDirectoryProvider.GetDirectory(), false)) { string[] searchFieldsAsString = (from f in searchFields select f.AsString()).ToArray(); MultiFieldQueryParser queryParser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_29, searchFieldsAsString, analyzer); if (searchOption == SearchOptions.AllWords) { queryParser.DefaultOperator = QueryParser.Operator.AND; } if (searchOption == SearchOptions.AtLeastOneWord) { queryParser.DefaultOperator = QueryParser.Operator.OR; } try { Query query = queryParser.Parse(phrase); TopDocs topDocs = searcher.Search(query, 100); Highlighter highlighter = new Highlighter(new SimpleHTMLFormatter("<b class=\"searchkeyword\">", "</b>"), new QueryScorer(query)); List <SearchResult> searchResults = new List <SearchResult>(topDocs.TotalHits); for (int i = 0; i < Math.Min(100, topDocs.TotalHits); i++) { Document doc = searcher.Doc(topDocs.ScoreDocs[i].Doc); SearchResult result = new SearchResult(); result.DocumentType = DocumentTypeFromString(doc.GetField(SearchField.DocumentType.AsString()).StringValue); result.Relevance = topDocs.ScoreDocs[i].Score * 100; switch (result.DocumentType) { case DocumentType.Page: PageDocument page = new PageDocument(); page.PageFullName = doc.GetField(SearchField.PageFullName.AsString()).StringValue; page.Title = doc.GetField(SearchField.Title.AsString()).StringValue; TokenStream tokenStream1 = analyzer.TokenStream(SearchField.Title.AsString(), new StringReader(page.Title)); page.HighlightedTitle = highlighter.GetBestFragments(tokenStream1, page.Title, 3, " [...] "); page.Content = doc.GetField(SearchField.Content.AsString()).StringValue; tokenStream1 = analyzer.TokenStream(SearchField.Content.AsString(), new StringReader(page.Content)); page.HighlightedContent = highlighter.GetBestFragments(tokenStream1, page.Content, 3, " [...] "); result.Document = page; break; case DocumentType.Message: MessageDocument message = new MessageDocument(); message.PageFullName = doc.GetField(SearchField.PageFullName.AsString()).StringValue; message.DateTime = DateTime.Parse(doc.GetField(SearchField.MessageDateTime.AsString()).StringValue); message.Subject = doc.GetField(SearchField.Title.AsString()).StringValue; message.Body = doc.GetField(SearchField.Content.AsString()).StringValue; TokenStream tokenStream2 = analyzer.TokenStream(SearchField.Content.AsString(), new StringReader(message.Body)); message.HighlightedBody = highlighter.GetBestFragments(tokenStream2, message.Body, 3, " [...] "); result.Document = message; break; case DocumentType.Attachment: PageAttachmentDocument attachment = new PageAttachmentDocument(); attachment.PageFullName = doc.GetField(SearchField.PageFullName.AsString()).StringValue; attachment.FileName = doc.GetField(SearchField.FileName.AsString()).StringValue; attachment.FileContent = doc.GetField(SearchField.FileContent.AsString()).StringValue; TokenStream tokenStream3 = analyzer.TokenStream(SearchField.Content.AsString(), new StringReader(attachment.FileContent)); attachment.HighlightedFileContent = highlighter.GetBestFragments(tokenStream3, attachment.FileContent, 3, " [...] "); result.Document = attachment; break; case DocumentType.File: FileDocument file = new FileDocument(); file.FileName = doc.GetField(SearchField.FileName.AsString()).StringValue; file.FileContent = doc.GetField(SearchField.FileContent.AsString()).StringValue; TokenStream tokenStream4 = analyzer.TokenStream(SearchField.Content.AsString(), new StringReader(file.FileContent)); file.HighlightedFileContent = highlighter.GetBestFragments(tokenStream4, file.FileContent, 3, " [...]"); result.Document = file; break; case DocumentType.SourceControlFile: FileDocument scfile = new FileDocument(); scfile.FileName = doc.GetField(SearchField.FileName.AsString()).StringValue; scfile.FileContent = doc.GetField(SearchField.FileContent.AsString()).StringValue; TokenStream tokenStream5 = analyzer.TokenStream(SearchField.Content.AsString(), new StringReader(scfile.FileContent)); scfile.HighlightedFileContent = highlighter.GetBestFragments(tokenStream5, scfile.FileContent, 3, " [...]"); result.Document = scfile; break; } searchResults.Add(result); } return(searchResults); } catch (ParseException) { return(new List <SearchResult>(0)); } } }
/// <summary> /// Loads the proper Index Directory Provider, given its name. /// </summary> /// <param name="name">The fully qualified name (such as "Namespace.ProviderClass, MyAssembly"), or <c>null</c>/<b>String.Empty</b>/"<b>default</b>" for the default provider.</param> /// <returns>The Index Directory provider.</returns> public static IIndexDirectoryProviderV30 LoadIndexDirectoryProvider(string name) { if (name == null || name.Length == 0 || string.Compare(name, "default", true, CultureInfo.InvariantCulture) == 0) { return(new FSIndexDirectoryProvider()); } IIndexDirectoryProviderV30 result = null; Exception inner = null; if (name.Contains(",")) { string[] fields = name.Split(','); if (fields.Length == 2) { fields[0] = fields[0].Trim(' ', '"'); fields[1] = fields[1].Trim(' ', '"'); try { // assemblyName should be an absolute path or a relative path in bin or public\Plugins Assembly asm; Type t; string assemblyName = fields[1]; if (!assemblyName.ToLowerInvariant().EndsWith(".dll")) { assemblyName += ".dll"; } if (File.Exists(assemblyName)) { asm = Assembly.Load(LoadAssemblyFromDisk(assemblyName)); t = asm.GetType(fields[0]); SettingsStorageProviderAssemblyName = Path.GetFileName(assemblyName); } else { string tentativePluginsPath = null; try { // Settings.PublicDirectory is only available when running the web app tentativePluginsPath = Path.Combine(Settings.PublicDirectory, "Plugins"); tentativePluginsPath = Path.Combine(tentativePluginsPath, assemblyName); } catch { } if (!string.IsNullOrEmpty(tentativePluginsPath) && File.Exists(tentativePluginsPath)) { asm = Assembly.Load(LoadAssemblyFromDisk(tentativePluginsPath)); t = asm.GetType(fields[0]); IndexDirectoryProviderAssemblyName = Path.GetFileName(tentativePluginsPath); } else { // Trim .dll t = Type.GetType(fields[0] + "," + assemblyName.Substring(0, assemblyName.Length - 4), true, true); IndexDirectoryProviderAssemblyName = assemblyName; } } result = t.GetConstructor(new Type[0]).Invoke(new object[0]) as IIndexDirectoryProviderV30; } catch (Exception ex) { inner = ex; result = null; } } } if (result == null) { throw new ArgumentException("Could not load the specified Settings Storage Provider", inner); } else { return(result); } }