Package net.fp.rp.search.mid.intelligence

Source Code of net.fp.rp.search.mid.intelligence.BasicIntelligence

/*
* Copyright (C) 2004 Paul Browne, http://www.firstpartners.net,
* built with the help of Fast-Soft (fastsoftdev@yahoo.com)
*
* released under terms of the GPL license
* http://www.opensource.org/licenses/gpl-license.php
*
* This product includes software developed by the
* Apache Software Foundation (http://www.apache.org)."
*
* This product includes software developed by the
* Spring Framework Project (http://www.springframework.org)."
*
*/
package net.fp.rp.search.mid.intelligence;

import net.fp.rp.common.exception.RpException;
import net.fp.rp.search.back.datastore.BasicFeedbackDataStore;
import net.fp.rp.search.back.search.SearchQuery;
import net.fp.rp.search.back.struct.DocumSetStruct;
import net.fp.rp.search.back.struct.DocumStruct;
import net.fp.rp.search.common.util.Util;
import net.fp.rp.search.mid.feedback.BaseFeedback;
import net.fp.rp.search.mid.feedback.CategoryFeedback;
import net.fp.rp.search.mid.feedback.DocumentFeedback;
import net.fp.rp.search.mid.feedback.SearchFeedback;
import net.fp.rp.search.mid.global.PluginManager;
import net.fp.rp.search.plugins.IFeedback;
import net.fp.rp.search.plugins.ISearchResult;
import net.fp.rp.search.plugins.events.IInterestedInFeedback;
import net.fp.rp.search.plugins.events.IInterestedInResultsFilter;
import net.fp.rp.search.plugins.events.IInterestedInSearch;

import org.apache.log4j.Logger;

import java.io.File;

import java.util.LinkedList;
import java.util.StringTokenizer;


