package org.deri.grefine.rdf.vocab.imp;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;
import org.deri.grefine.rdf.app.ApplicationContext;
import org.deri.grefine.rdf.vocab.IPredefinedVocabularyManager;
import org.deri.grefine.rdf.vocab.Vocabulary;
import org.deri.grefine.rdf.vocab.VocabularyImporter;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import org.json.JSONWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PredefinedVocabularyManager implements IPredefinedVocabularyManager{
final static Logger logger = LoggerFactory.getLogger("predefined_vocabulary_manager");
private static final String PREDEFINED_VOCABS_FILE_NAME = "predefined_vocabs.tsv";
private static final String SAVED_VOCABULARIES_FILE_NAME = "vocabularies_meta.json";
private final File workingDir;
private ApplicationContext applicationContext;
private Map<String, Vocabulary> predefinedVocabulariesMap = new HashMap<String,Vocabulary>();
public PredefinedVocabularyManager(ApplicationContext ctxt, File workingDir) throws IOException, JSONException{
this.workingDir = workingDir;
this.applicationContext = ctxt;
try{
reconstructVocabulariesFromFile();
}catch(FileNotFoundException ex){
addPredefinedVocabularies();
save();
}
}
public Map<String,Vocabulary> getPredefinedVocabulariesMap(){
return predefinedVocabulariesMap;
}
/*
* Private methods
*/
private void addPredefinedVocabularies() throws IOException {
InputStream in = getPredefinedVocabularyFile();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
StringTokenizer tokenizer;
// Read File Line By Line
while ((strLine = br.readLine()) != null) {
tokenizer = new StringTokenizer(strLine, "\t");
try {
String name = tokenizer.nextToken();
String uri = tokenizer.nextToken();
String url = tokenizer.nextToken();
//import and index
this.applicationContext.getVocabularySearcher().importAndIndexVocabulary(name, uri,url, new VocabularyImporter());
this.predefinedVocabulariesMap.put(name,new Vocabulary(name, uri));
} catch (Exception e) {
// predefined vocabularies are not defined properly
// ignore the exception, just log it
logger.warn("unable to add predefined vocabularies", e);
}
}
br.close();
applicationContext.getVocabularySearcher().update();
}
protected InputStream getPredefinedVocabularyFile(){
return this.getClass().getResourceAsStream(PREDEFINED_VOCABS_FILE_NAME);
}
private void reconstructVocabulariesFromFile() throws IOException, JSONException{
File vocabulariesFile = new File(workingDir, SAVED_VOCABULARIES_FILE_NAME);
if(vocabulariesFile.exists()){
load();
}else{
throw new FileNotFoundException();
}
}
private void save() throws IOException {
File tempFile = new File(workingDir, "vocabs.temp.json");
try {
saveToFile(tempFile);
} catch (Exception e) {
e.printStackTrace();
logger.error("Failed to save project metadata",e);
return;
}
File file = new File(workingDir, SAVED_VOCABULARIES_FILE_NAME);
File oldFile = new File(workingDir, "vocabs.old.json");
if (file.exists()) {
file.renameTo(oldFile);
}
tempFile.renameTo(file);
if (oldFile.exists()) {
oldFile.delete();
}
}
private void saveToFile(File metadataFile) throws Exception {
Writer writer = new OutputStreamWriter(new FileOutputStream(metadataFile));
try {
JSONWriter jsonWriter = new JSONWriter(writer);
write(jsonWriter,new Properties());
} finally {
writer.close();
}
}
protected void load() throws IOException, JSONException{
File vocabsFile = new File(workingDir,SAVED_VOCABULARIES_FILE_NAME);
FileReader reader = new FileReader(vocabsFile);
try {
JSONTokener tokener = new JSONTokener(reader);
JSONObject obj = (JSONObject) tokener.nextValue();
JSONArray prefixes = obj.getJSONArray("prefixes");
for(int i=0;i<prefixes.length();i++){
JSONObject p = prefixes.getJSONObject(i);
String name = p.getString("name");
String uri = p.getString("uri");
this.predefinedVocabulariesMap.put(name,new Vocabulary(name,uri));
}
} finally {
reader.close();
}
}
private void write(JSONWriter writer,Properties options) throws JSONException{
writer.object();
writer.key("prefixes");
writer.array();
for(Vocabulary v:this.predefinedVocabulariesMap.values()){
v.write(writer);
}
writer.endArray();
writer.endObject();
}
//this is added just to enable testing
PredefinedVocabularyManager(){
this.workingDir = null;
}
}