Inviare molti files RDF/XML ad un triplestore

Bulk upload RDF/XML files

Download Eclipse Project

Prerequisiti: questa applicazione è un'applicazione Java, che può essere eseguita in un ambiente Unix grazie allo script sendManyRDF.sh. I prerequisiti sono:

  • La directory con i vari RDF/XML files deve trovarsi nella stessa macchina su cui è eseguita l'applicazione. Questa directory può contenere altre sotto-directory, nidificate a qualsiasi livello (la ricerca dei files è ricorsiva).
  • La macchina su cui l'applicazione è eseguita deve avere installata almeno la JDK1.6 (il path deve essere impostato nello script sendManyRDF.sh, sia nella variabile JAVA_HOME che PATH).
  • Bisogna conoscere l'indirizzo del triplestore (che può trovarsi in anche in un'altra macchina, purché accessibile via HTTP) e il nome del repository su cui si va a scrivere
  • È necessario indicare un context quando si effettua l'upload.

L'applicazione usa le API di Sesame e può essere usata con Sesame, OWLIM, Virtuoso Sesame Connector ed Allegrograph. Una volta scaricato il progetto Eclipse, su to il progetto Eclipse, si può usare Apache Ant col file build_scripts.xml per generare l'applicazione eseguibile in un sitema Unix, formata da una cartella "applications" con gli eseguibili e i compilati e una cartella "lib" con i jars necessari. Ecco il codice della classe principale che si occupa dell'upload:

 
 /* 
  * Send RDF files to the repository. Requires four command line parameters:
  * args[0]: the path to the filesystem directory that contains RDF files 
  * to send to the triplestoree
  * args[1]: the triplestore prefix
  * args[2]: the repository ID
  * args[3]: the context
  */
public class SendManyRDFFiles {

	//source directory location
	private String sourceLocation;
	//list of files
	private List<String> sourceRDF;

	//location
	private String prefix;
	private String id;
	private String context;

	public SendManyRDFFiles(String sourceLocation, String prefix, String id, 
			String context) {
		this.sourceLocation = sourceLocation;
		this.prefix = prefix;
		this.id = id;
		this.context = context;
	}

	/**
	 * Send RDF files to the repository. Requires four command line parameters:
	 * args[0]: the path to the filesystem directory that contains RDF files 
	 * to send to the triplestoree
	 * args[1]: the triplestore prefix
	 * args[2]: the repository ID
	 * args[3]: the context
	 * @param args
	 */
	public static void main(String[] args){

		//check if there is a list of year to convert
		if(args.length==4){
			SendManyRDFFiles sender = new SendManyRDFFiles(args[0], 
			args[1], args[2], args[3]);
			sender.run();
		}
		else {
			System.out.println("Please, specify the four "+
			"needed parameters: source location of files,"+
			"repository prefix, repository id, context");
		}

	}

	/**
	 * Send RDF files to the repository
	 */
	public void run(){
		this.setUpFiles();
		try {
			this.sendFiles();
		} catch(Exception e){
			e.printStackTrace();
		}
	}

	/**
	 * Recursively read the source directory to select all files to add
	 */
	private void setUpFiles() {
		//source directory
		File dir = new File(this.sourceLocation);

		//lost of rdf files to index
		this.sourceRDF = new LinkedList<String>();

		//recursive search
		this.recursiveSearch(dir);
		
		System.out.println("Number of RDF files: "+this.sourceRDF.size());
	}
	
	private void recursiveSearch(File dir){
		//look for XML files in the current directory
		File[] listFiles = dir.listFiles();
		//directories
		Set<File> listDirs = new TreeSet<File>();
		
		//scan files
		if(listFiles!=null){
			//scan files
			for(File contentFile: listFiles){
				String filename = contentFile.getName()
					.toLowerCase();
				//XML files
				if(filename.contains(".rdf")){
					//add filepath to the list
					this.sourceRDF.add(contentFile
						.getAbsolutePath());
				}
				else {
					if(contentFile.isDirectory())
						listDirs.add(contentFile);
				}
			}
		}
		
		//recursive application
		listFiles = null;
		for(File subDir: listDirs){
			this.recursiveSearch(subDir);
		}
	}

	private void sendFiles() throws RepositoryException {
		//timestamp
		DateFormat dateFormat = new 
			SimpleDateFormat("yyyy/MM/dd HH:mm:ss");

		//querier
		QuerierSesame querier = new QuerierSesame();

		//repository
		DataSourceTriplestore dataS = new 
			DataSourceTriplestore(prefix, id);
		HTTPRepository tS = dataS.getHTTPServer();
		//System.out.println(tS.getConnection());
		//System.out.println(tS.isWritable());

		System.out.println("Start Date Time : " 
			+ dateFormat.format(new Date()));
		querier.addFiles(sourceRDF, 
			QuerierSesame.RDFXML, tS, context);
		System.out.println("End Date Time: " 
			+ dateFormat.format(new Date()));
		
		tS.shutDown();
	}
}
			
	

Ecco invece il codice dello script bash eseguibile (in cui andrà settata correttamente la posizione della JDK):

	 
#!/bin/sh
# Script for sending many RDF files, stored in a directory (that can contain 
# many levels of subdirectories) to a sparql endpoint
#
# ./sendManyRDF.sh /work/agris/RDF_Output/2012/ 
# 	http://localhost:8090/openrdf-sesame/ test http://localhost:80/test
#

thisfile=`which $0`
thisdir=`dirname $thisfile`
JAVA_HOME="/usr/local/jdk1.6.0_22"
PATH="/usr/local/jdk1.6.0_22/bin"

OPT_JARS="../lib/*.jar"
CP=""
for thing in $OPT_JARS
do
    if [ -f $thing ]; then       
        CP="${CP}:$thing"
    else if [ -d $thing ]; then  
        CP="$CP:$thing"
     fi
    fi
done
CP="$CP:."

if [ $# -lt 4 ]  # number of arguments passed to script
then
    echo "Please, specify the four needed parameters: source location 
    		of files, repository prefix, repository id, context"
else
    exec java -classpath $CP -Xss64M -Xmx2048M 
    		org.fao.oekc.agris_records.SendManyRDFFiles "$@"
fi

exit