diff --git a/app/pom.xml b/app/pom.xml index 4431c026fe..f4f464a633 100644 --- a/app/pom.xml +++ b/app/pom.xml @@ -308,6 +308,23 @@ limitations under the License. ${lucene.version} + + org.apache.solr + solr-solrj + 9.1.1 + + + + io.netty + netty-codec + + + io.netty + netty-common + + + + @@ -365,7 +382,7 @@ limitations under the License. org.apache.commons commons-text - 1.9 + 1.10.0 @@ -571,6 +588,20 @@ limitations under the License. test + + org.mockito + mockito-core + 3.2.4 + test + + + + org.instancio + instancio-junit + 2.9.0 + test + + diff --git a/app/src/main/java/org/apache/roller/weblogger/business/jpa/JPAWebloggerModule.java b/app/src/main/java/org/apache/roller/weblogger/business/jpa/JPAWebloggerModule.java index 8a8b301263..d9e189494f 100644 --- a/app/src/main/java/org/apache/roller/weblogger/business/jpa/JPAWebloggerModule.java +++ b/app/src/main/java/org/apache/roller/weblogger/business/jpa/JPAWebloggerModule.java @@ -48,7 +48,7 @@ import org.apache.roller.weblogger.business.plugins.PluginManagerImpl; import org.apache.roller.weblogger.business.runnable.ThreadManager; import org.apache.roller.weblogger.business.search.IndexManager; -import org.apache.roller.weblogger.business.search.IndexManagerImpl; +import org.apache.roller.weblogger.business.search.lucene.LuceneIndexManager; import org.apache.roller.weblogger.business.themes.ThemeManager; import org.apache.roller.weblogger.business.themes.ThemeManagerImpl; import org.apache.roller.weblogger.planet.business.WebloggerRomeFeedFetcher; @@ -81,7 +81,7 @@ public void configure(Binder binder) { binder.bind(MediaFileManager.class).to( JPAMediaFileManagerImpl.class); binder.bind(FileContentManager.class).to( FileContentManagerImpl.class); - binder.bind(IndexManager.class).to( IndexManagerImpl.class); + binder.bind(IndexManager.class).to( LuceneIndexManager.class); binder.bind(PluginManager.class).to( PluginManagerImpl.class); binder.bind(ThemeManager.class).to( ThemeManagerImpl.class); diff --git a/app/src/main/java/org/apache/roller/weblogger/business/search/IndexManager.java b/app/src/main/java/org/apache/roller/weblogger/business/search/IndexManager.java index 85956f055b..8a8a933f05 100644 --- a/app/src/main/java/org/apache/roller/weblogger/business/search/IndexManager.java +++ b/app/src/main/java/org/apache/roller/weblogger/business/search/IndexManager.java @@ -19,53 +19,58 @@ import org.apache.roller.weblogger.WebloggerException; import org.apache.roller.weblogger.business.InitializationException; -import org.apache.roller.weblogger.business.search.operations.IndexOperation; -import org.apache.roller.weblogger.pojos.WeblogEntry; +import org.apache.roller.weblogger.business.URLStrategy; import org.apache.roller.weblogger.pojos.Weblog; +import org.apache.roller.weblogger.pojos.WeblogEntry; /** - * Interface to Roller's Lucene-based search facility. + * Interface to Roller's full-text search facility. * @author Dave Johnson */ -public interface IndexManager -{ - /** Does index need to be rebuild */ - boolean isInconsistentAtStartup(); - - /** Remove user from index, returns immediately and operates in background */ - void removeWebsiteIndex(Weblog website) throws WebloggerException; - - /** Remove entry from index, returns immediately and operates in background */ - void removeEntryIndexOperation(WeblogEntry entry) throws WebloggerException; - - /** Add entry to index, returns immediately and operates in background */ - void addEntryIndexOperation(WeblogEntry entry) throws WebloggerException; - - /** R-index entry, returns immediately and operates in background */ - void addEntryReIndexOperation(WeblogEntry entry) throws WebloggerException; - - /** Execute operation immediately */ - void executeIndexOperationNow(final IndexOperation op); +public interface IndexManager { - /** - * Release all resources associated with Roller session. - */ - void release(); - - /** * Initialize the search system. - * * @throws InitializationException If there is a problem during initialization. */ void initialize() throws InitializationException; - - + /** Shutdown to be called on application shutdown */ void shutdown(); - void rebuildWebsiteIndex(Weblog website) throws WebloggerException; + /** + * Release all resources associated with Roller session. + */ + void release(); + + /** Does index need to be rebuilt */ + boolean isInconsistentAtStartup(); + + /** Add entry to index, returns immediately and operates in background */ + void addEntryIndexOperation(WeblogEntry entry) throws WebloggerException; + + /** Re-index entry, returns immediately and operates in background */ + void addEntryReIndexOperation(WeblogEntry entry) throws WebloggerException; + + void rebuildWeblogIndex(Weblog weblog) throws WebloggerException; + + void rebuildWeblogIndex() throws WebloggerException; - void rebuildWebsiteIndex() throws WebloggerException; + /** Remove weblog from index, returns immediately and operates in background */ + void removeWeblogIndex(Weblog weblog) throws WebloggerException; + /** Remove entry from index, returns immediately and operates in background */ + void removeEntryIndexOperation(WeblogEntry entry) throws WebloggerException; + + SearchResultList search( + String term, + String weblogHandle, + String category, + String locale, + int pageNum, + int entryCount, + URLStrategy urlStrategy + ) throws WebloggerException; } + + diff --git a/app/src/main/java/org/apache/roller/weblogger/business/search/SearchResultList.java b/app/src/main/java/org/apache/roller/weblogger/business/search/SearchResultList.java new file mode 100644 index 0000000000..5fcaab22ad --- /dev/null +++ b/app/src/main/java/org/apache/roller/weblogger/business/search/SearchResultList.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. The ASF licenses this file to You + * under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. For additional information regarding + * copyright in this work, please see the NOTICE file in the top level + * directory of this distribution. + */ + +/* Created on March 8, 2023 */ + +package org.apache.roller.weblogger.business.search; + +import java.util.List; +import java.util.Set; +import org.apache.roller.weblogger.pojos.wrapper.WeblogEntryWrapper; + +public class SearchResultList { + int limit; + int offset; + Set categories; + List results; + public SearchResultList( + List results, Set categories, int limit, int offset) { + this.results = results; + this.categories = categories; + this.limit = limit; + this.offset = offset; + } + public int getLimit() { + return limit; + } + public int getOffset() { + return offset; + } + public List getResults() { + return results; + } + public Set getCategories() { + return categories; + } +} diff --git a/app/src/main/java/org/apache/roller/weblogger/business/search/SearchResultMap.java b/app/src/main/java/org/apache/roller/weblogger/business/search/SearchResultMap.java new file mode 100644 index 0000000000..f3c985c95c --- /dev/null +++ b/app/src/main/java/org/apache/roller/weblogger/business/search/SearchResultMap.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. The ASF licenses this file to You + * under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. For additional information regarding + * copyright in this work, please see the NOTICE file in the top level + * directory of this distribution. + */ + +/* Created on March 8, 2023 */ + +package org.apache.roller.weblogger.business.search; + +import java.util.Date; +import java.util.Map; +import java.util.Set; +import org.apache.roller.weblogger.pojos.wrapper.WeblogEntryWrapper; + +public class SearchResultMap { + int limit; + int offset; + Set categories; + Map> results; + public SearchResultMap(Map> results, Set categories, int limit, int offset) { + this.results = results; + this.categories = categories; + this.limit = limit; + this.offset = offset; + } + public int getLimit() { + return limit; + } + public int getOffset() { + return offset; + } + public Map> getResults() { + return results; + } + public Set getCategories() { + return categories; + } +} diff --git a/app/src/main/java/org/apache/roller/weblogger/business/search/operations/AddEntryOperation.java b/app/src/main/java/org/apache/roller/weblogger/business/search/lucene/AddEntryOperation.java similarity index 88% rename from app/src/main/java/org/apache/roller/weblogger/business/search/operations/AddEntryOperation.java rename to app/src/main/java/org/apache/roller/weblogger/business/search/lucene/AddEntryOperation.java index 1321ada889..1d8e500220 100644 --- a/app/src/main/java/org/apache/roller/weblogger/business/search/operations/AddEntryOperation.java +++ b/app/src/main/java/org/apache/roller/weblogger/business/search/lucene/AddEntryOperation.java @@ -16,7 +16,7 @@ * directory of this distribution. */ /* Created on Jul 16, 2003 */ -package org.apache.roller.weblogger.business.search.operations; +package org.apache.roller.weblogger.business.search.lucene; import java.io.IOException; @@ -24,7 +24,6 @@ import org.apache.commons.logging.LogFactory; import org.apache.lucene.index.IndexWriter; import org.apache.roller.weblogger.WebloggerException; -import org.apache.roller.weblogger.business.search.IndexManagerImpl; import org.apache.roller.weblogger.business.Weblogger; import org.apache.roller.weblogger.business.WeblogEntryManager; import org.apache.roller.weblogger.pojos.WeblogEntry; @@ -37,7 +36,7 @@ public class AddEntryOperation extends WriteToIndexOperation { //~ Static fields/initializers ============================================= - private static Log mLogger = + private static Log logger = LogFactory.getFactory().getInstance(AddEntryOperation.class); //~ Instance fields ======================================================== @@ -50,7 +49,7 @@ public class AddEntryOperation extends WriteToIndexOperation { /** * Adds a web log entry into the index. */ - public AddEntryOperation(Weblogger roller, IndexManagerImpl mgr,WeblogEntry data) { + public AddEntryOperation(Weblogger roller, LuceneIndexManager mgr, WeblogEntry data) { super(mgr); this.roller = roller; this.data = data; @@ -69,7 +68,7 @@ public void doRun() { WeblogEntryManager wMgr = roller.getWeblogEntryManager(); this.data = wMgr.getWeblogEntry(this.data.getId()); } catch (WebloggerException ex) { - mLogger.error("Error getting weblogentry object", ex); + logger.error("Error getting weblogentry object", ex); return; } @@ -78,7 +77,7 @@ public void doRun() { writer.addDocument(getDocument(data)); } } catch (IOException e) { - mLogger.error("Problems adding doc to index", e); + logger.error("Problems adding doc to index", e); } finally { if (roller != null) { roller.release(); diff --git a/app/src/main/java/org/apache/roller/weblogger/business/search/FieldConstants.java b/app/src/main/java/org/apache/roller/weblogger/business/search/lucene/FieldConstants.java similarity index 96% rename from app/src/main/java/org/apache/roller/weblogger/business/search/FieldConstants.java rename to app/src/main/java/org/apache/roller/weblogger/business/search/lucene/FieldConstants.java index 7b19361a7b..bfbd9a2db6 100644 --- a/app/src/main/java/org/apache/roller/weblogger/business/search/FieldConstants.java +++ b/app/src/main/java/org/apache/roller/weblogger/business/search/lucene/FieldConstants.java @@ -16,7 +16,7 @@ * directory of this distribution. */ /* Created on Jul 19, 2003 */ -package org.apache.roller.weblogger.business.search; +package org.apache.roller.weblogger.business.search.lucene; /** diff --git a/app/src/main/java/org/apache/roller/weblogger/business/search/operations/IndexOperation.java b/app/src/main/java/org/apache/roller/weblogger/business/search/lucene/IndexOperation.java similarity index 93% rename from app/src/main/java/org/apache/roller/weblogger/business/search/operations/IndexOperation.java rename to app/src/main/java/org/apache/roller/weblogger/business/search/lucene/IndexOperation.java index 22d8d7c24c..7c251e8bff 100644 --- a/app/src/main/java/org/apache/roller/weblogger/business/search/operations/IndexOperation.java +++ b/app/src/main/java/org/apache/roller/weblogger/business/search/lucene/IndexOperation.java @@ -15,8 +15,10 @@ * copyright in this work, please see the NOTICE file in the top level * directory of this distribution. */ + /* Created on Jul 16, 2003 */ -package org.apache.roller.weblogger.business.search.operations; + +package org.apache.roller.weblogger.business.search.lucene; import java.io.IOException; import java.util.List; @@ -32,8 +34,6 @@ import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.util.BytesRef; -import org.apache.roller.weblogger.business.search.FieldConstants; -import org.apache.roller.weblogger.business.search.IndexManagerImpl; import org.apache.roller.weblogger.config.WebloggerConfig; import org.apache.roller.weblogger.pojos.WeblogCategory; import org.apache.roller.weblogger.pojos.WeblogEntry; @@ -50,17 +50,17 @@ */ public abstract class IndexOperation implements Runnable { - private static Log mLogger = LogFactory.getFactory().getInstance( + private static Log logger = LogFactory.getFactory().getInstance( IndexOperation.class); // ~ Instance fields // ======================================================== - protected IndexManagerImpl manager; + protected LuceneIndexManager manager; private IndexWriter writer; // ~ Constructors // =========================================================== - public IndexOperation(IndexManagerImpl manager) { + public IndexOperation(LuceneIndexManager manager) { this.manager = manager; } @@ -172,7 +172,7 @@ protected IndexWriter beginWriting() { try { LimitTokenCountAnalyzer analyzer = new LimitTokenCountAnalyzer( - IndexManagerImpl.getAnalyzer(), + LuceneIndexManager.getAnalyzer(), WebloggerConfig.getIntProperty("lucene.analyzer.maxTokenCount")); IndexWriterConfig config = new IndexWriterConfig(analyzer); @@ -180,7 +180,7 @@ protected IndexWriter beginWriting() { writer = new IndexWriter(manager.getIndexDirectory(), config); } catch (IOException e) { - mLogger.error("ERROR creating writer", e); + logger.error("ERROR creating writer", e); } return writer; @@ -194,7 +194,7 @@ protected void endWriting() { try { writer.close(); } catch (IOException e) { - mLogger.error("ERROR closing writer", e); + logger.error("ERROR closing writer", e); } } } diff --git a/app/src/main/java/org/apache/roller/weblogger/business/search/IndexUtil.java b/app/src/main/java/org/apache/roller/weblogger/business/search/lucene/IndexUtil.java similarity index 94% rename from app/src/main/java/org/apache/roller/weblogger/business/search/IndexUtil.java rename to app/src/main/java/org/apache/roller/weblogger/business/search/lucene/IndexUtil.java index 70e25da849..1f3f00d3f1 100644 --- a/app/src/main/java/org/apache/roller/weblogger/business/search/IndexUtil.java +++ b/app/src/main/java/org/apache/roller/weblogger/business/search/lucene/IndexUtil.java @@ -16,7 +16,7 @@ * directory of this distribution. */ /* Created on Jul 20, 2003 */ -package org.apache.roller.weblogger.business.search; +package org.apache.roller.weblogger.business.search.lucene; import java.io.IOException; import java.io.StringReader; @@ -49,7 +49,7 @@ public static Term getTerm(String field, String input) { if (input == null || field == null) { return null; } - Analyzer analyzer = IndexManagerImpl.getAnalyzer(); + Analyzer analyzer = LuceneIndexManager.getAnalyzer(); Term term = null; try { TokenStream tokens = analyzer.tokenStream(field, new StringReader(input)); diff --git a/app/src/main/java/org/apache/roller/weblogger/business/search/IndexManagerImpl.java b/app/src/main/java/org/apache/roller/weblogger/business/search/lucene/LuceneIndexManager.java similarity index 60% rename from app/src/main/java/org/apache/roller/weblogger/business/search/IndexManagerImpl.java rename to app/src/main/java/org/apache/roller/weblogger/business/search/lucene/LuceneIndexManager.java index 077382b264..7a7e5b5125 100644 --- a/app/src/main/java/org/apache/roller/weblogger/business/search/IndexManagerImpl.java +++ b/app/src/main/java/org/apache/roller/weblogger/business/search/lucene/LuceneIndexManager.java @@ -16,41 +16,49 @@ * directory of this distribution. */ -package org.apache.roller.weblogger.business.search; +package org.apache.roller.weblogger.business.search.lucene; import java.io.File; import java.io.IOException; - import java.lang.reflect.InvocationTargetException; import java.nio.file.Files; import java.nio.file.Path; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; - import org.apache.commons.beanutils.ConstructorUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.miscellaneous.LimitTokenCountAnalyzer; import org.apache.lucene.analysis.standard.StandardAnalyzer; +import org.apache.lucene.document.Document; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; +import org.apache.lucene.search.ScoreDoc; +import org.apache.lucene.search.TopFieldDocs; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; import org.apache.roller.weblogger.WebloggerException; import org.apache.roller.weblogger.business.InitializationException; +import org.apache.roller.weblogger.business.URLStrategy; +import org.apache.roller.weblogger.business.WeblogEntryManager; import org.apache.roller.weblogger.business.Weblogger; -import org.apache.roller.weblogger.business.search.operations.AddEntryOperation; -import org.apache.roller.weblogger.business.search.operations.IndexOperation; -import org.apache.roller.weblogger.business.search.operations.ReIndexEntryOperation; -import org.apache.roller.weblogger.business.search.operations.RebuildWebsiteIndexOperation; -import org.apache.roller.weblogger.business.search.operations.RemoveEntryOperation; -import org.apache.roller.weblogger.business.search.operations.RemoveWebsiteIndexOperation; -import org.apache.roller.weblogger.pojos.WeblogEntry; -import org.apache.roller.weblogger.pojos.Weblog; +import org.apache.roller.weblogger.business.WebloggerFactory; +import org.apache.roller.weblogger.business.search.IndexManager; +import org.apache.roller.weblogger.business.search.SearchResultList; import org.apache.roller.weblogger.config.WebloggerConfig; +import org.apache.roller.weblogger.config.WebloggerRuntimeConfig; +import org.apache.roller.weblogger.pojos.Weblog; +import org.apache.roller.weblogger.pojos.WeblogEntry; +import org.apache.roller.weblogger.pojos.wrapper.WeblogEntryWrapper; /** * Lucene implementation of IndexManager. This is the central entry point into @@ -60,12 +68,12 @@ * @author mraible (formatting and making indexDir configurable) */ @com.google.inject.Singleton -public class IndexManagerImpl implements IndexManager { +public class LuceneIndexManager implements IndexManager { private IndexReader reader; private final Weblogger roller; - private final static Log mLogger = LogFactory.getFactory().getInstance(IndexManagerImpl.class); + private final static Log logger = LogFactory.getFactory().getInstance(LuceneIndexManager.class); private boolean searchEnabled = true; @@ -87,7 +95,7 @@ public class IndexManagerImpl implements IndexManager { * @param roller - the weblogger instance */ @com.google.inject.Inject - protected IndexManagerImpl(Weblogger roller) { + protected LuceneIndexManager(Weblogger roller) { this.roller = roller; // check config to see if the internal search is enabled @@ -102,8 +110,8 @@ protected IndexManagerImpl(Weblogger roller) { this.indexDir = searchIndexDir.replace('/', File.separatorChar); // a little debugging - mLogger.info("search enabled: " + this.searchEnabled); - mLogger.info("index dir: " + this.indexDir); + logger.info("search enabled: " + this.searchEnabled); + logger.info("index dir: " + this.indexDir); String test = indexDir + File.separator + ".index-inconsistent"; indexConsistencyMarker = new File(test); @@ -120,7 +128,7 @@ public void initialize() throws InitializationException { // delete index if inconsistency marker exists if (indexConsistencyMarker.exists()) { - mLogger.debug("Index inconsistent: marker exists"); + logger.debug("Index inconsistent: marker exists"); inconsistentAtStartup = true; deleteIndex(); } else { @@ -129,11 +137,11 @@ public void initialize() throws InitializationException { if (!makeIndexDir.exists()) { makeIndexDir.mkdirs(); inconsistentAtStartup = true; - mLogger.debug("Index inconsistent: new"); + logger.debug("Index inconsistent: new"); } indexConsistencyMarker.createNewFile(); } catch (IOException e) { - mLogger.error(e); + logger.error(e); } } @@ -145,43 +153,43 @@ public void initialize() throws InitializationException { reader = DirectoryReader.open(getIndexDirectory()); } } catch (IOException | IllegalArgumentException ex) { // IAE for incompatible codecs - mLogger.warn("Failed to open search index, scheduling rebuild.", ex); + logger.warn("Failed to open search index, scheduling rebuild.", ex); inconsistentAtStartup = true; deleteIndex(); } } else { - mLogger.debug("Creating index"); + logger.debug("Creating index"); inconsistentAtStartup = true; deleteIndex(); createIndex(getIndexDirectory()); } if (inconsistentAtStartup) { - mLogger.info("Index was inconsistent. Rebuilding index in the background..."); + logger.info("Index was inconsistent. Rebuilding index in the background..."); try { - rebuildWebsiteIndex(); + rebuildWeblogIndex(); } catch (WebloggerException ex) { - mLogger.error("ERROR: scheduling re-index operation", ex); + logger.error("ERROR: scheduling re-index operation", ex); } } else { - mLogger.info("Index initialized and ready for use."); + logger.info("Index initialized and ready for use."); } } } @Override - public void rebuildWebsiteIndex() throws WebloggerException { + public void rebuildWeblogIndex() throws WebloggerException { scheduleIndexOperation(new RebuildWebsiteIndexOperation(roller, this, null)); } @Override - public void rebuildWebsiteIndex(Weblog website) throws WebloggerException { + public void rebuildWeblogIndex(Weblog website) throws WebloggerException { scheduleIndexOperation(new RebuildWebsiteIndexOperation(roller, this, website)); } @Override - public void removeWebsiteIndex(Weblog website) throws WebloggerException { + public void removeWeblogIndex(Weblog website) throws WebloggerException { scheduleIndexOperation(new RemoveWebsiteIndexOperation(roller, this, website)); } @@ -200,6 +208,45 @@ public void removeEntryIndexOperation(WeblogEntry entry) throws WebloggerExcepti executeIndexOperationNow(new RemoveEntryOperation(roller, this, entry)); } + @Override + public SearchResultList search( + String term, + String weblogHandle, + String category, + String locale, + int pageNum, + int entryCount, + URLStrategy urlStrategy) throws WebloggerException { + + SearchOperation search = new SearchOperation(this); + search.setTerm(term); + boolean weblogSpecific = !WebloggerRuntimeConfig.isSiteWideWeblog(weblogHandle); + if (weblogSpecific) { + search.setWeblogHandle(weblogHandle); + } + if (category != null) { + search.setCategory(category); + } + if (locale != null) { + search.setLocale(locale); + } + + executeIndexOperationNow(search); + if (search.getResultsCount() >= 0) { + TopFieldDocs docs = search.getResults(); + ScoreDoc[] hitsArr = docs.scoreDocs; + return convertHitsToEntryList( + hitsArr, + search, + pageNum, + entryCount, + weblogHandle, + weblogSpecific, + urlStrategy); + } + throw new WebloggerException("Error executing search"); + } + public ReadWriteLock getReadWriteLock() { return rwl; } @@ -224,10 +271,10 @@ private static Analyzer instantiateAnalyzer() { final Class clazz = Class.forName(className); return (Analyzer) ConstructorUtils.invokeConstructor(clazz, null); } catch (final ClassNotFoundException e) { - mLogger.error("failed to lookup analyzer class: " + className, e); + logger.error("failed to lookup analyzer class: " + className, e); return instantiateDefaultAnalyzer(); } catch (final NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) { - mLogger.error("failed to instantiate analyzer: " + className, e); + logger.error("failed to instantiate analyzer: " + className, e); return instantiateDefaultAnalyzer(); } } @@ -240,29 +287,27 @@ private void scheduleIndexOperation(final IndexOperation op) { try { // only if search is enabled if (this.searchEnabled) { - mLogger.debug("Starting scheduled index operation: " + logger.debug("Starting scheduled index operation: " + op.getClass().getName()); roller.getThreadManager().executeInBackground(op); } } catch (InterruptedException e) { - mLogger.error("Error executing operation", e); + logger.error("Error executing operation", e); } } /** * @param op */ - @Override - public void executeIndexOperationNow(final IndexOperation op) { + private void executeIndexOperationNow(final IndexOperation op) { try { // only if search is enabled if (this.searchEnabled) { - mLogger.debug("Executing index operation now: " - + op.getClass().getName()); + logger.debug("Executing index operation now: " + op.getClass().getName()); roller.getThreadManager().executeInForeground(op); } } catch (InterruptedException e) { - mLogger.error("Error executing operation", e); + logger.error("Error executing operation", e); } } @@ -275,7 +320,7 @@ public synchronized IndexReader getSharedIndexReader() { try { reader = DirectoryReader.open(getIndexDirectory()); } catch (IOException ex) { - mLogger.error("Error opening DirectoryReader", ex); + logger.error("Error opening DirectoryReader", ex); throw new RuntimeException(ex); } } @@ -293,7 +338,7 @@ public Directory getIndexDirectory() { try { return FSDirectory.open(Path.of(indexDir)); } catch (IOException e) { - mLogger.error("Problem accessing index directory", e); + logger.error("Problem accessing index directory", e); } return null; } @@ -302,7 +347,7 @@ private boolean indexExists() { try { return DirectoryReader.indexExists(getIndexDirectory()); } catch (IOException e) { - mLogger.error("Problem accessing index directory", e); + logger.error("Problem accessing index directory", e); } return false; } @@ -317,7 +362,7 @@ private void deleteIndex() { Files.delete(Path.of(indexDir, file)); } } catch (IOException ex) { - mLogger.error("Problem accessing index directory", ex); + logger.error("Problem accessing index directory", ex); } } @@ -329,18 +374,18 @@ private void createIndex(Directory dir) { IndexWriterConfig config = new IndexWriterConfig( new LimitTokenCountAnalyzer( - IndexManagerImpl.getAnalyzer(), 128)); + LuceneIndexManager.getAnalyzer(), 128)); writer = new IndexWriter(dir, config); } catch (IOException e) { - mLogger.error("Error creating index", e); + logger.error("Error creating index", e); } finally { if (writer != null) { try { writer.close(); } catch (IOException ex) { - mLogger.warn("Unable to close IndexWriter.", ex); + logger.warn("Unable to close IndexWriter.", ex); } } } @@ -360,9 +405,81 @@ public void shutdown() { try { reader.close(); } catch (IOException ex) { - mLogger.error("Unable to close reader.", ex); + logger.error("Unable to close reader.", ex); } } } + /** + * Convert hits to entries. + * + * @param hits + * the hits + * @param search + * the search + * @throws WebloggerException + * the weblogger exception + */ + static SearchResultList convertHitsToEntryList( + ScoreDoc[] hits, + SearchOperation search, + int pageNum, + int entryCount, + String weblogHandle, + boolean websiteSpecificSearch, + URLStrategy urlStrategy) + throws WebloggerException { + + List results = new ArrayList<>(); + + // determine offset + int offset = pageNum * entryCount; + if (offset >= hits.length) { + offset = 0; + } + + // determine limit + int limit = entryCount; + if (offset + limit > hits.length) { + limit = hits.length - offset; + } + + try { + Set categories = new TreeSet<>(); + TreeSet categorySet = new TreeSet<>(); + Weblogger roller = WebloggerFactory.getWeblogger(); + WeblogEntryManager weblogMgr = roller.getWeblogEntryManager(); + + WeblogEntry entry; + Document doc; + String handle; + Timestamp now = new Timestamp(new Date().getTime()); + for (int i = offset; i < offset + limit; i++) { + doc = search.getSearcher().doc(hits[i].doc); + handle = doc.getField(FieldConstants.WEBSITE_HANDLE).stringValue(); + entry = weblogMgr.getWeblogEntry(doc.getField(FieldConstants.ID).stringValue()); + + if (!(websiteSpecificSearch && handle.equals(weblogHandle)) + && doc.getField(FieldConstants.CATEGORY) != null) { + categorySet.add(doc.getField(FieldConstants.CATEGORY).stringValue()); + } + + // maybe null if search result returned inactive user + // or entry's user is not the requested user. + // but don't return future posts + if (entry != null && entry.getPubTime().before(now)) { + results.add(WeblogEntryWrapper.wrap(entry, urlStrategy)); + } + } + + if (!categorySet.isEmpty()) { + categories = categorySet; + } + + return new SearchResultList(results, categories, limit, offset); + + } catch (IOException e) { + throw new WebloggerException(e); + } + } } diff --git a/app/src/main/java/org/apache/roller/weblogger/business/search/operations/ReIndexEntryOperation.java b/app/src/main/java/org/apache/roller/weblogger/business/search/lucene/ReIndexEntryOperation.java similarity index 86% rename from app/src/main/java/org/apache/roller/weblogger/business/search/operations/ReIndexEntryOperation.java rename to app/src/main/java/org/apache/roller/weblogger/business/search/lucene/ReIndexEntryOperation.java index 224908bfd5..e0d8e3c6ba 100644 --- a/app/src/main/java/org/apache/roller/weblogger/business/search/operations/ReIndexEntryOperation.java +++ b/app/src/main/java/org/apache/roller/weblogger/business/search/lucene/ReIndexEntryOperation.java @@ -16,7 +16,7 @@ * directory of this distribution. */ /* Created on Jul 16, 2003 */ -package org.apache.roller.weblogger.business.search.operations; +package org.apache.roller.weblogger.business.search.lucene; import java.io.IOException; @@ -27,8 +27,6 @@ import org.apache.roller.weblogger.WebloggerException; import org.apache.roller.weblogger.business.WeblogEntryManager; import org.apache.roller.weblogger.business.Weblogger; -import org.apache.roller.weblogger.business.search.FieldConstants; -import org.apache.roller.weblogger.business.search.IndexManagerImpl; import org.apache.roller.weblogger.pojos.WeblogEntry; /** @@ -41,7 +39,7 @@ public class ReIndexEntryOperation extends WriteToIndexOperation { // ~ Static fields/initializers // ============================================= - private static Log mLogger = LogFactory.getFactory().getInstance( + private static Log logger = LogFactory.getFactory().getInstance( AddEntryOperation.class); // ~ Instance fields @@ -56,7 +54,7 @@ public class ReIndexEntryOperation extends WriteToIndexOperation { /** * Adds a web log entry into the index. */ - public ReIndexEntryOperation(Weblogger roller, IndexManagerImpl mgr, + public ReIndexEntryOperation(Weblogger roller, LuceneIndexManager mgr, WeblogEntry data) { super(mgr); this.roller = roller; @@ -76,7 +74,7 @@ public void doRun() { WeblogEntryManager wMgr = roller.getWeblogEntryManager(); this.data = wMgr.getWeblogEntry(this.data.getId()); } catch (WebloggerException ex) { - mLogger.error("Error getting weblogentry object", ex); + logger.error("Error getting weblogentry object", ex); return; } @@ -92,7 +90,7 @@ public void doRun() { writer.addDocument(getDocument(data)); } } catch (IOException e) { - mLogger.error("Problems adding/deleting doc to index", e); + logger.error("Problems adding/deleting doc to index", e); } finally { if (roller != null) { roller.release(); diff --git a/app/src/main/java/org/apache/roller/weblogger/business/search/operations/ReadFromIndexOperation.java b/app/src/main/java/org/apache/roller/weblogger/business/search/lucene/ReadFromIndexOperation.java similarity index 80% rename from app/src/main/java/org/apache/roller/weblogger/business/search/operations/ReadFromIndexOperation.java rename to app/src/main/java/org/apache/roller/weblogger/business/search/lucene/ReadFromIndexOperation.java index e45ac3b433..81e4bb9615 100644 --- a/app/src/main/java/org/apache/roller/weblogger/business/search/operations/ReadFromIndexOperation.java +++ b/app/src/main/java/org/apache/roller/weblogger/business/search/lucene/ReadFromIndexOperation.java @@ -15,21 +15,20 @@ * copyright in this work, please see the NOTICE file in the top level * directory of this distribution. */ -package org.apache.roller.weblogger.business.search.operations; +package org.apache.roller.weblogger.business.search.lucene; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.roller.weblogger.business.search.IndexManagerImpl; /** * @author aim4min */ public abstract class ReadFromIndexOperation extends IndexOperation { - public ReadFromIndexOperation(IndexManagerImpl mgr) { + public ReadFromIndexOperation(LuceneIndexManager mgr) { super(mgr); } - private static Log mLogger = LogFactory.getFactory().getInstance( + private static Log logger = LogFactory.getFactory().getInstance( ReadFromIndexOperation.class); @Override @@ -39,7 +38,7 @@ public final void run() { doRun(); } catch (Exception e) { - mLogger.error("Error acquiring read lock on index", e); + logger.error("Error acquiring read lock on index", e); } finally { manager.getReadWriteLock().readLock().unlock(); } diff --git a/app/src/main/java/org/apache/roller/weblogger/business/search/operations/RebuildWebsiteIndexOperation.java b/app/src/main/java/org/apache/roller/weblogger/business/search/lucene/RebuildWebsiteIndexOperation.java similarity index 85% rename from app/src/main/java/org/apache/roller/weblogger/business/search/operations/RebuildWebsiteIndexOperation.java rename to app/src/main/java/org/apache/roller/weblogger/business/search/lucene/RebuildWebsiteIndexOperation.java index 7a43ba50b3..69b8217aa7 100644 --- a/app/src/main/java/org/apache/roller/weblogger/business/search/operations/RebuildWebsiteIndexOperation.java +++ b/app/src/main/java/org/apache/roller/weblogger/business/search/lucene/RebuildWebsiteIndexOperation.java @@ -16,7 +16,7 @@ * directory of this distribution. */ /* Created on Jul 16, 2003 */ -package org.apache.roller.weblogger.business.search.operations; +package org.apache.roller.weblogger.business.search.lucene; import java.text.MessageFormat; import java.util.Date; @@ -30,9 +30,6 @@ import org.apache.roller.weblogger.WebloggerException; import org.apache.roller.weblogger.business.WeblogEntryManager; import org.apache.roller.weblogger.business.Weblogger; -import org.apache.roller.weblogger.business.search.FieldConstants; -import org.apache.roller.weblogger.business.search.IndexManagerImpl; -import org.apache.roller.weblogger.business.search.IndexUtil; import org.apache.roller.weblogger.pojos.Weblog; import org.apache.roller.weblogger.pojos.WeblogEntry; import org.apache.roller.weblogger.pojos.WeblogEntry.PubStatus; @@ -48,7 +45,7 @@ public class RebuildWebsiteIndexOperation extends WriteToIndexOperation { // ~ Static fields/initializers // ============================================= - private static Log mLogger = LogFactory.getFactory().getInstance( + private static Log logger = LogFactory.getFactory().getInstance( RebuildWebsiteIndexOperation.class); // ~ Instance fields @@ -66,7 +63,7 @@ public class RebuildWebsiteIndexOperation extends WriteToIndexOperation { * @param website * The website to rebuild the index for, or null for all users. */ - public RebuildWebsiteIndexOperation(Weblogger roller, IndexManagerImpl mgr, + public RebuildWebsiteIndexOperation(Weblogger roller, LuceneIndexManager mgr, Weblog website) { super(mgr); this.roller = roller; @@ -85,16 +82,16 @@ public void doRun() { // the weblog object passed in as a detached object which is proned to // lazy initialization problems, so requery for the object now if (this.website != null) { - mLogger.debug("Reindexining weblog " + website.getHandle()); + logger.debug("Reindexining weblog " + website.getHandle()); try { this.website = roller.getWeblogManager().getWeblog( this.website.getId()); } catch (WebloggerException ex) { - mLogger.error("Error getting website object", ex); + logger.error("Error getting website object", ex); return; } } else { - mLogger.debug("Reindexining entire site"); + logger.debug("Reindexining entire site"); } IndexWriter writer = beginWriting(); @@ -124,11 +121,11 @@ public void doRun() { wesc.setStatus(PubStatus.PUBLISHED); List entries = weblogManager.getWeblogEntries(wesc); - mLogger.debug("Entries to index: " + entries.size()); + logger.debug("Entries to index: " + entries.size()); for (WeblogEntry entry : entries) { writer.addDocument(getDocument(entry)); - mLogger.debug(MessageFormat.format( + logger.debug(MessageFormat.format( "Indexed entry {0}: {1}", entry.getPubTime(), entry.getAnchor())); } @@ -137,7 +134,7 @@ public void doRun() { roller.release(); } } catch (Exception e) { - mLogger.error("ERROR adding/deleting doc to index", e); + logger.error("ERROR adding/deleting doc to index", e); } finally { endWriting(); if (roller != null) { @@ -149,10 +146,10 @@ public void doRun() { double length = (end.getTime() - start.getTime()) / (double) RollerConstants.SEC_IN_MS; if (website == null) { - mLogger.info("Completed rebuilding index for all users in '" + logger.info("Completed rebuilding index for all users in '" + length + "' secs"); } else { - mLogger.info("Completed rebuilding index for website handle: '" + logger.info("Completed rebuilding index for website handle: '" + website.getHandle() + "' in '" + length + "' seconds"); } } diff --git a/app/src/main/java/org/apache/roller/weblogger/business/search/operations/RemoveEntryOperation.java b/app/src/main/java/org/apache/roller/weblogger/business/search/lucene/RemoveEntryOperation.java similarity index 85% rename from app/src/main/java/org/apache/roller/weblogger/business/search/operations/RemoveEntryOperation.java rename to app/src/main/java/org/apache/roller/weblogger/business/search/lucene/RemoveEntryOperation.java index aae130d7b8..1280a02a38 100644 --- a/app/src/main/java/org/apache/roller/weblogger/business/search/operations/RemoveEntryOperation.java +++ b/app/src/main/java/org/apache/roller/weblogger/business/search/lucene/RemoveEntryOperation.java @@ -16,7 +16,7 @@ * directory of this distribution. */ /* Created on Jul 16, 2003 */ -package org.apache.roller.weblogger.business.search.operations; +package org.apache.roller.weblogger.business.search.lucene; import java.io.IOException; @@ -27,8 +27,6 @@ import org.apache.roller.weblogger.WebloggerException; import org.apache.roller.weblogger.business.WeblogEntryManager; import org.apache.roller.weblogger.business.Weblogger; -import org.apache.roller.weblogger.business.search.FieldConstants; -import org.apache.roller.weblogger.business.search.IndexManagerImpl; import org.apache.roller.weblogger.pojos.WeblogEntry; /** @@ -41,7 +39,7 @@ public class RemoveEntryOperation extends WriteToIndexOperation { // ~ Static fields/initializers // ============================================= - private static Log mLogger = LogFactory.getFactory().getInstance( + private static Log logger = LogFactory.getFactory().getInstance( RemoveEntryOperation.class); // ~ Instance fields @@ -53,7 +51,7 @@ public class RemoveEntryOperation extends WriteToIndexOperation { // ~ Constructors // =========================================================== - public RemoveEntryOperation(Weblogger roller, IndexManagerImpl mgr, + public RemoveEntryOperation(Weblogger roller, LuceneIndexManager mgr, WeblogEntry data) { super(mgr); this.roller = roller; @@ -73,7 +71,7 @@ public void doRun() { WeblogEntryManager wMgr = roller.getWeblogEntryManager(); this.data = wMgr.getWeblogEntry(this.data.getId()); } catch (WebloggerException ex) { - mLogger.error("Error getting weblogentry object", ex); + logger.error("Error getting weblogentry object", ex); return; } @@ -84,7 +82,7 @@ public void doRun() { writer.deleteDocuments(term); } } catch (IOException e) { - mLogger.error("Error deleting doc from index", e); + logger.error("Error deleting doc from index", e); } finally { endWriting(); } diff --git a/app/src/main/java/org/apache/roller/weblogger/business/search/operations/RemoveWebsiteIndexOperation.java b/app/src/main/java/org/apache/roller/weblogger/business/search/lucene/RemoveWebsiteIndexOperation.java similarity index 85% rename from app/src/main/java/org/apache/roller/weblogger/business/search/operations/RemoveWebsiteIndexOperation.java rename to app/src/main/java/org/apache/roller/weblogger/business/search/lucene/RemoveWebsiteIndexOperation.java index 6c5d154c9b..8c7a401f81 100644 --- a/app/src/main/java/org/apache/roller/weblogger/business/search/operations/RemoveWebsiteIndexOperation.java +++ b/app/src/main/java/org/apache/roller/weblogger/business/search/lucene/RemoveWebsiteIndexOperation.java @@ -16,7 +16,7 @@ * directory of this distribution. */ /* Created on Jul 16, 2003 */ -package org.apache.roller.weblogger.business.search.operations; +package org.apache.roller.weblogger.business.search.lucene; import java.io.IOException; import java.util.Date; @@ -28,9 +28,6 @@ import org.apache.roller.util.RollerConstants; import org.apache.roller.weblogger.WebloggerException; import org.apache.roller.weblogger.business.Weblogger; -import org.apache.roller.weblogger.business.search.FieldConstants; -import org.apache.roller.weblogger.business.search.IndexManagerImpl; -import org.apache.roller.weblogger.business.search.IndexUtil; import org.apache.roller.weblogger.pojos.Weblog; /** @@ -43,7 +40,7 @@ public class RemoveWebsiteIndexOperation extends WriteToIndexOperation { // ~ Static fields/initializers // ============================================= - private static Log mLogger = LogFactory.getFactory().getInstance( + private static Log logger = LogFactory.getFactory().getInstance( RemoveWebsiteIndexOperation.class); // ~ Instance fields @@ -61,7 +58,7 @@ public class RemoveWebsiteIndexOperation extends WriteToIndexOperation { * @param website * The website to rebuild the index for, or null for all sites. */ - public RemoveWebsiteIndexOperation(Weblogger roller, IndexManagerImpl mgr, + public RemoveWebsiteIndexOperation(Weblogger roller, LuceneIndexManager mgr, Weblog website) { super(mgr); this.roller = roller; @@ -82,7 +79,7 @@ public void doRun() { this.website = roller.getWeblogManager().getWeblog( this.website.getId()); } catch (WebloggerException ex) { - mLogger.error("Error getting website object", ex); + logger.error("Error getting website object", ex); return; } @@ -101,7 +98,7 @@ public void doRun() { } } } catch (IOException e) { - mLogger.info("Problems deleting doc from index", e); + logger.info("Problems deleting doc from index", e); } finally { endWriting(); } @@ -110,7 +107,7 @@ public void doRun() { double length = (end.getTime() - start.getTime()) / (double) RollerConstants.SEC_IN_MS; if (website != null) { - mLogger.info("Completed deleting indices for website '" + logger.info("Completed deleting indices for website '" + website.getName() + "' in '" + length + "' seconds"); } } diff --git a/app/src/main/java/org/apache/roller/weblogger/business/search/operations/SearchOperation.java b/app/src/main/java/org/apache/roller/weblogger/business/search/lucene/SearchOperation.java similarity index 81% rename from app/src/main/java/org/apache/roller/weblogger/business/search/operations/SearchOperation.java rename to app/src/main/java/org/apache/roller/weblogger/business/search/lucene/SearchOperation.java index 165313dc5b..a1f2f4e1e7 100644 --- a/app/src/main/java/org/apache/roller/weblogger/business/search/operations/SearchOperation.java +++ b/app/src/main/java/org/apache/roller/weblogger/business/search/lucene/SearchOperation.java @@ -16,7 +16,7 @@ * directory of this distribution. */ /* Created on Jul 18, 2003 */ -package org.apache.roller.weblogger.business.search.operations; +package org.apache.roller.weblogger.business.search.lucene; import java.io.IOException; @@ -34,10 +34,7 @@ import org.apache.lucene.search.SortField; import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.TopFieldDocs; -import org.apache.roller.weblogger.business.search.FieldConstants; import org.apache.roller.weblogger.business.search.IndexManager; -import org.apache.roller.weblogger.business.search.IndexManagerImpl; -import org.apache.roller.weblogger.business.search.IndexUtil; /** * An operation that searches the index. @@ -49,12 +46,14 @@ public class SearchOperation extends ReadFromIndexOperation { // ~ Static fields/initializers // ============================================= - private static Log mLogger = LogFactory.getFactory().getInstance( + private static Log logger = LogFactory.getFactory().getInstance( SearchOperation.class); private static final String[] SEARCH_FIELDS = new String[] { - FieldConstants.CONTENT, FieldConstants.TITLE, - FieldConstants.C_CONTENT }; + FieldConstants.CONTENT, + FieldConstants.TITLE, + FieldConstants.C_CONTENT + }; private static final Sort SORTER = new Sort(new SortField( FieldConstants.PUBLISHED, SortField.Type.STRING, true)); @@ -66,7 +65,7 @@ public class SearchOperation extends ReadFromIndexOperation { private TopFieldDocs searchresults; private String term; - private String websiteHandle; + private String weblogHandle; private String category; private String locale; private String parseError; @@ -80,7 +79,7 @@ public class SearchOperation extends ReadFromIndexOperation { public SearchOperation(IndexManager mgr) { // TODO: finish moving IndexManager to backend, so this cast is not // needed - super((IndexManagerImpl) mgr); + super((LuceneIndexManager) mgr); } // ~ Methods @@ -106,7 +105,7 @@ public void doRun() { searcher = new IndexSearcher(reader); MultiFieldQueryParser multiParser = new MultiFieldQueryParser( - SEARCH_FIELDS, IndexManagerImpl.getAnalyzer()); + SEARCH_FIELDS, LuceneIndexManager.getAnalyzer()); // Make it an AND by default. Comment this out for an or (default) multiParser.setDefaultOperator(MultiFieldQueryParser.Operator.AND); @@ -114,37 +113,34 @@ public void doRun() { // Create a query object out of our term Query query = multiParser.parse(term); - Term tUsername = IndexUtil.getTerm(FieldConstants.WEBSITE_HANDLE, - websiteHandle); - - if (tUsername != null) { + Term handleTerm = IndexUtil.getTerm(FieldConstants.WEBSITE_HANDLE, weblogHandle); + if (handleTerm != null) { query = new BooleanQuery.Builder() .add(query, BooleanClause.Occur.MUST) - .add(new TermQuery(tUsername), BooleanClause.Occur.MUST) + .add(new TermQuery(handleTerm), BooleanClause.Occur.MUST) .build(); } if (category != null) { - Term tCategory = new Term(FieldConstants.CATEGORY, category.toLowerCase()); + Term catTerm = new Term(FieldConstants.CATEGORY, category.toLowerCase()); query = new BooleanQuery.Builder() .add(query, BooleanClause.Occur.MUST) - .add(new TermQuery(tCategory), BooleanClause.Occur.MUST) + .add(new TermQuery(catTerm), BooleanClause.Occur.MUST) .build(); } - Term tLocale = IndexUtil.getTerm(FieldConstants.LOCALE, locale); - - if (tLocale != null) { + Term localeTerm = IndexUtil.getTerm(FieldConstants.LOCALE, locale); + if (localeTerm != null) { query = new BooleanQuery.Builder() .add(query, BooleanClause.Occur.MUST) - .add(new TermQuery(tLocale), BooleanClause.Occur.MUST) + .add(new TermQuery(localeTerm), BooleanClause.Occur.MUST) .build(); } searchresults = searcher.search(query, docLimit, SORTER); } catch (IOException e) { - mLogger.error("Error searching index", e); + logger.error("Error searching index", e); parseError = e.getMessage(); } catch (ParseException e) { @@ -206,11 +202,11 @@ public String getParseError() { /** * Sets the website handle. * - * @param websiteHandle + * @param weblogHandle * the new website handle */ - public void setWebsiteHandle(String websiteHandle) { - this.websiteHandle = websiteHandle; + public void setWeblogHandle(String weblogHandle) { + this.weblogHandle = weblogHandle; } /** diff --git a/app/src/main/java/org/apache/roller/weblogger/business/search/operations/WriteToIndexOperation.java b/app/src/main/java/org/apache/roller/weblogger/business/search/lucene/WriteToIndexOperation.java similarity index 78% rename from app/src/main/java/org/apache/roller/weblogger/business/search/operations/WriteToIndexOperation.java rename to app/src/main/java/org/apache/roller/weblogger/business/search/lucene/WriteToIndexOperation.java index b6cef109d0..17a45c129e 100644 --- a/app/src/main/java/org/apache/roller/weblogger/business/search/operations/WriteToIndexOperation.java +++ b/app/src/main/java/org/apache/roller/weblogger/business/search/lucene/WriteToIndexOperation.java @@ -16,11 +16,10 @@ * directory of this distribution. */ /* Created on Aug 12, 2003 */ -package org.apache.roller.weblogger.business.search.operations; +package org.apache.roller.weblogger.business.search.lucene; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.roller.weblogger.business.search.IndexManagerImpl; /** * An operation that writes to index. @@ -28,23 +27,23 @@ */ public abstract class WriteToIndexOperation extends IndexOperation { - public WriteToIndexOperation(IndexManagerImpl mgr) { + public WriteToIndexOperation(LuceneIndexManager mgr) { super(mgr); } - private static Log mLogger = + private static Log logger = LogFactory.getFactory().getInstance(WriteToIndexOperation.class); @Override public void run() { try { manager.getReadWriteLock().writeLock().lock(); - mLogger.debug("Starting search index operation"); + logger.debug("Starting search index operation"); doRun(); - mLogger.debug("Search index operation complete"); + logger.debug("Search index operation complete"); } catch (Exception e) { - mLogger.error("Error acquiring write lock on index", e); + logger.error("Error acquiring write lock on index", e); } finally { manager.getReadWriteLock().writeLock().unlock(); diff --git a/app/src/main/java/org/apache/roller/weblogger/business/search/operations/package-info.java b/app/src/main/java/org/apache/roller/weblogger/business/search/lucene/package-info.java similarity index 89% rename from app/src/main/java/org/apache/roller/weblogger/business/search/operations/package-info.java rename to app/src/main/java/org/apache/roller/weblogger/business/search/lucene/package-info.java index d4390b65a6..2999916019 100644 --- a/app/src/main/java/org/apache/roller/weblogger/business/search/operations/package-info.java +++ b/app/src/main/java/org/apache/roller/weblogger/business/search/lucene/package-info.java @@ -17,6 +17,6 @@ */ /** - * Lucene-based search operations. + * Lucene search index implementation. */ -package org.apache.roller.weblogger.business.search.operations; \ No newline at end of file +package org.apache.roller.weblogger.business.search.lucene; \ No newline at end of file diff --git a/app/src/main/java/org/apache/roller/weblogger/business/search/package-info.java b/app/src/main/java/org/apache/roller/weblogger/business/search/package-info.java index 6c735b68b5..d9c5796e7c 100644 --- a/app/src/main/java/org/apache/roller/weblogger/business/search/package-info.java +++ b/app/src/main/java/org/apache/roller/weblogger/business/search/package-info.java @@ -17,6 +17,6 @@ */ /** - * Search index manager implementation uses Lucene. + * Search index interface with Lucene and Solr implementations. */ package org.apache.roller.weblogger.business.search; \ No newline at end of file diff --git a/app/src/main/java/org/apache/roller/weblogger/business/search/solr/SolrIndexManager.java b/app/src/main/java/org/apache/roller/weblogger/business/search/solr/SolrIndexManager.java new file mode 100644 index 0000000000..c71d7a9f00 --- /dev/null +++ b/app/src/main/java/org/apache/roller/weblogger/business/search/solr/SolrIndexManager.java @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. The ASF licenses this file to You + * under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. For additional information regarding + * copyright in this work, please see the NOTICE file in the top level + * directory of this distribution. + */ + +/* Created on March 8, 2023 */ + +package org.apache.roller.weblogger.business.search.solr; + +import org.apache.roller.weblogger.WebloggerException; +import org.apache.roller.weblogger.business.InitializationException; +import org.apache.roller.weblogger.business.URLStrategy; +import org.apache.roller.weblogger.business.search.IndexManager; +import org.apache.roller.weblogger.business.search.SearchResultList; +import org.apache.roller.weblogger.business.search.SearchResultMap; +import org.apache.roller.weblogger.pojos.Weblog; +import org.apache.roller.weblogger.pojos.WeblogEntry; + +public class SolrIndexManager implements IndexManager { + @Override + public void initialize() throws InitializationException { + + } + + @Override + public void shutdown() { + + } + + @Override + public void release() { + + } + + @Override + public boolean isInconsistentAtStartup() { + return false; + } + + @Override + public void addEntryIndexOperation(WeblogEntry entry) throws WebloggerException { + + } + + @Override + public void addEntryReIndexOperation(WeblogEntry entry) throws WebloggerException { + + } + + @Override + public void rebuildWeblogIndex(Weblog weblog) throws WebloggerException { + + } + + @Override + public void rebuildWeblogIndex() throws WebloggerException { + + } + + @Override + public void removeWeblogIndex(Weblog weblog) throws WebloggerException { + + } + + @Override + public void removeEntryIndexOperation(WeblogEntry entry) throws WebloggerException { + + } + + @Override + public SearchResultList search(String term, String weblogHandle, String category, String locale, int pageNum, int entryCount, URLStrategy urlStrategy) throws WebloggerException { + return null; + } + +} diff --git a/app/src/main/java/org/apache/roller/weblogger/pojos/WeblogEntry.java b/app/src/main/java/org/apache/roller/weblogger/pojos/WeblogEntry.java index 032dfcb8e7..7cf07da5f0 100644 --- a/app/src/main/java/org/apache/roller/weblogger/pojos/WeblogEntry.java +++ b/app/src/main/java/org/apache/roller/weblogger/pojos/WeblogEntry.java @@ -530,7 +530,7 @@ public Set getTags() { } @SuppressWarnings("unused") - private void setTags(Set tagSet) throws WebloggerException { + public void setTags(Set tagSet) throws WebloggerException { this.tagSet = tagSet; this.removedTags = new HashSet<>(); this.addedTags = new HashSet<>(); diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/rendering/model/SearchResultsFeedModel.java b/app/src/main/java/org/apache/roller/weblogger/ui/rendering/model/SearchResultsFeedModel.java index ce6f9be064..1e1adf26e4 100644 --- a/app/src/main/java/org/apache/roller/weblogger/ui/rendering/model/SearchResultsFeedModel.java +++ b/app/src/main/java/org/apache/roller/weblogger/ui/rendering/model/SearchResultsFeedModel.java @@ -18,32 +18,19 @@ package org.apache.roller.weblogger.ui.rendering.model; -import java.io.IOException; -import java.sql.Timestamp; import java.util.ArrayList; import java.util.Collections; -import java.util.Date; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.TreeSet; import org.apache.commons.text.StringEscapeUtils; - -import org.apache.commons.lang3.StringUtils; -import org.apache.lucene.document.Document; -import org.apache.lucene.search.ScoreDoc; -import org.apache.lucene.search.TopFieldDocs; import org.apache.roller.weblogger.WebloggerException; import org.apache.roller.weblogger.business.URLStrategy; -import org.apache.roller.weblogger.business.WeblogEntryManager; -import org.apache.roller.weblogger.business.Weblogger; import org.apache.roller.weblogger.business.WebloggerFactory; -import org.apache.roller.weblogger.business.search.FieldConstants; import org.apache.roller.weblogger.business.search.IndexManager; -import org.apache.roller.weblogger.business.search.operations.SearchOperation; +import org.apache.roller.weblogger.business.search.SearchResultList; import org.apache.roller.weblogger.config.WebloggerRuntimeConfig; import org.apache.roller.weblogger.pojos.Weblog; -import org.apache.roller.weblogger.pojos.WeblogEntry; import org.apache.roller.weblogger.pojos.wrapper.WeblogCategoryWrapper; import org.apache.roller.weblogger.pojos.wrapper.WeblogEntryWrapper; import org.apache.roller.weblogger.pojos.wrapper.WeblogWrapper; @@ -68,19 +55,17 @@ public class SearchResultsFeedModel implements Model { // the pager used by the 3.0+ rendering system private SearchResultsFeedPager pager = null; - private final List results = new ArrayList<>(); + private List results = new ArrayList<>(); private Set categories = Collections.emptySet(); - private boolean websiteSpecificSearch = true; - private int hits = 0; private int offset = 0; private int limit = 0; - private int entryCount = 0; + private String errorMessage = ""; - @Override + @Override public String getModelName() { return "model"; } @@ -89,11 +74,9 @@ public String getModelName() { public void init(Map initData) throws WebloggerException { // we expect the init data to contain a weblogRequest object - WeblogRequest weblogRequest = (WeblogRequest) initData - .get("parsedRequest"); + WeblogRequest weblogRequest = (WeblogRequest) initData.get("parsedRequest"); if (weblogRequest == null) { - throw new WebloggerException( - "expected weblogRequest from init data"); + throw new WebloggerException("expected weblogRequest from init data"); } if (weblogRequest instanceof WeblogFeedRequest) { @@ -101,7 +84,7 @@ public void init(Map initData) throws WebloggerException { } else { throw new WebloggerException( "weblogRequest is not a WeblogFeedRequest." - + " FeedModel only supports feed requests."); + + " FeedModel only supports feed requests."); } // look for url strategy @@ -126,38 +109,28 @@ public void init(Map initData) throws WebloggerException { return; } - this.entryCount = WebloggerRuntimeConfig - .getIntProperty("site.newsfeeds.defaultEntries"); + int entryCount = WebloggerRuntimeConfig.getIntProperty("site.newsfeeds.defaultEntries"); // setup the search - IndexManager indexMgr = WebloggerFactory.getWeblogger() - .getIndexManager(); - - SearchOperation search = new SearchOperation(indexMgr); - search.setTerm(feedRequest.getTerm()); - - if (WebloggerRuntimeConfig.isSiteWideWeblog(feedRequest - .getWeblogHandle())) { - this.websiteSpecificSearch = false; - } else { - search.setWebsiteHandle(feedRequest.getWeblogHandle()); - } - - if (StringUtils.isNotEmpty(feedRequest.getWeblogCategoryName())) { - search.setCategory(feedRequest.getWeblogCategoryName()); - } - - // execute search - indexMgr.executeIndexOperationNow(search); - - if (search.getResultsCount() > -1) { - - TopFieldDocs docs = search.getResults(); - ScoreDoc[] hitsArr = docs.scoreDocs; - this.hits = search.getResultsCount(); - - // Convert the Hits into WeblogEntryData instances. - convertHitsToEntries(hitsArr, search); + IndexManager indexMgr = WebloggerFactory.getWeblogger().getIndexManager(); + try { + SearchResultList searchResult = indexMgr.search( + feedRequest.getTerm(), + feedRequest.getWeblogHandle(), + feedRequest.getWeblogCategoryName(), + feedRequest.getLocale(), + feedRequest.getPage(), + entryCount, + urlStrategy + ); + this.hits = searchResult.getResults().size(); + this.offset = searchResult.getOffset(); + this.limit = searchResult.getLimit(); + this.results = searchResult.getResults(); + this.categories = searchResult.getCategories(); + + } catch (WebloggerException we) { + errorMessage = we.getMessage(); } // search completed, setup pager based on results @@ -170,68 +143,6 @@ public Pager getSearchResultsPager() { return pager; } - /** - * Convert hits to entries. - * - * @param hits - * the hits - * @param search - * the search - * @throws WebloggerException - * the weblogger exception - */ - private void convertHitsToEntries(ScoreDoc[] hits, SearchOperation search) - throws WebloggerException { - - // determine offset - this.offset = feedRequest.getPage() * this.entryCount; - if (this.offset >= hits.length) { - this.offset = 0; - } - - // determine limit - this.limit = this.entryCount; - if (this.offset + this.limit > hits.length) { - this.limit = hits.length - this.offset; - } - - try { - TreeSet categorySet = new TreeSet<>(); - Weblogger roller = WebloggerFactory.getWeblogger(); - WeblogEntryManager weblogMgr = roller.getWeblogEntryManager(); - - WeblogEntry entry; - Document doc; - String handle; - Timestamp now = new Timestamp(new Date().getTime()); - for (int i = offset; i < offset + limit; i++) { - doc = search.getSearcher().doc(hits[i].doc); - handle = doc.getField(FieldConstants.WEBSITE_HANDLE) - .stringValue(); - - entry = weblogMgr.getWeblogEntry(doc.getField( - FieldConstants.ID).stringValue()); - - if (!(websiteSpecificSearch && handle.equals(feedRequest.getWeblogHandle())) - && doc.getField(FieldConstants.CATEGORY) != null) { - categorySet.add(doc.getField(FieldConstants.CATEGORY).stringValue()); - } - - // maybe null if search result returned inactive user - // or entry's user is not the requested user. - // but don't return future posts - if (entry != null && entry.getPubTime().before(now)) { - results.add(WeblogEntryWrapper.wrap(entry, urlStrategy)); - } - } - - if (!categorySet.isEmpty()) { - this.categories = categorySet; - } - } catch (IOException e) { - throw new WebloggerException(e); - } - } /** * Get weblog being displayed. @@ -274,10 +185,14 @@ public String getCategoryName() { return feedRequest.getWeblogCategoryName(); } + public String getErrorMessage() { + return errorMessage; + } + public WeblogCategoryWrapper getWeblogCategory() { if (feedRequest.getWeblogCategory() != null) { return WeblogCategoryWrapper.wrap(feedRequest.getWeblogCategory(), - urlStrategy); + urlStrategy); } return null; } diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/rendering/model/SearchResultsModel.java b/app/src/main/java/org/apache/roller/weblogger/ui/rendering/model/SearchResultsModel.java index 9f7ebb2b15..3c3bd9a509 100644 --- a/app/src/main/java/org/apache/roller/weblogger/ui/rendering/model/SearchResultsModel.java +++ b/app/src/main/java/org/apache/roller/weblogger/ui/rendering/model/SearchResultsModel.java @@ -18,7 +18,6 @@ package org.apache.roller.weblogger.ui.rendering.model; -import java.io.IOException; import java.sql.Timestamp; import java.util.Collections; import java.util.Date; @@ -26,30 +25,19 @@ import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; - import org.apache.commons.text.StringEscapeUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.lucene.document.Document; -import org.apache.lucene.search.ScoreDoc; -import org.apache.lucene.search.TopFieldDocs; import org.apache.roller.util.DateUtil; import org.apache.roller.weblogger.WebloggerException; import org.apache.roller.weblogger.business.URLStrategy; -import org.apache.roller.weblogger.business.WeblogEntryManager; -import org.apache.roller.weblogger.business.Weblogger; import org.apache.roller.weblogger.business.WebloggerFactory; -import org.apache.roller.weblogger.business.search.FieldConstants; import org.apache.roller.weblogger.business.search.IndexManager; -import org.apache.roller.weblogger.business.search.operations.SearchOperation; -import org.apache.roller.weblogger.config.WebloggerRuntimeConfig; -import org.apache.roller.weblogger.pojos.WeblogEntry; +import org.apache.roller.weblogger.business.search.SearchResultList; import org.apache.roller.weblogger.pojos.WeblogEntryWrapperComparator; import org.apache.roller.weblogger.pojos.wrapper.WeblogCategoryWrapper; import org.apache.roller.weblogger.pojos.wrapper.WeblogEntryWrapper; import org.apache.roller.weblogger.ui.rendering.pagers.SearchResultsPager; import org.apache.roller.weblogger.ui.rendering.pagers.WeblogEntriesPager; import org.apache.roller.weblogger.ui.rendering.util.WeblogSearchRequest; -import org.apache.roller.weblogger.util.I18nMessages; /** * Extends normal page renderer model to represent search results. @@ -65,7 +53,7 @@ public class SearchResultsModel extends PageModel { private URLStrategy urlStrategy = null; // the actual search results mapped by Day -> Set of entries - private final Map> results = new TreeMap<>(Collections.reverseOrder()); + private Map> results = new TreeMap<>(Collections.reverseOrder()); // the pager used by the 3.0+ rendering system private SearchResultsPager pager = null; @@ -74,8 +62,7 @@ public class SearchResultsModel extends PageModel { private int offset = 0; private int limit = 0; private Set categories = new TreeSet(); - private boolean websiteSpecificSearch = true; - private String errorMessage = null; + private String errorMessage = ""; @Override public void init(Map initData) throws WebloggerException { @@ -83,8 +70,7 @@ public void init(Map initData) throws WebloggerException { // we expect the init data to contain a searchRequest object searchRequest = (WeblogSearchRequest) initData.get("searchRequest"); if (searchRequest == null) { - throw new WebloggerException( - "expected searchRequest from init data"); + throw new WebloggerException("expected searchRequest from init data"); } // look for url strategy @@ -98,55 +84,59 @@ public void init(Map initData) throws WebloggerException { // if there is no query, then we are done if (searchRequest.getQuery() == null) { - pager = new SearchResultsPager(urlStrategy, searchRequest, results, - false); + pager = new SearchResultsPager(urlStrategy, searchRequest, results, false); return; } // setup the search - IndexManager indexMgr = WebloggerFactory.getWeblogger() - .getIndexManager(); - - SearchOperation search = new SearchOperation(indexMgr); - search.setTerm(searchRequest.getQuery()); - - if (WebloggerRuntimeConfig.isSiteWideWeblog(searchRequest - .getWeblogHandle())) { - this.websiteSpecificSearch = false; - } else { - search.setWebsiteHandle(searchRequest.getWeblogHandle()); - } + IndexManager indexMgr = WebloggerFactory.getWeblogger().getIndexManager(); + try { + SearchResultList searchResultList = indexMgr.search( + searchRequest.getQuery(), + searchRequest.getWeblogHandle(), + searchRequest.getWeblogCategoryName(), + searchRequest.getLocale(), + searchRequest.getPageNum(), + RESULTS_PER_PAGE, + urlStrategy + ); + hits = searchResultList.getResults().size(); + offset = searchResultList.getOffset(); + limit = searchResultList.getLimit(); + categories = searchResultList.getCategories(); - if (StringUtils.isNotEmpty(searchRequest.getWeblogCategoryName())) { - search.setCategory(searchRequest.getWeblogCategoryName()); - } + Timestamp now = new Timestamp(new Date().getTime()); + for (WeblogEntryWrapper entry : searchResultList.getResults()) { + if (entry.getPubTime().before(now)) { + addEntryToResults(results, entry); + } + } - if (searchRequest.getLocale() != null) { - search.setLocale(searchRequest.getLocale()); + } catch (WebloggerException we) { + errorMessage = we.getMessage(); } - // execute search - indexMgr.executeIndexOperationNow(search); - - if (search.getResultsCount() == -1) { - // this means there has been a parsing (or IO) error - this.errorMessage = I18nMessages.getMessages( - searchRequest.getLocaleInstance()).getString( - "error.searchProblem"); - } else { + // search completed, setup pager based on results + pager = new SearchResultsPager( + urlStrategy, searchRequest, results, (hits > (offset + limit))); + } - TopFieldDocs docs = search.getResults(); - ScoreDoc[] hitsArr = docs.scoreDocs; - this.hits = search.getResultsCount(); + private void addEntryToResults( + Map> results, + WeblogEntryWrapper entry) { - // Convert the Hits into WeblogEntryData instances. - convertHitsToEntries(hitsArr, search); + // convert entry's each date to midnight (00m 00h 00s) + Date midnight = DateUtil.getStartOfDay(entry.getPubTime()); + // ensure we do not get duplicates from Lucene by + // using a Set Collection. Entries sorted by pubTime. + Set set = results.get(midnight); + if (set == null) { + // date is not mapped yet, so we need a new Set + set = new TreeSet<>(new WeblogEntryWrapperComparator()); + results.put(midnight, set); } - - // search completed, setup pager based on results - pager = new SearchResultsPager(urlStrategy, searchRequest, results, - (hits > (offset + limit))); + set.add(entry); } /** @@ -169,86 +159,6 @@ public WeblogEntriesPager getWeblogEntriesPager(String category) { return pager; } - /** - * Convert hits to entries. - * - * @param hits - * the hits - * @param search - * the search - * @throws WebloggerException - * the weblogger exception - */ - private void convertHitsToEntries(ScoreDoc[] hits, SearchOperation search) - throws WebloggerException { - - // determine offset - this.offset = searchRequest.getPageNum() * RESULTS_PER_PAGE; - if (this.offset >= hits.length) { - this.offset = 0; - } - - // determine limit - this.limit = RESULTS_PER_PAGE; - if (this.offset + this.limit > hits.length) { - this.limit = hits.length - this.offset; - } - - try { - Set categorySet = new TreeSet<>(); - Weblogger roller = WebloggerFactory.getWeblogger(); - WeblogEntryManager weblogMgr = roller.getWeblogEntryManager(); - - WeblogEntry entry; - Document doc; - String handle; - Timestamp now = new Timestamp(new Date().getTime()); - for (int i = offset; i < offset + limit; i++) { - doc = search.getSearcher().doc(hits[i].doc); - handle = doc.getField(FieldConstants.WEBSITE_HANDLE) - .stringValue(); - - entry = weblogMgr.getWeblogEntry(doc.getField( - FieldConstants.ID).stringValue()); - - if (!(websiteSpecificSearch && handle.equals(searchRequest.getWeblogHandle())) - && doc.getField(FieldConstants.CATEGORY) != null) { - categorySet.add(doc.getField(FieldConstants.CATEGORY).stringValue()); - } - - // maybe null if search result returned inactive user - // or entry's user is not the requested user. - // but don't return future posts - if (entry != null && entry.getPubTime().before(now)) { - addEntryToResults(WeblogEntryWrapper.wrap(entry, - urlStrategy)); - } - } - - if (!categorySet.isEmpty()) { - this.categories = categorySet; - } - } catch (IOException e) { - throw new WebloggerException(e); - } - } - - private void addEntryToResults(WeblogEntryWrapper entry) { - - // convert entry's each date to midnight (00m 00h 00s) - Date midnight = DateUtil.getStartOfDay(entry.getPubTime()); - - // ensure we do not get duplicates from Lucene by - // using a Set Collection. Entries sorted by pubTime. - Set set = this.results.get(midnight); - if (set == null) { - // date is not mapped yet, so we need a new Set - set = new TreeSet<>(new WeblogEntryWrapperComparator()); - this.results.put(midnight, set); - } - set.add(entry); - } - public String getTerm() { String query = searchRequest.getQuery(); return (query == null) @@ -291,8 +201,7 @@ public String getWeblogCategoryName() { @Override public WeblogCategoryWrapper getWeblogCategory() { if (searchRequest.getWeblogCategory() != null) { - return WeblogCategoryWrapper.wrap( - searchRequest.getWeblogCategory(), urlStrategy); + return WeblogCategoryWrapper.wrap(searchRequest.getWeblogCategory(), urlStrategy); } return null; } diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/WeblogSearchRequest.java b/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/WeblogSearchRequest.java index bf699f9e70..d1037ee5d6 100644 --- a/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/WeblogSearchRequest.java +++ b/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/WeblogSearchRequest.java @@ -35,7 +35,7 @@ public class WeblogSearchRequest extends WeblogRequest { private static Log log = LogFactory.getLog(WeblogSearchRequest.class); - private static final String SEARCH_SERVLET = "/roller-ui/rendering/search"; + public static final String SEARCH_SERVLET = "/roller-ui/rendering/search"; // lightweight attributes private String query = null; diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/Maintenance.java b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/Maintenance.java index 63c9443ef4..30225eedb2 100644 --- a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/Maintenance.java +++ b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/Maintenance.java @@ -28,7 +28,6 @@ import org.apache.roller.weblogger.pojos.Weblog; import org.apache.roller.weblogger.ui.struts2.util.UIAction; import org.apache.roller.weblogger.util.cache.CacheManager; -import org.apache.struts2.convention.annotation.AllowedMethods; /** * Allows user to perform maintenance operations such as flushing the page cache @@ -58,7 +57,7 @@ public String index() { try { IndexManager manager = WebloggerFactory.getWeblogger() .getIndexManager(); - manager.rebuildWebsiteIndex(getActionWeblog()); + manager.rebuildWeblogIndex(getActionWeblog()); addMessage("maintenance.message.indexed"); } catch (Exception ex) { diff --git a/app/src/main/resources/log4j2.xml b/app/src/main/resources/log4j2.xml index 4e21134fad..6b916d695c 100644 --- a/app/src/main/resources/log4j2.xml +++ b/app/src/main/resources/log4j2.xml @@ -70,6 +70,7 @@ limitations under the License. + diff --git a/app/src/main/resources/rome.properties b/app/src/main/resources/rome.properties index f544fb2fad..427ad3707e 100644 --- a/app/src/main/resources/rome.properties +++ b/app/src/main/resources/rome.properties @@ -18,7 +18,7 @@ # Some RSS 0.91 feeds have pubDates in items WireFeedParser.classes=org.apache.roller.planet.util.rome.PlanetRSS091UParser \ - org.apache.roller.planet.util.rome.PlanetRSS091NParser + org.apache.roller.planet.util.rome.PlanetRSS091NParser Converter.classes =org.apache.roller.planet.util.rome.PlanetConverterForRSS091U \ org.apache.roller.planet.util.rome.PlanetConverterForRSS091N \ diff --git a/app/src/test/java/org/apache/roller/util/DerbyManager.java b/app/src/test/java/org/apache/roller/util/DerbyManager.java index f28a6d4a6e..ba6ef05086 100644 --- a/app/src/test/java/org/apache/roller/util/DerbyManager.java +++ b/app/src/test/java/org/apache/roller/util/DerbyManager.java @@ -51,7 +51,7 @@ public void startDerby() throws Exception { //System.setProperty("derby.drda.logConnections","true"); NetworkServerControl server = new NetworkServerControl(); server.start(new PrintWriter(System.out)); - + try {Thread.sleep(2000);} catch (Exception ignored) {} System.out.println("Runtime Info: " + server.getRuntimeInfo()); diff --git a/app/src/test/java/org/apache/roller/weblogger/business/IndexManagerTest.java b/app/src/test/java/org/apache/roller/weblogger/business/IndexManagerTest.java deleted file mode 100644 index 617f0082c4..0000000000 --- a/app/src/test/java/org/apache/roller/weblogger/business/IndexManagerTest.java +++ /dev/null @@ -1,157 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. The ASF licenses this file to You -* under the Apache License, Version 2.0 (the "License"); you may not -* use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. For additional information regarding -* copyright in this work, please see the NOTICE file in the top level -* directory of this distribution. -*/ -package org.apache.roller.weblogger.business; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.roller.util.RollerConstants; -import org.apache.roller.weblogger.TestUtils; -import org.apache.roller.weblogger.business.search.IndexManager; -import org.apache.roller.weblogger.business.search.IndexManagerImpl; -import org.apache.roller.weblogger.business.search.operations.AddEntryOperation; -import org.apache.roller.weblogger.business.search.operations.SearchOperation; -import org.apache.roller.weblogger.pojos.User; -import org.apache.roller.weblogger.pojos.Weblog; -import org.apache.roller.weblogger.pojos.WeblogCategory; -import org.apache.roller.weblogger.pojos.WeblogEntry; -import org.apache.roller.weblogger.pojos.WeblogEntry.PubStatus; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.sql.Timestamp; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * Test Search Manager business layer operations. - */ -public class IndexManagerTest { - User testUser = null; - Weblog testWeblog = null; - public static Log log = LogFactory.getLog(IndexManagerTest.class); - - /** - * All tests in this suite require a user and a weblog. - */ - @BeforeEach - public void setUp() throws Exception { - - // setup weblogger - TestUtils.setupWeblogger(); - - try { - testUser = TestUtils.setupUser("entryTestUser"); - testWeblog = TestUtils.setupWeblog("entryTestWeblog", testUser); - TestUtils.endSession(true); - - //WeblogManager wmgr = WebloggerFactory.getWeblogger().getWeblogManager(); - //assertEquals(1, wmgr.getWeblogCount()); - - } catch (Exception ex) { - log.error("ERROR in test setup", ex); - throw new Exception("Test setup failed", ex); - } - } - - @AfterEach - public void tearDown() throws Exception { - - try { - TestUtils.teardownWeblog(testWeblog.getId()); - TestUtils.teardownUser(testUser.getUserName()); - TestUtils.endSession(true); - } catch (Exception ex) { - log.error("ERROR in test teardown", ex); - throw new Exception("Test teardown failed", ex); - } - } - - @Test - public void testSearch() throws Exception { - WeblogEntryManager wem = WebloggerFactory.getWeblogger().getWeblogEntryManager(); - - WeblogEntry wd1 = new WeblogEntry(); - wd1.setTitle("The Tholian Web"); - wd1.setText( - "When the Enterprise attempts to ascertain the fate of the " - +"U.S.S. Defiant which vanished 3 weeks ago, the warp engines " - +"begin to lose power, and Spock reports strange sensor readings."); - wd1.setAnchor("dummy1"); - wd1.setCreatorUserName(testUser.getUserName()); - wd1.setStatus(PubStatus.PUBLISHED); - wd1.setUpdateTime(new Timestamp(System.currentTimeMillis())); - wd1.setPubTime(new Timestamp(System.currentTimeMillis())); - wd1.setWebsite(TestUtils.getManagedWebsite(testWeblog)); - - WeblogCategory cat = wem.getWeblogCategory(testWeblog.getWeblogCategory("General").getId()); - wd1.setCategory(cat); - - wem.saveWeblogEntry(wd1); - TestUtils.endSession(true); - wd1 = TestUtils.getManagedWeblogEntry(wd1); - - IndexManager imgr = WebloggerFactory.getWeblogger().getIndexManager(); - imgr.executeIndexOperationNow( - new AddEntryOperation(WebloggerFactory.getWeblogger(), (IndexManagerImpl)imgr, wd1)); - - WeblogEntry wd2 = new WeblogEntry(); - wd2.setTitle("A Piece of the Action"); - wd2.setText( - "The crew of the Enterprise attempts to make contact with " - +"the inhabitants of planet Sigma Iotia II, and Uhura puts Kirk " - +"in communication with Boss Oxmyx."); - wd2.setAnchor("dummy2"); - wd2.setStatus(PubStatus.PUBLISHED); - wd2.setCreatorUserName(testUser.getUserName()); - wd2.setUpdateTime(new Timestamp(System.currentTimeMillis())); - wd2.setPubTime(new Timestamp(System.currentTimeMillis())); - wd2.setWebsite(TestUtils.getManagedWebsite(testWeblog)); - - cat = wem.getWeblogCategory(testWeblog.getWeblogCategory("General").getId()); - wd2.setCategory(cat); - - wem.saveWeblogEntry(wd2); - TestUtils.endSession(true); - wd2 = TestUtils.getManagedWeblogEntry(wd2); - - imgr.executeIndexOperationNow( - new AddEntryOperation(WebloggerFactory.getWeblogger(), (IndexManagerImpl)imgr, wd2)); - - Thread.sleep(RollerConstants.SEC_IN_MS); - - SearchOperation search = new SearchOperation(imgr); - search.setTerm("Enterprise"); - imgr.executeIndexOperationNow(search); - assertEquals(2, search.getResultsCount()); - - SearchOperation search2 = new SearchOperation(imgr); - search2.setTerm("Tholian"); - imgr.executeIndexOperationNow(search2); - assertEquals(1, search2.getResultsCount()); - - // Clean up - imgr.removeEntryIndexOperation(wd1); - imgr.removeEntryIndexOperation(wd2); - - SearchOperation search3 = new SearchOperation(imgr); - search3.setTerm("Enterprise"); - imgr.executeIndexOperationNow(search3); - assertEquals(0, search3.getResultsCount()); - } -} diff --git a/app/src/test/java/org/apache/roller/weblogger/business/search/IndexManagerTest.java b/app/src/test/java/org/apache/roller/weblogger/business/search/IndexManagerTest.java new file mode 100644 index 0000000000..7f146b0b9a --- /dev/null +++ b/app/src/test/java/org/apache/roller/weblogger/business/search/IndexManagerTest.java @@ -0,0 +1,158 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. The ASF licenses this file to You +* under the Apache License, Version 2.0 (the "License"); you may not +* use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. For additional information regarding +* copyright in this work, please see the NOTICE file in the top level +* directory of this distribution. +*/ +package org.apache.roller.weblogger.business.search; + +import java.sql.Timestamp; +import java.util.Collections; +import java.util.List; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.roller.util.RollerConstants; +import org.apache.roller.weblogger.TestUtils; +import org.apache.roller.weblogger.business.WeblogEntryManager; +import org.apache.roller.weblogger.business.WebloggerFactory; +import org.apache.roller.weblogger.pojos.User; +import org.apache.roller.weblogger.pojos.Weblog; +import org.apache.roller.weblogger.pojos.WeblogCategory; +import org.apache.roller.weblogger.pojos.WeblogEntry; +import org.instancio.Instancio; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.apache.roller.weblogger.ui.rendering.model.SearchResultsModel.RESULTS_PER_PAGE; +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Test Search Manager business layer operations. + */ +public class IndexManagerTest { + User testUser = null; + Weblog testWeblog = null; + public static Log log = LogFactory.getLog(IndexManagerTest.class); + + /** + * All tests in this suite require a user and a weblog. + */ + @BeforeEach + public void setUp() throws Exception { + + // setup weblogger + TestUtils.setupWeblogger(); + + try { + testUser = TestUtils.setupUser("entrytestuser"); + testWeblog = TestUtils.setupWeblog("entrytestweblog", testUser); + TestUtils.endSession(true); + } catch (Exception ex) { + log.error("ERROR in test setup", ex); + throw new Exception("Test setup failed", ex); + } + } + + @AfterEach + public void tearDown() throws Exception { + + try { + TestUtils.teardownWeblog(testWeblog.getId()); + TestUtils.teardownUser(testUser.getUserName()); + TestUtils.endSession(true); + } catch (Exception ex) { + log.error("ERROR in test teardown", ex); + throw new Exception("Test teardown failed", ex); + } + } + + @Test + public void testBasicOperation() throws Exception { + + IndexManager indexManager = WebloggerFactory.getWeblogger().getIndexManager(); + WeblogEntryManager entryManager = WebloggerFactory.getWeblogger().getWeblogEntryManager(); + + List entries = createWeblogEntries(testWeblog, indexManager, entryManager); + + try { + SearchResultList result = indexManager.search("Enterprise", + testWeblog.getHandle(), null, testWeblog.getLocale(), 0, RESULTS_PER_PAGE, + WebloggerFactory.getWeblogger().getUrlStrategy()); + assertEquals(2, result.getResults().size()); + + result = indexManager.search("Tholian", + testWeblog.getHandle(), null, testWeblog.getLocale(), 0, RESULTS_PER_PAGE, + WebloggerFactory.getWeblogger().getUrlStrategy()); + assertEquals(1, result.getResults().size()); + + } finally { + for (WeblogEntry entry : entries) { + indexManager.removeEntryIndexOperation(TestUtils.getManagedWeblogEntry(entry)); + } + indexManager.removeWeblogIndex(testWeblog); + } + } + + /** + * Create some weblog entries, two with some Star Trek content + */ + public static List createWeblogEntries( + Weblog testWeblog, + IndexManager indexManager, + WeblogEntryManager entryManager) throws Exception { + + List entries = Instancio.ofList(WeblogEntry.class).size(10).create(); + + entries.get(0).setTitle("The Tholian Web"); + entries.get(0).setPubTime(new Timestamp(System.currentTimeMillis())); + entries.get(0).setText( + "When the Enterprise attempts to ascertain the fate of the " + +"U.S.S. Defiant which vanished 3 weeks ago, the warp engines " + +"begin to lose power, and Spock reports strange sensor readings."); + + Thread.sleep(500); + + entries.get(1).setTitle("A Piece of the Action"); + entries.get(1).setPubTime(new Timestamp(System.currentTimeMillis())); + entries.get(1).setText( + "The crew of the Enterprise attempts to make contact with " + +"the inhabitants of planet Sigma Iotia II, and Uhura puts Kirk " + +"in communication with Boss Oxmyx."); + + // save and index those entries + + for (WeblogEntry entry : entries) { + + // fill in relationship fields to make JPA happy + + WeblogCategory cat = entryManager.getWeblogCategory( + testWeblog.getWeblogCategory("General").getId()); + entry.setCategory(cat); + entry.setWebsite(TestUtils.getManagedWebsite(testWeblog)); + entry.setEntryAttributes(Collections.emptySet()); + entry.setTags(Collections.emptySet()); + + entry.setLocale(testWeblog.getLocale()); + + entryManager.saveWeblogEntry(entry); + TestUtils.endSession(true); + + indexManager.addEntryIndexOperation(entry); + } + + Thread.sleep(RollerConstants.SEC_IN_MS); + return entries; + } +} diff --git a/app/src/test/java/org/apache/roller/weblogger/ui/rendering/model/SearchResultsFeedModelTest.java b/app/src/test/java/org/apache/roller/weblogger/ui/rendering/model/SearchResultsFeedModelTest.java new file mode 100644 index 0000000000..1ca19b1161 --- /dev/null +++ b/app/src/test/java/org/apache/roller/weblogger/ui/rendering/model/SearchResultsFeedModelTest.java @@ -0,0 +1,128 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. The ASF licenses this file to You + * under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. For additional information regarding + * copyright in this work, please see the NOTICE file in the top level + * directory of this distribution. + */ + +/* Created on March 8, 2023 */ + +package org.apache.roller.weblogger.ui.rendering.model; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.servlet.http.HttpServletRequest; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.roller.weblogger.TestUtils; +import org.apache.roller.weblogger.WebloggerException; +import org.apache.roller.weblogger.business.WeblogEntryManager; +import org.apache.roller.weblogger.business.WebloggerFactory; +import org.apache.roller.weblogger.business.search.IndexManagerTest; +import org.apache.roller.weblogger.business.search.IndexManager; +import org.apache.roller.weblogger.pojos.User; +import org.apache.roller.weblogger.pojos.Weblog; +import org.apache.roller.weblogger.pojos.WeblogEntry; +import org.apache.roller.weblogger.ui.rendering.util.WeblogFeedRequest; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.apache.roller.weblogger.business.search.IndexManagerTest.createWeblogEntries; +import static org.apache.roller.weblogger.ui.rendering.util.WeblogSearchRequest.SEARCH_SERVLET; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class SearchResultsFeedModelTest { + User testUser = null; + Weblog testWeblog = null; + public static Log log = LogFactory.getLog(IndexManagerTest.class); + + @BeforeEach + public void setUp() throws Exception { + TestUtils.setupWeblogger(); + try { + testUser = TestUtils.setupUser("entrytestuser"); + testWeblog = TestUtils.setupWeblog("entrytestweblog", testUser); + TestUtils.endSession(true); + } catch (Exception ex) { + log.error("ERROR in test setup", ex); + throw new Exception("Test setup failed", ex); + } + } + + @AfterEach + public void tearDown() throws Exception { + try { + TestUtils.teardownWeblog(testWeblog.getId()); + TestUtils.teardownUser(testUser.getUserName()); + TestUtils.endSession(true); + } catch (Exception ex) { + log.error("ERROR in test teardown", ex); + throw new Exception("Test teardown failed", ex); + } + } + + @Test + void testBasicOperation() throws Exception { + + IndexManager indexManager = + WebloggerFactory.getWeblogger().getIndexManager(); + WeblogEntryManager entryManager = WebloggerFactory.getWeblogger().getWeblogEntryManager(); + + List entries = createWeblogEntries(testWeblog, indexManager, entryManager); + + try { + SearchResultsFeedModel model = executeSearch("Enterprise"); + assertEquals(2, model.getResults().size()); + + model = executeSearch("Tholian"); + assertEquals(1, model.getResults().size()); + + } finally { + for (WeblogEntry entry : entries) { + indexManager.removeEntryIndexOperation(TestUtils.getManagedWeblogEntry(entry)); + } + indexManager.removeWeblogIndex(testWeblog); + } + } + + SearchResultsFeedModel executeSearch(String term) throws WebloggerException { + HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getServletPath()).thenReturn(SEARCH_SERVLET); + when(request.getRequestURL()).thenReturn( + new StringBuffer(String.format("http://localhost/%s", SEARCH_SERVLET))); + when(request.getPathInfo()).thenReturn(null); + +// WeblogSearchRequest searchRequest = new WeblogSearchRequest(request); +// searchRequest.setWeblogHandle(testWeblog.getHandle()); +// searchRequest.setQuery(term); + + WeblogFeedRequest feedRequest = new WeblogFeedRequest(); + feedRequest.setWeblog(testWeblog); + feedRequest.setTerm(term); + + Map initData = new HashMap<>(); + //initData.put("searchRequest", searchRequest); + initData.put("parsedRequest", feedRequest); + + SearchResultsFeedModel model = new SearchResultsFeedModel(); + model.init(initData); + return model; + } + + +} \ No newline at end of file diff --git a/app/src/test/java/org/apache/roller/weblogger/ui/rendering/model/SearchResultsModelTest.java b/app/src/test/java/org/apache/roller/weblogger/ui/rendering/model/SearchResultsModelTest.java new file mode 100644 index 0000000000..9c38e3bda7 --- /dev/null +++ b/app/src/test/java/org/apache/roller/weblogger/ui/rendering/model/SearchResultsModelTest.java @@ -0,0 +1,142 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. The ASF licenses this file to You + * under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. For additional information regarding + * copyright in this work, please see the NOTICE file in the top level + * directory of this distribution. + */ + +/* Created on March 8, 2023 */ + +package org.apache.roller.weblogger.ui.rendering.model; + +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import javax.servlet.http.HttpServletRequest; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.roller.weblogger.TestUtils; +import org.apache.roller.weblogger.WebloggerException; +import org.apache.roller.weblogger.business.WeblogEntryManager; +import org.apache.roller.weblogger.business.WebloggerFactory; +import org.apache.roller.weblogger.business.search.IndexManagerTest; +import org.apache.roller.weblogger.business.search.IndexManager; +import org.apache.roller.weblogger.pojos.User; +import org.apache.roller.weblogger.pojos.Weblog; +import org.apache.roller.weblogger.pojos.WeblogEntry; +import org.apache.roller.weblogger.pojos.wrapper.WeblogEntryWrapper; +import org.apache.roller.weblogger.ui.rendering.util.WeblogPageRequest; +import org.apache.roller.weblogger.ui.rendering.util.WeblogSearchRequest; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.apache.roller.weblogger.business.search.IndexManagerTest.createWeblogEntries; +import static org.apache.roller.weblogger.ui.rendering.util.WeblogSearchRequest.SEARCH_SERVLET; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class SearchResultsModelTest { + User testUser = null; + Weblog testWeblog = null; + public static Log log = LogFactory.getLog(IndexManagerTest.class); + + @BeforeEach + public void setUp() throws Exception { + TestUtils.setupWeblogger(); + try { + testUser = TestUtils.setupUser("entrytestuser"); + testWeblog = TestUtils.setupWeblog("entrytestweblog", testUser); + TestUtils.endSession(true); + } catch (Exception ex) { + log.error("ERROR in test setup", ex); + throw new Exception("Test setup failed", ex); + } + } + + @AfterEach + public void tearDown() throws Exception { + try { + TestUtils.teardownWeblog(testWeblog.getId()); + TestUtils.teardownUser(testUser.getUserName()); + TestUtils.endSession(true); + } catch (Exception ex) { + log.error("ERROR in test teardown", ex); + throw new Exception("Test teardown failed", ex); + } + } + + @Test + void testBasicOperation() throws Exception { + + IndexManager indexManager = WebloggerFactory.getWeblogger().getIndexManager(); + WeblogEntryManager entryManager = WebloggerFactory.getWeblogger().getWeblogEntryManager(); + + List entries = createWeblogEntries(testWeblog, indexManager, entryManager); + + try { + SearchResultsModel model = executeSearch("Enterprise"); + assertEquals(1, model.getResults().size()); + int count = 0; + for (Date midnight : model.getResults().keySet()) { + Set wrappers = model.getResults().get(midnight); + count += wrappers.size(); + } + assertEquals(2, count); + + model = executeSearch("Tholian"); + assertEquals(1, model.getResults().size()); + count = 0; + for (Date midnight : model.getResults().keySet()) { + Set wrappers = model.getResults().get(midnight); + count += wrappers.size(); + } + assertEquals(1, count); + + } finally { + for (WeblogEntry entry : entries) { + indexManager.removeEntryIndexOperation(TestUtils.getManagedWeblogEntry(entry)); + } + indexManager.removeWeblogIndex(testWeblog); + } + } + + SearchResultsModel executeSearch(String term) throws WebloggerException { + HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getServletPath()).thenReturn(SEARCH_SERVLET); + when(request.getRequestURL()).thenReturn( + new StringBuffer(String.format("http://localhost/%s", SEARCH_SERVLET))); + when(request.getPathInfo()).thenReturn(null); + + WeblogSearchRequest searchRequest = new WeblogSearchRequest(request); + searchRequest.setWeblogHandle(testWeblog.getHandle()); + searchRequest.setQuery(term); + + WeblogPageRequest pageRequest = new WeblogPageRequest(); + + Map initData = new HashMap<>(); + initData.put("searchRequest", searchRequest); + initData.put("parsedRequest", pageRequest); + initData.put("pageRequest", pageRequest); + + SearchResultsModel model = new SearchResultsModel(); + model.init(initData); + return model; + } + + +} \ No newline at end of file diff --git a/app/src/test/resources/log4j2.xml b/app/src/test/resources/log4j2.xml index b2c3181669..1967b03919 100644 --- a/app/src/test/resources/log4j2.xml +++ b/app/src/test/resources/log4j2.xml @@ -52,7 +52,7 @@ limitations under the License. - +