Annotation of java/classes/org/w3c/rdf/SiRPAC.java, revision 1.10
1.1 jsaarela 1: /**
2: * SiRPAC - Simple RDF Parser & Compiler
3: * Copyright © World Wide Web Consortium, (Massachusetts Institute of Technology,
4: * Institut National de Recherche en Informatique et en Automatique, Keio University).
5: * All Rights Reserved.
6: * Please see the full Copyright clause at <http://www.w3.org/COPYRIGHT.html>
7: *
8: * This program translates RDF descriptions into triple representation
9: * This version is suitable for embedded use as well as command line use
10: *
11: * This version uses SAX V1.0 available at <http://www.microstar.com/XML/SAX/>
12: *
1.4 jsaarela 13: * $Log: SiRPAC.java,v $
1.10 ! jsaarela 14: * Revision 1.9 1998/08/28 10:03:25 jsaarela
! 15: * Distribution release 1.3 on 28-Aug-98.
! 16: *
1.9 jsaarela 17: * Revision 1.8 1998/08/19 13:18:13 jsaarela
18: * Compatibility with RDF M&S -19980819 and Namespaces in XML -19980820
19: *
1.8 jsaarela 20: * Revision 1.7 1998/08/12 15:12:48 jsaarela
21: * Updated namespace management to correspond with the
22: * Namespaces in XML specification dated 2-Aug-98.
23: *
1.7 jsaarela 24: * Revision 1.6 1998/07/31 09:42:27 jsaarela
25: * Error reporting improved.
26: * This is distribution V1.1
27: *
1.6 jsaarela 28: * Revision 1.5 1998/07/30 13:39:45 jsaarela
29: * multiple internal references fixed,
30: * properties without children fixed.
31: *
1.5 jsaarela 32: * Revision 1.4 1998/07/29 08:27:53 jsaarela
33: * Bug fix: processProperty can now correctly determine the target
34: * of the propertyValue. Didn't work with typedNodes.
35: *
1.4 jsaarela 36: * Revision 1.3 1998/07/28 09:40:41 jsaarela
37: * 1st distribution release.
38: *
1.1 jsaarela 39: *
40: * @author Janne Saarela <jsaarela@w3.org>
41: */
42: package org.w3c.rdf;
43:
44: import org.xml.sax.HandlerBase;
45: import org.xml.sax.InputSource;
46: import org.xml.sax.Locator;
47: import org.xml.sax.AttributeList;
48: import org.xml.sax.EntityResolver;
49: import org.xml.sax.DTDHandler;
50: import org.xml.sax.DocumentHandler;
51: import org.xml.sax.ErrorHandler;
52: import org.xml.sax.SAXParseException;
53: import org.xml.sax.Parser;
54: import org.xml.sax.InputSource;
55: import org.xml.sax.SAXException;
56:
57: import org.xml.sax.helpers.*;
58:
59: import java.net.URL;
60: import java.util.*;
61: import java.io.*;
62:
63: public class SiRPAC implements EntityResolver, DTDHandler, DocumentHandler,
1.10 ! jsaarela 64: ErrorHandler {
! 65: final static public String REVISION = "$Id: SiRPAC.java,v 1.9 1998/08/28 10:03:25 jsaarela Exp $";
! 66: public final static String RDFSCHEMA = new String ("http://www.w3.org/TR/WD-rdf-syntax#");
! 67: public final static String XMLSCHEMA = new String ("xml");
! 68:
! 69: private Stack m_namespaceStack = new Stack ();
! 70: private Stack m_elementStack = new Stack ();
! 71: private Element m_root = null;
! 72: private Vector m_triples = new Vector ();
! 73: private String m_sErrorMsg = new String ();
! 74:
! 75: /**
! 76: * Namespace management
! 77: */
! 78: public String namespace (String sPrefix) {
! 79: if (sPrefix == null) {
! 80: sPrefix = new String ("xmlns");
! 81: }
! 82: for (int x = m_namespaceStack.size()-1; x >=0; x--) {
! 83: Hashtable ht = (Hashtable)m_namespaceStack.elementAt (x);
! 84: String sURI = (String)ht.get (sPrefix);
! 85: if (sURI != null)
! 86: return sURI;
! 87: }
! 88: /**
! 89: * Give error only if
! 90: * 1. the prefix is not from the reserved xml namespace
! 91: * 2. the prefix is not xmlns which is to look for the default
! 92: * namespace
! 93: */
! 94: if (sPrefix.equals (XMLSCHEMA)) {
! 95: return XMLSCHEMA;
! 96: } else if (sPrefix.equals ("xmlns")) {
! 97: return "";
! 98: } else {
! 99: addError ("Unresolved namespace prefix "+sPrefix);
! 100: }
! 101: return "";
! 102: }
! 103:
! 104: public static void main (String args[]) throws Exception {
! 105: if (args.length != 1) {
! 106: System.err.println("Usage: java -Dsax.parser=<classname> org.w3c.rdf.SiRPAC <rdf_document>");
! 107: System.err.println ("This is revision "+REVISION);
! 108: System.exit(1);
! 109: }
! 110:
! 111: SiRPAC compiler = null;
! 112: try {
! 113: // Create a new parser.
! 114: Parser p = ParserFactory.makeParser();
! 115:
! 116: // Create a new handler.
! 117: compiler = new SiRPAC();
1.2 jsaarela 118:
1.10 ! jsaarela 119: // Register the handlers
! 120: p.setEntityResolver(compiler);
! 121: p.setDTDHandler (compiler);
! 122: p.setDocumentHandler(compiler);
! 123: p.setErrorHandler (compiler);
1.2 jsaarela 124:
1.10 ! jsaarela 125: FileInputStream input = new FileInputStream(args[0]);
! 126: InputSource source = new InputSource(input);
! 127: source.setSystemId(args[0]);
1.2 jsaarela 128:
1.10 ! jsaarela 129: p.parse(source);
! 130: } catch (SAXException e) {
! 131: if (compiler != null)
! 132: compiler.addError (e.getMessage());
! 133: else
! 134: e.printStackTrace ();
! 135: } catch (Exception e) {
! 136: if (compiler != null)
! 137: compiler.addError ("Internal error "+e);
! 138: else
! 139: e.printStackTrace ();
! 140: }
1.5 jsaarela 141:
1.10 ! jsaarela 142: String sErrors = compiler.errors ();
! 143: if (sErrors != null && sErrors.length() > 0) {
! 144: System.out.println ("Errors during parsing:\n"+sErrors);
! 145: } else {
! 146: compiler.printTriples (System.out);
! 147: }
1.2 jsaarela 148: }
149:
1.10 ! jsaarela 150: public InputSource resolveEntity (String publicId, String systemId) {
! 151: return null;
! 152: }
1.1 jsaarela 153:
1.10 ! jsaarela 154: public void notationDecl (String name, String publicId, String systemId) {
! 155: }
1.7 jsaarela 156:
157: /**
1.10 ! jsaarela 158: * Display unparsed entity declarations as they are reported.
! 159: *
! 160: * @see org.xml.sax.DTDHandler#unparsedEntityDecl
1.7 jsaarela 161: */
1.10 ! jsaarela 162: public void unparsedEntityDecl (String name,
! 163: String publicId,
! 164: String systemId,
! 165: String notationName) {
! 166: }
! 167:
! 168: public void setDocumentLocator (Locator locator) {
! 169: }
1.7 jsaarela 170:
1.10 ! jsaarela 171: public void startDocument () {
! 172: m_sErrorMsg = "";
! 173: }
! 174:
! 175: public void endDocument () throws SAXException {
! 176: processRDF (m_root);
1.1 jsaarela 177: }
178:
1.10 ! jsaarela 179: public void doctype (String name, String publicID, String systemID) {
1.7 jsaarela 180: }
181:
1.10 ! jsaarela 182: public void startElement (String name, AttributeList al) throws SAXException {
! 183: Hashtable namespaces = new Hashtable ();
! 184:
! 185: /**
! 186: * The following loop tries to identify special xmlns prefix
! 187: * attributes and update the namespace stack accordingly.
! 188: * While doing all this, it builds another AttributeList instance
! 189: * which will hold the expanded names of the attributes
! 190: * (I think this approach is only useful for RDF which uses
! 191: * attributes as an abbreviated syntax for element names)
! 192: */
! 193: AttributeListImpl newAL = new AttributeListImpl ();
! 194:
! 195: int iLength = al.getLength ();
! 196: if (iLength == 0) {
! 197: // ohwell, no attributes
! 198: } else for (int x = 0; x < iLength; x++) {
! 199: String aName = al.getName (x);
! 200: if (aName.equals ("xmlns")) {
! 201: String aValue = al.getValue (aName);
! 202: namespaces.put (aName, aValue);
! 203: } else if (aName.startsWith ("xmlns:")) {
! 204: String aValue = al.getValue (aName);
! 205: aName = aName.substring (6);
! 206: namespaces.put (aName, aValue);
! 207: }
! 208: }
! 209: /**
! 210: * Place new namespace declarations into the stack
! 211: * (Yes, I could optimize this a bit, not it wastes space
! 212: * if there are no xmlns definitions)
! 213: */
! 214: m_namespaceStack.push (namespaces);
! 215:
! 216: /**
! 217: * Figure out the prefix part if it exists and
! 218: * determine the namespace of the element accordingly
! 219: */
! 220: String sNamespace = null;
! 221: String sElementName = null;
! 222: Element newElement = null;
! 223: int i = name.indexOf (':');
! 224: if (i > 0) {
! 225: String sPrefix = name.substring (0, i);
! 226: sNamespace = namespace (sPrefix);
! 227: sElementName = name.substring (i+1);
! 228: } else {
! 229: sNamespace = namespace ("xmlns");
! 230: sElementName = name;
! 231: }
! 232:
! 233: /**
! 234: * Finally look for attributes other than the special xmlns,
! 235: * expand them, and place to the new AttributeListImpl
! 236: */
! 237: for (int x = 0; x < iLength; x++) {
! 238: String sAttributeNamespace = null;
! 239: String aName = al.getName (x);
! 240: if (!aName.startsWith ("xmlns")) {
! 241: String aValue = al.getValue (aName);
! 242: String aType = al.getType (aName);
! 243:
! 244: int iIndex = aName.indexOf (':');
! 245: if (iIndex > 0) {
! 246: String sPrefix = aName.substring (0, iIndex);
! 247: sAttributeNamespace = namespace (sPrefix);
! 248: aName = aName.substring (iIndex+1);
! 249: } else {
! 250: if (sNamespace == null)
! 251: sAttributeNamespace = namespace ("xmlns");
! 252: else
! 253: sAttributeNamespace = sNamespace;
! 254: }
! 255: newAL.addAttribute (sAttributeNamespace+aName,
! 256: aType,
! 257: aValue);
! 258: }
! 259: }
! 260:
! 261: newElement = new Element (sNamespace + sElementName,
! 262: newAL);
! 263: checkAttributes (newElement);
! 264:
! 265: /**
! 266: * Update the containment hierarchy
! 267: * with the stack.
! 268: */
! 269: if (!m_elementStack.empty()) {
! 270: Element e = (Element)m_elementStack.peek ();
! 271: e.addChild (newElement);
1.7 jsaarela 272: }
1.10 ! jsaarela 273:
! 274: /**
! 275: * Place the new element into the stack
! 276: */
! 277: m_elementStack.push (newElement);
! 278: }
! 279:
! 280: public void endElement (String name) {
! 281: m_root = (Element)m_elementStack.pop ();
! 282: m_namespaceStack.pop ();
1.7 jsaarela 283: }
284:
1.10 ! jsaarela 285: public void characters (char ch[], int start, int length)
! 286: throws SAXException {
! 287: /**
! 288: * Place all characters as Data instance to the containment
! 289: * hierarchy with the help of the stack.
! 290: */
! 291: Element e = (Element)m_elementStack.peek ();
! 292: String s = new String (ch, start, length+start);
! 293:
! 294: /**
! 295: * Warning: this is not correct procedure according to XML spec.
! 296: * All whitespace matters!
! 297: */
! 298: String sTrimmed = s.trim();
! 299: if (sTrimmed.length() > 0)
! 300: e.addChild (new Data (s));
! 301: }
! 302:
! 303: public void ignorableWhitespace (char ch[], int start, int length) {
! 304: }
! 305:
! 306: public void processingInstruction (String target, String data) {
1.1 jsaarela 307: }
308:
309: /**
1.10 ! jsaarela 310: * Report all warnings, and continue parsing.
! 311: *
! 312: * @see org.xml.sax.ErrorHandler#warning
1.1 jsaarela 313: */
1.10 ! jsaarela 314: public void warning (SAXParseException exception)
! 315: {
! 316: m_sErrorMsg = "Warning: " +
! 317: exception.getMessage() +
! 318: " (" +
! 319: // exception.getSystemId() +
! 320:
! 321: "line <a href=\"#" +
! 322: exception.getLineNumber() +
! 323: "\">" +
! 324: exception.getLineNumber() +
! 325: "</a>, column " +
! 326: exception.getColumnNumber() +
! 327: ")<br>";
! 328: }
1.1 jsaarela 329:
330:
331: /**
1.10 ! jsaarela 332: * Report all recoverable errors, and try to continue parsing.
! 333: *
! 334: * @see org.xml.sax.ErrorHandler#error
1.1 jsaarela 335: */
1.10 ! jsaarela 336: public void error (SAXParseException exception)
! 337: {
! 338: m_sErrorMsg = "Recoverable Error: " +
! 339: exception.getMessage() +
! 340: " (" +
! 341: // exception.getSystemId() +
! 342:
! 343: "line <a href=\"#" +
! 344: exception.getLineNumber() +
! 345: "\">" +
! 346: exception.getLineNumber() +
! 347: "</a>, column " +
! 348: exception.getColumnNumber() +
! 349: ")<br>";
! 350: }
! 351:
1.1 jsaarela 352:
353: /**
1.10 ! jsaarela 354: * Report all fatal errors, and try to continue parsing.
! 355: *
! 356: * <p>Note: results are no longer reliable once a fatal error has
! 357: * been reported.</p>
! 358: *
! 359: * @see org.xml.sax.ErrorHandler#fatalError
1.1 jsaarela 360: */
1.10 ! jsaarela 361: public void fatalError (SAXParseException exception)
! 362: {
! 363: m_sErrorMsg = "Fatal Error: " +
! 364: exception.getMessage() +
! 365: " (" +
! 366: // exception.getSystemId() +
! 367: "line <a href=\"#" +
! 368: exception.getLineNumber() +
! 369: "\">" +
! 370: exception.getLineNumber() +
! 371: "</a>, column " +
! 372: exception.getColumnNumber() +
! 373: ")<br>";
! 374: }
1.1 jsaarela 375:
1.10 ! jsaarela 376: public String errors () {
1.1 jsaarela 377: return m_sErrorMsg;
1.10 ! jsaarela 378: }
1.1 jsaarela 379:
1.10 ! jsaarela 380: public void addError (String sMsg) {
1.2 jsaarela 381: m_sErrorMsg += sMsg;
1.6 jsaarela 382: m_sErrorMsg += "<br>\n";
1.10 ! jsaarela 383: }
1.2 jsaarela 384:
1.10 ! jsaarela 385: public static Parser createParser (String className) {
! 386: Parser parser = null;
! 387:
! 388: try {
! 389: // Get the named class.
! 390: Class c = Class.forName(className);
! 391: // Instantiate the parser.
! 392: parser = (Parser)(c.newInstance());
! 393: } catch (ClassNotFoundException e) {
! 394: System.err.println("SAX parser class " + className +
! 395: "cannot be loaded.");
! 396: System.exit(1);
! 397: } catch (IllegalAccessException e) {
! 398: System.err.println("SAX parser class " + className +
! 399: " does not have a zero-argument constructor.");
! 400: System.exit(1);
! 401: } catch (InstantiationException e) {
! 402: System.err.println("SAX parser class " + className +
! 403: " cannot be instantiated.");
! 404: System.exit(1);
! 405: }
! 406:
! 407: // Check the the parser object
! 408: // actually implements the Parser interface.
! 409: if (!(parser instanceof org.xml.sax.Parser)) {
! 410: System.err.println("Class " + className +
! 411: " does not implement org.xml.sax.Parser.");
! 412: System.exit(1);
! 413: }
! 414:
! 415: return parser;
! 416: }
1.1 jsaarela 417:
418: /**
1.10 ! jsaarela 419: * If a URL is relative, make it absolute against the current directory.
1.1 jsaarela 420: */
1.10 ! jsaarela 421: private static String makeAbsoluteURL (String url)
! 422: throws java.net.MalformedURLException {
! 423: URL baseURL;
! 424:
! 425: String currentDirectory = System.getProperty("user.dir");
! 426: String fileSep = System.getProperty("file.separator");
! 427: String file = currentDirectory.replace(fileSep.charAt(0), '/') + '/';
! 428:
! 429: if (file.charAt(0) != '/') {
! 430: file = "/" + file;
! 431: }
! 432: baseURL = new URL("file", null, file);
! 433:
! 434: return new URL(baseURL, url).toString();
! 435: }
1.1 jsaarela 436:
437:
438: /**
1.10 ! jsaarela 439: * Escape special characters for display.
1.1 jsaarela 440: */
1.10 ! jsaarela 441: private static String escapeCharacters(char ch[], int start, int length) {
! 442: StringBuffer out = new StringBuffer();
1.1 jsaarela 443:
1.10 ! jsaarela 444: for (int i = start; i < start+length; i++) {
! 445: if (ch[i] >= 0x20 && ch[i] < 0x7f) {
! 446: out.append(ch[i]);
! 447: } else {
! 448: out.append("&#" + (int)ch[i] + ';');
1.1 jsaarela 449: }
450: }
1.10 ! jsaarela 451:
! 452: return out.toString();
1.1 jsaarela 453: }
454:
455: /**
1.10 ! jsaarela 456: * Start processing an RDF/XML document instance
1.1 jsaarela 457: */
1.10 ! jsaarela 458: void processRDF (Element rdf) throws SAXException {
! 459: resolve ();
1.1 jsaarela 460:
1.10 ! jsaarela 461: /**
! 462: * RDF leaves it optional to use the RDF root element
! 463: * -> process only one description block
! 464: */
! 465: if (isDescription (rdf)) {
! 466: processDescription (rdf, false, false, true);
! 467: return;
! 468: }
1.1 jsaarela 469:
1.10 ! jsaarela 470: Enumeration e = rdf.children();
1.1 jsaarela 471: while (e.hasMoreElements()) {
1.10 ! jsaarela 472: Element ele = (Element)e.nextElement();
1.1 jsaarela 473:
1.10 ! jsaarela 474: if (isDescription (ele)) {
! 475: processDescription (ele, false, false, true);
! 476: } else if (isContainer (ele)) {
! 477: processContainer (ele);
! 478: } else if (isTypedProperty (ele)) {
! 479: processTypedNode (ele);
1.1 jsaarela 480: }
481: }
482: }
483:
484: /**
1.10 ! jsaarela 485: * Manage the production 6.12 in the spec
1.1 jsaarela 486: */
1.10 ! jsaarela 487: public String processTypedNode (Element typedNode) throws SAXException {
! 488: String sID = typedNode.getAttribute (RDFSCHEMA, "ID");
! 489: String sBagID = typedNode.getAttribute (RDFSCHEMA, "bagID");
! 490: String sAbout = typedNode.getAttribute (RDFSCHEMA, "about");
! 491: String sAboutEach = typedNode.getAttribute (RDFSCHEMA, "aboutEach");
! 492: String sAboutEachPrefix = typedNode.getAttribute (RDFSCHEMA, "aboutEachPrefix");
1.1 jsaarela 493:
1.10 ! jsaarela 494: if (typedNode.getAttribute (RDFSCHEMA, "resource") != null) {
! 495: addError ("'resource' attribute not allowed for a typedNode "+typedNode.name());
! 496: }
! 497: /**
! 498: * We are going to manage this typedNode using the processDescription
! 499: * routine later on. Before that, place all properties encoded as
! 500: * attributes to separate child nodes.
! 501: */
! 502: Enumeration e = typedNode.attributes ();
! 503: while (e.hasMoreElements()) {
! 504: String sAttribute = (String)e.nextElement();
! 505: String sValue = typedNode.getAttribute (sAttribute);
! 506: sValue = sValue.trim ();
! 507:
! 508: if (!sAttribute.startsWith (RDFSCHEMA) &&
! 509: !sAttribute.startsWith (XMLSCHEMA)) {
! 510: if (sValue.length() > 0) {
! 511: Element newProperty = new Element (sAttribute,
! 512: new AttributeListImpl ());
! 513: newProperty.addAttribute (RDFSCHEMA + "ID", sID);
! 514: newProperty.addAttribute (RDFSCHEMA + "bagID", sBagID);
! 515: Data newData = new Data (sValue);
! 516: newProperty.addChild (newData);
! 517: typedNode.addChild (newProperty);
! 518: typedNode.removeAttribute (sAttribute);
1.1 jsaarela 519: }
520: }
521: }
522:
1.10 ! jsaarela 523: String sObject = new String ();
! 524: if (sID != null)
! 525: sObject = sID;
! 526: else
! 527: sObject = newReificationID();
! 528:
! 529: typedNode.ID (sObject);
1.1 jsaarela 530:
1.10 ! jsaarela 531: // special case: should the typedNode have aboutEach attribute,
! 532: // the instanceOf property should distribute to pointed
! 533: // collection also -> create a child node to the typedNode
! 534: Enumeration eTargets = typedNode.targets ();
! 535: if (sAboutEach != null &&
! 536: eTargets.hasMoreElements()) {
! 537: Element newProperty = new Element (RDFSCHEMA + "type",
! 538: new AttributeListImpl());
! 539: Data newData = new Data (typedNode.name());
! 540: newProperty.addChild (newData);
! 541: typedNode.addChild (newProperty);
! 542: } else {
! 543: addTriple (RDFSCHEMA + "type",
! 544: sObject,
! 545: typedNode.name());
! 546: }
1.1 jsaarela 547:
1.10 ! jsaarela 548: String sDesc = processDescription (typedNode, false, false, true);
1.1 jsaarela 549:
1.10 ! jsaarela 550: return sObject;
1.1 jsaarela 551: }
552:
1.7 jsaarela 553: /**
1.10 ! jsaarela 554: * processDescription takes the following parameters
! 555: *
! 556: * @param description The Description element itself
! 557: * @param inProperty A flag to tell whether this is a nested description
! 558: inside a property.
! 559: * @param reificate Do we need to reificate
! 560: * @param createBag Do we create a bag collection out of nested properties
! 561: *
! 562: * @return An ID for the description
1.7 jsaarela 563: */
1.10 ! jsaarela 564: private String processDescription (Element description,
! 565: boolean inProperty,
! 566: boolean reificate,
! 567: boolean createBag) throws SAXException {
! 568: /**
! 569: * Return immediately if the description has already been managed
! 570: */
! 571: if (description.done())
! 572: return description.ID();
! 573:
! 574: int iChildCount = 1;
! 575: boolean bOnce = true;
! 576:
! 577: /**
! 578: * Determine first all relevant values
! 579: */
! 580: String sAbout = description.getAttribute (RDFSCHEMA, "about");
! 581: String sAboutEach = description.getAttribute (RDFSCHEMA, "aboutEach");
! 582: String sAboutEachPrefix = description.getAttribute (RDFSCHEMA, "aboutEachPrefix");
! 583: String sBagid = description.getAttribute (RDFSCHEMA, "bagID");
! 584: String sID = description.getAttribute (RDFSCHEMA, "ID");
! 585: Element target = description.target();
! 586:
! 587: boolean hasTarget = description.targets().hasMoreElements();
! 588: boolean targetIsContainer = false;
! 589: String sTargetAbout = null;
! 590: String sTargetBagid = null;
! 591: String sTargetID = null;
1.7 jsaarela 592:
1.10 ! jsaarela 593: /**
! 594: * Determine what the target of the Description reference is
! 595: */
! 596: if (hasTarget) {
! 597: sTargetAbout = target.getAttribute (RDFSCHEMA, "about");
! 598: sTargetBagid = target.getAttribute (RDFSCHEMA, "bagID");
! 599: sTargetID = target.getAttribute (RDFSCHEMA, "ID");
! 600:
! 601: /**
! 602: * Target is collection if
! 603: * 1. it is identified with bagID attribute
! 604: * 2. it is identified with ID attribute and is a collection
! 605: */
! 606: if (sTargetBagid != null) {
! 607: targetIsContainer = (sAbout.substring(1).equals (sTargetBagid));
1.5 jsaarela 608: } else {
1.10 ! jsaarela 609: if (sTargetID != null &&
! 610: sAbout.substring(1).equals (sTargetID) &&
! 611: isContainer (target)) {
! 612: targetIsContainer = true;
! 613: }
1.5 jsaarela 614: }
1.10 ! jsaarela 615: }
! 616:
! 617:
! 618: /**
! 619: * Check if there are properties encoded using the abbreviated
! 620: * syntax
! 621: */
! 622: expandAttributes (description, description);
! 623:
! 624: /**
! 625: * Manage the aboutEach attribute here
! 626: */
! 627: if (sAboutEach != null) {
! 628: if (hasTarget) {
! 629: Enumeration e = target.children ();
! 630: while (e.hasMoreElements()) {
! 631: Element ele = (Element)e.nextElement ();
! 632:
! 633: String sResource = ele.getAttribute (RDFSCHEMA, "resource");
! 634: Element newDescription = null;
! 635: if (sResource != null) {
! 636: newDescription = new Element (RDFSCHEMA + "Description",
! 637: new AttributeListImpl ());
! 638: newDescription.addAttribute (RDFSCHEMA + "about", sResource);
! 639: }
! 640: Enumeration e2 = description.children();
! 641: while (e2.hasMoreElements()) {
! 642: Element ele2 = (Element)e2.nextElement ();
! 643: if (newDescription != null) {
! 644: newDescription.addChild (ele2);
! 645: }
! 646: }
! 647: if (newDescription != null)
! 648: processDescription (newDescription, false, false, false);
! 649: }
1.5 jsaarela 650: }
1.10 ! jsaarela 651: return null;
1.5 jsaarela 652: }
653:
1.10 ! jsaarela 654: /**
! 655: * Manage the aboutEachPrefix attribute here
! 656: */
! 657: if (sAboutEachPrefix != null) {
! 658: if (hasTarget) {
! 659: Enumeration e = description.targets();
! 660: while (e.hasMoreElements()) {
! 661: target = (Element)e.nextElement ();
! 662: sTargetAbout = target.getAttribute (RDFSCHEMA, "about");
! 663: Element newDescription = new Element (RDFSCHEMA + "Description",
! 664: new AttributeListImpl ());
! 665: newDescription.addAttribute (RDFSCHEMA + "about", sTargetAbout);
! 666:
! 667: Enumeration e2 = description.children();
! 668: while (e2.hasMoreElements()) {
! 669: Element ele2 = (Element)e2.nextElement ();
! 670: newDescription.addChild (ele2);
! 671: }
! 672: processDescription (newDescription, false, false, false);
! 673: }
! 674: }
! 675: return null;
1.1 jsaarela 676: }
677:
1.10 ! jsaarela 678: /**
! 679: * Enumerate through the children
! 680: */
! 681: Enumeration e = description.children();
! 682:
! 683: while (e.hasMoreElements()) {
! 684: Element n = (Element)e.nextElement();
! 685:
! 686: if (isDescription (n)) {
! 687: addError ("Cannot nest Description inside Description");
! 688: } else if (isListItem (n)) {
! 689: addError ("Cannot nest Listitem inside Description");
! 690: } else if (isContainer (n)) {
! 691: addError ("Cannot nest container inside Description");
! 692: } else if (n instanceof Element) {
! 693:
! 694: String sChildID = null;
! 695:
! 696: if (hasTarget && targetIsContainer) {
! 697: sChildID = processProperty (n, description,
! 698: (target.bagID() != null ? target.bagID() : target.ID()),
! 699: false);
! 700: description.ID (sChildID);
! 701: createBag = false;
! 702: } else if (hasTarget) {
! 703: sChildID = processProperty (n, description,
! 704: sTargetAbout, reificate);
! 705: } else if (!hasTarget && !inProperty) {
! 706: if (description.ID() == null) {
! 707: description.ID (newReificationID());
! 708: }
! 709: if (sAbout == null)
! 710: if (sID != null)
! 711: sAbout = sID;
! 712: else
! 713: sAbout = description.ID();
! 714: sChildID = processProperty (n, description,
! 715: ( sAbout != null ? sAbout : sID),
! 716: createBag);
! 717: } else if (!hasTarget && inProperty) {
! 718: if (sAbout == null) {
! 719: if (sID != null) {
! 720: description.ID (sID);
! 721: sAbout = sID;
! 722: } else {
! 723: if (description.ID() == null)
! 724: description.ID (newReificationID());
! 725: sAbout = description.ID();
! 726: }
! 727: } else {
! 728: description.ID (sAbout);
! 729: }
! 730: sChildID = processProperty (n, description,
! 731: sAbout,
! 732: false);
! 733: }
1.1 jsaarela 734:
1.10 ! jsaarela 735: /**
! 736: * Each Description block creates also a Bag node which
! 737: * has links to all properties within the block.
! 738: */
! 739: if (createBag) {
! 740: String sNamespace = RDFSCHEMA;
! 741: if (bOnce) {
! 742: bOnce = false;
! 743: if (description.bagID() == null)
! 744: description.bagID (newReificationID());
! 745: if (description.ID() == null)
! 746: description.ID (description.bagID());
! 747:
! 748: addTriple (sNamespace + "type",
! 749: description.bagID(),
! 750: sNamespace + "Bag");
! 751: }
! 752: if (sChildID != null) {
! 753: addTriple (sNamespace + "_" + iChildCount,
! 754: description.bagID(),
! 755: sChildID);
! 756: iChildCount++;
! 757: }
! 758: }
! 759: }
1.1 jsaarela 760: }
1.10 ! jsaarela 761:
! 762: description.done (true);
! 763:
! 764: return description.ID();
1.1 jsaarela 765: }
766:
1.6 jsaarela 767: /**
1.10 ! jsaarela 768: * processProperty handles all elements not defined as special
! 769: * RDF elements.
! 770: *
! 771: * @param property The Property element itself
! 772: * @param description The Description element in which this property appears
! 773: * @param sTarget The target resource
! 774: * @param reificate Should this property be reificated
! 775: *
! 776: * @return the new ID which can be used to identify the property
1.6 jsaarela 777: */
1.10 ! jsaarela 778: private String processProperty (Element property,
! 779: Element description,
! 780: String sTarget,
! 781: boolean reificate) throws SAXException {
! 782: String sPropertyID = null;
1.1 jsaarela 783:
1.10 ! jsaarela 784: /**
! 785: * Do the same trick as with Description blocks:
! 786: * if the Property uses abbreviated syntax, transform
! 787: * the structure into corresponding full tree representation
! 788: * which is handled correctly by the code for the non-abbreviated
! 789: * syntax.
! 790: */
1.1 jsaarela 791:
1.10 ! jsaarela 792: String sResource = property.getAttribute (RDFSCHEMA, "resource");
! 793: String sAbout = property.getAttribute (RDFSCHEMA, "about");
1.1 jsaarela 794:
1.10 ! jsaarela 795: Element d = new Element (RDFSCHEMA + "Description",
! 796: new AttributeListImpl());
1.1 jsaarela 797:
1.10 ! jsaarela 798: /**
! 799: * Tricky part: use the resource attribute to name
! 800: * the intermediate Description block
! 801: */
! 802: if (sResource != null) {
! 803: d.addAttribute (RDFSCHEMA + "about", sResource);
1.1 jsaarela 804: }
805:
806: /**
1.10 ! jsaarela 807: * If we found properties and attributes and generated the subtree,
! 808: * attach it to the property itself and let the code below take
! 809: * care of the rest.
1.1 jsaarela 810: */
1.10 ! jsaarela 811: if (expandAttributes (d, property)) {
! 812: property.addChild (d);
! 813: }
1.1 jsaarela 814:
1.10 ! jsaarela 815: /**
! 816: * Tricky part 2: if the resource attribute is present for a property
! 817: * AND there are no children, the value of the property is either
! 818: * 1. the URI in the resource attribute OR
! 819: * 2. the node ID of the resolved #resource attribute
! 820: */
! 821: if (sResource != null && !property.children().hasMoreElements()) {
! 822: if (property.target() == null) {
! 823: if (reificate) {
! 824: sPropertyID = reificate (property.name(),
! 825: sTarget,
! 826: sResource,
! 827: property.ID());
! 828: property.ID (sPropertyID);
! 829: } else {
! 830: addTriple (property.name(),
! 831: sTarget,
! 832: sResource);
! 833: }
! 834: } else {
! 835: if (reificate) {
! 836: sPropertyID = reificate (property.name(),
! 837: sTarget,
! 838: property.target().ID(),
! 839: property.ID());
! 840: property.ID (sPropertyID);
! 841: } else {
! 842: addTriple (property.name(),
! 843: sTarget,
! 844: property.target().ID());
! 845: }
! 846: }
! 847: return property.ID();
! 848: }
1.1 jsaarela 849:
850: /**
1.10 ! jsaarela 851: * Does this property make a reference somewhere using the
! 852: * <i>resource</i> attribute
1.1 jsaarela 853: */
1.10 ! jsaarela 854: if (sResource != null && property.target() != null) {
! 855: sPropertyID = processDescription (property.target(),
! 856: true, false, false);
1.1 jsaarela 857: if (reificate) {
1.10 ! jsaarela 858: sPropertyID = reificate (property.name(),
! 859: sTarget,
! 860: sPropertyID,
! 861: property.ID());
1.1 jsaarela 862: property.ID (sPropertyID);
863: } else {
1.10 ! jsaarela 864: addTriple (property.name(),
! 865: sTarget,
! 866: sPropertyID);
1.1 jsaarela 867: }
1.10 ! jsaarela 868:
! 869: return sPropertyID;
! 870: }
! 871:
! 872: /**
! 873: * Is the value of the attribute given as a URI in the
! 874: * about attribute?
! 875: */
! 876: if (sAbout != null) {
1.1 jsaarela 877: if (reificate) {
1.10 ! jsaarela 878: sPropertyID = reificate (property.name(),
1.4 jsaarela 879: sTarget,
1.10 ! jsaarela 880: sAbout,
! 881: property.ID());
1.1 jsaarela 882: property.ID (sPropertyID);
883: } else {
1.10 ! jsaarela 884: addTriple (property.name(),
! 885: sTarget,
! 886: sAbout);
! 887: }
! 888: }
! 889:
! 890: /**
! 891: * Before looping through the children, let's check
! 892: * is there are any. If not, the value of the property is an anonymous node
! 893: */
! 894: Enumeration e2 = property.children();
! 895: if (!(e2.hasMoreElements())) {
! 896: if (reificate) {
! 897: sPropertyID = reificate (property.name(),
! 898: sTarget,
! 899: newReificationID(),
! 900: property.ID());
! 901: } else {
! 902: addTriple (property.name(),
! 903: sTarget,
! 904: newReificationID());
! 905: }
! 906: }
! 907: while (e2.hasMoreElements()) {
! 908: Element n2 = (Element)e2.nextElement();
! 909:
! 910: if (isDescription (n2)) {
! 911: Element d2 = n2;
! 912:
! 913: sPropertyID = processDescription (d2, true, false, false);
! 914:
! 915: d2.ID (sPropertyID);
! 916:
! 917: if (reificate) {
! 918: sPropertyID = reificate (property.name(),
! 919: sTarget,
! 920: sPropertyID,
! 921: property.ID());
! 922: } else {
! 923: addTriple (property.name(),
! 924: sTarget, sPropertyID);
! 925: }
! 926:
! 927: } else if (n2 instanceof Data) {
! 928: /**
! 929: * We've got real data
! 930: */
! 931: String sValue = ((Data)n2).data();
! 932:
! 933: /**
! 934: * Only if the content is not empty PCDATA (whitespace that is),
! 935: * print the triple
! 936: */
! 937: sValue = sValue.trim();
! 938: if (sValue.length() > 0) {
! 939: if (reificate) {
! 940: sPropertyID = reificate (property.name(),
! 941: sTarget,
! 942: sValue,
! 943: property.ID());
! 944: property.ID (sPropertyID);
! 945: } else {
! 946: addTriple (property.name(),
! 947: sTarget,
! 948: sValue);
! 949: }
! 950: }
! 951: } else if (isContainer (n2)) {
! 952:
! 953: String sCollectionID = processContainer (n2);
! 954: sPropertyID = sCollectionID;
! 955:
! 956: /**
! 957: * Attach the collection to the current Property
! 958: */
! 959: if (description.target() != null) {
! 960: if (reificate) {
! 961: sPropertyID = reificate (property.name(),
! 962: description.target().getAttribute (RDFSCHEMA, "about"),
! 963: sCollectionID,
! 964: property.ID());
! 965: property.ID (sPropertyID);
! 966: } else {
! 967: addTriple (property.name(),
! 968: description.target().getAttribute (RDFSCHEMA, "about"),
! 969: sCollectionID);
! 970: }
! 971: } else {
! 972: if (reificate) {
! 973: sPropertyID = reificate (property.name(),
! 974: sTarget,
! 975: sCollectionID,
! 976: property.ID());
! 977: property.ID (sPropertyID);
! 978: } else {
! 979: addTriple (property.name(),
! 980: sTarget,
! 981: sCollectionID);
! 982: }
! 983: }
! 984: } else if (isTypedProperty (n2)) {
! 985: sPropertyID = processTypedNode (n2);
! 986: addTriple (property.name(),
1.5 jsaarela 987: sTarget,
1.10 ! jsaarela 988: sPropertyID);
1.1 jsaarela 989: }
990: }
1.10 ! jsaarela 991:
! 992: return sPropertyID;
1.1 jsaarela 993: }
994:
1.10 ! jsaarela 995: private String processContainer (Element n) throws SAXException {
! 996: String sID = n.ID();
! 997: if (sID == null)
! 998: sID = newReificationID();
1.1 jsaarela 999:
1.10 ! jsaarela 1000: /**
! 1001: * Do the instantiation only once
! 1002: */
! 1003: if (!n.done()) {
! 1004: String sNamespace = RDFSCHEMA;
! 1005: if (isSequence (n)) {
! 1006: addTriple (sNamespace+"type",
! 1007: sID,
! 1008: sNamespace+"Seq");
! 1009: } else if (isAlternative (n)) {
! 1010: addTriple (sNamespace+"type",
! 1011: sID,
! 1012: sNamespace+"Alt");
! 1013: } else if (isBag (n)) {
! 1014: addTriple (sNamespace+"type",
! 1015: sID,
! 1016: sNamespace+"Bag");
! 1017: }
! 1018: n.done (true);
! 1019: }
! 1020:
! 1021: expandAttributes (n, n);
1.1 jsaarela 1022:
1.10 ! jsaarela 1023: Enumeration e = ((Element)n).children();
! 1024:
! 1025: if (!e.hasMoreElements() &&
! 1026: isAlternative (n)) {
! 1027: addError ("An RDF:Alt container must have at least one listitem");
! 1028: }
! 1029:
! 1030: int iCounter = 1;
! 1031: while (e.hasMoreElements()) {
! 1032: Element n2 = (Element)e.nextElement();
! 1033: if (isListItem (n2)) {
! 1034: processListItem (sID, n2, iCounter);
! 1035: iCounter++;
! 1036: } else {
! 1037: addError ("Cannot nest "+n2.name()+" inside container");
! 1038: }
! 1039: }
! 1040:
! 1041: return sID;
! 1042: }
! 1043:
! 1044: private void processListItem (String sID, Element listitem, int iCounter)
! 1045: throws SAXException {
! 1046: /**
! 1047: * Two different cases for
! 1048: * 1. LI element without content (resource available)
! 1049: * 2. LI element with content (resource unavailable)
! 1050: */
! 1051: String sResource = listitem.getAttribute (RDFSCHEMA, "resource");
! 1052: if (sResource != null) {
! 1053: addTriple (RDFSCHEMA+"_"+iCounter,
1.1 jsaarela 1054: sID,
1.10 ! jsaarela 1055: sResource);
! 1056: // validity checking
! 1057: if (listitem.children().hasMoreElements()) {
! 1058: addError ("Listitem with 'resource' attribute cannot have child nodes");
! 1059: }
! 1060: } else {
! 1061: Enumeration e = listitem.children();
! 1062: while (e.hasMoreElements()) {
! 1063: Element n = (Element)e.nextElement();
! 1064: if (n instanceof Data) {
! 1065: addTriple (RDFSCHEMA+"_"+iCounter,
! 1066: sID,
! 1067: ((Data)n).data());
! 1068: } else if (isDescription (n)) {
! 1069: String sNodeID = processDescription (n, false, false, false);
! 1070: addTriple (RDFSCHEMA+"_"+iCounter,
! 1071: sID,
! 1072: sNodeID);
! 1073: } else if (isListItem (n)) {
! 1074: addError ("Cannot nest listitem inside listitem");
! 1075: } else if (isTypedProperty (n)) {
! 1076: String sNodeID = processTypedNode (n);
! 1077: addTriple (RDFSCHEMA+"_"+iCounter,
! 1078: sID,
! 1079: sNodeID);
! 1080: }
! 1081: }
1.1 jsaarela 1082: }
1083: }
1084:
1.10 ! jsaarela 1085: private void checkAttributes (Element e) {
! 1086: String sResource = e.getAttribute (RDFSCHEMA, "resource");
! 1087: if (sResource != null &&
! 1088: sResource.startsWith("#")) {
! 1089: resolveLater (e);
! 1090: }
! 1091: String sAboutEach = e.getAttribute (RDFSCHEMA, "aboutEach");
! 1092: if (sAboutEach != null &&
! 1093: sAboutEach.startsWith("#")) {
! 1094: resolveLater (e);
! 1095: }
! 1096: String sAboutEachPrefix = e.getAttribute (RDFSCHEMA, "aboutEachPrefix");
! 1097: if (sAboutEachPrefix != null) {
! 1098: resolveLater (e);
! 1099: }
1.8 jsaarela 1100:
1.10 ! jsaarela 1101: String sAbout = e.getAttribute (RDFSCHEMA, "about");
! 1102: if (sAbout != null) {
! 1103: if (sAbout.startsWith("#")) {
! 1104: resolveLater (e);
! 1105: } else {
! 1106: registerResource (e);
! 1107: }
! 1108: }
! 1109:
! 1110: String sBagID = e.getAttribute (RDFSCHEMA, "bagID");
! 1111: if (sBagID != null) {
! 1112: registerID (sBagID, e);
! 1113: e.bagID (sBagID);
! 1114: }
1.6 jsaarela 1115:
1.10 ! jsaarela 1116: String sID = e.getAttribute (RDFSCHEMA, "ID");
! 1117: if (sID != null) {
! 1118: registerID (sID, e);
! 1119: e.ID (sID); // default value
! 1120: }
1.1 jsaarela 1121:
1.10 ! jsaarela 1122: if (sID != null && sAbout != null) {
! 1123: addError ("'ID' and 'about' attribute may not appear within the same Description block");
1.1 jsaarela 1124: }
1125: }
1126:
1.10 ! jsaarela 1127: private boolean expandAttributes (Element parent, Element ele)
! 1128: throws SAXException {
! 1129: boolean foundAbbreviation = false;
! 1130: Enumeration e = ele.attributes ();
! 1131: while (e.hasMoreElements()) {
! 1132: String sAttribute = (String)e.nextElement();
! 1133: String sValue = ele.getAttribute (sAttribute).trim();
! 1134:
! 1135: if (sAttribute.startsWith (XMLSCHEMA))
! 1136: continue;
! 1137: if (sAttribute.startsWith (RDFSCHEMA) &&
! 1138: !sAttribute.endsWith ("value"))
! 1139: continue;
1.8 jsaarela 1140: if (sValue.length() > 0) {
1141: foundAbbreviation = true;
1.10 ! jsaarela 1142: Element newElement = new Element (sAttribute,
! 1143: new AttributeListImpl());
1.8 jsaarela 1144: Data newData = new Data (sValue);
1145: newElement.addChild (newData);
1146: parent.addChild (newElement);
1147: }
1148: }
1.10 ! jsaarela 1149: return foundAbbreviation;
! 1150: }
! 1151:
! 1152: /**
! 1153: * reificate creates one new node and four new triples
! 1154: * and returns the ID of the new node
! 1155: */
! 1156: private String reificate (String sProperty,
! 1157: String sPropertyObject,
! 1158: String sPropertyValue,
! 1159: String sNodeID) {
! 1160: String sNamespace = RDFSCHEMA;
! 1161: if (sNodeID == null)
! 1162: sNodeID = newReificationID();
! 1163:
! 1164: /**
! 1165: * The original property must remain in the data model
! 1166: */
! 1167: addTriple (sProperty, sPropertyObject, sPropertyValue);
! 1168:
! 1169: /**
! 1170: * Do not reificate reificated properties
! 1171: */
! 1172:
! 1173: if (sProperty.equals (sNamespace+"propObj") ||
! 1174: sProperty.equals (sNamespace+"propName") ||
! 1175: sProperty.equals (sNamespace+"value") ||
! 1176: sProperty.equals (sNamespace+"type")) {
! 1177: return null;
! 1178: }
! 1179:
! 1180: /**
! 1181: * Reificate by creating 4 new triples
! 1182: */
! 1183:
! 1184: addTriple (sNamespace + "propName",
! 1185: sNodeID,
! 1186: sProperty);
! 1187:
! 1188: addTriple (sNamespace + "propObj",
! 1189: sNodeID,
! 1190: sPropertyObject);
! 1191:
! 1192: addTriple (sNamespace + "value",
! 1193: sNodeID,
! 1194: sPropertyValue);
! 1195:
! 1196: addTriple (sNamespace + "type",
! 1197: sNodeID,
! 1198: sNamespace + "Property");
! 1199:
! 1200: return sNodeID;
! 1201: }
! 1202:
! 1203: private void addTriple (String sProperty, String sPropertyObj, String sPropertyValue) {
! 1204: Triple t = new Triple (sProperty, sPropertyObj, sPropertyValue);
! 1205: m_triples.addElement (t);
! 1206: }
! 1207:
! 1208: public void printTriples (PrintStream ps) {
! 1209: for (int x = 0; x < m_triples.size(); x++) {
! 1210: Triple t = (Triple)m_triples.elementAt (x);
! 1211: ps.println ("triple(\""+t.property()+"\",\""+t.object()+"\",\""+t.value()+"\").");
! 1212: }
! 1213: }
! 1214:
! 1215: public Enumeration triples () {
! 1216: return m_triples.elements ();
! 1217: }
! 1218:
! 1219: /**
! 1220: * Helper functions to identify different elements
! 1221: */
! 1222: public boolean isDescription (Element e) {
! 1223: return isRDF(e) &&
! 1224: e.name().endsWith ("Description");
! 1225: }
! 1226:
! 1227: public boolean isListItem (Element e) {
! 1228: return isRDF(e) &&
! 1229: ( e.name().endsWith ("li") ||
! 1230: e.name().indexOf ("_") > -1);
1.8 jsaarela 1231: }
1232:
1.10 ! jsaarela 1233: public boolean isContainer (Element e) {
! 1234: return (isSequence (e) ||
! 1235: isAlternative (e) ||
! 1236: isBag (e));
! 1237: }
! 1238:
! 1239: public boolean isSequence (Element e) {
! 1240: return isRDF(e) &&
! 1241: e.name().endsWith ("Seq");
! 1242: }
! 1243:
! 1244: public boolean isAlternative (Element e) {
! 1245: return isRDF(e) &&
! 1246: e.name().endsWith ("Alt");
! 1247: }
! 1248:
! 1249: public boolean isBag (Element e) {
! 1250: return isRDF(e) &&
! 1251: e.name().endsWith ("Bag");
! 1252: }
! 1253:
! 1254: /**
! 1255: * This method matches all elements in practice
! 1256: */
! 1257: public boolean isTypedProperty (Element e) {
! 1258: if (e.name().length() > 0)
! 1259: return true;
! 1260: else
! 1261: return false;
! 1262: }
! 1263:
! 1264: public boolean isRDF (Element e) {
! 1265: return e.name().startsWith (RDFSCHEMA);
! 1266: }
! 1267:
! 1268: /**
! 1269: * Methods for node reference management
! 1270: */
! 1271:
! 1272: private Vector m_vResources = new Vector ();
! 1273: private Vector m_vResolveQueue = new Vector ();
! 1274: private Hashtable m_hIDtable = new Hashtable ();
! 1275: private int m_iReificationCounter = 0;
! 1276:
! 1277: public void resolveLater (Element e) {
! 1278: m_vResolveQueue.addElement (e);
! 1279: }
! 1280:
! 1281: public void resolve () {
! 1282: for (int x = 0; x < m_vResolveQueue.size(); x++) {
! 1283: Element e = (Element)m_vResolveQueue.elementAt(x);
! 1284:
! 1285: String sAbout = e.getAttribute (RDFSCHEMA, "about");
! 1286: if (sAbout != null) {
! 1287: if (sAbout.startsWith ("#"))
! 1288: sAbout = sAbout.substring (1);
! 1289: Element e2 = (Element)lookforNode(sAbout);
! 1290: if (e2 != null) {
! 1291: e.addTarget (e2);
! 1292: } else {
! 1293: addError ("Unresolved internal reference to "+sAbout);
! 1294: }
! 1295: }
! 1296:
! 1297: String sResource = e.getAttribute (RDFSCHEMA, "resource");
! 1298: if (sResource != null) {
! 1299: if (sResource.startsWith ("#"))
! 1300: sResource = sResource.substring (1);
! 1301: Element e2 = (Element)lookforNode(sResource);
! 1302: if (e2 != null) {
! 1303: e.addTarget (e2);
! 1304: }
! 1305: }
! 1306:
! 1307: String sAboutEach = e.getAttribute (RDFSCHEMA, "aboutEach");
! 1308: if (sAboutEach != null) {
! 1309: sAboutEach = sAboutEach.substring (1);
! 1310: Element e2 = (Element)lookforNode(sAboutEach);
! 1311: if (e2 != null) {
! 1312: e.addTarget (e2);
! 1313: }
! 1314: }
! 1315:
! 1316: String sAboutEachPrefix = e.getAttribute (RDFSCHEMA, "aboutEachPrefix");
! 1317: if (sAboutEachPrefix != null) {
! 1318: for (int y = 0; y < m_vResources.size(); y++) {
! 1319: Element ele = (Element)m_vResources.elementAt(y);
! 1320: String sA = ele.getAttribute (RDFSCHEMA, "about");
! 1321: if (sA.startsWith (sAboutEachPrefix)) {
! 1322: e.addTarget (ele);
! 1323: }
! 1324: }
! 1325: }
! 1326: }
! 1327: m_vResolveQueue.removeAllElements();
! 1328: }
! 1329:
! 1330: public Element lookforNode (String sID) {
! 1331: if (sID == null)
! 1332: return null;
! 1333: else
! 1334: return (Element)m_hIDtable.get (sID);
! 1335: }
! 1336:
! 1337: public void registerID (String sID, Element e) {
! 1338: if (m_hIDtable.get (sID) != null)
! 1339: addError(sID+" ID already defined.");
! 1340: m_hIDtable.put (sID, e);
! 1341: }
! 1342:
! 1343: public String newReificationID () {
! 1344: m_iReificationCounter++;
! 1345: return new String ("genid" + m_iReificationCounter);
! 1346: }
! 1347:
! 1348: public void registerResource (Element e) {
! 1349: m_vResources.addElement (e);
! 1350: }
1.1 jsaarela 1351: }
Webmaster