Annotation of java/classes/org/w3c/rdf/RDF2LP2.java, revision 1.1
1.1 ! jsaarela 1: /**
! 2: * Translate RDF descriptions into triple representation
! 3: * This version is suitable for embedded use as well as command line use
! 4: *
! 5: * This version uses SAX V1.0 http://www.microstar.com/XML/SAX/
! 6: *
! 7: * $Log: RDF2LP2.java,v $
! 8: * Revision 1.3 1998/06/08 15:46:39 jsaarela
! 9: * Intermediate log from an almost RDF abbr.syntax compliant version.
! 10: * Misses management of typedNodes.
! 11: *
! 12: * Revision 1.2 1998/05/15 12:54:39 jsaarela
! 13: * Almost totally rewritten version of the compiler.
! 14: *
! 15: * Revision 1.1 1998/05/14 16:07:51 jsaarela
! 16: * A working version with extra reification.
! 17: *
! 18: *
! 19: * @author Janne Saarela
! 20: */
! 21: package org.w3c.rdf;
! 22:
! 23: import org.xml.sax.HandlerBase;
! 24: import org.xml.sax.InputSource;
! 25: import org.xml.sax.Locator;
! 26: import org.xml.sax.AttributeList;
! 27: import org.xml.sax.EntityResolver;
! 28: import org.xml.sax.DTDHandler;
! 29: import org.xml.sax.DocumentHandler;
! 30: import org.xml.sax.ErrorHandler;
! 31: import org.xml.sax.SAXParseException;
! 32: import org.xml.sax.Parser;
! 33: import org.xml.sax.InputSource;
! 34: import org.xml.sax.SAXException;
! 35:
! 36: import org.xml.sax.helpers.*;
! 37:
! 38: import java.net.URL;
! 39: import java.util.*;
! 40: import java.io.*;
! 41:
! 42: public class RDF2LP2 implements EntityResolver, DTDHandler, DocumentHandler,
! 43: ErrorHandler {
! 44: final static public String rcsRevision = "$Id: RDF2LP2.java,v 1.3 1998/06/08 15:46:39 jsaarela Exp $";
! 45:
! 46: private Stack m_elementStack = new Stack ();
! 47: private Element m_root = null;
! 48: private Vector m_triples = new Vector ();
! 49:
! 50: /**
! 51: * Namespace management
! 52: */
! 53: static private Hashtable s_namespaces = new Hashtable();
! 54: public static void addNamespace (String sAs, String sHref) {
! 55: s_namespaces.put (sAs.toLowerCase(), sHref);
! 56: }
! 57:
! 58: public static String namespace (String sAs) {
! 59: return (String)s_namespaces.get (sAs.toLowerCase());
! 60: }
! 61:
! 62: public static void main (String args[]) throws Exception
! 63: {
! 64: if (args.length != 1) {
! 65: System.err.println("Usage: java RDF2LP2 <document>");
! 66: System.exit(1);
! 67: }
! 68:
! 69: // Create a new parser.
! 70: Parser p = ParserFactory.makeParser("com.microstar.xml.SAXDriver");
! 71:
! 72: // Create a new handler.
! 73: RDF2LP2 rdf2lp = new RDF2LP2();
! 74:
! 75: // Register the handlers
! 76: p.setEntityResolver(rdf2lp);
! 77: p.setDTDHandler (rdf2lp);
! 78: p.setDocumentHandler(rdf2lp);
! 79: p.setErrorHandler (rdf2lp);
! 80:
! 81: FileInputStream input = new FileInputStream(args[0]);
! 82: InputSource source = new InputSource(input);
! 83: source.setSystemId(args[0]);
! 84:
! 85: p.parse(source);
! 86: }
! 87:
! 88: public InputSource resolveEntity (String publicId, String systemId)
! 89: {
! 90: return null;
! 91: }
! 92:
! 93: public void notationDecl (String name, String publicId, String systemId)
! 94: {
! 95: }
! 96:
! 97:
! 98: /**
! 99: * Display unparsed entity declarations as they are reported.
! 100: *
! 101: * @see org.xml.sax.DTDHandler#unparsedEntityDecl
! 102: */
! 103: public void unparsedEntityDecl (String name,
! 104: String publicId,
! 105: String systemId,
! 106: String notationName)
! 107: {
! 108: }
! 109:
! 110: public void setDocumentLocator (Locator locator)
! 111: {
! 112: }
! 113:
! 114: public void startDocument () {
! 115: }
! 116:
! 117: public void endDocument () {
! 118: // m_root.linearize (0, System.out);
! 119: processRDF (m_root);
! 120: printTriples (System.out);
! 121: }
! 122:
! 123: public void doctype (String name, String publicID, String systemID) {
! 124: }
! 125:
! 126: public void startElement (String name, AttributeList al) {
! 127: int iLength = al.getLength ();
! 128: if (iLength == 0) {
! 129: // System.out.println("[Attributes not available]");
! 130: } else for (int x = 0; x < iLength; x++) {
! 131: String aname = al.getName (x);
! 132: String special = "";
! 133: }
! 134:
! 135: /**
! 136: * Create a new element and update the containment hierarchy
! 137: * with the stack.
! 138: */
! 139: Element newElement = new Element (name, al);
! 140:
! 141: if (!m_elementStack.empty()) {
! 142: Element e = (Element)m_elementStack.peek ();
! 143: e.addChild (newElement);
! 144: }
! 145:
! 146: /**
! 147: * Place the new element into the stack
! 148: */
! 149: m_elementStack.push (newElement);
! 150: }
! 151:
! 152: public void endElement (String name)
! 153: {
! 154: m_root = (Element)m_elementStack.pop ();
! 155: }
! 156:
! 157: public void characters (char ch[], int start, int length)
! 158: {
! 159: /**
! 160: * Place all characters as Data instance to the containment
! 161: * hierarchy with the help of the stack.
! 162: */
! 163: Element e = (Element)m_elementStack.peek ();
! 164: String s = new String (ch, start, length+start);
! 165:
! 166: /**
! 167: * Warning: this is not correct procedure according to XML spec.
! 168: * All whitespace matters!
! 169: */
! 170: String sTrimmed = s.trim();
! 171: if (sTrimmed.length() > 0)
! 172: e.addChild (new Data (s));
! 173: }
! 174:
! 175: public void ignorableWhitespace (char ch[], int start, int length)
! 176: {
! 177: }
! 178:
! 179: public void processingInstruction (String target, String data)
! 180: {
! 181: if (target.equalsIgnoreCase ("xml:namespace")) {
! 182: /**
! 183: * Figure out the href and as attributes from the namespace
! 184: * declaration
! 185: */
! 186: StringReader sr = new StringReader (data);
! 187: StreamTokenizer st = new StreamTokenizer (sr);
! 188:
! 189: int token1, token2, token3, token4, token5, token6;
! 190: try {
! 191: while ((token1 = st.nextToken()) != StreamTokenizer.TT_EOF) {
! 192: String sHref = st.sval;
! 193: token2 = st.nextToken();
! 194: token3 = st.nextToken();
! 195: String sHrefValue = st.sval;
! 196: token4 = st.nextToken();
! 197: String sAs = st.sval;
! 198: token5 = st.nextToken();
! 199: token6 = st.nextToken();
! 200: String sAsValue = st.sval;
! 201: if (token1 == StreamTokenizer.TT_WORD &&
! 202: token2 == '=' &&
! 203: token3 == 34 &&
! 204: token4 == StreamTokenizer.TT_WORD &&
! 205: token5 == '=' &&
! 206: token6 == 34 &&
! 207: sHref.equals ("ns") &&
! 208: sAs.equals ("prefix")) {
! 209: RDF2LP2.addNamespace (sAsValue, sHrefValue);
! 210: }
! 211: }
! 212: } catch (Exception e) {
! 213: System.out.println ("# Malformed namespace declaration "+data);
! 214: e.printStackTrace();
! 215: }
! 216: }
! 217: }
! 218:
! 219: /**
! 220: * Report all warnings, and continue parsing.
! 221: *
! 222: * @see org.xml.sax.ErrorHandler#warning
! 223: */
! 224: public void warning (SAXParseException exception)
! 225: {
! 226: System.out.println("Warning: " +
! 227: exception.getMessage() +
! 228: " (" +
! 229: exception.getSystemId() +
! 230: ':' +
! 231: exception.getLineNumber() +
! 232: ',' +
! 233: exception.getColumnNumber() +
! 234: ')');
! 235: }
! 236:
! 237:
! 238: /**
! 239: * Report all recoverable errors, and try to continue parsing.
! 240: *
! 241: * @see org.xml.sax.ErrorHandler#error
! 242: */
! 243: public void error (SAXParseException exception)
! 244: {
! 245: System.out.println("Recoverable Error: " +
! 246: exception.getMessage() +
! 247: " (" +
! 248: exception.getSystemId() +
! 249: ':' +
! 250: exception.getLineNumber() +
! 251: ',' +
! 252: exception.getColumnNumber() +
! 253: ')');
! 254: }
! 255:
! 256:
! 257: /**
! 258: * Report all fatal errors, and try to continue parsing.
! 259: *
! 260: * <p>Note: results are no longer reliable once a fatal error has
! 261: * been reported.</p>
! 262: *
! 263: * @see org.xml.sax.ErrorHandler#fatalError
! 264: */
! 265: public void fatalError (SAXParseException exception)
! 266: {
! 267: System.out.println("Fatal Error: " +
! 268: exception.getMessage() +
! 269: " (" +
! 270: exception.getSystemId() +
! 271: ':' +
! 272: exception.getLineNumber() +
! 273: ',' +
! 274: exception.getColumnNumber() +
! 275: ')');
! 276: }
! 277:
! 278: public static Parser createParser (String className) {
! 279: Parser parser = null;
! 280:
! 281: try {
! 282: // Get the named class.
! 283: Class c = Class.forName(className);
! 284: // Instantiate the parser.
! 285: parser = (Parser)(c.newInstance());
! 286: } catch (ClassNotFoundException e) {
! 287: System.err.println("SAX parser class " + className +
! 288: "cannot be loaded.");
! 289: System.exit(1);
! 290: } catch (IllegalAccessException e) {
! 291: System.err.println("SAX parser class " + className +
! 292: " does not have a zero-argument constructor.");
! 293: System.exit(1);
! 294: } catch (InstantiationException e) {
! 295: System.err.println("SAX parser class " + className +
! 296: " cannot be instantiated.");
! 297: System.exit(1);
! 298: }
! 299:
! 300: // Check the the parser object
! 301: // actually implements the Parser interface.
! 302: if (!(parser instanceof org.xml.sax.Parser)) {
! 303: System.err.println("Class " + className +
! 304: " does not implement org.xml.sax.Parser.");
! 305: System.exit(1);
! 306: }
! 307:
! 308: return parser;
! 309: }
! 310:
! 311: /**
! 312: * If a URL is relative, make it absolute against the current directory.
! 313: */
! 314: private static String makeAbsoluteURL (String url)
! 315: throws java.net.MalformedURLException {
! 316: URL baseURL;
! 317:
! 318: String currentDirectory = System.getProperty("user.dir");
! 319: String fileSep = System.getProperty("file.separator");
! 320: String file = currentDirectory.replace(fileSep.charAt(0), '/') + '/';
! 321:
! 322: if (file.charAt(0) != '/') {
! 323: file = "/" + file;
! 324: }
! 325: baseURL = new URL("file", null, file);
! 326:
! 327: return new URL(baseURL, url).toString();
! 328: }
! 329:
! 330:
! 331: /**
! 332: * Escape special characters for display.
! 333: */
! 334: private static String escapeCharacters(char ch[], int start, int length) {
! 335: StringBuffer out = new StringBuffer();
! 336:
! 337: for (int i = start; i < start+length; i++) {
! 338: if (ch[i] >= 0x20 && ch[i] < 0x7f) {
! 339: out.append(ch[i]);
! 340: } else {
! 341: out.append("&#" + (int)ch[i] + ';');
! 342: }
! 343: }
! 344:
! 345: return out.toString();
! 346: }
! 347:
! 348: /**
! 349: * Start processing an RDF/XML document instance
! 350: */
! 351: void processRDF (Element rdf) {
! 352: Element.resolve ();
! 353:
! 354: Enumeration e = rdf.children();
! 355: while (e.hasMoreElements()) {
! 356: Element ele = (Element)e.nextElement();
! 357:
! 358: if (isDescription (ele)) {
! 359: processDescription (ele, false, false, true);
! 360: } else if (isCollection (ele)) {
! 361: processCollection (ele);
! 362: } else if (isTypedProperty (ele)) {
! 363: String sID = ele.getAttribute ("ID");
! 364: String sBagID = ele.getAttribute ("bagID");
! 365: String sAbout = ele.getAttribute ("about");
! 366:
! 367: Enumeration e2 = ele.attributes ();
! 368: while (e2.hasMoreElements()) {
! 369: String sAttribute = (String)e2.nextElement();
! 370: String sValue = ele.getAttribute (sAttribute);
! 371: sValue = sValue.trim ();
! 372: if (!sAttribute.equals ("ID") &&
! 373: !sAttribute.equals ("bagID") &&
! 374: !sAttribute.equals ("about")) {
! 375: if (sValue.length() > 0) {
! 376: System.out.println ("Typednode with attribute "+sAttribute+" and value "+sValue);
! 377: Element newProperty = new Element (sAttribute,
! 378: new AttributeListImpl());
! 379: newProperty.addAttribute ("ID", sID);
! 380: newProperty.addAttribute ("about", sAbout);
! 381: Data newData = new Data (sValue);
! 382: newProperty.addChild (newData);
! 383: ele.addChild (newProperty);
! 384: }
! 385: }
! 386: }
! 387: String sObject = new String ();
! 388: if (sAbout != null)
! 389: sObject = sAbout;
! 390: else if (sID != null)
! 391: sObject = sID;
! 392: else
! 393: sObject = Element.newReificationID();
! 394:
! 395: String sDesc = processDescription (ele, false, false, true);
! 396: addTriple (Element.RDFSCHEMA + "#instanceOf",
! 397: sObject,
! 398: ele.name());
! 399: }
! 400: }
! 401: }
! 402:
! 403: /**
! 404: * processDescription takes the following parameters
! 405: *
! 406: * @param description The Description element itself
! 407: * @param inProperty A flag to tell whether this is a nested description
! 408: inside a property.
! 409: * @param reificate Do we need to reificate
! 410: * @param createBag Do we create a bag collection out of nested properties
! 411: *
! 412: * @return An ID for the description
! 413: */
! 414: private String processDescription (Element description,
! 415: boolean inProperty,
! 416: boolean reificate,
! 417: boolean createBag) {
! 418: if (description.done())
! 419: return description.ID();
! 420:
! 421: int iChildCount = 1;
! 422: boolean bOnce = true;
! 423:
! 424: /**
! 425: * Determine first all relevant values
! 426: */
! 427: String sAbout = description.getAttribute ("about");
! 428: String sAboutEach = description.getAttribute ("aboutEach");
! 429: String sBagid = description.getAttribute ("bagID");
! 430: String sID = description.getAttribute ("ID");
! 431: Element target = description.target();
! 432: boolean hasTarget = ( target != null );
! 433: boolean targetIsBag = false;
! 434: String sTargetAbout = null;
! 435: String sTargetBagid = null;
! 436:
! 437: if (hasTarget) {
! 438: sTargetAbout = target.getAttribute ("about");
! 439: sTargetBagid = target.getAttribute ("bagID");
! 440: if (sAbout != null && sTargetBagid != null) {
! 441: targetIsBag = (sAbout.substring(1).equals (sTargetBagid));
! 442: }
! 443: }
! 444:
! 445: /**
! 446: * Manage the properties encoded as attributes by creating
! 447: * a new child node for each one of them. In this way
! 448: * the code for non-abbreviated properties will also work.
! 449: */
! 450:
! 451: Enumeration e = description.attributes ();
! 452: while (e.hasMoreElements()) {
! 453: String sAttribute = (String)e.nextElement ();
! 454: String sValue = description.getAttribute(sAttribute);
! 455: sValue = sValue.trim ();
! 456:
! 457: /**
! 458: * Create child nodes for non-RDF specific attributes
! 459: */
! 460: if (!sAttribute.equals ("about") &&
! 461: !sAttribute.equals ("aboutEach") &&
! 462: !sAttribute.equals ("ID") &&
! 463: !sAttribute.equals ("bagID")) {
! 464: if (sValue.length() > 0) {
! 465: Element ele = new Element (sAttribute,
! 466: new AttributeListImpl());
! 467: ele.addChild (new Data (sValue));
! 468: description.addChild (ele);
! 469: }
! 470: }
! 471: }
! 472:
! 473: /**
! 474: * Resolve distributive referents here
! 475: *
! 476: * Use straight-forward replication of properties
! 477: * to newly created description nodes
! 478: */
! 479:
! 480: if (hasTarget && sAboutEach != null) {
! 481:
! 482: e = target.children ();
! 483: while (e.hasMoreElements()) {
! 484: Element ele = (Element)e.nextElement ();
! 485:
! 486: String sResource = ele.getAttribute ("resource");
! 487: Element newDescription = null;
! 488: if (sResource != null) {
! 489: newDescription = new Element ("RDF:Description",
! 490: new AttributeListImpl());
! 491: newDescription.addAttribute ("about", sResource);
! 492: }
! 493: Enumeration e2 = description.children();
! 494: while (e2.hasMoreElements()) {
! 495: Element ele2 = (Element)e2.nextElement ();
! 496: if (newDescription != null) {
! 497: newDescription.addChild (ele2);
! 498: }
! 499: }
! 500: if (newDescription != null)
! 501: processDescription (newDescription, false, false, false);
! 502: }
! 503:
! 504: // should not return anything I think
! 505: return null;
! 506: }
! 507:
! 508: /**
! 509: * Enumerate through the children
! 510: */
! 511: e = description.children();
! 512:
! 513: while (e.hasMoreElements()) {
! 514: Element n = (Element)e.nextElement();
! 515:
! 516: if (isCollection (n)) {
! 517: processCollection (n);
! 518:
! 519: } else if (n instanceof Element) {
! 520:
! 521: /**
! 522: * Quote from the spec:
! 523: *
! 524: * The Description element itself creates an instance of a Bag
! 525: * node. The members of this Bag are the nodes corresponding
! 526: * to the reification of each of the properties in the
! 527: * Description. If the BAGID attribute is specified its value
! 528: * is the identifier of this Bag, else the Bag is anonymous.
! 529: */
! 530: String sChildID = null;
! 531:
! 532: if (hasTarget && targetIsBag) {
! 533: sChildID = processProperty (n, description,
! 534: target.ID(), false);
! 535: description.ID (sChildID);
! 536: } else if (hasTarget) {
! 537: sChildID = processProperty (n, description,
! 538: sTargetAbout, reificate);
! 539: description.ID (sChildID);
! 540: } else if (!hasTarget && !inProperty) {
! 541: if (sAbout == null)
! 542: if (sID != null)
! 543: sAbout = sID;
! 544: else
! 545: sAbout = description.ID();
! 546: sChildID = processProperty (n, description,
! 547: ( sAbout != null ? sAbout : sID),
! 548: createBag);
! 549: description.ID (sChildID);
! 550: } else if (!hasTarget && inProperty) {
! 551: if (sAbout == null) {
! 552: if (sID != null) {
! 553: description.ID (sID);
! 554: sAbout = sID;
! 555: } else {
! 556: description.ID (Element.newReificationID());
! 557: sAbout = description.ID();
! 558: }
! 559: }
! 560: sChildID = processProperty (n, description,
! 561: sAbout, reificate);
! 562: }
! 563:
! 564:
! 565: if (createBag) {
! 566: String sNamespace = Element.RDFSCHEMA;
! 567: if (bOnce) {
! 568: bOnce = false;
! 569: description.ID (Element.newReificationID());
! 570:
! 571: addTriple (sNamespace + "#instanceOf",
! 572: description.ID(),
! 573: sNamespace + "#Bag");
! 574: }
! 575: addTriple (sNamespace + "#"+iChildCount,
! 576: description.ID(),
! 577: sChildID);
! 578: iChildCount++;
! 579: }
! 580: }
! 581: }
! 582:
! 583: description.done (true);
! 584:
! 585: return description.ID();
! 586: }
! 587:
! 588: /**
! 589: * processProperty handles all elements not defined as special
! 590: * RDF elements.
! 591: *
! 592: * @param property The Property element itself
! 593: * @param description The Description element in which this property appears
! 594: * @param sTarget The target resource
! 595: * @param reificate Should this property be reificated
! 596: *
! 597: * @return the new ID which can be used to identify the property
! 598: */
! 599: private String processProperty (Element property,
! 600: Element description,
! 601: String sTarget,
! 602: boolean reificate) {
! 603: String sPropertyID = null;
! 604:
! 605: /**
! 606: * Do the same trick as with Description blocks:
! 607: * if the Property uses abbreviated syntax, transform
! 608: * the structure into corresponding full tree representation
! 609: * which is handled correctly by the code for the non-abbreviated
! 610: * syntax.
! 611: */
! 612:
! 613: String sID = property.getAttribute ("ID");
! 614: boolean bAbbreviated = false;
! 615: Element d = new Element ("RDF:Description",
! 616: new AttributeListImpl());
! 617:
! 618: Enumeration e = property.attributes ();
! 619: while (e.hasMoreElements()) {
! 620: String sAttribute = (String)e.nextElement();
! 621: String sValue = property.getAttribute (sAttribute);
! 622: sValue = sValue.trim ();
! 623: if (!sAttribute.equals ("about") &&
! 624: !sAttribute.equals ("ID") &&
! 625: !sAttribute.equals ("bagID")) {
! 626: if (sValue.length() > 0) {
! 627: bAbbreviated = true;
! 628: Element newProperty = new Element (sAttribute,
! 629: new AttributeListImpl());
! 630: Data newData = new Data (sValue);
! 631: newProperty.addChild (newData);
! 632: d.addChild (newProperty);
! 633: }
! 634: }
! 635: }
! 636: /**
! 637: * If we found properties and attributes and generated the subtree,
! 638: * attach it to the property itself and let the code below take
! 639: * care of the rest.
! 640: */
! 641: if (bAbbreviated) {
! 642: property.addChild (d);
! 643: }
! 644:
! 645: /**
! 646: * Does this property make a reference somewhere using # notation?
! 647: */
! 648: String sAbout = property.getAttribute ("about");
! 649: if (sAbout != null) {
! 650: if (property.target() != null) {
! 651: if (reificate) {
! 652: sPropertyID = reificate (property.expandName(),
! 653: sTarget, sPropertyID);
! 654: property.ID (sPropertyID);
! 655: } else {
! 656: sPropertyID = processDescription (property.target(),
! 657: true, false, false);
! 658: addTriple (property.expandName(),
! 659: sTarget,
! 660: sPropertyID);
! 661: }
! 662: }
! 663:
! 664: if (sAbout.charAt(0) == '#' &&
! 665: property.target() == null) {
! 666: System.err.println ("Unsolved reference "+property.getAttribute ("about"));
! 667: return null;
! 668: }
! 669: if (property.target() == null) {
! 670: if (reificate) {
! 671: sPropertyID = reificate (property.expandName(),
! 672: sTarget,
! 673: sAbout);
! 674: property.ID (sPropertyID);
! 675: } else {
! 676: addTriple (property.expandName(),
! 677: sTarget,
! 678: sAbout);
! 679: }
! 680: }
! 681: return sPropertyID;
! 682:
! 683: }
! 684:
! 685: Enumeration e2 = property.children();
! 686: while (e2.hasMoreElements()) {
! 687: Element n2 = (Element)e2.nextElement();
! 688:
! 689: if (isDescription (n2)) {
! 690: Element d2 = n2;
! 691:
! 692: sPropertyID = processDescription (d2, true, false, false);
! 693: d2.ID (sPropertyID);
! 694:
! 695: if (reificate) {
! 696: sPropertyID = reificate (property.expandName(),
! 697: sTarget, sPropertyID);
! 698: } else {
! 699: addTriple (property.expandName(),
! 700: sTarget, sPropertyID);
! 701: }
! 702:
! 703: } else if (n2 instanceof Data) {
! 704: /**
! 705: * We've got real data
! 706: */
! 707: String sValue = ((Data)n2).data();
! 708:
! 709: /**
! 710: * Only if the content is not empty PCDATA (whitespace that is),
! 711: * print the triple
! 712: */
! 713: sValue = sValue.trim();
! 714: if (sValue.length() > 0) {
! 715: if (reificate) {
! 716: sPropertyID = reificate (property.expandName(),
! 717: sTarget,
! 718: sValue);
! 719: property.ID (sPropertyID);
! 720: } else {
! 721: addTriple (property.expandName(),
! 722: sTarget,
! 723: sValue);
! 724: }
! 725: }
! 726: } else if (isCollection (n2)) {
! 727:
! 728: String sCollectionID = processCollection (n2);
! 729: sPropertyID = sCollectionID;
! 730:
! 731: /**
! 732: * Attach the collection to the current Property
! 733: */
! 734: if (description.target() != null) {
! 735: if (reificate) {
! 736: sPropertyID = reificate (property.expandName(),
! 737: description.target().getAttribute ("about"),
! 738: sCollectionID);
! 739: property.ID (sPropertyID);
! 740: } else {
! 741: addTriple (property.expandName(),
! 742: description.target().getAttribute ("about"),
! 743: sCollectionID);
! 744: }
! 745: } else {
! 746: if (reificate) {
! 747: sPropertyID = reificate (property.expandName(),
! 748: description.getAttribute ("about"),
! 749: sCollectionID);
! 750: property.ID (sPropertyID);
! 751: } else {
! 752: addTriple (property.expandName(),
! 753: description.getAttribute ("about"),
! 754: sCollectionID);
! 755: }
! 756: }
! 757: } else if (isTypedProperty (n2)) {
! 758: sPropertyID = processProperty (n2, description, sTarget, reificate);
! 759: addTriple (property.expandName(),
! 760: sTarget,
! 761: sPropertyID);
! 762: }
! 763: }
! 764:
! 765: return sPropertyID;
! 766: }
! 767:
! 768: private String processCollection (Element n) {
! 769: String sID = n.getAttribute ("ID");
! 770: if (sID == null)
! 771: sID = Element.newReificationID();
! 772:
! 773: /**
! 774: * Do the instantiation only once
! 775: */
! 776: if (!n.done()) {
! 777: String sNamespace = Element.RDFSCHEMA;
! 778: if (isSequence (n)) {
! 779: addTriple (sNamespace+"#instanceOf",
! 780: sID,
! 781: sNamespace+"#Sequence");
! 782: } else if (isAlternative (n)) {
! 783: addTriple (sNamespace+"#instanceOf",
! 784: sID,
! 785: sNamespace+"#Alt");
! 786: } else if (isBag (n)) {
! 787: addTriple (sNamespace+"#instanceOf",
! 788: sID,
! 789: sNamespace+"#Bag");
! 790: }
! 791: n.done (true);
! 792: }
! 793:
! 794: Enumeration e = ((Element)n).children();
! 795: int iCounter = 1;
! 796: while (e.hasMoreElements()) {
! 797: Element n2 = (Element)e.nextElement();
! 798: if (n2.name().equalsIgnoreCase ("rdf:li")) {
! 799: processListItem (sID, n2, iCounter);
! 800: iCounter++;
! 801: }
! 802: }
! 803:
! 804: return sID;
! 805: }
! 806:
! 807: private void processListItem (String sID, Element listitem, int iCounter) {
! 808: /**
! 809: * Two different cases for
! 810: * 1. LI element without content (href available)
! 811: * 2. LI element with content (href unavailable)
! 812: */
! 813: String sNamespace = RDF2LP2.namespace (listitem.prefix());
! 814: String sAbout = listitem.getAttribute ("resource");
! 815: if (sAbout != null) {
! 816: addTriple (sNamespace+"#"+iCounter,
! 817: sID,
! 818: sAbout);
! 819: } else {
! 820: Enumeration e = listitem.children();
! 821: while (e.hasMoreElements()) {
! 822: Element n = (Element)e.nextElement();
! 823: if (n instanceof Data) {
! 824: addTriple (sNamespace+"#"+iCounter,
! 825: sID,
! 826: ((Data)n).data());
! 827: } else if (isDescription (n)) {
! 828: processDescription (n, false, false, true);
! 829: }
! 830: }
! 831: }
! 832: }
! 833:
! 834: /**
! 835: * reificate creates one new node and four new triples
! 836: * and returns the ID of the new node
! 837: */
! 838: private String reificate (String sProperty,
! 839: String sPropertyObject,
! 840: String sPropertyValue) {
! 841: /**
! 842: * Reificate by creating 4 new triples
! 843: */
! 844: String sNamespace = Element.RDFSCHEMA;
! 845: String sNodeID = Element.newReificationID();
! 846:
! 847: addTriple (sNamespace + "#PropName",
! 848: sNodeID,
! 849: sProperty);
! 850:
! 851: addTriple (sNamespace + "#PropObj",
! 852: sNodeID,
! 853: sPropertyObject);
! 854:
! 855: addTriple (sNamespace + "#PropValue",
! 856: sNodeID,
! 857: sPropertyValue);
! 858:
! 859: addTriple (sNamespace + "#instanceOf",
! 860: sNodeID,
! 861: sNamespace + "#Property");
! 862:
! 863: return sNodeID;
! 864: }
! 865:
! 866: private void addTriple (String sProperty, String sPropertyObj, String sPropertyValue) {
! 867: Triple t = new Triple (sProperty, sPropertyObj, sPropertyValue);
! 868: m_triples.addElement (t);
! 869: }
! 870:
! 871: public void printTriples (PrintStream ps) {
! 872: for (int x = 0; x < m_triples.size(); x++) {
! 873: Triple t = (Triple)m_triples.elementAt (x);
! 874: ps.println ("triple(\""+t.property()+"\",\""+t.object()+"\",\""+t.value()+"\").");
! 875: }
! 876: }
! 877:
! 878: public Enumeration triples () {
! 879: return m_triples.elements ();
! 880: }
! 881:
! 882: /**
! 883: * Helper functions to identify different elements
! 884: */
! 885: public boolean isDescription (Element e) {
! 886: return e.name().equalsIgnoreCase ("rdf:description");
! 887: }
! 888:
! 889: public boolean isCollection (Element e) {
! 890: return (e.name().equalsIgnoreCase ("rdf:seq") ||
! 891: e.name().equalsIgnoreCase ("rdf:alt") ||
! 892: e.name().equalsIgnoreCase ("rdf:bag"));
! 893: }
! 894:
! 895: public boolean isSequence (Element e) {
! 896: return e.name().equalsIgnoreCase ("rdf:seq");
! 897: }
! 898:
! 899: public boolean isAlternative (Element e) {
! 900: return e.name().equalsIgnoreCase ("rdf:alt");
! 901: }
! 902:
! 903: public boolean isBag (Element e) {
! 904: return e.name().equalsIgnoreCase ("rdf:bag");
! 905: }
! 906:
! 907: public boolean isTypedProperty (Element e) {
! 908: int i = e.name().indexOf (":");
! 909: return i > -1;
! 910: }
! 911: }
Webmaster