/*
* 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.back.datastore;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Selector;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.rdf.model.impl.SelectorImpl;
import net.fp.rp.common.exception.RpException;
import net.fp.rp.search.back.datastore.vocabulary.RP;
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.IFeedbackDataStore;
import org.apache.log4j.Logger;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
/**
* Simple Meta Data Store as an XML file.
*
* @author brownpa
* Copyright @link www.firstpartners.net/red
*/
public class BasicFeedbackDataStore implements IFeedbackDataStore {
/** Folder name for storing the feedback events */
public static final String DEFAULT_SPECIAL_DATA = "SpecialData";
/** Model name for the feedback event */
static final String MODEL_NAME = "feedback";
/** Model extension for the feedback event */
static final String MODEL_EXTENSION = ".xml";
/** Internal counter for storing the feedback information */
private static int counter;
static {
counter = 0;
}
/** Logger for this class and subclasses */
protected final Logger logger = Logger.getLogger(getClass());
/**
* Get the Feedback object from the model
*
* @param modelpath The model path
*
* @return Feedback object from the model
*
* @throws RpException If an error occur in reading the model
*/
public BaseFeedback read(String modelpath) throws RpException {
// create an empty model
Model model = ModelFactory.createDefaultModel();
synchronized (this) {
try {
//read the RDF/XML file
model.read(new InputStreamReader(new FileInputStream(modelpath)),
"");
//Predicate for filtering the feedback type
Selector selector = new SelectorImpl(null, RP.type,
(RDFNode) null);
// Filtering
StmtIterator iter = model.listStatements(selector);
if (iter.hasNext()) {
//get the statement
Statement stmt = iter.nextStatement();
//get the resource
Resource node = stmt.getSubject();
//get the type
String type = stmt.getObject().toString();
logger.debug("Feedback type is " + type);
if (type.equalsIgnoreCase(BaseFeedback.TYPE_SEARCH_FEEDBACK)) {
String score = node.getProperty(RP.score).getObject()
.toString();
String searchquery = node.getProperty(RP.searchquery)
.getObject().toString();
logger.debug("Feedback search is " + searchquery + "/" +
score);
return new SearchFeedback(Integer.valueOf(score)
.intValue(),
searchquery);
} else if (type.equalsIgnoreCase(
BaseFeedback.TYPE_DOCUMENT_FEEDBACK)) {
String score = node.getProperty(RP.score).getObject()
.toString();
String id = node.getProperty(RP.documentID).getObject()
.toString();
String categName = node.getProperty(RP.categoryName)
.getObject().toString();
String summary = node.getProperty(RP.summary).getObject()
.toString();
logger.debug("Feedback document constructed");
return new DocumentFeedback(Integer.valueOf(score)
.intValue(), id,
categName, summary);
} else if (type.equalsIgnoreCase(
BaseFeedback.TYPE_CATEGORY_FEEDBACK)) {
String score = node.getProperty(RP.score).getObject()
.toString();
String categName = node.getProperty(RP.categoryName)
.getObject().toString();
String categLocation = node.getProperty(RP.categoryLocation)
.getObject().toString();
logger.debug("Feedback category constructed");
return new CategoryFeedback(Integer.valueOf(score)
.intValue(),
categName, categLocation);
} else {
logger.warn("The feedback type is not supported");
throw new RpException("feedback.model.type.error");
}
} else {
logger.warn("No feedback type was defined in the model ");
throw new RpException("feedback.model.type.missing");
}
} catch (FileNotFoundException e) {
logger.warn("No feedback model stored in the system path " +
modelpath);
throw new RpException("feedback.model.missing",
new Object[] { modelpath });
}
}
}
/**
* Save the feedback data
*
* @param advice Feedback object
*
* @throws RpException If an error occur in storing the model
*/
public void save(BaseFeedback advice) throws RpException {
//get the root folder
String root = PluginManager.getCategoryManager().getRoot();
synchronized (this) {
//generate the feedback folder (in case that not exists)
String path = Util.addFolder(root, DEFAULT_SPECIAL_DATA);
logger.info("Feedback folder will be "+ path);
File f = new File(path);
if (!f.exists()) {
f.mkdirs();
}
//get the available counter
boolean found = false;
while (!found) {
String modelname = MODEL_NAME + (++counter) + MODEL_EXTENSION;
logger.info("Try counter " + modelname);
File file = new File(Util.addFolder(path, modelname));
if (!file.isFile()) {
found = true;
}
}
logger.info("Available counter is " + counter);
try {
//define the model name
String modelname = MODEL_NAME + counter + MODEL_EXTENSION;
File file = new File(Util.addFolder(path, modelname));
//create a new model
Model model = ModelFactory.createDefaultModel();
model.setNsPrefix(RP.getPrefix(), RP.getURI());
//create the resources
Resource node = model.createResource();
node.addProperty(RP.type, advice.getType());
node.addProperty(RP.date, advice.getDate());
//save the feedback data
if (advice instanceof SearchFeedback) {
SearchFeedback feedback = (SearchFeedback) advice;
node.addProperty(RP.score,
String.valueOf(feedback.getScore()));
node.addProperty(RP.searchquery, feedback.getFeedbackQuery());
//node.addProperty(RP.issearch, "true");
} else if (advice instanceof DocumentFeedback) {
DocumentFeedback feedback = (DocumentFeedback) advice;
node.addProperty(RP.score,
String.valueOf(feedback.getScore()));
node.addProperty(RP.documentID, feedback.getDocumentID());
node.addProperty(RP.categoryName, feedback.getCategoryName());
node.addProperty(RP.summary, feedback.getSummary());
} else if (advice instanceof CategoryFeedback) {
CategoryFeedback feedback = (CategoryFeedback) advice;
node.addProperty(RP.score,
String.valueOf(feedback.getScore()));
node.addProperty(RP.categoryName, feedback.getCategoryName());
node.addProperty(RP.categoryLocation,
feedback.getCategoryLocation());
}
//write the model
model.write(new FileOutputStream(file));
model.close();
} catch (Throwable e) {
logger.warn("Error in storing the model in the system path " +
path, e);
throw new RpException("feedback.model.store.error",
new Object[] { path });
}
}
}
/**
* @return Returns the counter.
*/
public static int getCounter() {
return counter;
}
/**
* @param counter The counter to set.
*/
public static void setCounter(int counter) {
BasicFeedbackDataStore.counter = counter;
}
}