Posts mit dem Label Java werden angezeigt. Alle Posts anzeigen
Posts mit dem Label Java werden angezeigt. Alle Posts anzeigen

Donnerstag, 17. Januar 2013

DELETE triples from Virtuoso via Java

I already wrote about how to access a triple store via Java using Jena. There I also mentioned that writing SPARQL UPDATE queries (INSERT, UPDATE, DELETE) against external triple stores may not work if the triple store does not support SPARQL 1.1 UPDATE.

In my scenario I wanted to DELETE triples from a Virtuoso endpoint. The query syntax Virtuoso supports is
DELETE FROM <graph> { ?s ?p ?o.} WHERE { GRAPH <graph> { ?s ?p ?o.} }
which is not the syntax defined by SPARQL 1.1 UPDATE - DELETE. If you hand this query string over to Jena, it will transform it into valid SPARQL 1.1 UPDATE syntax, which will result in an error at the Virtuoso side.

To be able to submit a DELETE query to Virtuoso anyway, Jena cannot be used. Instead HTTP Post has to be used directly.

Therefore I found a nice solution in the Jena Users Mailinglist archive, which I minimally updated to fit Virtuosos needs.
private boolean runUpdateQuery(String queryString) throws Exception {
    SPARQLUpdate p = new SPARQLUpdate();
    p.setEndpoint(endpoint);
    p.setUpdateString(queryString);
    String response = p.execute();
    if (!response.contains("done")) {
        System.err.println("UPDATE/SPARQL failed: " + queryString);
        return false;
    }
    return true;
}
Whereby SPARQLUpdate is defined as: 
package de.semweb.sparql;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;

/**
 *
 * @author admos0
 */
public class SPARQLUpdate {

    private String updateString = "";
    private String endpoint = "";

    public SPARQLUpdate() {
        // empty constructor
    }

    public SPARQLUpdate(String input) {
        this.updateString = input;
    }

    /**
     * @method  execute the update
     * @return  the response <String>
     */
    public String execute() throws Exception {
        if (this.endpoint.equals("")) throw new Exception("No endpoint specified");
        if (this.updateString.equals("")) throw new Exception("No update string specified");
   
   
        // Construct data
        String data = URLEncoder.encode("query", "UTF-8") + "=" +
                URLEncoder.encode(this.getUpdateString(), "UTF-8");
   
   
        // Send data
        URL url = new URL(endpoint);
   
        URLConnection conn = url.openConnection();
        conn.setDoOutput(true);
        OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
        wr.write(data);
        wr.flush();
   
        // Get the response
        BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        String response = "";
        String line;
        while ((line = rd.readLine()) != null) {
            response += line;
        }
       
        wr.close();
        rd.close();
       
        return response;
    }

    /**
     * @param set the endpoint
     */
    public void setEndpoint(String endpoint) {
        this.endpoint = endpoint;
    }

    /**
     * @return the endpoint
     */
    public String getEndpoint() {
        return this.endpoint;
    }


    /**
     * @param updateString the updateString to set
     */
    public void setUpdateString(String updateString) {
        this.updateString = updateString;
    }

    /**
     * @return the updateString
     */
    public String getUpdateString() {
        return updateString;
    }
}


Access Triple Store via Java

The easiest way to access triple stores via Java is to use Jena ARQ.
ARQ is a query engine for Jena that supports the SPARQL RDF Query language. SPARQL is the query language developed by the W3C RDF Data Access Working Group.
You can easily access the data in the store using SELECT, ASK, DESCRIBE, and CONSTRUCT queries.
Query query = QueryFactory.create("queryString");
QueryExecution queryExec = QueryExecutionFactory.sparqlService( endpoint, query );
ResultSet result = queryExec.execSelect(); // or execSelectTriples()
It results in a ResultSet or an Interator of triples which can easily be processed further.
while (result.hasNext()) {
    QuerySolution solution = result.next();
    Resource id = solution.getResource("id");
    Resource title = solution.getLiteral("title");
}
One QuerySolution thereby is one result row of the query and each cell can be accessed by the variable name used in the SPARQL query.

But sometimes you do not want to just extract data from your triple store, but INSERT, UPDATE or DELETE triples. This can also be done using Jena.
UpdateRequest update = UpdateFactory.create(queryString);           
UpdateProcessor uExec = UpdateExecutionFactory.createRemote(update, endpoint);
uExec.execute(); 
Attention: This just works with triple stores supporting SPARQL 1.1 UPDATE.

Freitag, 31. August 2012

Semscape - Visualizing Semantic Data Landscapes with Cytoscape 3.0 (GSoC 2012)

Semscape is a cytoscape 3.0 plugin which was developed by Yigang Zhou in the Google Summer of Code 2012. The project was mentored by Andra Waagmeester, Andrea Splendiani, Helena Deus, and me. 
Semscape allows to explore RDF endpoints via SPARQL queries and graphically represents the results in Cytoscape. In contrast to existing RDF visualization solutions, Semscape not only can represent data extracted out of SPARQL endpoints, but also the underlying schema of the data. This feature makes it much easier to explore foreign endpoints, where the RDF model is unknown.

For more information see:

Montag, 11. Juni 2012

Testing UIMA with JUnit - I

Some basic functionc can help to test UIMA functions with JUnit tests. Here is my used UIMATestUtils.class:

public class UIMATestUtils {
   
    /**
     * Read type system
     * @return
     * @throws InvalidXMLException
     * @throws IOException
     */
    static public TypeSystemDescription readTypeSystem() throws InvalidXMLException, IOException {
        URL myURL = UIMAFramework.class.getResource("/TypeSystem.xml");
        TypeSystemDescription typeSysDes = UIMAFramework.getXMLParser()
                .parseTypeSystemDescription(new XMLInputSource(myURL));
        return typeSysDes;
    }

