package er.lucenceadaptor.example;
import java.io.File;
import java.io.IOException;
import java.util.Random;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Collector;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TermRangeQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.NumericUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.webobjects.appserver.WOActionResults;
import com.webobjects.appserver.WORequest;
import com.webobjects.directtoweb.D2W;
import com.webobjects.eoaccess.EOUtilities;
import com.webobjects.eocontrol.EOAndQualifier;
import com.webobjects.eocontrol.EOEditingContext;
import com.webobjects.eocontrol.EOEnterpriseObject;
import com.webobjects.eocontrol.EOFetchSpecification;
import com.webobjects.eocontrol.EOKeyValueQualifier;
import com.webobjects.eocontrol.EOQualifier;
import com.webobjects.eocontrol.EOSortOrdering;
import com.webobjects.foundation.NSArray;
import com.webobjects.foundation.NSDictionary;
import com.webobjects.foundation.NSLog;
import com.webobjects.foundation.NSTimestamp;
import er.directtoweb.ERD2WDirectAction;
import er.extensions.components.ERXLoremIpsumGenerator;
import er.extensions.eof.ERXEC;
import er.extensions.eof.qualifiers.ERXBetweenQualifier;
import er.lucenceadaptor.example.components.Main;
import er.luceneadaptor.ERLuceneAdaptor;
import er.luceneadaptor.ERLuceneAdaptorChannel;
public class DirectAction extends ERD2WDirectAction {
private final class SimpleCollector extends Collector {
private Scorer scorer;
private int docBase;
private IndexSearcher _searcher;
SimpleCollector(IndexSearcher searcher) {
_searcher = searcher;
}
// simply print docId and score of every matching document
@Override
public void collect(int id) throws IOException {
Document document = _searcher.doc(id);
String fieldValue = document.get("userCount");
Number userCount = NumericUtils.prefixCodedToLong(fieldValue);
boolean contains = document.get("content").indexOf(" facilisis") > 0;
System.out.println("doc=" + id + docBase + " score=" + scorer.score() + "->" + userCount + "-" + contains);
}
@Override
public boolean acceptsDocsOutOfOrder() {
return true;
}
@Override
public void setNextReader(IndexReader reader, int docBase) throws IOException {
this.docBase = docBase;
}
@Override
public void setScorer(Scorer scorer) throws IOException {
this.scorer = scorer;
}
}
private final static Logger log = LoggerFactory.getLogger(DirectAction.class);
public DirectAction(WORequest request) {
super(request);
}
@Override
public WOActionResults defaultAction() {
return pageWithName(Main.class);
}
/**
* Checks if a page configuration is allowed to render. Provide a more
* intelligent access scheme as the default just returns false. And be sure
* to read the javadoc to the super class.
*
* @param pageConfiguration
* @return
*/
@Override
protected boolean allowPageConfiguration(String pageConfiguration) {
return true;
}
public WOActionResults loginAction() {
String username = request().stringFormValueForKey("username");
String password = request().stringFormValueForKey("password");
NSLog.out.appendln("***DirectAction.loginAction - username: " + username + " : password: " + password + "***");
// ENHANCEME - add appropriate login behaviour here
return D2W.factory().defaultPage(session());
}
private static IndexReader reader;
public WOActionResults directQueryAction() throws IOException {
if(reader == null) {
Directory directory = FSDirectory.open(new File("/tmp/test"));
reader = IndexReader.open(directory);
}
IndexSearcher searcher = new IndexSearcher(reader);
for(int i = 0; i < searcher.maxDoc() && i < 10; i++) {
Document doc = searcher.doc(i);
// log.info(doc);
}
Query query = null;
String key = "ipse".toLowerCase();
if(false) {
NumericRangeQuery q = NumericRangeQuery.newIntRange("userCount", Integer.valueOf(30), Integer.valueOf(10000), true, true);
//q = NumericRangeQuery.newLongRange("userCount", Long.valueOf(30), Long.valueOf(10000), true, true);
query = q;
} else {
TermQuery q1 = new TermQuery(new Term("contents", key));
TermRangeQuery q2 = new TermRangeQuery("userCount", NumericUtils.longToPrefixCoded(30), NumericUtils.longToPrefixCoded(300), false, false);
BooleanQuery q = new BooleanQuery();
//q.add(q1, BooleanClause.Occur.MUST);
q.add(q2, BooleanClause.Occur.MUST);
query = q;
}
log.info("{}", query);
if (true) {
TopDocs docs = searcher.search(query, Integer.MAX_VALUE);
int hits = docs.totalHits;
for (int i = 0; i < hits && i < 50; i++) {
int docId = docs.scoreDocs[i].doc;
Document document = searcher.doc(docId);
String fieldValue = document.get("userCount");
String content = document.get("contents");
Number userCount = NumericUtils.prefixCodedToLong(fieldValue);
boolean contains = content.indexOf(key) >= 0;
log.info("{}/{}->{}-{}", i, docId, userCount, document);
}
} else {
Collector streamingHitCollector = new SimpleCollector(searcher);
searcher.search(query, streamingHitCollector);
}
return D2W.factory().defaultPage(session());
}
public WOActionResults eofQueryAction() throws IOException {
EOEditingContext ec = ERXEC.newEditingContext();
ec.lock();
try {
EOQualifier q1 = new EOKeyValueQualifier("contents", EOQualifier.QualifierOperatorLike, "suspend*");
EOQualifier q2 = new ERXBetweenQualifier("userCount", Long.valueOf(30), Long.valueOf(800));
// EOQualifier q3 = new EOKeyValueQualifier("userCount", EOQualifier.QualifierOperatorEqual, Long.valueOf(82));
//EOQualifier q3 = new EOKeyValueQualifier("userCount", EOQualifier.QualifierOperatorLessThan, Long.valueOf(82));
EOQualifier q3 = new EOKeyValueQualifier("userCount", EOQualifier.QualifierOperatorLessThanOrEqualTo, Long.valueOf(802));
EOQualifier qualifier = new EOAndQualifier(new NSArray<EOQualifier>(new EOQualifier[]{q1, q2, q3}));
EOFetchSpecification fs = new EOFetchSpecification("LuceneAsset", qualifier, null);
fs.setFetchLimit(5);
fs.setSortOrderings(new NSArray(new EOSortOrdering("userCount", EOSortOrdering.CompareAscending)));
Query query = ERLuceneAdaptorChannel.queryForQualifier(new EOKeyValueQualifier("userCount", EOQualifier.QualifierOperatorLessThanOrEqualTo, 802), EOUtilities.entityNamed(ec, "LuceneAsset"));
fs.setHints(new NSDictionary(query, ERLuceneAdaptor.QUERY_HINTS));
NSArray<EOEnterpriseObject> result = ec.objectsWithFetchSpecification(fs);
log.info("{}: {}", result.count(), result.valueForKey("userCount"));
for (EOEnterpriseObject eo : result) {
log.info("{}: {}", result.count(), eo);
}
} finally {
ec.unlock();
}
return D2W.factory().defaultPage(session());
}
public WOActionResults createAction() {
EOEditingContext ec = ERXEC.newEditingContext();
ec.lock();
try {
Random random = new Random(12);
for (int i = 0; i < 100; i++) {
EOEnterpriseObject eo = EOUtilities.createAndInsertInstance(ec, "LuceneAsset");
eo.takeValueForKey(new NSTimestamp().timestampByAddingGregorianUnits(0, 0, -random.nextInt(2500), 0, 0, 0), "creationDate");
eo.takeValueForKey(ERXLoremIpsumGenerator.sentence(), "contents");
eo.takeValueForKey(random.nextDouble(), "price");
eo.takeValueForKey(Long.valueOf(random.nextInt(2500)), "userCount");
}
ec.saveChanges();
} finally {
ec.unlock();
}
return pageWithName(Main.class);
}
}