/[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.2 by gnu_andrew, Mon Mar 28 19:29:21 2005 UTC revision 1.3 by gnu_andrew, Sun Apr 3 17:15:39 2005 UTC
# Line 21  Line 21 
21    
22  package nongnu.cashews.rdf;  package nongnu.cashews.rdf;
23    
24    import java.io.File;
25    import java.io.FileInputStream;
26    import java.io.FileNotFoundException;
27    import java.io.IOException;
28    import java.net.URI;
29    import java.net.URISyntaxException;
30    import java.util.logging.ConsoleHandler;
31    import java.util.logging.Handler;
32    import java.util.logging.Level;
33    import java.util.logging.Logger;
34    
35    import org.xml.sax.Attributes;
36    import org.xml.sax.InputSource;
37    import org.xml.sax.SAXException;
38    import org.xml.sax.XMLReader;
39    import org.xml.sax.helpers.DefaultHandler;
40    import org.xml.sax.helpers.XMLReaderFactory;
41    
42  /**  /**
43   * This class deals with the parsing of RDF in XML form, as defined by the   * This class deals with the parsing of RDF in XML form, as defined by the
44   * <a href="http://www.w3.org/TR/rdf-syntax-grammar/">RDFXML </a> syntax   * <a href="http://www.w3.org/TR/rdf-syntax-grammar/">RDFXML </a> syntax
# Line 33  package nongnu.cashews.rdf; Line 51  package nongnu.cashews.rdf;
51  public class XMLParser  public class XMLParser
52  {  {
53    
54      /**
55       * The RDF namespace.
56       */
57      public static final String
58        RDF_NAMESPACE = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
59    
60      /**
61       * The reader, which interprets the XML file.
62       *
63       * @serial the XML reader.
64       */
65      private XMLReader reader;
66    
67      /**
68       * Constructs a new XML-based RDF parser, using the specified handler
69       * for messages.
70       *
71       * @param handler the handler to use for log messages.
72       * @throws SAXException if the parser fails to obtain an
73       *         <code>XMLReader</code> instance.
74       */
75      public XMLParser(Handler handler)
76        throws SAXException
77      {
78        reader = XMLReaderFactory.createXMLReader();    
79        reader.setContentHandler(new RDFHandler(handler));
80      }
81    
82      /**
83       * Parse an RDF document from the specified system identifier (URI).
84       *
85       * @param systemId the URI of the RDF document.
86       * @throws SAXException if an error occurs in parsing.
87       * @throws IOException if an error occurs in the underlying input.
88       */
89      public void parse(String systemId)
90        throws IOException, SAXException
91      {
92        reader.parse(systemId);
93      }
94    
95      /**
96       * Parse an RDF document from the specified input source.
97       *
98       * @param source the source of the RDF document.
99       * @throws SAXException if an error occurs in parsing.
100       * @throws IOException if an error occurs in the underlying input.
101       */
102      public void parse(InputSource source)
103        throws IOException, SAXException
104      {
105        reader.parse(source);
106      }
107    
108      /**
109       * Parse an RDF document from the specified file.
110       *
111       * @param file the file containing the RDF document.
112       * @throws SAXException if an error occurs in parsing.
113       * @throws IOException if an error occurs in the underlying input.
114       */
115      public void parse(File file)
116        throws IOException, SAXException
117      {
118        parse(new InputSource(new FileInputStream(file)));
119      }
120    
121      /**
122       * A simple test harness to parse the RDF files supplied on the command
123       * line.
124       *
125       * @param args the command line arguments.
126       * @throws SAXException if a <code>XMLReader</code> can't be obtained
127       *         or an error occurs during parsing.
128       * @throws IOException if an error occurs in the underlying input.
129       * @throws FileNotFoundException if one of the specified files can't
130       *         be found.
131       */
132      public static void main(String[] args)
133        throws SAXException, IOException, FileNotFoundException
134      {
135        Handler handler = new ConsoleHandler();
136        handler.setLevel(Level.FINE);
137        XMLParser parser = new XMLParser(handler);
138        for (int a = 0; a < args.length; ++a)
139            parser.parse(new File(args[a]));
140      }
141    
142      /**
143       * Handles capturing the XML events and turning them into an RDF
144       * <code>Graph</code>.
145       *
146       * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
147       */
148      private class RDFHandler
149        extends DefaultHandler
150      {
151    
152        /**
153         * A <code>Logger</code> instance to log events generated by the
154         * parsing process.
155         */
156        private Logger logger;
157    
158        /**
159         * Flag to indicate whether we are inside an RDF document
160         * or not.  There is not a one-to-one correspondence between
161         * an RDF document and the XML document.  RDF is to usually
162         * to be expected inside an RDF element.  However, a single
163         * <code>Description</code> element may occur on its own, outside
164         * this context.  In either of these cases, this flag should
165         * be set.
166         */
167        private boolean inRDF;
168    
169        /**
170         * Flag to indicate whether we are inside a subject node or
171         * not.
172         */
173        private boolean inSubject;
174    
175        /**
176         * Flag to indicate whether we are inside a predicate node or
177         * not.
178         */
179        private boolean inPredicate;
180    
181        /**
182         * The current triple.
183         */
184        private Triple triple;
185    
186        /**
187         * The current subject in the current RDF triple.
188         */
189        private Subject subject;
190    
191        /**
192         * The current predicate in the current RDF triple.
193         */
194        private Predicate predicate;
195    
196        /**
197         * The current object in the current RDF triple.
198         */
199        private RDFObject object;
200    
201        /**
202         * The String form of the URI of the current predicate.
203         */
204        private String predicateURI;
205    
206        /**
207         * Constructs a new <code>RDFHandler</code>, using the specified
208         * handler for log messages.
209         *
210         * @param handler the handler to use for log messages.
211         */
212        public RDFHandler(Handler handler)
213        {
214          logger = Logger.getLogger("nongnu.cashews.rdf.XMLParser");
215          logger.addHandler(handler);
216          logger.setLevel(handler.getLevel());
217        }
218    
219        /**
220         * Captures the start of the document and sets up the initial
221         * state.
222         */
223        public void startDocument()
224        {
225          inSubject = false;
226          inRDF = false;
227          inPredicate = false;
228          predicateURI = null;
229        }
230    
231        /**
232         * Captures the start of an XML element.
233         *
234         * @param uri the namespace URI.
235         * @param localName the local name of the element inside the namespace.
236         * @param qName the local name qualified with the namespace URI.  This
237         *              may or may not be provided, as we don't ask for namespace
238         *              prefixes.
239         * @param attributes the attributes of this element.
240         * @throws SAXException if some error occurs in parsing.
241         */
242        public void startElement(String uri, String localName,
243                                 String qName, Attributes attributes)
244          throws SAXException
245        {
246          if (uri.equals(RDF_NAMESPACE))
247            {
248              if (localName.equals("RDF"))
249                {
250                  inRDF = true;
251                  logger.finer("Start of RDF block");
252                }
253              else if (localName.equals("Description"))
254                {
255                  logger.finer("Start of RDF description block");
256                  inRDF = true;
257                  if (!inSubject)
258                    {
259                      String value = attributes.getValue(RDF_NAMESPACE, "about");
260                      if (value != null)
261                        {
262                          subject = parseRDFURI(value);
263                        }
264                      inSubject = true;
265                      logger.fine("Created subject: " + subject);
266                    }
267                  else
268                    logger.warning("Invalid use of RDF namespace: " + uri +
269                                   localName);
270                }
271            }
272          else
273            {
274              if (inSubject)
275                {
276                  predicateURI = uri + localName;
277                  logger.finer("Start of predicate: " + predicateURI);
278                  predicate = parseRDFURI(predicateURI);
279                  logger.fine("Created predicate: " + predicate);
280                  inSubject = false;
281                  inPredicate = true;
282                }
283            }
284        }
285    
286        /**
287         * Attempts to returns the RDF URI parsed from the specified
288         * <code>String</code>.
289         *
290         * @param value the value to parse.
291         * @return an RDF URI.
292         * @throws SAXException if the URI can't be parsed.
293         */
294        private RDFURI parseRDFURI(String value)
295          throws SAXException
296        {
297          try
298            {
299              return new RDFURI(new URI(value));
300            }
301          catch (URISyntaxException e)
302            {
303              throw new SAXException("Failed to parse URI: " + e, e);
304            }
305        }
306    
307        /**
308         * Captures characters within an XML element.
309         *
310         * @param ch the array of characters.
311         * @param start the start index of the characters to use.
312         * @param length the number of characters to use from the start index on.
313         * @throws SAXException if some error occurs in parsing.
314         */
315        public void characters(char[] ch, int start, int length)
316          throws SAXException
317        {
318          String value = new String(ch, start, length).trim();
319          if (value.length() == 0)
320            return;
321          logger.finer("Characters: " + value);
322          if (inPredicate)
323            {
324              object = new Literal(value);
325              logger.fine("Created object: " + object);
326            }
327        }
328    
329        /**
330         * Captures the end of an XML element.
331         *
332         * @param uri the namespace URI.
333         * @param localName the local name of the element inside the namespace.
334         * @param qName the local name qualified with the namespace URI.  This
335         *              may or may not be provided, as we don't ask for namespace
336         *              prefixes.
337         * @throws SAXException if some error occurs in parsing.
338         */
339        public void endElement(String uri, String localName,
340                               String qName)
341          throws SAXException
342        {
343          if (uri.equals(RDF_NAMESPACE))
344            {
345              if (localName.equals("RDF"))
346                {
347                  inRDF = false;
348                  logger.finer("End of RDF block");
349                }
350              else if (localName.equals("Description"))
351                {
352                  logger.finer("End of description block");
353                  triple = new Triple(subject, predicate, object);
354                  logger.fine("Created triple: " + triple);
355                  inSubject = false;
356                }
357            }
358          else if (inPredicate && predicateURI.equals(uri + localName))
359          {
360            inPredicate = false;
361            inSubject = true;
362            predicateURI = null;
363            logger.finer("End of predicate block");
364          }
365        }
366    
367      }
368    
369  }  }

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3

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