You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@jena.apache.org by Herbie Porter <he...@gmail.com> on 2012/04/11 12:04:22 UTC

Deleting all instances of Class from a Model

Hey everyone,

I'm developing an app to represent weather data in a semantic dataset using
Jena and TDB.  I've got all the data into Jena but I'm having trouble
updating it.  Every 3 hours for every weather monitoring station in my
dataset I would like to be able to delete all old observations and replace
them with new predictions.

An example of my RDF xml representing a *#LandMeterologicalStation* in
Southampton, an *#MeteorlogicalObservation* for this station and
the associated */2006/time#Instant *time/date object.

*RDF/XML:*
*<rdf:Description rdf:about="http://www.witw.com/Data/Stations/Southampton">
*
*    <rdf:type rdf:resource="
http://www.semanticweb.org/ontologies/2012/1/monitoringStation.owl#LandMeterologicalStation
"/>*
*    <wgs84_pos:location>http://www.witw.com/Data/Points/1234
</wgs84_pos:location>*
*    <j.0:currentObservation>
http://www.witw.com/Data/Observations/1234_2012-04-11T10:31:24.184+01:00
</j.0:currentObservation>*
*    <j.0:predictedObservation>
http://www.witw.com/Data/Observations/1234_2012-04-11T10:31:24.258+01:00
</j.0:predictedObservation>*
*    <j.0:predictedObservation>
http://www.witw.com/Data/Observations/1234_2012-04-11T10:32:22.577+01:00
</j.0:predictedObservation>*
*    <j.0:predictedObservation>
http://www.witw.com/Data/Observations/1234_2012-04-11T10:42:36.491+01:00
</j.0:predictedObservation>*
*    <j.0:spatialGranularity rdf:datatype="
http://www.w3.org/2001/XMLSchema#integer">1</j.0:spatialGranularity>*
*    <j.0:stationContinent rdf:datatype="
http://www.w3.org/2001/XMLSchema#string">UK</j.0:stationContinent>*
*    <j.0:stationCountry rdf:datatype="
http://www.w3.org/2001/XMLSchema#string">England</j.0:stationCountry>*
*    <j.0:stationId rdf:datatype="http://www.w3.org/2001/XMLSchema#string
">1234</j.0:stationId>*
*    <j.0:stationName rdf:datatype="http://www.w3.org/2001/XMLSchema#string
">Southampton</j.0:stationName>*
*  </rdf:Description>*
*
*
*  <rdf:Description rdf:about="
http://www.witw.com/Data/Observations/1234_2012-04-11T10:31:24.258+01:00">*
*    <rdf:type rdf:resource="
http://www.semanticweb.org/ontologies/2012/1/monitoringStation.owl#MeteorlogicalObservation
"/>*
*    <j.0:observationTime>
http://www.witw.com/Data/Instants/1234_2012-04-11T10:31:24.258+01:00
</j.0:observationTime>*
*    <j.0:temperature rdf:datatype="http://www.w3.org/2001/XMLSchema#integer
">2</j.0:temperature>*
*    <j.0:temperatureFeelsLike rdf:datatype="
http://www.w3.org/2001/XMLSchema#integer">3</j.0:temperatureFeelsLike>*
*    <j.0:uvIndex rdf:datatype="http://www.w3.org/2001/XMLSchema#integer
">1</j.0:uvIndex>*
*    <j.0:visibility rdf:datatype="http://www.w3.org/2001/XMLSchema#string
">VG</j.0:visibility>*
*    <j.0:weatherType rdf:datatype="http://www.w3.org/2001/XMLSchema#integer
">2</j.0:weatherType>*
*    <j.0:windDir rdf:datatype="http://www.w3.org/2001/XMLSchema#double
">180.0</j.0:windDir>*
*    <j.0:windSpeed rdf:datatype="http://www.w3.org/2001/XMLSchema#integer
">4</j.0:windSpeed>*
*    <j.0:windSpeedGust rdf:datatype="
http://www.w3.org/2001/XMLSchema#integer">5</j.0:windSpeedGust>*
*  </rdf:Description>*
*
*
*
  <rdf:Description rdf:about="
http://www.witw.com/Data/Instants/1234_2012-04-11T10:31:24.258+01:00">
    <rdf:type rdf:resource="/2006/time#Instant"/>
    <j.1:inXSDDateTime rdf:datatype="
