/* $This file is distributed under the terms of the license in /doc/license.txt$ */

package edu.cornell.mannlib.vitro.webapp.ontology.update;

import java.io.InputStream;
import java.util.List;

import javax.servlet.ServletContext;

import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.shared.Lock;

import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;

/**
 * Performs knowledge base updates if necessary to align with a
 * new ontology version.
 * 
 * This class assumes that config and mapping data files are available
 * at DATA_DIR.
 * 
 * @author bjl23
 *
 */
public class OntologyUpdater {

	private final String DATA_DIR = "/WEB-INF/ontologies/update/";
	private final String ASK_QUERY_FILE = DATA_DIR + "ask.sparql";
	private final String SUCCESS_ASSERTIONS = DATA_DIR + "success.n3";
	private final String SUCCESS_RDF_FORMAT = "N3";
	private final String DIFF_FILE = DATA_DIR + "diff.tab.txt";
	
	private ServletContext context;
	private OntModelSelector ontModelSelector;
	
	public OntologyUpdater(ServletContext context, 
			OntModelSelector ontModelSelector) {
		this.context = context;
		this.ontModelSelector = ontModelSelector;
	}
	
	public void update() {	
		// Check to see if the update is necessary.
		if (updateRequired()) {
			performUpdate();
			// add assertions to the knowledge base showing that the 
			// update was successful, so we don't need to run it again.
			assertSuccess();
		}
	}
	
	private void performUpdate() {
		List<AtomicOntologyChange> changes = getAtomicOntologyChanges();
		
		//preprocessChanges(changes);
		//updateTBox(changes);
		
		updateABox(changes);
		
		updateAnnotations();
		
		// perform additional additions and retractions
	}
	
	private List<AtomicOntologyChange> getAtomicOntologyChanges() {
		return null; //Anup's code is called here
	}
	
	private void updateABox(List<AtomicOntologyChange> changes) {
		// perform operations based on change objects
		// run additional SPARQL CONSTRUCTS 

	}
	
	private void updateAnnotations() {
		// Stella's code is called here
	}
	
	/**
	 * Executes a SPARQL ASK query to determine whether the knowledge base
	 * needs to be updated to conform to a new ontology version
	 */
	private boolean updateRequired() {
		String sparqlQueryStr = loadSparqlQuery(ASK_QUERY_FILE);
		if (sparqlQueryStr == null) {
			return false;
		}
		Model m = ontModelSelector.getApplicationMetadataModel();
		Query query = QueryFactory.create(sparqlQueryStr);
		QueryExecution qexec = QueryExecutionFactory.create(query, m);
		return qexec.execAsk();
	}
	
	/**
	 * loads a SPARQL ASK query from a text file
	 * @param filePath
	 * @return the query string or null if file not found
	 */
	private String loadSparqlQuery(String filePath) {
		return null; // TODO implement me!
	}
	
	private void assertSuccess() {
	    Model m = ontModelSelector.getApplicationMetadataModel();
	    InputStream inStream = context.getResourceAsStream(SUCCESS_ASSERTIONS);
	    m.enterCriticalSection(Lock.WRITE);
	    try {
	    	m.read(inStream, SUCCESS_RDF_FORMAT);
	    } finally {
	    	m.leaveCriticalSection();
	    }
	}
	
}

@@ -156,80 +156,311 @@
 .io.
-InputStream;%0Aimport java.util.List;%0A%0Aimport javax.servlet.ServletContext
+BufferedReader;%0Aimport java.io.File;%0Aimport java.io.FileNotFoundException;%0Aimport java.io.FileReader;%0Aimport java.io.IOException;%0Aimport java.io.InputStream;%0Aimport java.util.List;%0A%0Aimport javax.servlet.ServletContext;%0A%0Aimport org.apache.commons.logging.Log;%0Aimport org.apache.commons.logging.LogFactory
 ;%0A%0Ai
@@ -626,32 +626,69 @@
 y.QueryFactory;%0A
+import com.hp.hpl.jena.query.Syntax;%0A
 import com.hp.hp
@@ -1368,16 +1368,85 @@
 txt%22;%0A%09%0A
+%09private final Log log = LogFactory.getLog(OntologyUpdater.class);%0A%09%0A
 %09private
@@ -1701,16 +1701,35 @@
 update()
+ throws IOException
  %7B%09%0A%09%09//
@@ -2759,16 +2759,35 @@
 quired()
+ throws IOException
  %7B%0A%09%09Str
@@ -3286,46 +3286,389 @@
 th) 
-%7B%0A%09%09return null; // TODO implement me!
+throws IOException %7B%0A%09%09File file = new File(context.getRealPath(filePath));%09%0A%09%09if (!file.exists()) %7B%0A%09%09%09return null;%0A%09%09%7D%0A%09%09BufferedReader reader = new BufferedReader(new FileReader(file));%0A%09%09StringBuffer fileContents = new StringBuffer();%0A%09%09String ln;%09%09%0A%09%09while ((ln = reader.readLine()) != null) %7B%0A%09%09%09fileContents.append(ln).append('%5Cn');%0A%09%09%7D%0A%09%09return fileContents.toString();%09%09%09%09
 %0A%09%7D%0A

work on NIHVIVO-205 ontology update