Merge pull request #123 from snoopdave/solr-impl
Isolate Lucene API in search.lucene
diff --git a/app/pom.xml b/app/pom.xml
index 8c89d28..ae1a622 100644
--- a/app/pom.xml
+++ b/app/pom.xml
@@ -308,6 +308,23 @@
<version>${lucene.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.solr</groupId>
+ <artifactId>solr-solrj</artifactId>
+ <version>9.1.1</version>
+ <!-- exclude vulnerable dependencies -->
+ <exclusions>
+ <exclusion>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-codec</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-common</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
<!-- slf4j implementing the apache commons-logging interfaces -->
<!-- note: commons-logging needs to be excluded in all dependencies transitive depending on it.
See 2006 RFE https://issues.apache.org/jira/browse/MNG-1977 for maven's missing feature of global exclusions -->
@@ -571,6 +588,20 @@
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <version>3.2.4</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.instancio</groupId>
+ <artifactId>instancio-junit</artifactId>
+ <version>2.9.0</version>
+ <scope>test</scope>
+ </dependency>
+
</dependencies>
<build>
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 8a8b301..d9e1894 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 @@
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 85956f0..8a8a933 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 {
+
+ /**
+ * 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();
/**
* 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;
+ /** Does index need to be rebuilt */
+ boolean isInconsistentAtStartup();
- void rebuildWebsiteIndex() throws WebloggerException;
+ /** 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;
+
+ /** 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 0000000..5fcaab2
--- /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<String> categories;
+ List<WeblogEntryWrapper> results;
+ public SearchResultList(
+ List<WeblogEntryWrapper> results, Set<String> 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<WeblogEntryWrapper> getResults() {
+ return results;
+ }
+ public Set<String> 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 0000000..f3c985c
--- /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<String> categories;
+ Map<Date, Set<WeblogEntryWrapper>> results;
+ public SearchResultMap(Map<Date, Set<WeblogEntryWrapper>> results, Set<String> 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<Date, Set<WeblogEntryWrapper>> getResults() {
+ return results;
+ }
+ public Set<String> 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 1321ada..1d8e500 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 @@
//~ Static fields/initializers =============================================
- private static Log mLogger =
+ private static Log logger =
LogFactory.getFactory().getInstance(AddEntryOperation.class);
//~ Instance fields ========================================================
@@ -50,7 +49,7 @@
/**
* 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 @@
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 @@
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 7b19361..bfbd9a2 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 92%
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 22d8d7c..7c251e8 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 @@
try {
LimitTokenCountAnalyzer analyzer = new LimitTokenCountAnalyzer(
- IndexManagerImpl.getAnalyzer(),
+ LuceneIndexManager.getAnalyzer(),
WebloggerConfig.getIntProperty("lucene.analyzer.maxTokenCount"));
IndexWriterConfig config = new IndexWriterConfig(analyzer);
@@ -180,7 +180,7 @@
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 @@
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 70e25da..1f3f00d 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 @@
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 077382b..7a7e5b5 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 @@
* @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 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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<WeblogEntryWrapper> 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<String> categories = new TreeSet<>();
+ TreeSet<String> 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 224908b..e0d8e3c 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 @@
// ~ 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 @@
/**
* 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 @@
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 @@
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 e45ac3b..81e4bb9 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 @@
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 84%
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 7a43ba5..69b8217 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 @@
// ~ 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 @@
* @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 @@
// 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 @@
wesc.setStatus(PubStatus.PUBLISHED);
List<WeblogEntry> 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 @@
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 @@
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 aae130d..1280a02 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 @@
// ~ 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 @@
// ~ Constructors
// ===========================================================
- public RemoveEntryOperation(Weblogger roller, IndexManagerImpl mgr,
+ public RemoveEntryOperation(Weblogger roller, LuceneIndexManager mgr,
WeblogEntry data) {
super(mgr);
this.roller = roller;
@@ -73,7 +71,7 @@
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 @@
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 6c5d154..8c7a401 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 @@
// ~ 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 @@
* @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 @@
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 @@
}
}
} 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 @@
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 165313d..a1f2f4e 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 @@
// ~ 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 @@
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 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 @@
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 @@
// 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 @@
/**
* 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 b6cef10..17a45c1 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 d4390b6..2999916 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 6c735b6..d9c5796 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 0000000..c71d7a9
--- /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 032dfcb..7cf07da 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 @@
}
@SuppressWarnings("unused")
- private void setTags(Set<WeblogEntryTag> tagSet) throws WebloggerException {
+ public void setTags(Set<WeblogEntryTag> 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 ce6f9be..1e1adf2 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 @@
// the pager used by the 3.0+ rendering system
private SearchResultsFeedPager pager = null;
- private final List<WeblogEntryWrapper> results = new ArrayList<>();
+ private List<WeblogEntryWrapper> results = new ArrayList<>();
private Set<String> 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 void init(Map<String, Object> 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 @@
} 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 @@
return;
}
- this.entryCount = WebloggerRuntimeConfig
- .getIntProperty("site.newsfeeds.defaultEntries");
+ int entryCount = WebloggerRuntimeConfig.getIntProperty("site.newsfeeds.defaultEntries");
// setup the search
- IndexManager indexMgr = WebloggerFactory.getWeblogger()
- .getIndexManager();
+ 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();
- 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);
+ } catch (WebloggerException we) {
+ errorMessage = we.getMessage();
}
// search completed, setup pager based on results
@@ -170,68 +143,6 @@
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<String> 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 @@
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 9f7ebb2..3c3bd9a 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 @@
private URLStrategy urlStrategy = null;
// the actual search results mapped by Day -> Set of entries
- private final Map<Date, Set<WeblogEntryWrapper>> results = new TreeMap<>(Collections.reverseOrder());
+ private Map<Date, Set<WeblogEntryWrapper>> results = new TreeMap<>(Collections.reverseOrder());
// the pager used by the 3.0+ rendering system
private SearchResultsPager pager = null;
@@ -74,8 +62,7 @@
private int offset = 0;
private int limit = 0;
private Set<String> categories = new TreeSet<String>();
- private boolean websiteSpecificSearch = true;
- private String errorMessage = null;
+ private String errorMessage = "";
@Override
public void init(Map<String, Object> initData) throws WebloggerException {
@@ -83,8 +70,7 @@
// 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 @@
// 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();
+ 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();
- SearchOperation search = new SearchOperation(indexMgr);
- search.setTerm(searchRequest.getQuery());
+ Timestamp now = new Timestamp(new Date().getTime());
+ for (WeblogEntryWrapper entry : searchResultList.getResults()) {
+ if (entry.getPubTime().before(now)) {
+ addEntryToResults(results, entry);
+ }
+ }
- if (WebloggerRuntimeConfig.isSiteWideWeblog(searchRequest
- .getWeblogHandle())) {
- this.websiteSpecificSearch = false;
- } else {
- search.setWebsiteHandle(searchRequest.getWeblogHandle());
- }
-
- if (StringUtils.isNotEmpty(searchRequest.getWeblogCategoryName())) {
- search.setCategory(searchRequest.getWeblogCategoryName());
- }
-
- if (searchRequest.getLocale() != null) {
- search.setLocale(searchRequest.getLocale());
- }
-
- // 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 {
-
- TopFieldDocs docs = search.getResults();
- ScoreDoc[] hitsArr = docs.scoreDocs;
- this.hits = search.getResultsCount();
-
- // Convert the Hits into WeblogEntryData instances.
- convertHitsToEntries(hitsArr, search);
-
+ } catch (WebloggerException we) {
+ errorMessage = we.getMessage();
}
// search completed, setup pager based on results
- pager = new SearchResultsPager(urlStrategy, searchRequest, results,
- (hits > (offset + limit)));
+ pager = new SearchResultsPager(
+ urlStrategy, searchRequest, results, (hits > (offset + limit)));
+ }
+
+ private void addEntryToResults(
+ Map<Date, Set<WeblogEntryWrapper>> results,
+ 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<WeblogEntryWrapper> 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);
+ }
+ set.add(entry);
}
/**
@@ -169,86 +159,6 @@
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<String> 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<WeblogEntryWrapper> 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 @@
@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 bf699f9..d1037ee 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 @@
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 63c9443..30225ee 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 @@
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 4e21134..6b916d6 100644
--- a/app/src/main/resources/log4j2.xml
+++ b/app/src/main/resources/log4j2.xml
@@ -70,6 +70,7 @@
<!-- roller.log; everything not defined here will end up in server.log -->
<Logger name="org.apache.roller" level="info" additivity="false"> <AppenderRef ref="asyncRoller"/> </Logger>
+ <Logger name="org.apache.roller.weblogger.ui.struts2.util.UISecurityInterceptor" level="debug" additivity="false"> <AppenderRef ref="asyncRoller"/> </Logger>
<Logger name="org.apache.velocity" level="info" additivity="false"> <AppenderRef ref="asyncRoller"/> </Logger>
<Logger name="org.springframework" level="info" additivity="false"> <AppenderRef ref="asyncRoller"/> </Logger>
<Logger name="org.apache.struts2" level="info" additivity="false"> <AppenderRef ref="asyncRoller"/> </Logger>
diff --git a/app/src/main/resources/rome.properties b/app/src/main/resources/rome.properties
index f544fb2..427ad37 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 f28a6d4..ba6ef05 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 @@
//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 617f008..0000000
--- 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 0000000..7f146b0
--- /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<WeblogEntry> 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<WeblogEntry> createWeblogEntries(
+ Weblog testWeblog,
+ IndexManager indexManager,
+ WeblogEntryManager entryManager) throws Exception {
+
+ List<WeblogEntry> 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 0000000..1ca19b1
--- /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<WeblogEntry> 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<String, Object> 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 0000000..9c38e3b
--- /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<WeblogEntry> 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<WeblogEntryWrapper> 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<WeblogEntryWrapper> 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<String, Object> 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 b2c3181..1967b03 100644
--- a/app/src/test/resources/log4j2.xml
+++ b/app/src/test/resources/log4j2.xml
@@ -52,7 +52,7 @@
<Loggers>
<!-- roller.log; everything not defined here will end up in server.log -->
- <Logger name="org.apache.roller" level="info" additivity="false"> <AppenderRef ref="roller"/> </Logger>
+ <Logger name="org.apache.roller" level="debug" additivity="false"> <AppenderRef ref="roller"/> </Logger>
<Logger name="org.apache.velocity" level="info" additivity="false"> <AppenderRef ref="roller"/> </Logger>
<Logger name="org.springframework" level="info" additivity="false"> <AppenderRef ref="roller"/> </Logger>
<Logger name="org.apache.struts2" level="debug" additivity="false"> <AppenderRef ref="roller"/> </Logger>