Serializing JENA OntModel Changes

I need to keep a couple of Jena Models (OntModels in particular) synchronized over a socket, and I'd like to make this one change at a time (for various reasons - one of them is that every expression added or removed from OntModels also adapts the JESS rule base .). I can listen to add / remove events in OntModels and then create simple event instances that wrap the added / removed statements along with a ChangeType that indicates the Statement was added or removed, but serializing the Statement turned out to be a problem.

Unfortunately, all the JENA serialization documentation I found is related to serializing the entire model to xml / rdf / n3 / etc. Since statements are just triplets of strings (at the same level, anyway), it looks like it should be trivial to serialize data at the Statement level. However, Jena , it seems, does not provide an API for creating expressions with the usual strings that "doing the right thing." Problems arise with typed literals. eg:

I can create an operator:

<http://someuri/myont#foo> <http://someuri/myont#weight> "50.7"^^www.w3.org/2001/XMLSchema#double

      

but the line I can get looks like this:

"http://someuri/myont#foo" "http://someuri/myont#weight" "50.7^^www.w3.org/2001/XMLSchema#double"

      

(note the lack of "before ^^)

This is not such a big problem as the literal can still be parsed with a regex, but I was unable to create an expression with the correct literal. The obvious approach (ModelCon.createStatement (Resource, Property, String)) generates an untyped string literal with the full value of the passed string.

Does anyone know how I can reliably serialize (and deserialize, of course) individual Jena statements?

+1


source to share


4 answers


I would serialize the changes in N-TRIPLES format. Jena has a built-in N-TRIPLES serializer and parser, but the N-TRIPLES syntax is (intentionally) very simple so it's easy to create it manually in code.

However, it might be even easier to keep a simple mem model to store changes, event handlers write the changes to that model and then serialize that model over the wire according to your timing schedule. Likewise, at the far end, I read updates from sync channel to mem temporary model, then yourOntModel.add( changesModel )

should add updates very simply.



Yang

+2


source


Not an area that I was looking at at great depth, but I remembered that Talis did some research and was able to follow the breadcrumbs corresponding vocabulary "Set of Changes".

http://vocab.org/changeset/schema



I'm surprised you are having trouble serializing individual statements with JENA, but perhaps if you created the graph according to the changeset schema and serialized the graph, you were more fortunate? Alternatively, add a statement to a new graph and serialize the graph of one triplex.

+1


source


Maybe you should try replacing the String parameter for createStatement with Model.createLiteral (String) ...

0


source


The solution I came across is below. I ended up using the reg-ex approach due to time constraints (I haven't seen other suggestions on this matter until recently)

This is probably not the best approach, but it seems to work well (and I tested it with a test suite in which I use the use cases I need to solve at this stage).

The method createStatement(...)

is in the OntUtilities helper class.

   /**
    * Serialization output method.
    * 
    * @param out
    * @throws IOException
    */
   private void writeObject(final ObjectOutputStream out) throws IOException {
     out.defaultWriteObject();
     out.writeObject(_statement.getSubject().getURI());
     out.writeObject(_statement.getPredicate().getURI());
     out.writeObject(_statement.getObject().toString());
   }

   /**
    * deserialization method.
    * 
    * @param in
    * @throws IOException
    * @throws ClassNotFoundException
    */
   private void readObject(final ObjectInputStream in) throws IOException, 
      ClassNotFoundException {
     in.defaultReadObject();

     final String subject = (String)in.readObject();
     final String predicate = (String)in.readObject();
     final String object = (String)in.readObject();

     _statement = OntUtilities.createStatement(subject, predicate, object);
   }

   /**
    * Creates a statement from a triple of strings.  These strings may be fully
    * qualified uris, or shortened "namespace" uris (eg: shai:TST)
    * 
    * @param sub The resource uri (the subject)
    * @param pred The predicate uri (the property)
    * @param ob The object uri.
    * @return A JENA Statement.
    */
   public static Statement createStatement(final String sub, final String pred,
         final String ob) {
      final Model m = ModelFactory.createDefaultModel();

      final String s = OntUtilities.nsUriToUri(sub);
      final String p = OntUtilities.nsUriToUri(pred);
      final String o = OntUtilities.nsUriToUri(ob);

      Statement stmt = null;
      try {
         // try making a uri as a syntax-verification step.
         new URI(o);
         // it was valid, so well use o as a resource:
         final Resource obj = m.createResource(o);
         stmt = m.createStatement(m.createResource(s), m.createProperty(p), obj);
      } catch (final URISyntaxException e) { 
         // o was *not* a uri.
         if (o.contains("^^")) {
            final int idx = o.lastIndexOf("^^");

            final String value = o.substring(0, idx);
            final String uri = o.substring(idx+2);

            final Literal lit = m.createTypedLiteral(value, getDataType(uri));

            stmt = m.createStatement(m.createResource(s), m.createProperty(p), lit);
         } else {
            // just use the string as-is:
            stmt = m.createStatement(m.createResource(s), m.createProperty(p), o);
         }
      }
      return stmt; 
   }

      

0


source







All Articles