Index: doc/api/.cvsignore
===================================================================
RCS file: /cvsroot/cashew-s-editor/cashews/doc/api/.cvsignore,v
retrieving revision 1.1.1.1
diff -u -3 -p -u -r1.1.1.1 .cvsignore
--- doc/api/.cvsignore 31 Jan 2005 04:02:18 -0000 1.1.1.1
+++ doc/api/.cvsignore 18 Apr 2005 00:45:44 -0000
@@ -1,2 +1,4 @@
Makefile
Makefile.in
+create_html
+html
Index: lib/.cvsignore
===================================================================
RCS file: /cvsroot/cashew-s-editor/cashews/lib/.cvsignore,v
retrieving revision 1.2
diff -u -3 -p -u -r1.2 .cvsignore
--- lib/.cvsignore 28 Mar 2005 19:29:21 -0000 1.2
+++ lib/.cvsignore 18 Apr 2005 00:45:44 -0000
@@ -5,6 +5,8 @@ classes
eclipse.jar
owls.jar
rdf.jar
+commons.jar
+xml.jar
deps.sh
gen-classlist.sh
mkdep.pl
Index: src/nongnu/cashews/commons/Pair.java
===================================================================
RCS file: /cvsroot/cashew-s-editor/cashews/src/nongnu/cashews/commons/Pair.java,v
retrieving revision 1.3
diff -u -3 -p -u -r1.3 Pair.java
--- src/nongnu/cashews/commons/Pair.java 17 Apr 2005 18:35:32 -0000 1.3
+++ src/nongnu/cashews/commons/Pair.java 18 Apr 2005 00:45:44 -0000
@@ -132,9 +132,7 @@ public class Pair
*/
public int hashCode()
{
- return super.hashCode()
- + 13 * left.hashCode()
- + 17 * right.hashCode();
+ return 13 * left.hashCode() + 17 * right.hashCode();
}
/**
Index: src/nongnu/cashews/commons/PairStack.java
===================================================================
RCS file: src/nongnu/cashews/commons/PairStack.java
diff -N src/nongnu/cashews/commons/PairStack.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/nongnu/cashews/commons/PairStack.java 18 Apr 2005 00:45:44 -0000
@@ -0,0 +1,100 @@
+/* PairStack.java -- A stack of heterogenous pairs.
+ Copyright (C) 2005 The University of Sheffield.
+
+ This file is part of the CASheW-s editor.
+
+ The CASheW-s editor is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ The CASheW-s editor is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with The CASheW-s editor; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA.
+*/
+
+package nongnu.cashews.commons;
+
+import java.util.Stack;
+
+/**
+ * A stack of heterogenous pairs.
+ *
+ * @author Andrew John Hughes (address@hidden)
+ * @see java.util.Stack
+ */
+public class PairStack
+ extends Stack>
+{
+
+ /**
+ * Serialization ID.
+ */
+ private static final long serialVersionUID = 4077300638060255809L;
+
+ /**
+ * Constructs an empty PairStack
.
+ */
+ public PairStack()
+ {
+ super();
+ }
+
+ /**
+ * Returns the pair at the top of the stack, without removing it.
+ *
+ * @return the pair at the top of the stack.
+ */
+ public Pair peek()
+ {
+ return super.peek();
+ }
+
+ /**
+ * Pops the pair at the top of the stack, and returns it.
+ *
+ * @return the pair at the top of the stack. The top of the stack is
+ * now the item below that returned.
+ */
+ public Pair pop()
+ {
+ return super.pop();
+ }
+
+ /**
+ * Pushes the supplied value onto the top of the stack. The value
+ * is a pair composed of the two supplied values.
+ *
+ * @param left the left-hand value of the pair.
+ * @param right the right-hand value of the pair.
+ * @return the pair that was added.
+ */
+ public Pair push(A left, B right)
+ {
+ return super.push(new Pair(left,right));
+ }
+
+ /**
+ * Returns the distance of the supplied value from the top of the stack,
+ * or -1 if the value is not on the stack. 1 represents the top item
+ * on the stack. The value used is a pair composed
+ * of the two supplied values. Values are compared using the equality
+ * test of the pair.
+ *
+ * @param left the left-hand value of the pair.
+ * @param right the right-hand value of the pair.
+ * @return the index of the pair of values on the stack, or -1 if the
+ * pair isn't present.
+ */
+ public int search(A left, B right)
+ {
+ return super.search(new Pair(left,right));
+ }
+
+}
Index: src/nongnu/cashews/rdf/RDFHandler.java
===================================================================
RCS file: /cvsroot/cashew-s-editor/cashews/src/nongnu/cashews/rdf/RDFHandler.java,v
retrieving revision 1.1
diff -u -3 -p -u -r1.1 RDFHandler.java
--- src/nongnu/cashews/rdf/RDFHandler.java 17 Apr 2005 18:35:32 -0000 1.1
+++ src/nongnu/cashews/rdf/RDFHandler.java 18 Apr 2005 00:45:44 -0000
@@ -23,11 +23,16 @@ package nongnu.cashews.rdf;
import java.net.URI;
import java.net.URISyntaxException;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
import java.util.logging.Handler;
import java.util.logging.Logger;
+import nongnu.cashews.commons.Pair;
import nongnu.cashews.commons.PairMap;
import nongnu.cashews.commons.PairSet;
+import nongnu.cashews.commons.PairStack;
import nongnu.cashews.xml.XmlBaseHandler;
import org.xml.sax.Attributes;
@@ -109,6 +114,11 @@ public class RDFHandler
private RDFObject object;
/**
+ * The String form of the URI of the current subject.
+ */
+ private String subjectURI;
+
+ /**
* The String form of the URI of the current predicate.
*/
private String predicateURI;
@@ -123,7 +133,19 @@ public class RDFHandler
* within a particular base URI.
*/
private PairSet ids;
-
+
+ /**
+ * The stack of current subject and predicate pairs. This allows
+ * us to handle nested triples, where the object of one triple
+ * is the triple nested inside that triple.
+ */
+ private PairStack currentState;
+
+ /**
+ * The set of blank node IDs.
+ */
+ private Set nodeIDs;
+
/**
* Constructs a new RDFHandler
, using the specified
* handler for log messages.
@@ -155,6 +177,9 @@ public class RDFHandler
object = null;
ids = new PairSet();
graph = new Graph();
+ subjectURI = null;
+ currentState = new PairStack();
+ nodeIDs = new HashSet();
}
/**
@@ -235,7 +260,9 @@ public class RDFHandler
{
/* Abbreviation of typed rdf:Description */
parseAttributes(attributes);
- setSubjectType(uri + localName);
+ subjectURI = uri + localName;
+ rdfLogger.finer("Start of subject with type: " + subjectURI);
+ setSubjectType(subjectURI);
}
}
}
@@ -311,10 +338,7 @@ public class RDFHandler
rdfLogger.finer("End of RDF block");
}
else if (localName.equals("Description"))
- {
- rdfLogger.finer("End of description block");
- inSubject = false;
- }
+ endSubject();
}
else if (inPredicate && predicateURI.equals(uri + localName))
{
@@ -327,6 +351,8 @@ public class RDFHandler
graph.addTriple(triple);
rdfLogger.finer("End of predicate block");
}
+ else if (inSubject && subjectURI.equals(uri + localName))
+ endSubject();
}
/**
@@ -355,6 +381,7 @@ public class RDFHandler
for (int a = 0; a < attributes.getLength(); ++a)
attribs.put(attributes.getURI(a), attributes.getLocalName(a),
attributes.getValue(a));
+ rdfLogger.finer("Attributes: " + attribs);
handleAttributes(attribs);
}
@@ -367,27 +394,52 @@ public class RDFHandler
protected void handleAttributes(PairMap attributes)
throws SAXException
{
+ if (inPredicate)
+ {
+ /* A nested triple */
+ rdfLogger.finer("Left state: " +
+ currentState.push(subject,predicate));
+ inPredicate = false;
+ subject = null;
+ predicate = null;
+ }
/* Check for RDF URI subject */
String value = attributes.get(RDF_NAMESPACE, "about");
if (value != null)
- subject = parseRDFURI(value);
+ {
+ subject = parseRDFURI(value);
+ attributes.remove(RDF_NAMESPACE, "about");
+ }
else
{
value = attributes.get(RDF_NAMESPACE, "ID");
if (value != null)
{
+ attributes.remove(RDF_NAMESPACE, "ID");
boolean added =
ids.add(getBaseURI(), value);
if (added)
subject = new
RDFURI(getBaseURI().resolve("#" + value));
+ else
+ rdfLogger.severe("Duplicate node ID: "
+ + getBaseURI().resolve("#" + value));
}
else
{
/* Check for blank node subject */
value = attributes.get(RDF_NAMESPACE, "nodeID");
if (value != null)
- subject = new Blank(value);
+ {
+ attributes.remove(RDF_NAMESPACE, "nodeID");
+ boolean added = nodeIDs.add(value);
+ if (added)
+ subject = new Blank(value);
+ else
+ rdfLogger.severe("Duplicate blank node ID: " + value);
+ }
+ else
+ subject = new Blank(generateBlankID());
}
}
if (subject == null)
@@ -398,8 +450,24 @@ public class RDFHandler
inSubject = true;
rdfLogger.fine("Created subject: " + subject);
}
+ /* Handle any remaining attributes as property attributes */
+ for (Map.Entry,String> entry : attributes.entrySet())
+ {
+ Pair key = entry.getKey();
+ triple = new Triple(subject,
+ parseRDFURI(key.getLeft() + key.getRight()),
+ new Literal(entry.getValue()));
+ rdfLogger.fine("Created triple using property attribute: " + triple);
+ graph.addTriple(triple);
+ }
}
+ /**
+ * Sets the type of the subject node to the value
+ * parsed from the supplied string.
+ *
+ * @param value the value to parse.
+ */
private void setSubjectType(String value)
{
if (value != null && subject instanceof Node)
@@ -410,4 +478,54 @@ public class RDFHandler
}
}
+ /**
+ * Generate an ID for a blank node.
+ *
+ * @return a blank node ID.
+ */
+ private String generateBlankID()
+ {
+ boolean added = false;
+ String randomID;
+ do
+ {
+ randomID = Long.toString(Math.round(Math.random() * Long.MAX_VALUE));
+ added = nodeIDs.add(randomID);
+ } while (!added);
+ return randomID;
+ }
+
+ /**
+ * Handle the end of a subject node, including one that is
+ * nested inside another. Subject nodes take two forms, so
+ * it becomes necessary to have common handling for these.
+ */
+ private void endSubject()
+ {
+ inSubject = false;
+ subjectURI = null;
+ predicateURI = null;
+ if (currentState.empty())
+ subject = null;
+ else
+ {
+ /* Closure of nested triple; return to previous state */
+ object = (RDFObject) subject;
+ Pair previous = currentState.pop();
+ rdfLogger.finer("New state: " + previous);
+ subject = previous.getLeft();
+ predicate = previous.getRight();
+ if (subject instanceof Node)
+ {
+ URI subjectType = ((Node) subject).getType();
+ if (subjectType != null)
+ subjectURI = subjectType.toString();
+ }
+ if (predicate instanceof RDFURI)
+ predicateURI = ((RDFURI) predicate).getURI().toString();
+ inPredicate = true;
+ }
+ rdfLogger.finer("End of subject block");
+ }
+
}
Index: src/nongnu/cashews/rdf/XMLParser.java
===================================================================
RCS file: /cvsroot/cashew-s-editor/cashews/src/nongnu/cashews/rdf/XMLParser.java,v
retrieving revision 1.9
diff -u -3 -p -u -r1.9 XMLParser.java
--- src/nongnu/cashews/rdf/XMLParser.java 17 Apr 2005 18:35:32 -0000 1.9
+++ src/nongnu/cashews/rdf/XMLParser.java 18 Apr 2005 00:45:44 -0000
@@ -21,8 +21,6 @@
package nongnu.cashews.rdf;
-import java.io.File;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.logging.ConsoleHandler;
import java.util.logging.Handler;
@@ -74,18 +72,16 @@ public class XMLParser
* @throws SAXException if a XMLReader
can't be obtained
* or an error occurs during parsing.
* @throws IOException if an error occurs in the underlying input.
- * @throws FileNotFoundException if one of the specified files can't
- * be found.
*/
public static void main(String[] args)
- throws SAXException, IOException, FileNotFoundException
+ throws SAXException, IOException
{
Handler handler = new ConsoleHandler();
handler.setLevel(Level.FINE);
XMLParser parser = new XMLParser(handler);
for (int a = 0; a < args.length; ++a)
{
- parser.parse(new File(args[a]));
+ parser.parse(args[a]);
System.out.println(parser.getRDFHandler().getGraph());
}
}
Index: src/nongnu/cashews/xml/Parser.java
===================================================================
RCS file: /cvsroot/cashew-s-editor/cashews/src/nongnu/cashews/xml/Parser.java,v
retrieving revision 1.1
diff -u -3 -p -u -r1.1 Parser.java
--- src/nongnu/cashews/xml/Parser.java 17 Apr 2005 18:35:32 -0000 1.1
+++ src/nongnu/cashews/xml/Parser.java 18 Apr 2005 00:45:44 -0000
@@ -22,7 +22,6 @@
package nongnu.cashews.xml;
import java.io.File;
-import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.logging.ConsoleHandler;
@@ -125,7 +124,7 @@ public class Parser
public void parse(File file)
throws IOException, SAXException
{
- parse(new InputSource(new FileInputStream(file)));
+ parse(file.toURI().toString());
}
/**
@@ -156,7 +155,7 @@ public class Parser
handler.setLevel(Level.FINE);
Parser parser = new Parser(handler);
for (int a = 0; a < args.length; ++a)
- parser.parse(new File(args[a]));
+ parser.parse(args[a]);
}
}