Changes between Version 1 and Version 2 of WikiStart


Ignore:
Timestamp:
04/04/05 10:53:56 (19 years ago)
Author:
kiesel
Comment:

imported from Sven's page, images missing

Legend:

Unmodified
Added
Removed
Modified
  • WikiStart

    v1 v2  
    1 = Welcome to Trac 0.8 'Qualia' = 
    2  
    3 Trac is a '''minimalistic''' approach to '''web-based''' management of 
    4 '''software projects'''. Its goal is to simplify effective tracking and handling of software issues, enhancements and overall progress. 
    5  
    6 All aspects of Trac have been designed with the single goal to  
    7 '''help developers write great software''' while '''staying out of the way''' 
    8 and imposing as little as possible on a team's established process and 
    9 culture. 
    10  
    11 As all Wiki pages, this page is editable, this means that you can 
    12 modify the contents of this page simply by using your 
    13 web-browser. Simply click on the "Edit this page" link at the bottom 
    14 of the page. WikiFormatting will give you a detailed description of 
    15 available Wiki formatting commands. 
    16  
    17 "[wiki:TracAdmin trac-admin] ''yourenvdir'' initenv" created 
    18 a new Trac environment, containing a default set of wiki pages and some sample 
    19 data. This newly created environment also contains  
    20 [wiki:TracGuide documentation] to help you get started with your project. 
    21  
    22 You can use [wiki:TracAdmin trac-admin] to configure 
    23 [http://trac.edgewall.com/ Trac] to better fit your project, especially in 
    24 regard to ''components'', ''versions'' and ''milestones''.  
    25  
    26  
    27 TracGuide is a good place to start. 
    28  
    29 Enjoy! [[BR]] 
    30 ''The Trac Team'' 
    31  
    32 == Starting Points == 
    33  
    34  * TracGuide --  Built-in Documentation 
    35  * [http://projects.edgewall.com/trac/ The Trac project] -- Trac Open Source Project 
    36  * [http://projects.edgewall.com/trac/wiki/TracFaq Trac FAQ] -- Frequently Asked Questions 
    37  * TracSupport --  Trac Support 
     1== 1. Introduction == 
     2 
     3rdf2java is a small tool written in Java. It allows an easy handling with RDF data. Instead of using an RDF api for creating and searching for RDF triples, i.e., (subject, predicate, object), you just work with Java objects representing RDF subjects / objects. 
     4 
     5Normally, you'd first create an RDFS (RDF Schema) file, containing declarations for classes and properties. RDF data (e.g. in an RDF file) would refer to this RDFS file, just like an XML file can refer to a DTD or to an XML Schema file. The RDF Schema specifies what kind of RDF subjects (i.e. instances of these classes) would be allowed and how they would be linked to each other (-> properties). 
     6So, you have RDFS specifications and RDF data (instances) matching this RDF Schema. 
     7 
     8Similarly we first create (generate) Java classes corresponding to the RDFS classes. Then we can "read in" RDF data, which are instances of RDFS classes and convert them to Java objects, being instances of the respective Java classes. 
     9 
     10The original tool was written by Michael Sintek. Information and download of the old tool can be found [http://www.dfki.uni-kl.de/frodo/rdf2java/ here]. 
     11I developed his tool further to suit our increasing needs in the [http://www.dfki.uni-kl.de/frodo/ FRODO] project. 
     12 
     13== 1.1  Example: == 
     14 
     15Consider the following RDFS file (XML syntax) declaring a class Person having two properties: (1) name is a string-valued property (->Literal) and (2) hasParent demands a reference to another instance of Person. 
     16[I won't go into detail wrt. RDFS and its typical XML syntax; see http://www.w3.org/TR/rdf-schema/ for more information on this topic.] 
     17 
     18{{{ 
     19<?xml version='1.0' encoding='ISO-8859-1'?> 
     20<!DOCTYPE rdf:RDF [ 
     21     <!ENTITY rdf 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'> 
     22     <!ENTITY rdfs 'http://www.w3.org/TR/1999/PR-rdf-schema-19990303#'> 
     23     <!ENTITY example1 'http://org.dfki/rdf2java/example1#'> 
     24]> 
     25 
     26<rdf:RDF  
     27     xmlns:rdf="&rdf;" 
     28     xmlns:rdfs="&rdfs;" 
     29     xmlns:example1="&example1;"> 
     30 
     31<rdfs:Class rdf:about="&example1;Person"> 
     32    <rdfs:subClassOf rdf:resource="&rdfs;Resource"/> 
     33</rdfs:Class> 
     34 
     35<rdf:Property rdf:about="&example1;hasParent"> 
     36    <rdfs:range rdf:resource="&example1;Person"/> 
     37    <rdfs:domain rdf:resource="&example1;Person"/> 
     38</rdf:Property> 
     39 
     40<rdf:Property rdf:about="&example1;name"> 
     41    <rdfs:domain rdf:resource="&example1;Person"/> 
     42    <rdfs:range rdf:resource="&rdfs;Literal"/> 
     43</rdf:Property> 
     44 
     45</rdf:RDF> 
     46}}} 
     47 
     48Just to give you an idea, here's the plain set of RDF triples (subject, predicate, object) for the RDF Schema above. You may need to use your scroll bar! I sorted the triples for your convenience; don't forget, they aren't, really: 
     49 
     50{{{ 
     51http://org.dfki/rdf2java/example1#Person    , http://www.w3.org/1999/02/22-rdf-syntax-ns#type             , http://www.w3.org/TR/1999/PR-rdf-schema-19990303#Class 
     52http://org.dfki/rdf2java/example1#Person    , http://www.w3.org/TR/1999/PR-rdf-schema-19990303#subClassOf , http://www.w3.org/TR/1999/PR-rdf-schema-19990303#Resource 
     53http://org.dfki/rdf2java/example1#hasParent , http://www.w3.org/1999/02/22-rdf-syntax-ns#type             , http://www.w3.org/1999/02/22-rdf-syntax-ns#Property 
     54http://org.dfki/rdf2java/example1#hasParent , http://www.w3.org/TR/1999/PR-rdf-schema-19990303#domain     , http://org.dfki/rdf2java/example1#Person 
     55http://org.dfki/rdf2java/example1#hasParent , http://www.w3.org/TR/1999/PR-rdf-schema-19990303#range      , http://org.dfki/rdf2java/example1#Person 
     56http://org.dfki/rdf2java/example1#name      , http://www.w3.org/1999/02/22-rdf-syntax-ns#type             , http://www.w3.org/1999/02/22-rdf-syntax-ns#Property 
     57http://org.dfki/rdf2java/example1#name      , http://www.w3.org/TR/1999/PR-rdf-schema-19990303#domain     , http://org.dfki/rdf2java/example1#Person 
     58http://org.dfki/rdf2java/example1#name      , http://www.w3.org/TR/1999/PR-rdf-schema-19990303#range      , http://www.w3.org/TR/1999/PR-rdf-schema-19990303#Literal 
     59}}} 
     60 
     61Assume, there is an RDF file containing some instances of this RDFS class (Person): 
     62 
     63{{{ 
     64<?xml version='1.0' encoding='ISO-8859-1'?> 
     65<!DOCTYPE rdf:RDF [ 
     66     <!ENTITY rdf 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'> 
     67     <!ENTITY rdfs 'http://www.w3.org/TR/1999/PR-rdf-schema-19990303#'> 
     68     <!ENTITY example1 'http://org.dfki/rdf2java/example1#'> 
     69]> 
     70 
     71<rdf:RDF  
     72     xmlns:rdf="&rdf;" 
     73     xmlns:rdfs="&rdfs;" 
     74     xmlns:example1="&example1;"> 
     75 
     76<example1:Person rdf:about="&example1;example1_00005" 
     77     example1:name="Bart Simpson"> 
     78    <example1:hasParent rdf:resource="&example1;example1_00006"/> 
     79</example1:Person> 
     80 
     81<example1:Person rdf:about="&example1;example1_00006" 
     82     example1:name="Homer Simpson"/> 
     83 
     84</rdf:RDF> 
     85}}} 
     86 
     87Again, just to give you an idea of the plain RDF, here are the triples, again ordered for your convenience (you may need to use your scroll bar): 
     88 
     89{{{ 
     90http://org.dfki/rdf2java/example1#example1_00005 , http://www.w3.org/1999/02/22-rdf-syntax-ns#type , http://org.dfki/rdf2java/example1#Person 
     91http://org.dfki/rdf2java/example1#example1_00005 , http://org.dfki/rdf2java/example1#hasParent     , http://org.dfki/rdf2java/example1#example1_00006 
     92http://org.dfki/rdf2java/example1#example1_00005 , http://org.dfki/rdf2java/example1#name          , Bart Simpson 
     93http://org.dfki/rdf2java/example1#example1_00006 , http://www.w3.org/1999/02/22-rdf-syntax-ns#type , http://org.dfki/rdf2java/example1#Person 
     94http://org.dfki/rdf2java/example1#example1_00006 , http://org.dfki/rdf2java/example1#name          , Homer Simpson 
     95}}} 
     96 
     97When you visualize these set of triples you receive the following picture (only the RDF data is shown, not the RDF Schema). Boxes represent resources (RDF subjects) whereas ellipses show literals (strings), which can only be RDF objects. The named and directed edges visualize the predicates. Click on the image to get a bigger version. 
     98 
     99XXX image missing 
     100graph representation of these RDF triples 
     101 
     102This RDF data contains two Persons: Bart Simpson and Homer Simson, whereas Bart has a parent, namely Homer. 
     103 
     104Now, assume further, there is a Java class named Person, having the following structure: 
     105 
     106{{{ 
     107public class Person 
     108{ 
     109    public void putName(String name) {...} 
     110    public String getName() {...} 
     111 
     112    public void putHasParent(Person parent) {...} 
     113    public Person getHasParent() {...} 
     114} 
     115}}} 
     116 
     117The classes may get more complicated later, and the implementation is still missing, but for the moment that should do to get the picture... Besides the structure (the public getters and putters) are more important than the concrete implementation. 
     118 
     119Using RDF Import (rdf2java API), you can transform the RDF data above into two Java objects, i.e., instances of the class Person. These instances will be created using Java's reflection API, so, they are created during run-time. After creation, both will be initialized calling the public method putName, and for one of them the method putHasParent will be called, too. This will result in two Java objects, one for "Bart" and one for "Homer". Additionally, the Bart-object links to the Homer-object. 
     120 
     121There is of course a bit more salt in the objects, e.g., Person does really extend from a class called THING, which in turn extends from a class called RDFResource, but this will be handled later. Just to give you a hint: RDFResource provides getters and putters for the object's URI (unified resource identifier). Hence, calling the method getURI on the Bart-object, you receive http://org.dfki/rdf2java/example1#example1_00005, whereas when you call getURI on the Homer-object, you get http://org.dfki/rdf2java/example1#example1_00006. See the RDF file above to make yourself clear why. 
     122 
     123What you don't see in the example is, that classes can be sub-classes of another class. As RDFS doesn't provide multiple inheritance, rdf2java doesn't support multiple inheritance either. This remark is for people using Protégé-2000 (see below) to generate and work on RDF/S. 
     124 
     125== 1.2  What rdf2java can do == 
     126 
     127Opposed to plain RDF, rdf2java distinguishes between, you could say, "near" and "remote" objects. The reason is as follows: RDF data is just a set of triples (subject, predicate, object), which means, that links to objects are always represented by a triple (object, relation, other-object). As soon as this triple exists, the relation exists, no matter whether the linked resource exists or not, the reference to that resource always does. 
     128 
     129On the Java-side, this is different. Keeping in mind the simple structure of the class Person above, the referenced Java object must be available, to establish the relation. For example, If the Homer-object is not available (there is no no Java-pointer available),  you can not reference the Homer-object, and hence, you can not establish a link (relation) between the two, although there might be such a Homer-object "living" on some other computer or in some other Java-VM (Java virtual machine). 
     130 
     131Therefore, rdf2java distinguishes between the two cases: (1) An object is either available in the current Java-VM, then it is an instance of THING; (2) The object is not available in the current Java-VM, then it is represented by an RDFResource, providing at least the URI of the referenced object. 
     132A THING is an RDFResource, which means, that also THINGS know about their URIs. 
     133 
     134== 1.3  What rdf2java can not do == 
     135 
     136We are using Java objects as representatives for RDF subjects / objects. As such a Java object is an instance of some Java class, Java binds the object's Java pointer forever to this object, and furthermore to its class. Hence, the class of a Java object can never change, which means, that the represented RDF subject can never change it's belonging to a class. But this is different from the plain RDF world, where this is possible. 
     137However, when you know, that an RDF subject will never change it's class, you won't have any problems using rdf2java. 
     138 
     139== 1.4  rdf2java works well with RDFS produced by Protégé-2000 == 
     140RDFS unfortunately lacks some property constraints, such as, specifying whether a property can only contain a single value (only one triple with that predicate allowed), or whether there can be multiple values for that property. 
     141 
     142We are using Protégé-2000 to create our Models / Meta-Models and file out the result as RDF/S. 
     143Protégé-2000 provides some interesing class and property declarations, that we don't want to miss when using rdf2java later on. Therefore rdf2java interpretes some of the Protégé-2000 specific declarations. 
     144 
     145RDF files exported via rdf2java's RDF Export funtionality (Java objects --> RDF data) can, of course, be read in by Protégé-2000. 
     146 
     147Note: rdf2java does not support multiple inheritance (because Java doesn't either). 
     148 
     149If you like, look at some files in the example directory. However, the RDF/S files found there are slightly different than the one's I pasted above. That's because they have been generated using Protégé-2000 and, hence, they contain additional, Protégé-2000 specific modeling. If you have installed Protégé-2000, you can as well open the protege file (example1.pprj) there containing the modeling of the Person class, as well as, the modeling of the two instances for Bart and Homer. 
     150 
     151== 1.5  Online documentation (javadoc) of the rdf2java API == 
     152. . . can be found here XXX. 
     153 
     154== 2. Installation == 
     155rdf2java is a pure java tool, written using Java 2, JDK 1.3.1_02. Hence, I propose to NOT use an older JDK. However, the sources are included, whereas you could try to recompile the tool with whatever JDK you like. If you are using JBuilder 6 (or later), you will even find a project file "rdf2java.jpx", so you can open it directly into the JBuilder IDE and compile it, debug it, whatever... 
     156 
     157Just download rdf2java.zip and extract it to some directory, e.g., C:\java\  (an rdf2java directory will be created there automatically). 
     158 
     159Top-level directories: 
     160doc      : documentation (javadoc) 
     161import   : jar-files needed by rdf2java; these must be included in the CLASSPATH ("java -cp ..."), when using rdf2java. 
     162lib      : jar-file of the rdf2java tool; of course this must be included in the CLASSPATH, as well. 
     163src      : the complete source code 
     164testdata : some test data for examples 
     165 
     166All you need to use rdf2java is to get the CLASSPATH right, whenever starting a Java-VM. You can either set the CLASSPATH environment variable, or specify the classpath temporarily via the "-cp" parameter whenever you call the java interpreter. 
     167 
     168lib/rdf2javaApidoc.jar contains the API documentation (javadoc) in a jar-file. It is much more compact that way and could such be stored better in our CVS repository. 
     169 
     170All tools and elements included in rdf2java are in the package dfki.rdf.util. 
     171 
     172== 3. Create the Java files from a RDFS file == 
     173 
     174If you want to use RDF Import / Export functionality for some RDF data, you need a set of Java classes which correspond exactly to the RDF data, which means, that there must be a Java class for each RDF class instantiated in the RDF data. Furthermore, all relations between RDF subjects / objects must correspond to getter and putter methods in the Java classes. 
     175For example, if there is a triple (a, b, c) in the RDF data (meaning a --b--> c), the Java object for a must provide the methods getB and putB. 
     176 
     177== 3.1  RDFS2Class (dfki.rdf.util.RDFS2Class) == 
     178 
     179If there's an RDFS file available specifying the allowed classes and properties (i.e. relations), you can let rdf2java create the needed corresponding Java classes for you. The tool RDFS2Class, which is part of rdf2java, will generate the source code for theses classes out of a given RDFS file. 
     180 
     181Look up the batch-file testdata/assign/rdfs2class.bat for an example of how to call the RDFS2Class tool. 
     182 
     183Generally, you will have to call RDFS2Class as follows: 
     184 
     185{{{ 
     186java -cp <...CLASSPATH...> dfki.rdf.util.RDFS2Class <...FLAGS...> 
     187                                                    <...RDFS-FILE...> 
     188                                                    <...OUTPUT-SRC-DIR...> 
     189                                                    <...N1...>   <...P1...> 
     190                                                    <...N2...>   <...P2...> 
     191                                                    <...N3...>   <...P3...> 
     192                                                             . . . 
     193}}} 
     194 
     195whereas 
     196 
     197{{{ 
     198FLAGS:    -q: quiet operation, no output 
     199          -s: include toString()-stuff in generated java-files 
     200          -S: include recursive toString()-stuff in generated java-files 
     201              (used instead of -s) 
     202          -o: retain ordering of triples (usage of rdf:Seq in rdf-file) 
     203              by using arrays instead of sets 
     204          -I: insert stuff for incremental file-generation 
     205              (needed for potential later usage of -i) 
     206              ATTENTION: this option completely re-creates java-files and 
     207              erases every user-defined methods and slots,  
     208              maybe you'd better use "-i" ?! 
     209          -i: incremental generation of java-files, i.e. user added slots 
     210              are kept in the re-generated java-files 
     211              (this option includes already -I) 
     212 
     213RDFS-FILE      : the RDFS-file declaring the classes and properties 
     214 
     215OUTPUT-SRC-DIR : generated source files (not class files) go to this directory 
     216 
     217(N1, P1), ...  : pairs of namespaces and package-names; this specifies how to 
     218                 map namespaces to package-names 
     219}}} 
     220 
     221We typically use "-is" as FLAGS, which includes a toString method and allows for editing the Java classes without problems. 
     222 
     223As RDF/S normally uses namespaces to ensure uniqueness of RDF resources all over the world, rdf2java maps the needed namespaces to package-names. This means, that RDFS2Class will create the corresponding directory structure, as well. 
     224 
     225For our small example above, let's assume, you've got an appropriate RDF Schema file in C:\TEMP\example1.rdfs. Then you could call RDFS2Class with the following parameters: 
     226 
     227{{{ 
     228java -cp <...CLASSPATH...> dfki.rdf.util.RDFS2Class 
     229                           -is 
     230                           C:\TEMP\example1.rdfs 
     231                           C:\TEMP\src 
     232                           http://org.dfki/rdf2java/example1# 
     233                                  org.dfki.rdf2java.example1 
     234}}} 
     235 
     236Please note, the last two(!) parameters. We are used to mapping the namespaces to packages with nearly identical names (slashes become dots), but you are not oblighed to do that. You could even map different namespaces to just one package. However, then you could not export (RDF Export) Java objects to RDF data. 
     237 
     238For more information, please look at some files in the example directory. 
     239However, the RDF/S files found there are slightly different than the one's I pasted above. That's because they have been generated using Protégé-2000 and, hence, they contain additional, Protégé-2000 specific modeling. Also the generated Java class org.dfki.rdf2java.example1.Person is a bit more complex than the structure snipped above, but after having a look at it, you should roughly get the picture. Besides, although you can, you won't look into these classes very often. They are structures for keeping and representing some RDF data. In most cases, you will do nothing more than just call the getters and putters of these objects. 
     240 
     2414. RDF Import / Export (RDF data <--> Java instances) 
     242Look at SimpleImportExport.java to get an understanding of how the import / export works. 
     243For a better understanding I pasted an extract of the most important parts of the code below (marginal stuff like, e.g., exception handling has been removed): 
     244 
     245{{{ 
     246import dfki.rdf.util.RDFImport; 
     247import dfki.rdf.util.RDFExport; 
     248 
     249import org.dfki.rdf2java.example1.Person; 
     250 
     251public class SimpleImportExport 
     252{ 
     253    public static void main( String[] args ) 
     254    { 
     255        final String NAMESPACE_1 = "http://org.dfki/rdf2java/example1#"; 
     256        final String PACKAGE_1   = "org.dfki.rdf2java.example1"; 
     257 
     258        Map mapNamespace2Package = new HashMap(); 
     259        mapNamespace2Package.put( NAMESPACE_1, PACKAGE_1 ); 
     260        RDFImport rdfImport = new RDFImport( mapNamespace2Package ); 
     261 
     262        // 1. import from RDF file "example1.rdf" 
     263        Map mapObjects = rdfImport.importObjects( "testdata/example/example1.rdf" ); 
     264        printout( mapObjects ); 
     265 
     266        // 2. make some changes (or additions) 
     267        //    e.g. add an object for "Lisa Simpson" 
     268        final String NAMESPACE_FOR_NEW_INSTANCES = NAMESPACE_1; 
     269        Person lisa = new Person(); 
     270        lisa.makeNewURI( NAMESPACE_FOR_NEW_INSTANCES ); 
     271        lisa.putName( "Lisa Simpson" ); 
     272        // get object for "Homer"; you must know Homer's URI: "http://...#example1_00006 
     273        Person homer = (Person)mapObjects.get( "http://org.dfki/rdf2java/example1#example1_00006" ); 
     274        lisa.putHasParent( homer ); 
     275        // add lisa object to mapObjects (so she can be exported in step 3 below) 
     276        mapObjects.put( lisa.getURI(), lisa ); 
     277        System.out.println( "\n\n----------\nadded lisa\n----------\n" ); 
     278        printout( mapObjects ); 
     279 
     280        // 3. export to RDF file "example1_lisa.rdf" 
     281        Map mapPackage2Namespace = new HashMap(); 
     282        mapPackage2Namespace.put( PACKAGE_1, NAMESPACE_1 ); 
     283        RDFExport rdfExport = new RDFExport( NAMESPACE_FOR_NEW_INSTANCES, mapPackage2Namespace ); 
     284        rdfExport.exportObjects( mapObjects.values(), "testdata/example/example1_lisa.rdf" ); 
     285    } 
     286 
     287    public static void printout( Map mapObjects ) 
     288    { 
     289        for( Iterator it = mapObjects.keySet().iterator(); it.hasNext(); ) 
     290        { 
     291            String sURI = (String)it.next(); 
     292            Object obj = mapObjects.get( sURI ); 
     293            System.out.println( "\n########## " + sURI + " ##########\n" + obj ); 
     294        } 
     295    } 
     296} 
     297}}} 
     298 
     299 
     300== 5. Knowledge Base (dfki.rdf.util.KnowledgeBase) == 
     301 
     302The !KnowledgeBase class stores and maintains Java objects (representing some RDF data). At first sight, it provides hardly more than a simple data storage class.  You could as well do fine with some java.util.Collection. However, the stored Java objects shall represent RDF data, which unfortunately delivers some problems. RDF (Resource Description Framework) is designed to talk about things (resources) with the explicit intention to talk about resources far away, think of all the distributed documents (e.g. web pages) around the world. You can put statements in one document describing another document somewhere else on the planet. 
     303 
     304As already mentioned before (see 1.2  What rdf2java can do), rdf2java distinguishes between the two cases: (1) An object is either available in the current Java-VM, then it is an instance of THING; (2) The object is not available in the current Java-VM, then it is represented by an RDFResource, providing at least the URI of the referenced object. 
     305A THING is an RDFResource, which means, that also THINGS know about their URIs. 
     306 
     307When importing RDF data, you get a set of Java objects. Some of them will maintain links to others, some of  them will link to resources not available by Java objects. In the latter case, such a Java object links to an RDFResource. 
     308 
     309Now assume, you have imported some RDF data and, hence, you have some Java objects representing this RDF data. When you, later on, want to import another RDF, which has relationships to the RDF you have imported earlier, then you have to take care using all these Java objects. In plain RDF, being hardly more than a set of triples (subject, predicate, object), you just have to add more triples and you're done. In the Java world, however, you've got the distinction between THINGS and RDFResources. When you import new RDF and hence get new Java objects, you have make sure, that all RDFResources pointing to you new Java object are converted to direct Java pointers to the new Java object. 
     310But it's even worse: Assume having independently imported two RDF files, meaning you have got two different collections of Java objects. Big problems arise as soon as you try to merge these two. 
     311You may say, this problem can be avoided. But think about distributed scenarios, think about agents sending RDF data among themselfs (in our research project FRODO our agents do that). What happens very often is, that agents are sending updates of their data, being RDF data. When using Java objects representating this RDF, you come to the point, where you have to assert new RDF data to old RDF data. 
     312 
     313The !KnowledgeBase class solves this problem by providing methods for such assertions. As an assertion of an object works on an older version of the same object, these methods have been named assign instead of assert, but maybe we should change this...? 
     314 
     315Now, let's come to the semantics of this assign "operator". 
     316Assume you have got some objects {ai} in the knowledge base and want to assign {bj}. Then, first of all, this is identical to an iterative assignment of  all bj individually. The assignment  {ai} <- bj  works according to the following rules: 
     317 
     318 * 1. case: there is an ak with ak.getURI() = bj.getURI():[[BR]]This more or less means: bj is already in the knowledge base (that's ak), but, the bj assigned can contain other values and/or links.[[BR]]Therefore ak stays in the knowledge base, but all it's properties are getting updated. Assume, ak has got properties p1(ak),...,pn(ak)with values v1(ak),...,vn(ak);analogously bj has values v1(bj),...,vn(bj),then proceed for all m=1,...,n in the following way: 
     319   * case 1.a: pm is a single value slot: vm(ak) <- vm(bj), i.e., take the newer value (this may be even no value, which empties the property). 
     320   * case 1.b: pm is a multiple value slot and the values are strings (literals): just take all the values from vm(bj), because that are the new ones. 
     321   * case 1.c: pm is a multiple value slot and the values are links to resources (other objects): this is the most interesting case...[[BR]]First of all, all values in vm(ak) not contained in vm(bj) are removed. Then, for the rest of the values (i.e. values contained in both) check: 
     322     * IF both, vm(ak) and vm(bj) are THINGS, THEN assign vm(ak) <- vm(bj); this leads to a recursion, so, the assignment is a quite inefficient procedure! 
     323     * OTHERWISE just take out vm(ak) and take in vm(bj). Exactly this "take in" and "take out" has (by now) one great disadvantage: It may ruin the order of the multiple values. For normal RDF this causes no trouble, as there is no specification about the order of the triples, but as soon as one uses ordering stuff like rdf:seq, there's problems ahead! Although rdf2java supports ordering of multiple values, we aren't using this, because it's quite against the idea of RDF. If we need ordering, we model it explicitly through explicit structures. 
     324   * 2. case: there exists no such k with ak.getURI() = bj.getURI():[[BR]]This is, of course, the easiest case: As bj is just a new object, we put it into the knowledge base and we're done. 
     325 
     326After this assignment procedure, there's a second pass done, which updates values being only references (RDFResource), although a THING is now available. These RDFResource values are then converted to Java pointers pointing to the respective THING. This is done by method updateRDFResourceSlots, which is automatically called in the assign method (in the KnowledgeBase class). 
     327 
     328'''Examples''' 
     329 
     330We change the old example slightly, as the old example lacks interesting cases. Therefore, we add an a inverse property to hasParent, namely hasChild. Furthermore we have to add the inverse values for this slot, as this isn't done automatically. The result is example2.* in the example directory. 
     331 
     332Assume, our knowledge base contains Java objects corresponding to RDF data declaring Bart and Homer Simpson and their relationships to each other (properties hasParent and hasChild). The RDF graph for this is shown on the left image after this paragraph (namespaces have been abreviated). 
     333Assume further we want to assign a new object for Lisa Simpson plus relevant relationships to this knowledge base. You see the graphical representation of the RDF data to assign on the right image below. We will see below, the assignment won't lead to the result you might expect. Later we will show the correct RDF data to assign... 
     334 
     335         <-  
     336 
     337XXX image missing  
     338 
     339         
     340the knowledge base so far 
     341         
     342        RDF data to assign to the knowledge base 
     343 
     344When looking at these pictures, keep in mind, that they are nothing more than the graphical representation of RDF triples; boxes represent RDF resources, ellipses represent literals (strings). Via rdf2java, resources (boxes) for instances of RDFS classes are represented by corresponding Java objects in the knowledge base, and outgoing edges are stored in these Java objects and are available via getter methods. 
     345 
     346Hence, before the assignment, the knowledge base (left pictures) contains two Java objects: one for Bart (example1:example1_00005) and one for Homer (example1:example1_00006). Furthermore, both objects store the respective value for the name property. Finally the Bart object stores a link to the Homer object for the hasParent property, and the Homer object stores the inverse link for the hasChild property, respectively. Note, that there's no object for example1:Person as this is a class and no instance. 
     347 
     348Analogously, the RDF data to assign (right image above) will be represented (e.g. after RDF Import) by two objects, one for Lisa's resource plus outgoing edges (properties name and hasParent) and one for Homer's resource plus outgoing edges (property hasChild). Note, that this Homer object is neither the same object as the one in the knowledge base, nor has it identical values; That Homer object, e.g., doesn't have a value for the name property, whereas the Homer object in the knowledge base has. 
     349 
     350When assigning the RDF data (right image above), both of the two objects (Lisa and Homer) have to be assigned. The assignment will take place in two steps (see above): (1) the main assignment procedure, (2) updating all the property values linking to an RDFResource, which after the assignment is available as a THING. 
     351The first step of assigning Lisa's object is easy, as it doesn't yet exist in the knowledge base. Therefore, the object will bluntly be added (including inthere all information about outgoing edges) to the knowledge base. 
     352Assigning the Homer object, or to be more precise: the RDF data stored in the Homer object, is a bit more complicated. First of all, there exists already a Homer object in the knowledge base. Hence, the object can not be simply added, but must be assigned to the already existing one. Therefore, all Homer properties have to be examined. 
     353name: left-side Homer stores a value, right-side Homer doesn't. Possible interpretation: right-side lacks (leaves out) this information? No! Our interpretation is: the right-side Homer is the newer one and contains all new data. Hence, the value for the name property will be deleted on the left-side Homer object. 
     354hasChild: both Homer objects have different (disjoint) values for that property, so we take the new ones, i.e., the ones at the right side. 
     355The result (knowledge base) is as follows: 
     356 
     357 
     358 
     359The result is not quite the one, you might have expected when I started this example. There are several mistakes: The Bart object forgot about his name. Then it still "knows" about his parent, but the Homer object doesn't reflect this relationship. As RDF/S doesn't know anything about inverse slots, this is this correct RDF. Finally it's not quite what we wanted to receive. The problem arose right at the beginning, where we specified, what RDF data to assign to the knowledge base. Let's make another assignment: 
     360 
     361         <-  
     362 
     363  
     364 
     365         
     366the knowledge base so far 
     367         
     368        RDF data to assign to the knowledge base 
     369 
     370Note, that example1:example1_00005 (on the right image) will only be represented by an RDFResource object, because the right-side Homer object just needs to links to a reference of this resource. There's no need to know about about or change this resource. The Homer object has to be changed because of the hasChild property. Hence, we need to represent that by a THING object and add / change the property values we like. 
     371However, the result of this assignment will be as follows: 
     372 
     373 
     374 
     375== 6. Additional Stuff == 
     376In addition to really needed stuff like, e.g., the KnowledgeBase class, other useful tools emerged naturally. 
     377 
     378== 6.1  RDF Diff (dfki.rdf.util.RDFDiff) == 
     379 
     380You often come to the point where to would like to test the difference between two RDF files. In contrast to XML, we don't have to come up with philosophical questions about equality of RDF things, because (1) we've got only triples here, the correspondation to some RDFS is the only constraint to the triples; (2) each resource you want to talk about, i.e, each RDF subject oder object has a unique resource identificator (URI). Hence, equality can be reduced to the triple level. 
     381Therefore, the difference between two RDF files is just the set difference of both triple sets. 
     382 
     383A call to "RDFDiff <abc.rdf> <xyz.rdf>" will result in two additional files: 
     384the newly created file abc.rdf.diff.rdf will contain all statements of abc.rdf minus the ones in xyz.rdf. Analogously, a file xyz.rdf.diff.rdf is created, too. 
     385 
     386== 6.2  RDF Nice (dfki.rdf.util.RDFNice) == 
     387 
     388Despite the fact, that RDF is generally nothing but a graph, typical RDF data often has hierarchical structure(s). 
     389And as the typical form of serialization of RDF is XML, which explicitly provides hierarchy, it is just a pity, that we aren't using the hierarchical presentation althought it's useful. Well, the reason for this is, of course, that you can't ever present RDF hierarchical, generally. But: In non-general, say, typical, scenarios, your RDF is nearly always structured hierarchically to the max. That's why I wrote this small tool. 
     390 
     391The idea behind RDF Nice is to give the XML serializer some hints about which predicate is a hierarchy-driving relation. You do this by assigning some predicates positive or negative numbers. If you assign a positive number to a predicate, this will indicate, that following this predicate will go DOWN the hierarchy; negative numbers indicate, that following the predicate is UP the hierarchy. You can prioritize these UP/DOWN indications by using higher numbers (+100 is stronger than +1, -10 is also stronger than +1, but weaker than +100). At the moment, you have to cope with integer numbers, a lexical ordering would, of course, be better... Note, that -10 is only ten times stronger than +1, which means, that eleven predicate of type +1 outperform one of  type -10! 
     392 
     393So, what's happening with all that numbers? 
     394 
     395 * First of all, RDF Nice puts all RDF subjects in a bag. Iteratively, subjects are being drawn out of this bag and are attached to some XML branch. 
     396 * Every time, a subject has to be chosen, to be taken out of the bag, RDF Nice calculates for each residuary subject a value. This value results from summing the values of all outgoing predicates plus the negative(!) sum of all incoming predicates. Then the subject with the highest value is taken. 
     397 * After the XML element has been created, the outgoing predicates together with the objects, these predicates are pointing to, are attached below the subject node. The ordering of these predicates will be according to there value, i.e., the predicate with the highest value will be the first child of the subject node. 
     398 * Whenever a predicate points to some subject still in the bag, the algorithm will go into recursion and that way create the hierarchical presentation. If the predicate points to some subject not in the bag, this means, either that subject is not part of the RDF data, or that subject has already attached elsewhere on the XML tree. Anyhow, in that case, the subject is not serialized again, but just referenced in the RDF typical manner. 
     399 
     400Whatever values you assign to predicates, the resulting RDF will always stay the same, just the presentation changes. However, I wouldn't swear to RDF Diff being bug-less. ;-) 
     401 
     402Call RDF Diff the following way to get a "nice" version of the RDF file for our small "Person" example: 
     403 
     404{{{ 
     405java -cp <...CLASSPATH...> dfki.rdf.util.RDFNice 
     406                           C:\TEMP\example1.rdf 
     407                           http://org.dfki/rdf2java/example1#hasParent -1000 
     408                           http://org.dfki/rdf2java/example1#name      1 
     409}}} 
     410 
     411So, the first parameter is the RDF file, followed by arbitrarily many pairs(!) of parameters, namely one for the predicate (the whole URI, not only the local name), and one for the value you want to assign to that predicate. RDF Nice produces another file (so no original RDF file will be harmed) with the same path and filename plus postfix ".nice.rdf", i.e., "example1.rdf.nice.rdf" in our example. 
     412Doing this, you get the following RDF, which is not quite impresing, but that's because the simple "Person" example is a bad one. The only hierarchical relation is pointing into the wrong direction, namely upwards, but XML serialization is always about the other direction, namely downwards. 
     413Note, that the predicate name comes before hasParent, because its value is greater (greater, not stronger!). 
     414 
     415{{{ 
     416<?xml version='1.0' encoding='ISO-8859-1'?> 
     417<!DOCTYPE rdf:RDF [ 
     418    <!ENTITY example1 'http://org.dfki/rdf2java/example1#'> 
     419    <!ENTITY rdf 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'> 
     420    <!ENTITY rdfs 'http://www.w3.org/TR/1999/PR-rdf-schema-19990303#'> 
     421 
     422]> 
     423<rdf:RDF  
     424    xmlns:example1="&example1;" 
     425    xmlns:rdf="&rdf;" 
     426    xmlns:rdfs="&rdfs;"> 
     427 
     428    <example1:Person  rdf:about="&example1;example1_00006" 
     429         example1:name="Homer Simpson"/> 
     430    <example1:Person  rdf:about="&example1;example1_00005" 
     431         example1:name="Bart Simpson"> 
     432        <example1:hasParent  rdf:resource="&example1;example1_00006"/> 
     433    </example1:Person> 
     434</rdf:RDF> 
     435}}} 
     436 
     437To get a better picture of RDF Nice, we switch to example2.* in the example directory. To rememver, we added a new property to the RDF Schema: the property hasChild being the inverse property to hasParent. Changing the call to RDF Nice (see rdfnice.bat) taking into account the new property (hasChildis assigned the negative value of hasParent: +1000), we receive the following XML serialization for example2_lisa.rdf (including Lisa): 
     438 
     439{{{ 
     440<?xml version='1.0' encoding='ISO-8859-1'?> 
     441<!DOCTYPE rdf:RDF [ 
     442    <!ENTITY example1 'http://org.dfki/rdf2java/example1#'> 
     443    <!ENTITY rdf 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'> 
     444    <!ENTITY rdfs 'http://www.w3.org/TR/1999/PR-rdf-schema-19990303#'> 
     445 
     446]> 
     447<rdf:RDF  
     448    xmlns:example1="&example1;" 
     449    xmlns:rdf="&rdf;" 
     450    xmlns:rdfs="&rdfs;"> 
     451 
     452    <example1:Person  rdf:about="&example1;example1_00006" 
     453         example1:name="Homer Simpson"> 
     454        <example1:hasChild> 
     455            <example1:Person  rdf:about="&example1;example1_00005" 
     456                 example1:name="Bart Simpson"> 
     457                <example1:hasParent  rdf:resource="&example1;example1_00006"/> 
     458            </example1:Person> 
     459        </example1:hasChild> 
     460        <example1:hasChild> 
     461            <example1:Person  rdf:about="&example1;example2_00007" 
     462                 example1:name="Lisa Simpson"> 
     463                <example1:hasParent  rdf:resource="&example1;example1_00006"/> 
     464            </example1:Person> 
     465        </example1:hasChild> 
     466    </example1:Person> 
     467</rdf:RDF> 
     468}}} 
     469 
     470== 6.3  RDF Dump (dfki.rdf.util.RDFDump) == 
     471Nothing much to say about this tool. It just load in an RDF file and dumps out the triples to System.out. The triples are output in pure ASCII and follow the following format: subject \t predicate \t object \n. So, TAB and NEWLINE are the delimiters; there's no SPACE, no bracket, no comma, nor anything else. 
     472Look and edit the Java code if you're longing for more... 
     473 
     474== The End == 
    38475 
    39476For a complete list of local wiki pages, see TitleIndex. 
    40  
    41 Trac is brought to you by [http://www.edgewall.com/ Edgewall Software], 
    42 providing professional Linux and software development services to clients 
    43 worldwide. Visit http://www.edgewall.com/ for more information. 
    44