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

net.java.ao.RelatedEntityImpl Maven / Gradle / Ivy

/*
 * Copyright 2007 Daniel Spiewak
 * 
 * Licensed 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.
 */
package net.java.ao;

import net.java.ao.types.TypeManager;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermDocs;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.similar.MoreLikeThis;
import org.apache.lucene.store.Directory;

import java.io.IOException;
import java.lang.reflect.Array;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Daniel Spiewak
 */
class RelatedEntityImpl {
    private RawEntity entity;

    public RelatedEntityImpl(RelatedEntity entity) {
        this.entity = (RawEntity) entity;
    }

    public RelatedEntity[] getRelated() throws IOException, SQLException {
        Class> type = entity.getEntityType();
        EntityManager entityManager = entity.getEntityManager();
        String table = entityManager.getNameConverters().getTableNameConverter().getName(type);
        List indexFields = Common.getSearchableFields(entityManager, type);
        String[] searchFields = new String[indexFields.size()];

        for (int i = 0; i < searchFields.length; i++) {
            searchFields[i] = table + '.' + indexFields.get(i);
        }

        Directory indexDir = ((SearchableEntityManager) entityManager).getIndexDir();
        IndexReader reader = null;

        try {
            reader = IndexReader.open(indexDir);
            IndexSearcher searcher = new IndexSearcher(indexDir);

            MoreLikeThis more = new MoreLikeThis(reader);
            more.setFieldNames(searchFields);
            more.setAnalyzer(((SearchableEntityManager) entityManager).getAnalyzer());

            int docID = -1;
            String primaryKeyField = Common.getPrimaryKeyField(type, entityManager.getNameConverters().getFieldNameConverter());
            Object primaryKeyValue = Common.getPrimaryKeyValue(entity);

            TermDocs docs = reader.termDocs(new Term(table + "." + primaryKeyField,
                    Common.getPrimaryKeyType(getTypeManager(), type).getLogicalType().valueToString(primaryKeyValue)));
            if (docs.next()) {
                docID = docs.doc();
            }

            if (docID < 0) {
                return (RelatedEntity[]) Array.newInstance(type, 0);
            }

            org.apache.lucene.search.Query query = more.like(docID);
            Hits hits = searcher.search(query);
            List> back = new ArrayList>();

            for (int i = 0; i < hits.length(); i++) {
                String entityKey = hits.doc(i).get(table + "." + primaryKeyField);
                if (entityKey.equals(primaryKeyValue.toString())) {
                    continue;
                }

                back.add((RelatedEntity) (entityManager).peer(entityManager.resolveEntityInfo(type),
                        Common.getPrimaryKeyType(getTypeManager(), type).getLogicalType().parseDefault(entityKey)));
            }

            return back.toArray((RelatedEntity[]) Array.newInstance(type, back.size()));
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                }
            }
        }
    }

    private TypeManager getTypeManager() {
        return entity.getEntityManager().getProvider().getTypeManager();
    }
}