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