/[cashew-s-editor]/cashews/src/nongnu/cashews/rdf/XMLParser.java
ViewVC logotype

Diff of /cashews/src/nongnu/cashews/rdf/XMLParser.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.8 by gnu_andrew, Sat Apr 9 22:11:10 2005 UTC revision 1.9 by gnu_andrew, Sun Apr 17 18:35:32 2005 UTC
# Line 22  Line 22 
22  package nongnu.cashews.rdf;  package nongnu.cashews.rdf;
23    
24  import java.io.File;  import java.io.File;
 import java.io.FileInputStream;  
25  import java.io.FileNotFoundException;  import java.io.FileNotFoundException;
26  import java.io.IOException;  import java.io.IOException;
 import java.net.URI;  
 import java.net.URISyntaxException;  
 import java.util.HashSet;  
 import java.util.Set;  
27  import java.util.logging.ConsoleHandler;  import java.util.logging.ConsoleHandler;
28  import java.util.logging.Handler;  import java.util.logging.Handler;
29  import java.util.logging.Level;  import java.util.logging.Level;
 import java.util.logging.Logger;  
30    
31  import nongnu.cashews.commons.Pair;  import nongnu.cashews.xml.Parser;
 import nongnu.cashews.xml.XmlBaseHandler;  
32    
 import org.xml.sax.Attributes;  
 import org.xml.sax.InputSource;  
33  import org.xml.sax.SAXException;  import org.xml.sax.SAXException;
 import org.xml.sax.XMLReader;  
 import org.xml.sax.helpers.XMLReaderFactory;  