http://www.w3.org/2001/XMLSchema#dateTime
">2012-04-11T09:31:24.258Z</j.1:inXSDDateTime>
  </rdf:Description>
*
*
  <rdf:Description rdf:about="
http://www.semanticweb.org/ontologies/2012/1/monitoringStation.owl#MeteorlogicalObservationWind
">*
*    <rdf:type rdf:resource="#Class"/>*
*  </rdf:Description>*
*
*
*Code snippet:*
*
*
* /***
* * Used when no current database for the RDF model exists. Loads an
ontology*
* * from the ontologyPath provided by the Spring config file and builds a*
* * database at the provided tbdDBPath.*
* */*
* public void setUpDatabase() {*
* logger.info("Setting Up RDF Database");*
* logger.info("Database Path: " + tbdDBPath);*
* logger.info("Ontology Path: " + ontologyPath);*
*
*
* dataset = TDBFactory.createDataset(tbdDBPath);*
* model = dataset.getDefaultModel();*
* ontModel = ModelFactory*
* .createOntologyModel(OntModelSpec.OWL_MEM, model);*
* ontModel.read(ontologyPath);*
* model.commit();*
* logger.info("Database UP :)");*
* } *

* public boolean removeAllStationProperties(String individualSubjectURI,*
* String propertyObjectURI, String individualObjectURI) {*
*
*
* logger.info("Trying to remove object with URI: " + propertyObjectURI);*
* *
* String encodedIndividualSubjectURI = URIref*
* .encode(individualSubjectURI);*
* String encodedPropertyObjectURI = URIref.encode(propertyObjectURI);*
* String encodedIndividualObjectURI = URIref.encode(individualObjectURI);*
* *
* dataset.begin(ReadWrite.WRITE);*
* model = dataset.getDefaultModel();*
* *
* ontModel = ModelFactory*
* .createOntologyModel(OntModelSpec.OWL_MEM, model);*
* try {*
* Individual individualSubject = ontModel*
* .getIndividual(encodedIndividualSubjectURI);*
*
*
* Resource objectResource = ontModel*
* .getResource(encodedIndividualObjectURI);*
* OntClass thisClass = objectResource.as(OntClass.class);*
* Iterator classIterator = thisClass.listInstances();*
*
*
* while (classIterator.hasNext()) {*
* OntResource thisResource = (OntResource) classIterator.next();*
* classIterator.remove();*
* }*
*
*
*// Second method of removing objects. *
*// *
*// Property thisProperty = ontModel*
*// .getProperty(encodedPropertyObjectURI);*
*//*
*// Individual individualObject = ontModel*
*// .getIndividual(encodedIndividualObjectURI);*
*//*
*// ontModel.remove(individualSubject, thisProperty, individualObject);*
*
*
* *
*// Third method attempted*
*//*
*// individualObject.removeProperties();*
*// individualObject.remove(); *
* *
* dataset.commit();*
* logger.info("Sucessfully removed object and all properties: "*
* + propertyObjectURI);*
* return true;*
*
*
* } finally {*
* dataset.end();*
* }*
* }*

I've tried using the following above method to delete all the *
#MeteorlogicalObservation** *instances but to no avail after 3
different approaches:

   1. Using an iterator over all the instances of the Class *
   #MeteorlogicalObservation.*
      1. Throws UnsupportedOperationException
   2. Calling ontModel.remove() and a predicate describing the relationship.
   3. Calling removeProperties() and remove on the *
   #LandMeterologicalStation.*
      1. This deletes all the *#LandMeterologicalStation *objects but not
      the *#MeteorlogicalObservations.*


To test I call removeAllStationProperties(); using:

* witwDataAdaptor*
* .removeAllStationProperties(*
* witwDataAdaptor.getLandStationIndividualURIPrefix()*
* + "Southampton",*
* "
http://www.semanticweb.org/ontologies/2012/1/witwWorldModel.owl#predictedObservation
",*
* "
http://www.semanticweb.org/ontologies/2012/1/monitoringStation.owl#MeteorlogicalObservation
");*
*
*
My main question is what is the best way to search for and delete all
instances of a class? Including deleting all associated class objects.  In
this example, I'd like to delete all  *#MeteorlogicalObservation *
and associated *#Instant *objects for a given *#LandMeterologicalStation*
 URI.

Thanks in advance for any help you guys can offer and sorry if its a big
post, I've tried to be as complete as possible :)

Herbie

Re: Deleting all instances of Class from a Model

Posted by Dave Reynolds <da...@gmail.com>.
Hi Herbie,

[code sample snipped]

> That's perfect, I'm having a go at implementing a generic version without
> typing so I can use re-use it but I understand the premise.

Good.

> I'm thinking I should have done a little more reading as I hadn't touched
> on schemagen and so far I've been creating all the POJOs by hand, once I've
> finished the schema I'll go back though and re-create all them using
> schemagen and re-implement.  Does Jena have the ability to encode and
> decode schemagen objects to and from RDF as that would be ideal and make a
> lot of my coding simpler?

No. All schemagen does is create java constants for each of the terms in 
a vocabulary.

There are various third party tools like jenabean which give POJO 
wrappers which you may be able to make use of, though I'm not sure that 
the project is that active at the moment.

Dave

[1] http://code.google.com/p/jenabean/

Re: Deleting all instances of Class from a Model

Posted by Herbie Porter <he...@gmail.com>.
Thanks for your reply Dave.


>  Hey everyone,
>>
>> I'm developing an app to represent weather data in a semantic dataset
>> using
>> Jena and TDB.
>>
>
> Interesting.


> [I'm involved in a pilot project to represent the MetOffice site-specific
> forecasts in RDF. Though the requirement there is to match the WMO standard
> modelling. So while the observation sets themselves use Data Cube, the
> surrounding metadata needs to compatible with OGC Observations &
> Measurements (i.e. ISO 19156, ISO 19123 et al).]
>

Small world, the data I'm actually modelling is exactly that, the public
site forecast data pulled down from the public Met Office API. I'm planning
to represent the data semantically using Jena then overlay it onto a Google
Map based web application. I'm slightly less restricted in that I can
represent the data how I want and being quite new to this area I've gone
for this fairly simplistic approach.  Are you working with the Met Office
then on this project?


>
>  An example of my RDF xml representing a *#LandMeterologicalStation* in
>> Southampton, an *#MeteorlogicalObservation* for this station and
>> the associated */2006/time#Instant *time/date object.
>>
>
> Not the cause of your current trouibles but that data has some problems:
>
>
>> *RDF/XML:*
>> *<rdf:Description rdf:about="http://www.witw.**
>> com/Data/Stations/Southampton<http://www.witw.com/Data/Stations/Southampton>
>> "**>
>> *
>> *<rdf:type rdf:resource="
>> http://www.semanticweb.org/**ontologies/2012/1/**monitoringStation.owl#**
>> LandMeterologicalStation<http://www.semanticweb.org/ontologies/2012/1/monitoringStation.owl#LandMeterologicalStation>
>> "/>*
>> *<wgs84_pos:location>http://**www.witw.com/Data/Points/1234<http://www.witw.com/Data/Points/1234>
>> </wgs84_pos:location>*
>> *<j.0:currentObservation>
>>
>> http://www.witw.com/Data/**Observations/1234_2012-04-**
>> 11T10:31:24.184+01:00<http://www.witw.com/Data/Observations/1234_2012-04-11T10:31:24.184+01:00>
>> </j.0:currentObservation>*
>>
>
> This is a literal, I strongly suspect you meant this to be a resource.
> There's similar problems with almost all the resources in the data.
>

Thanks, small typo in in my code when I was adding a resource property I
was calling addProperty() with the Subject and the Object.getURI() not the
Object so Jena was adding the Object URI as a literal and not as a resource
object.  Small typo with big ramifications ; )


>
> <snip>
>
>    <rdf:Description rdf:about="
>> http://www.semanticweb.org/**ontologies/2012/1/**monitoringStation.owl#**
>> MeteorlogicalObservationWind<http://www.semanticweb.org/ontologies/2012/1/monitoringStation.owl#MeteorlogicalObservationWind>
>> ">*
>> *<rdf:type rdf:resource="#Class"/>*
>>
>
> Suspect that shouldn't be #Class.
>


