Сериализация изменений JENA OntModel - PullRequest
1 голос
/ 17 декабря 2008

Мне нужно синхронизировать пару Jena моделей (в частности, OntModels) через сокет, и я хотел бы сделать это одно изменение за раз (по разным причинам - одна из которых каждый оператор, добавленный или удаленный из моделей OntModels, также адаптирует базу правил JESS.) Я могу слушать события добавления / удаления в моделях OntModels и затем создавать простые экземпляры событий, которые обертывают добавленные / удаленные операторы вместе с ChangeType, который указывает, что оператор был добавлен или удален, но сериализация этого оператора оказалась проблема.

К сожалению, вся найденная мною документация по сериализации JENA относится к сериализации всей модели в xml / rdf / n3 / и т. Д. Поскольку операторы - это просто тройки строк (на одном уровне, во всяком случае), похоже быть тривиальным для сериализации данных на уровне выписки. Однако Jena , похоже, не предоставляет API для создания операторов с простыми строками, которые "делают правильные вещи". Проблемы возникают с типизированными литералами. например:

Я могу создать утверждение:

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

но строковая версия, которую я могу получить, выглядит следующим образом:

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

(обратите внимание на отсутствие "перед ^^)

Это не было бы такой большой проблемой, так как литерал все еще можно анализировать с помощью регулярного выражения, но я не смог создать Statement с правильным литералом. Очевидный подход (ModelCon.createStatement (Resource, Property, String)) генерирует нетипизированный строковый литерал с полным переданным значением String.

Кто-нибудь знает, как я могу надежно сериализовать (и, конечно, десериализовать) отдельные утверждения Йены?

Ответы [ 4 ]

2 голосов
/ 10 января 2009

Я бы сериализовал изменения в формате N-TRIPLES. В Jena есть встроенный сериализатор и синтаксический анализатор N-TRIPLES, но синтаксис N-TRIPLES (преднамеренно) очень прост, поэтому его будет легко сгенерировать вручную в вашем коде.

Тем не менее, может быть даже проще хранить простую модель памяти для хранения изменений, попросить обработчики событий записать изменения в эту модель, а затем сериализовать эту модель по проводам в соответствии с вашим графиком синхронизации. Аналогично, в дальнем конце я считывал обновления из канала синхронизации во временную модель памяти, а затем yourOntModel.add( changesModel ) должен очень просто добавлять обновления.

Ian

1 голос
/ 05 января 2009

Не та область, на которую я смотрел очень подробно, но я вспомнил, что Талис проводил некоторые исследования и смог следовать хлебным крошкам к соответствующему словарю, называемому "Changeset".

http://vocab.org/changeset/schema

Я удивлен, что у вас возникли проблемы с сериализацией отдельных операторов с использованием JENA, но, возможно, если бы вы создали график в соответствии со схемой изменений и сериализовали этот график, вам бы больше повезло? В качестве альтернативы добавьте оператор в новый граф и сериализуйте граф из одной тройки.

0 голосов
/ 14 января 2009

Решение, которое я выбрал, приведено ниже. Я закончил тем, что использовал регулярный подход из-за нехватки времени (другие предложения по этому вопросу я не видел до недавнего времени)

Вероятно, это не лучший подход, но, похоже, он работает хорошо (и я проверил его с помощью набора тестов, в котором используются сценарии использования, с которыми мне нужно иметь дело в данный момент).

Метод createStatement(...) находится в вспомогательном классе OntUtilities.

   /**
    * 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 голосов
/ 13 января 2009

Возможно, вам следует попробовать заменить параметр String createStatement на Model.createLiteral (String) ...

...