34    
35  /**  /**
36   * This class deals with the parsing of RDF in XML form, as defined by the   * This class is simply a wrapper around the existing parser to enable
37   * <a href="http://www.w3.org/TR/rdf-syntax-grammar/">RDFXML </a> syntax   * the testing of RDF parsing.
  * standard.  It turns an XML-based representation of an RDF graph into a  
  * <code>Graph</code> object.  
38   *   *
39   * @author Andrew John Hughes (gnu_andrew@member.fsf.org)   * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
  * @see Graph  
40   */   */
41  public class XMLParser  public class XMLParser
42      extends Parser
43  {  {
44    
45    /**    /**
46     * The RDF namespace.     * Constructs a new RDF-based parser, using the specified handler
    */  
   public static final String  
     RDF_NAMESPACE = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";  
   
   /**  
    * The reader, which interprets the XML file.  
    *  
    * @serial the XML reader.  
    */  
   private XMLReader reader;  
   
   /**  
    * The resulting graph.  
    *  
    * @serial the graph of RDF triples.  
    */  
   private Graph graph;  
   
   /**  
    * The handler for the XML.  
    *  
    * @serial the XML handler.  
    */  
   private RDFHandler rdfHandler;  
   
   /**  
    * Constructs a new XML-based RDF parser, using the specified handler  
47     * for messages.     * for messages.
48     *     *
49     * @param handler the handler to use for log messages.     * @param logHandler the handler to use for log messages.
50     * @throws SAXException if the parser fails to obtain an     * @throws SAXException if the parser fails to obtain an
51     *         <code>XMLReader</code> instance.     *         <code>XMLReader</code> instance.
52     */     */
53    public XMLParser(Handler handler)    public XMLParser(Handler handler)
54      throws SAXException      throws SAXException
55    {    {
56      reader = XMLReaderFactory.createXMLReader();      super(handler, new RDFHandler(handler));
     rdfHandler = new RDFHandler(handler);  
     reader.setContentHandler(rdfHandler);  
   }  
   
   /**  
    * Parse an RDF document from the specified system identifier (URI).  
    *  
    * @param systemId the URI of the RDF document.  
    * @return the graph generated by the parsing process.  
    * @throws SAXException if an error occurs in parsing.  
    * @throws IOException if an error occurs in the underlying input.  
    */  
   public Graph parse(String systemId)  
     throws IOException, SAXException  
   {  
     return parse(new InputSource(systemId));  
   }  
   
   /**  
    * Parse an RDF document from the specified input source.  
    *  
    * @param source the source of the RDF document.  
    * @return the graph generated by the parsing process.  
    * @throws SAXException if an error occurs in parsing.  
    * @throws IOException if an error occurs in the underlying input.  
    */  
   public Graph parse(InputSource source)  
     throws IOException, SAXException  
   {  
     graph = new Graph();  
     rdfHandler.setBaseURI(source.getSystemId());  
     reader.parse(source);  
     return graph;  
57    }    }
58    
59    /**    /**
60     * Parse an RDF document from the specified file.     * Retrieves the RDF handler used by the parser.
61     *     *
62     * @param file the file containing the RDF document.     * @return the XML event handler.
    * @return the graph generated by the parsing process.  
    * @throws SAXException if an error occurs in parsing.  
    * @throws IOException if an error occurs in the underlying input.  
63     */     */
64    public Graph parse(File file)    public RDFHandler getRDFHandler()
     throws IOException, SAXException  
65    {    {
66      return parse(new InputSource(new FileInputStream(file)));      return (RDFHandler) getHandler();
67    }    }
68    
69    /**    /**
# Line 161  public class XMLParser Line 84  public class XMLParser
84      handler.setLevel(Level.FINE);      handler.setLevel(Level.FINE);
85      XMLParser parser = new XMLParser(handler);      XMLParser parser = new XMLParser(handler);
86      for (int a = 0; a < args.length; ++a)      for (int a = 0; a < args.length; ++a)
         System.out.println(parser.parse(new File(args[a])));  
   }  
   
   /**  
    * Handles capturing the XML events and turning them into an RDF  
    * <code>Graph</code>.  
    *  
    * @author Andrew John Hughes (gnu_andrew@member.fsf.org)  
    */  
   private class RDFHandler  
     extends XmlBaseHandler  
   {  
   
     /**  
      * A <code>Logger</code> instance to log events generated by the  
      * parsing process.  
      */  
     private Logger rdfLogger;  
   
     /**  
      * Flag to indicate whether we are inside an RDF document  
      * or not.  There is not a one-to-one correspondence between  
      * an RDF document and the XML document.  RDF is to usually  
      * to be expected inside an RDF element.  However, a single  
      * <code>Description</code> element may occur on its own, outside  
      * this context.  In either of these cases, this flag should  
      * be set.  
      */  
     private boolean inRDF;  
   
     /**  
      * Flag to indicate whether we are inside a subject node or  
      * not.  
      */  
     private boolean inSubject;  
   
     /**  
      * Flag to indicate whether we are inside a predicate node or  
      * not.  
      */  
     private boolean inPredicate;  
   
     /**  
      * The current triple.  
      */  
     private Triple triple;  
   
     /**  
      * The current subject in the current RDF triple.  
      */  
     private Subject subject;  
   
     /**  
      * The current predicate in the current RDF triple.  
      */  
     private Predicate predicate;  
   
     /**  
      * The current object in the current RDF triple.  
      */  
     private RDFObject object;  
   
     /**  
      * The String form of the URI of the current predicate.  
      */  
     private String predicateURI;  
   
     /**  
      * The type of the current literal.  
      */  
     private Type type;  
   
     /**  
      * The set of ids used in the RDF document.  RDF IDs must be unique  
      * within a particular base URI.  
      */  
     private Set<Pair<URI,String>> ids;  
   
     /**  
      * Constructs a new <code>RDFHandler</code>, using the specified  
      * handler for log messages.  
      *  
      * @param handler the handler to use for log messages.  
      */  
     public RDFHandler(Handler handler)  
     {  
       super(handler);  
       rdfLogger = Logger.getLogger("nongnu.cashews.rdf.XMLParser");  
       rdfLogger.addHandler(handler);  
       rdfLogger.setLevel(handler.getLevel());  
     }  
   
     /**  
      * Captures the start of the document and sets up the initial  
      * state.  
      */  
     public void startDocument()  
     {  
       super.startDocument();  
       inSubject = false;  
       inRDF = false;  
       inPredicate = false;  
       predicateURI = null;  
       type = null;  
       subject = null;  
       predicate = null;  
       object = null;  
       ids = new HashSet<Pair<URI,String>>();  
     }  
   
     /**  
      * Captures the start of an XML element.  
      *  
      * @param uri the namespace URI.  
      * @param localName the local name of the element inside the namespace.  
      * @param qName the local name qualified with the namespace URI.  This  
      *              may or may not be provided, as we don't ask for namespace  
      *              prefixes.  
      * @param attributes the attributes of this element.  
      * @throws SAXException if some error occurs in parsing.  
      */  
     public void startElement(String uri, String localName,  
                              String qName, Attributes attributes)  
       throws SAXException  
     {  
       super.startElement(uri, localName, qName, attributes);  
       if (uri.equals(RDF_NAMESPACE))  
         {  
           if (localName.equals("RDF"))  
             {  
               /* rdf:RDF */  
               inRDF = true;  
               rdfLogger.finer("Start of RDF block");  
             }  
           else if (localName.equals("Description"))  
             {  
               /* rdf:Description */  
               rdfLogger.finer("Start of RDF description block");  
               inRDF = true;  
               if (!inSubject)  
                 {  
                   /* Check for RDF URI subject */  
                   String value = attributes.getValue(RDF_NAMESPACE, "about");  
                   if (value != null)  
                       subject = parseRDFURI(value);  
                   else  
                     {  
                       value = attributes.getValue(RDF_NAMESPACE, "ID");  
                       if (value != null)  
                         {  
                           boolean added =  
                             ids.add(new Pair<URI,String>(getBaseURI(), value));  
                           if (added)  
                             subject = new  
                               RDFURI(getBaseURI().resolve("#" + value));  
                         }  
                       else  
                         {  
                           /* Check for blank node subject */  
                           value = attributes.getValue(RDF_NAMESPACE, "nodeID");  
                           if (value != null)  
                             subject = new Blank(value);  
                         }  
                     }  
                   if (subject == null)  
                     rdfLogger.severe("No subject found in RDF " +  
                                      "description.");  
                   else  
                     {  
                       inSubject = true;  
                       rdfLogger.fine("Created subject: " + subject);  
                     }  
                 }  
               else  
                 rdfLogger.warning("Invalid use of RDF namespace: " + uri +  
                                localName);  
             }  
         }  
       else  
         {  
           if (inRDF)  
             {  
               if (inSubject)  
                 {  
                   /* Predicate element */  
                   predicateURI = uri + localName;  
                   rdfLogger.finer("Start of predicate: " + predicateURI);  
                   predicate = parseRDFURI(predicateURI);  
                   rdfLogger.fine("Created predicate: " + predicate);  
                   inSubject = false;  
                   inPredicate = true;  
                   /* Check for RDF URI object */  
                   String value = attributes.getValue(RDF_NAMESPACE,  
                                                      "resource");  
                   if (value != null)  
                     {  
                       object = parseRDFURI(value);  
                       rdfLogger.fine("Created object: " + object);  
                     }  
                   else  
                     {  
                       /* Check for blank node object */  
                       value = attributes.getValue(RDF_NAMESPACE, "nodeID");  
                       if (value != null)  
                         {  
                           object = new Blank(value);  
                           rdfLogger.fine("Created object: " + object);  
                         }  
                     }  
                   /* Check for a type */  
                   value = attributes.getValue(RDF_NAMESPACE, "datatype");  
                   if (value != null)  
                     type = TypeFactory.getInstance(value);  
                 }  
             }  
         }  
     }  
   
     /**  
      * Attempts to returns the RDF URI parsed from the specified  
      * <code>String</code>.  
      *  
      * @param value the value to parse.  
      * @return an RDF URI.  
      * @throws SAXException if the URI can't be parsed.  
      */  
     private RDFURI parseRDFURI(String value)  
       throws SAXException  
     {  
       try  
         {  
           return new RDFURI(new URI(value));  
         }  
       catch (URISyntaxException e)  
         {  
           throw new SAXException("Failed to parse URI: " + e, e);  
         }  
     }  
   
     /**  
      * Captures characters within an XML element.  
      *  
      * @param ch the array of characters.  
      * @param start the start index of the characters to use.  
      * @param length the number of characters to use from the start index on.  
      * @throws SAXException if some error occurs in parsing.  
      */  
     public void characters(char[] ch, int start, int length)  
       throws SAXException  
     {  
       super.characters(ch, start, length);  
       String value = new String(ch, start, length).trim();  
       if (value.length() == 0)  
         return;  
       rdfLogger.finer("Characters: " + value);  
       if (inPredicate)  
         {  
           if (type == null)  
             object = new Literal(value);  
           else  
             object = new Literal(value, type);  
           rdfLogger.fine("Created object: " + object);  
         }  
     }  
   
     /**  
      * Captures the end of an XML element.  
      *  
      * @param uri the namespace URI.  
      * @param localName the local name of the element inside the namespace.  
      * @param qName the local name qualified with the namespace URI.  This  
      *              may or may not be provided, as we don't ask for namespace  
      *              prefixes.  
      * @throws SAXException if some error occurs in parsing.  
      */  
     public void endElement(String uri, String localName,  
                            String qName)  
       throws SAXException  
     {  
       super.endElement(uri, localName, qName);  
       if (uri.equals(RDF_NAMESPACE))  
         {  
           if (localName.equals("RDF"))  
             {  
               inRDF = false;  
               rdfLogger.finer("End of RDF block");  
             }  
           else if (localName.equals("Description"))  
             {  
               rdfLogger.finer("End of description block");  
               inSubject = false;  
             }  
         }  
       else if (inPredicate && predicateURI.equals(uri + localName))  
87        {        {
88          inPredicate = false;          parser.parse(new File(args[a]));
89          inSubject = true;          System.out.println(parser.getRDFHandler().getGraph());
         predicateURI = null;  
         type = null;  
         triple = new Triple(subject, predicate, object);  
         rdfLogger.fine("Created triple: " + triple);  
         graph.addTriple(triple);  
         rdfLogger.finer("End of predicate block");  
90        }        }
     }  
   
91    }    }
92    
93  }  }

Legend:
Removed from v.1.8  
changed lines
  Added in v.1.9

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26