/**
* Basic intelligence to implement filtering
*
* @author brownpa
* Copyright @link www.firstpartners.net/red
*/
public class BasicIntelligence implements IInterestedInResultsFilter,
    IInterestedInFeedback {
    /** Default character delimiters */
    static final String DELIMITERS = " ";

    /** Logger for this class and subclasses */
    protected final Logger logger = Logger.getLogger(getClass());

    /** Flag to mark that that plugin is ready for feedback calculation */
    private boolean readyForFeedbackCalculation;

    /** Weight for calculation of the scores for the links */
    public double weight;

    /** Number of the documents to be searched (top documents) */
    public int countTopDocs;

    /**
     * Constructor of the basic intelligence plugin
     */
    public BasicIntelligence() {
        readyForFeedbackCalculation = false;
    }

    /**
     * Gives the class a chance to update
     *
     * @param someInfo
     *
     * @return
     */
    public ISearchResult filterAndSortSearchResults(ISearchResult someInfo) {
        return null;
    }

    /**
     * What order we prefer the filter to be called in. lower number = filter
     * first
     *
     * @return int with the preferred filter ord er
     */
    public int preferredFilterOrder() {
        return 0;
    }

    /**
     * Deal with feedback to improve quality of results next time
     *
     * @param advice The feedback event
     */
    public void acceptFeedback(IFeedback advice) {
        //process the feedback according to the type
        if (advice instanceof SearchFeedback) {
            logger.info(
                "Search feedback - background process for score calculation");

            //split the query into words
            String query = ((SearchFeedback) advice).getFeedbackQuery();
            logger.info("Seach Feedback" + query);

            //tokenize the query using the default delimiters
            StringTokenizer tokenizer = new StringTokenizer(query, DELIMITERS);

            try {
                //get the plugins interested in search process
                IInterestedInSearch[] plugins = PluginManager.getInterestedInSearch();

                //links list
                LinkedList listLinks = new LinkedList();

                //iterate over the found it tokens
                while (tokenizer.hasMoreElements()) {
                    String term = tokenizer.nextToken();

                    //ignore the terms (conjuction:AND, OR) )
                    if ((!term.equalsIgnoreCase("and")) &&
                            (!term.equalsIgnoreCase("or"))) {
                        //construct the search query for the term
                        SearchQuery queryForm = new SearchQuery(term);

                        //for all the plugins invoke the search process
                        for (int i = 0; i < plugins.length; i++) {
                            //find the documents that contain the specified token ordered by direct score
                            plugins[i].doSearch(queryForm,
                                DocumStruct.FIELD_DIRECTSCORE, true,
                                countTopDocs,true);
                        }

                        //gather the results from all the plugins
                        for (int i = 0; i < plugins.length; i++) {
                            ISearchResult result = plugins[i].getResults();

                            //iterate over all the documents
                            double sumGroup = 0;

                            //sum for all the direct score of the nodes found it in the same set 
                            for (int j = 0; j < result.getDocuments().size();
                                    j++) {
                                DocumStruct doc = (DocumStruct) result.getDocuments()
                                                                      .get(j);

                                sumGroup = sumGroup +
                                    PluginManager.getCategoryStores()
                                                 .getDirectScore(doc.getCategoryName(),
                                        doc.getId());
                            }

                            //calculate the average
                            double average = 0.0;

                            if (result.getDocuments().size() > 0) {
                                average = sumGroup / result.getDocuments().size();
                            }

                            //case of "term AND categoryname:X" and set of term < set of categoryname:X (1 category in the system)
                            //store the new average score for each document in the set
                            for (int j = 0; j < result.getDocuments().size();
                                    j++) {
                                DocumStruct doc = (DocumStruct) result.getDocuments()
                                                                      .get(j);

                                //create a new document set and it to the list
                                listLinks.add(new DocumSetStruct(
                                        doc.getCategoryName(), doc.getId(),
                                        average * weight));
                            }
                        }
                    }
                }

                //get the user feedback score 
                int score = ((SearchFeedback) advice).getScore();

                //update the links and the documents scores
                PluginManager.getCategoryStores().updateDocumentLinksAndScore(listLinks,
                    score);

                //optimize the index
                PluginManager.getIndexManager().optimize();
            } catch (RpException e) {
                logger.warn("Exception occured in search feedback process", e);
            }
        } else if (advice instanceof DocumentFeedback) {
            logger.info(
                "Document feedback - background process for score calculation");

            try {
                //convert to feedback document
                DocumentFeedback feedback = (DocumentFeedback) advice;

                //update the document score
                PluginManager.getCategoryStores().updateDocumentDirectScore(feedback.getCategoryName(),
                    feedback.getDocumentID(), feedback.getScore());
            } catch (RpException e) {
                logger.warn("Exception occured in document feedback process", e);
            }
        } else if (advice instanceof CategoryFeedback) {
            logger.info(
                "Category feedback - background process for score calculation");

            try {
                //convert to feedback category
                CategoryFeedback feedback = (CategoryFeedback) advice;

                //update the category score
                PluginManager.getCategoryStores().updateCategoryScore(feedback.getCategoryName(),
                    feedback.getScore());
            } catch (RpException e) {
                logger.warn("Exception occured in category feedback process", e);
            }
        }
    }

    /**
     * Called by the PluginManager on each plugin when this class is first
     * loaded Read the feedback xml and recalculate the score according to
     * this
     *
     * @throws RpException
     */
    public void onLoad() throws RpException {
        //when CategoryManager and BasicIndexManager has finished the load process, the flag
        //will mark the plugin as ready for feedback recalculation process
        logger.info("BasicIntelligence - onLoad process");

        final LinkedList feedbackEventsList = new LinkedList();

        //get the root folder
        String root = PluginManager.getCategoryManager().getRoot();

        //get the feedback folder
        String feedbackPath = Util.addFolder(root,
                BasicFeedbackDataStore.DEFAULT_SPECIAL_DATA);

        //get the file list from the folder order by name ascendent
        File[] list = Util.getFileList(feedbackPath);

        if (list != null) {
            //process the feedback files
            for (int i = 0; i < list.length; i++) {
                //get the file path of the feedback event
                String modelpath = list[i].getPath();

                logger.info("Load the feedback event from model" + modelpath);

                try {
                    //read the feedback event model and convert it to a base feedback
                    BaseFeedback feedback = PluginManager.getFeedbackDataStores()
                                                         .read(modelpath);

                    //add the feedback object to the list
                    feedbackEventsList.add(feedback);
                } catch (RpException e) {
                    logger.warn("Error in reading the feedback event", e);
                }
            }
        } else {
            logger.warn("No feedback events in the system");
            readyForFeedbackCalculation = true;
        }

        Thread t = new Thread(new Runnable() {
                    public void run() {
                        //wait till the plugin is mark as ready for feedback re-calculation process
                        while (!readyForFeedbackCalculation);

                        //if there are feedback events accept it to the system
                        logger.info("There are " + feedbackEventsList.size() +
                            " feedback events");

                        for (int i = 0; i < feedbackEventsList.size(); i++) {
                            //get the event object
                            BaseFeedback advice = (BaseFeedback) feedbackEventsList.get(i);

                            //accept the feedback event
                            acceptFeedback(advice);
                        }
                    }
                });
        t.setPriority(Thread.MIN_PRIORITY);
        t.start();
    }

    /**
     * @return Returns the weight.
     */
    public double getWeight() {
        return weight;
    }

    /**
     * @param weight The weight to set.
     */
    public void setWeight(double weight) {
        this.weight = weight;
    }
    /**
     * @return Returns the countTopDocs.
     */
    public int getCountTopDocs() {
        return countTopDocs;
    }
    /**
     * @param countTopDocs The countTopDocs to set.
     */
    public void setCountTopDocs(int countTopDocs) {
        this.countTopDocs = countTopDocs;
    }
    /**
     * @return Returns the readyForFeedbackCalculation.
     */
    public boolean isReadyForFeedbackCalculation() {
        return readyForFeedbackCalculation;
    }
    /**
     * @param readyForFeedbackCalculation The readyForFeedbackCalculation to set.
     */
    public void setReadyForFeedbackCalculation(
            boolean readyForFeedbackCalculation) {
        this.readyForFeedbackCalculation = readyForFeedbackCalculation;
    }
}
TOP

Related Classes of net.fp.rp.search.mid.intelligence.BasicIntelligence

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.