    /**
     * Create CAS
     * @param inputFolder
     * @return
     * @throws IOException
     * @throws InvalidXMLException
     * @throws ResourceInitializationException
     * @throws CollectionException
     */
    static public CAS createCas(String inputFolder) throws ResourceInitializationException, InvalidXMLException, IOException, CollectionException {
        CollectionReaderDescription crDesc = CollectionReaderFactory
                .createDescription(XCasReader.class, readTypeSystem(),
                        AbstractDeployer.PARAM_INPUTDIR, inputFolder);
        XCasReader reader = (XCasReader) UIMAFramework.produceCollectionReader(crDesc);
        CAS cas = CasCreationUtils.createCas(reader.getProcessingResourceMetaData());
        reader.run(cas);
        return cas;
    }

    /**
     * Create JCas
     * @param inputFolder
     * @return
     * @throws IOException
     * @throws InvalidXMLException
     * @throws ResourceInitializationException
     * @throws CASException
     * @throws CollectionException
     */
    static public JCas createJCas(String inputFolder) throws ResourceInitializationException, InvalidXMLException, IOException, CASException, CollectionException {
        CAS cas = createCas(inputFolder);
        return cas.getJCas();
    }
The XCasReader thereby is an XMIDeserializer, which mainly calls the UIMA function XmiCasDeserializer.deserialize(in, aCAS);.

To test UIMA functions, you often need the typesystem descriptor, JCas, or CAS objects as parameters. These functions handle this for you, whereby the JCas and CAS creation is based on the xmi deserializer function of UIMA. This requires a folder containing the xmi file you want to use as base for you JCas or CAS object. 

Donnerstag, 24. Mai 2012

Why using e.printStackTrace() is a bad idea

This is my personal opinion, so feel free to leace a comment if you think differnt.

e.printStackTrace() is by default added to every catch block automatically generated by eclipse and so often stays in the code forever. Even in libraries given to the world you can find it, and the worst, not change it anymore.

In my actual case I wrote a program to run some textmining process. I introduced an exception handling which propagates all exceptions up to my two main functions, where they are cought and logged. The type of the exception as well as the error message are logged in the SEVERE level and the stack trace in the FINE level. My code is using the UIMA framework, which is a nice framework to process unstructured information, but somehow one of the developer left a e.printStackTrace() in. In general they use a modified Java logger, so I do not know why they have left e.printStackTrace() in, but it really is annoying for me. Due to this one line of code, I get every exception from the deep of the UIMA framework printed at least twice in my console. And I cannot do anything about it. The only solution would be to log into a file, which is perhaps usable for big runs, but not during development, and this is where this additional prints annoy me and my colleagues most.

So my advice: Do not use e.printStackTrace() anywhere. Just use the build in logger (or if you use an older Java version log4j) and give other coders the possibiliy to influence the outout behaviour of your code.
This counts double if you are writing a lib!

Mittwoch, 23. Mai 2012

JUnit - Testing for excepted exceptions

Testing for excepted exceptions is a commen use case. In JUnit 4 there is a nice possibilities to do this:
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void throwsNullPointerExceptionWithMessage() {
    thrown.expect(NullPointerException.class);
    thrown.expectMessage("Exception Message"); 
    // test code goes here
}
The rule just has to be defined once, and then can be reused wherever wanted. The expectMessage function just makes a substring search, so you do not need to have to provide the complete error message.

In JUnit < 4, the testing is more complex:
@Test
public void throwsNullPointerExceptionWithMessage() {
    boolean exceptionThrown = false;
    try {
        // test code goes here
    } catch (Exception e) {
        exceptionThrown = true;
        Assert.assertEquals("Not expected exection type", NullPointerException.class, e.getClass());
        Assert.assertTrue("Not expected error message", e.getMessage().contains("Exception Message")); 
    }
    Assert.assertTrue("Expected exception not thrown", exceptionThrown);
}

Dienstag, 22. Mai 2012

How to generate Java files from OWL-files in Jena - Extension

This is an extension of Andra Waagmester's "How to generate Java files from OWL-files in Jena."

For some files, like the PAV OWL-file, you will just get the header, but none of the predicates or classes. Here is the reason why:

Schemagen is picking a namespace for your ontology, and is defaulting to the value of the xmlns-attribute:

<rdf:RDF xmlns="&pav;2.0/"
     xml:base="&pav;2.0/"

Hence http://purl.org/pav/2.0/

However, all of their declarations are actually in a non-versioned namespace:
xmlns:pav="http://purl.org/pav/"

So it is necessary to tell schemagen to use the right namespace with -a, or change the file so that the namespaces are consistent. Run:

java -cp lib/icu4j-3.4.4.jar:lib/jena-arq-2.9.0-incubating.jar:lib/jena-core-2.7.0-incubating.jar:lib/jena-iri-0.9.0-incubating.jar:lib/log4j-1.2.16.jar:lib/slf4j-api-1.6.4.jar:lib/slf4j-log4j12-1.6.4.jar:lib/xercesImpl-2.10.0.jar:lib/xml-apis-1.4.01.jar jena.schemagen -i $inputFile -o "./src" --package "de.fraunhofer.scai.bio.uima.xcas2rdf.vocabulary" --owl -a "http://purl.org/pav/" pav

.. and it will generate what is expected.

Another tip is to add  --ontology to get OntProperty, OntClass, etc, declarations generated in the output file.