All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.venky.swf.plugins.lucene.index.LuceneIndexer Maven / Gradle / Ivy

package com.venky.swf.plugins.lucene.index;

import java.io.IOException;
import java.io.Reader;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.Query;
import org.apache.lucene.util.Version;

import com.venky.cache.Cache;
import com.venky.core.collections.SequenceSet;
import com.venky.core.string.StringUtil;
import com.venky.core.util.ObjectUtil;
import com.venky.swf.db.Database;
import com.venky.swf.db.JdbcTypeHelper.TypeConverter;
import com.venky.swf.db.JdbcTypeHelper.TypeRef;
import com.venky.swf.db.model.Model;
import com.venky.swf.db.model.reflection.ModelReflector;
import com.venky.swf.db.table.Record;
import com.venky.swf.plugins.lucene.index.background.IndexManager;
import com.venky.swf.plugins.lucene.index.common.ResultCollector;

public class LuceneIndexer {
	private static Cache indexerCache = new Cache() {

		@Override
		protected LuceneIndexer getValue(String tableName) {
			return new LuceneIndexer(tableName);
		}
	};
	public static  LuceneIndexer instance (Class modelClass){
		return instance(ModelReflector.instance(modelClass));
	}
	public static  LuceneIndexer instance (ModelReflector modelReflector){
		return (LuceneIndexer)indexerCache.get(modelReflector.getTableName());
	}
	
	
	private SequenceSet indexedColumns = new SequenceSet();
	private Map> indexedReferenceColumns = new HashMap>(); 
	private final String tableName ;

	public String getTableName() {
		return tableName;
	}
	
	private LuceneIndexer(String tableName) {
		if (ObjectUtil.isVoid(tableName)){
			throw new NullPointerException("Table name cannot be null!");
		}
		try {
			this.tableName = tableName;
			for (Class mClass: Database.getTable(tableName).getReflector().getModelClasses()){
				ModelReflector ref = ModelReflector.instance(mClass);
				for (Method indexedFieldGetter: ref.getIndexedFieldGetters()){
					String indexedColumnName = ref.getColumnDescriptor(indexedFieldGetter).getName();
					indexedColumns.add(indexedColumnName);
					if (ref.getReferredModelGetters().size() > 0){
						Method referredModelGetter = ref.getReferredModelGetterFor(indexedFieldGetter) ; 
						if (referredModelGetter != null){
							Class referredModelClass = ref.getReferredModelClass(referredModelGetter);
							indexedReferenceColumns.put(indexedColumnName, referredModelClass);
						}
					}
				}
			}
		}catch(Exception e){
			throw new RuntimeException(e);
		}
	}
	
	public boolean hasIndexedFields(){
		return !indexedColumns.isEmpty();
	}
	
	private Document getDocument(Record r) throws IOException {
		if (!hasIndexedFields()){
			return null;
		}
		Document doc = new Document();
		boolean addedFields = false;
		for (String fieldName: indexedColumns){
			Object value = r.get(fieldName);
			if (!ObjectUtil.isVoid(value) ){
				TypeRef ref = Database.getJdbcTypeHelper().getTypeRef(value.getClass());
				TypeConverter converter = ref.getTypeConverter();
				if (!ObjectUtil.equals(value,converter.valueOf(null))){
					if (!ref.isBLOB()){
						addedFields = true;
						if (Reader.class.isAssignableFrom(ref.getJavaClass())){
							doc.add(new Field(fieldName,(Reader)converter.valueOf(value)));
						}else{
							Class referredModelClass = indexedReferenceColumns.get(fieldName);
							if (ref.isNumeric() && referredModelClass != null){
								ModelReflector referredModelReflector = ModelReflector.instance(referredModelClass);
								Model referred = Database.getTable(referredModelClass).get(((Number)converter.valueOf(value)).intValue());
								doc.add(new Field(fieldName.substring(0,fieldName.length()-"_ID".length()),
										StringUtil.valueOf(referred.getRawRecord().get(referredModelReflector.getDescriptionColumn())), 
										Field.Store.YES,Field.Index.ANALYZED));
								doc.add(new Field(fieldName,
										StringUtil.valueOf(referred.getRawRecord().get(referredModelReflector.getDescriptionColumn())), 
										Field.Store.YES,Field.Index.ANALYZED));
							}else {
								String sValue = converter.toString(value);
								doc.add(new Field(fieldName,sValue, Field.Store.YES,Field.Index.ANALYZED));
							}
						}
					}
				}
			}
		}
		if (addedFields){
			doc.add(new Field("ID",StringUtil.valueOf(r.getId()), Field.Store.YES,Field.Index.NOT_ANALYZED));
		}else {
			doc = null;
		}
		return doc;
	}
	
	public List getDocuments(String luceneOperation){
		Cache> documentsByTable = (Cache>)Database.getInstance().getCurrentTransaction().getAttribute(luceneOperation);
		if (documentsByTable == null){
			documentsByTable = new Cache>() {
				@Override
				protected List getValue(String k) {
					return new ArrayList();
				}
				
			};
			Database.getInstance().getCurrentTransaction().setAttribute(luceneOperation,documentsByTable);
		}
		return documentsByTable.get(tableName);
	}
	
	public void addDocument(Record r) throws IOException{
		if (!hasIndexedFields()){
			return;
		}
		Document doc = getDocument(r);
		if (doc != null){
			getDocuments("lucene.added").add(doc);
		}
	}
	public void updateDocument(Record r) throws IOException{
		if (!hasIndexedFields()){
			return;
		}
		Document doc = getDocument(r);
		if (doc != null){
			getDocuments("lucene.updated").add(doc);
		}
	}
	public void removeDocument(Record r) throws IOException{
		if (!hasIndexedFields()){
			return;
		}
		Document doc = getDocument(r);
		if (doc != null){
			getDocuments("lucene.removed").add(doc);
		}
	}
	
	public List findIds(Query q, int numHits){
		final List ids = new ArrayList();
		fire(q ,numHits,new ResultCollector() {
			public void found(Document d) {
				ids.add(Integer.valueOf(d.getFieldable("ID").stringValue()));
			}
		});
		return ids;
	}
	public Query constructQuery(String queryString){
		String descriptionField = Database.getTable(tableName).getReflector().getDescriptionColumn();
		String defaultField = null;
		if (indexedColumns.contains(descriptionField)){
			defaultField = descriptionField;
		}else if (!indexedColumns.isEmpty()) {
			defaultField = indexedColumns.first();
		}else {
			defaultField = "ID";
		}
		try {
			return new QueryParser(Version.LUCENE_35,defaultField,new StandardAnalyzer(Version.LUCENE_35)).parse(queryString);
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
	}
	public void fire(Query q ,int numHits, ResultCollector callback) {
		try {
			if (!hasIndexedFields()){
				return;
			}
			IndexManager.instance().fire(tableName, q, numHits, callback);
		}catch (Exception ex){
			throw new RuntimeException(ex);
		}
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy