- From: Henry Story <henry.story@bblfish.net>
- Date: Thu, 25 Aug 2005 00:10:25 +0200
- To: bloged <users@bloged.dev.java.net>, semanticweb@sun.com, SWIG <semantic-web@w3.org>
I have been wanting to think more carefully about using annotations recently. As this topic is making headlines in the blogosphere [1][2] I thought I'd consider this here now, and use this as a basis to enter the discussion. I have already implemented this in the current BlogEd using a ad-hoc annotation scheme, so this clearly will work. If I can put it really concisely, the semantic web is a mathematical structure based on graph theory. It has many serializations. One of these is Java. OWL [3] gives us a vocabulary to describe object oriented structures such as those given by java. It is not obvious from reading the OWL specs, but with annotations it will become so. Here is a first attempt at annotation the AtomPerson class @OWL(AtomPerson.BASE+"Person") public interface AtomPerson { String BASE = "https://bloged.dev.java.net/Ontologies/Atom/ 2005-01-03/" @OWL(BASE+"name") public void setName(String name); public String getName(); @OWL(BASE+"email") public void addEmail(URI email); //should be mailto uri? public Collection<URI> getEmails(); @OWL(BASE+"dateOfBirth") public void setDateOfBirth(Date birth); public Date getDateOfBirth(); } So here we annotate the class and the bean methods with URIs. The nice thing is that any instance of this bean can then automatically be serialized to RDF/XML or any of the other RDF formats (once one agrees to the correct serializations for some of the primitive java types, such as int, or Date) The above gives us the semantics for RDFS [3.5]. To get OWL we just need the further annotation types [4] such as: - functional: if A rel B and A rel C the A == C - inverse functional: if A rel C and B rel C then A == B) - the max number of values for an instance and the min number (useful for the add... type beans) [4] (the setXXX methods clearly have at most one value) - transitivity (if A rel B rel C then A rel C) - symmetricity (if A rel B then B rel A) so for example @OWL(AtomPerson.BASE+"Person") public interface AtomPerson { String BASE = "https://bloged.dev.java.net/Ontologies/Atom/ 2005-01-03/" @OWL(BASE+"name") public void setName(String name); public String getName(); @OWL(BASE+"email") @OwlInverseFunctional public void addEmail(URI email); public Collection<URI> getEmails(); @OWL(BASE+"dateOfBirth") @OwlMaxCardinality(1) @OwlMinCardinality (1) public void setDateOfBirth(Date birth); public Date getDateOfBirth(); @OWL(BASE+"sibling") @OwlSymmetric @OwlTransitive public void addSibling(Person sibling); public Collection<Person> getAllSiblings(); } So the sibling relation (uniquely identified by the <https:// bloged.dev.java.net/Ontologies/Atom/2005-01-03/sibling> uri and by the addSibling and getSibling methods) is clearly -symmetric: because if Christina is my sibling then I am her sibling -transitive: because if Alex is a sibling of Christina then Alex is also my sibling There we have it. We now have written RDF/OWL in java. What does it give us? --------------------- - For one we can see how easy it is to understand OWL :-) - Using URIs for beans is a lot better than using table names. URIs are *Universal*. SQL tables layouts are different from one database to the next. It should be up to the database administrator only to set the mapping from RDF into his private internal scheme. We have done here all the mapping that needs to be done. - We can implement our beans by using dynamic proxies or other aspect oriented techniques to have our classes mirror an RDF or any normal relational (SQL) database - The above now maps very easily into UML class diagrams (which are just another notation for OWL) - We can annotate normal classes too (with some questions as to how the behavior is to be understood) - others? Backward compatibility ---------------------- All java beans by default already work this way. All we need to do is give every java class a URI. So let us invent a URI scheme for java classes: <java:com.sun.labs.tools.blog.AtomPerson,1.2> would be the URI of the current class [6] and the name relation could be reached via the URI <java:com.sun.labs.tools.blog.AtomPerson,1.2/name> So any java bean can already be transformed into OWL. The OWL annotation could then be seen to enable us to override the default URI for the class, interface or property. Improvements ------------ In the above I have only annotated the setter method. One could also annotate the getter, adder, getAll methods or even a field. This ends up creating too many places for annotations I think. Is there a standard solution for this? One of these [7] would be to just annotate the variable @OWL(AtomPerson.BASE+"Person") public interface AtomPerson { @Property(read | write) @OWL(BASE+"name") @OwlMaxCardinality(1) String name; @Property(read | write) @OWL(BASE+"email") @OwlInverseFunctional URI email; @Property(read | write) @OWL(BASE+"dateOfBirth") @OwlMaxCardinality(1) @OwlMinCardinality(1) Date birth; @Property(read | write) @OWL(BASE+"sibling") @OwlSymmetric @OwlTransitive Person sibling; } And apparently we can then use apt[8] to then create the getters, setters, adders, etc... Does anyone have any feedback on this? Any ideas where this could be most usefully discussed? Henry Story [1] http://www.softwarereality.com/programming/annotations.jsp [2] http://members.capmac.org/~orb/blog.cgi/tech/java/ Annotations_are_the.html [3] http://www.w3.org/2001/sw/WebOnt/ [3.5] http://www.w3.org/TR/rdf-schema/ [4] in the spirit of the article at http://java.sun.com/developer/technicalArticles/J2SE/ constraints/annotations.html [5] it seems clear to me that setters and getters don't give us quite all that we want. It would be really nice if java beans also had addXXX and getAllXXX. [6] https://bloged.dev.java.net/source/browse/bloged/src/com/sun/labs/ tools/blog/AtomPerson.java [7] see section "Constraints as Part of a Property Annotation" of [4] [8] http://java.sun.com/j2se/1.5.0/docs/guide/apt/GettingStarted.html
Received on Wednesday, 24 August 2005 22:10:39 UTC