I choose to sub split the wind off into a class containing the speed,
gustSpeed and direction.  Thinking about it in hindsight this wasn't really
necessary,at the time it tired in with the Java objects I created from
passing the JSON from the MetOffice.  I think I'll change these to plain
literals attached to each Observation as it just adds another layer of
un-necessary complexity.


>  My main question is what is the best way to search for and delete all
>> instances of a class? Including deleting all associated class objects.  In
>> this example, I'd like to delete all  *#MeteorlogicalObservation *
>> and associated *#Instant *objects for a given *#LandMeterologicalStation*
>>
>
> The trick is to build a safe list of the things you want to delete, then
> delete them:
>
> private void removeStationObservations(**Model model, String station) {
>    Resource stationR = model.getResource(station);
>    Set<RDFNode> observations = model.listObjectsOfProperty(**stationR,
> predictedObservation).toSet();
>    for (RDFNode obs : observations) {
>        model.remove(stationR, predictedObservation, obs);
>        Resource obsR = obs.asResource();
>        obsR.getPropertyResourceValue(**observationTime)
>             .removeProperties();
>        obsR.removeProperties();
>    }
> }
>
> where the properties like observationTime and predicatedObservation would
> be typically created via schemagen.


That's perfect, I'm having a go at implementing a generic version without
typing so I can use re-use it but I understand the premise.

I'm thinking I should have done a little more reading as I hadn't touched
on schemagen and so far I've been creating all the POJOs by hand, once I've
finished the schema I'll go back though and re-create all them using
schemagen and re-implement.  Does Jena have the ability to encode and
decode schemagen objects to and from RDF as that would be ideal and make a
lot of my coding simpler?

Thanks for your help

Herbie


>
>
> Dave
>

Re: Deleting all instances of Class from a Model

Posted by Dave Reynolds <da...@gmail.com>.
On 11/04/12 11:04, Herbie Porter wrote:
> Hey everyone,
>
> I'm developing an app to represent weather data in a semantic dataset using
> Jena and TDB.

Interesting.

[I'm involved in a pilot project to represent the MetOffice 
site-specific forecasts in RDF. Though the requirement there is to match 
the WMO standard modelling. So while the observation sets themselves use 
Data Cube, the surrounding metadata needs to compatible with OGC 
Observations & Measurements (i.e. ISO 19156, ISO 19123 et al).]

> An example of my RDF xml representing a *#LandMeterologicalStation* in
> Southampton, an *#MeteorlogicalObservation* for this station and
> the associated */2006/time#Instant *time/date object.

Not the cause of your current trouibles but that data has some problems:

>
> *RDF/XML:*
> *<rdf:Description rdf:about="http://www.witw.com/Data/Stations/Southampton">
> *
> *<rdf:type rdf:resource="
> http://www.semanticweb.org/ontologies/2012/1/monitoringStation.owl#LandMeterologicalStation
> "/>*
> *<wgs84_pos:location>http://www.witw.com/Data/Points/1234
> </wgs84_pos:location>*
> *<j.0:currentObservation>
> http://www.witw.com/Data/Observations/1234_2012-04-11T10:31:24.184+01:00
> </j.0:currentObservation>*

This is a literal, I strongly suspect you meant this to be a resource. 
There's similar problems with almost all the resources in the data.

<snip>

>    <rdf:Description rdf:about="
> http://www.semanticweb.org/ontologies/2012/1/monitoringStation.owl#MeteorlogicalObservationWind
> ">*
> *<rdf:type rdf:resource="#Class"/>*

Suspect that shouldn't be #Class.

> My main question is what is the best way to search for and delete all
> instances of a class? Including deleting all associated class objects.  In
> this example, I'd like to delete all  *#MeteorlogicalObservation *
> and associated *#Instant *objects for a given *#LandMeterologicalStation*

The trick is to build a safe list of the things you want to delete, then 
delete them:

private void removeStationObservations(Model model, String station) {
     Resource stationR = model.getResource(station);
     Set<RDFNode> observations = model.listObjectsOfProperty(stationR, 
predictedObservation).toSet();
     for (RDFNode obs : observations) {
         model.remove(stationR, predictedObservation, obs);
         Resource obsR = obs.asResource();
         obsR.getPropertyResourceValue(observationTime)
              .removeProperties();
         obsR.removeProperties();
     }
}

where the properties like observationTime and predicatedObservation 
would be typically created via schemagen.

Dave