KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > hp > hpl > jena > rdf > arp > XMLHandler


1 /*
2  * (c) Copyright 2001, 2002, 2003, 2004, 2005 Hewlett-Packard Development Company, LP All rights
3  * reserved.
4  *
5  * (c) Copyright 2003, Plugged In Software
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met: 1.
9  * Redistributions of source code must retain the above copyright notice, this
10  * list of conditions and the following disclaimer. 2. Redistributions in
11  * binary form must reproduce the above copyright notice, this list of
12  * conditions and the following disclaimer in the documentation and/or other
13  * materials provided with the distribution. 3. The name of the author may not
14  * be used to endorse or promote products derived from this software without
15  * specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
18  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
20  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  * $Id: XMLHandler.java,v 1.10 2005/04/15 15:37:44 chris-dollin Exp $
29  *
30  * AUTHOR: Jeremy J. Carroll
31  */

32 /*
33  * ARPFilter.java
34  *
35  * Created on June 21, 2001, 10:01 PM
36  */

37
38 package com.hp.hpl.jena.rdf.arp;
39
40 import java.util.*;
41
42 import org.xml.sax.Locator JavaDoc;
43 import org.xml.sax.Attributes JavaDoc;
44 import org.xml.sax.SAXException JavaDoc;
45 import org.xml.sax.SAXParseException JavaDoc;
46
47
48
49 /**
50  * This class converts SAX events into a stream
51  * of encapsulated events suitable for the RDF parser.
52  * In effect, this is the RDF lexer.
53  * updates by kers to handle exporting namespace prefix maps.
54  *
55  * @author jjc
56  */

57 abstract class XMLHandler
58     extends LexicalHandlerImpl
59     implements RDFParserConstants, ARPErrorNumbers {
60     static {
61         // org.apache.xerces.utils.XMLCharacterProperties.initCharFlags();
62
CharacterModel.isFullyNormalizedConstruct(
63             "make the linkage error happen early");
64     }
65
66     boolean encodingProblems = false;
67
68
69     public void startPrefixMapping(String JavaDoc prefix, String JavaDoc uri)
70          {
71         handlers.getNamespaceHandler().startPrefixMapping(prefix,uri);
72         
73     }
74     public void endPrefixMapping(String JavaDoc prefix)
75          {
76         handlers.getNamespaceHandler().endPrefixMapping(prefix);
77     }
78
79
80
81     void userWarning(ParseException e) throws SAXException JavaDoc {
82         //try {
83
handlers.getErrorHandler().warning(e.rootCause());
84         //}
85
//catch (Exception ee){
86
// throw new WrappedException(ee);
87
//}
88
}
89     void userError(ParseException e) throws SAXException JavaDoc {
90         if (e.getFatal())
91             handlers.getErrorHandler().fatalError(e.rootCause());
92         else
93             handlers.getErrorHandler().error(e.rootCause());
94     }
95     private Map nodeIdUserData;
96
97
98     Locator JavaDoc getLocator() {
99         return pipe == null ? null : pipe.getLocator();
100     }
101     StatementHandler getStatementHandler() {
102         return handlers.getStatementHandler();
103     }
104     public ARPHandlers getHandlers() {
105         return handlers;
106     }
107
108     ARPOptions getOptions() {
109         return options;
110     }
111     void setOptionsWith(ARPOptions newOpts) {
112         options = newOpts.copy();
113     }
114     void setHandlersWith(ARPHandlers newHh){
115         handlers = newHh.copy();
116     } // accessed in ARPQname.
117
XMLContext documentContext;
118     //String documentURI;
119
TokenPipe pipe;
120     Locator JavaDoc locator;
121     static final String JavaDoc rdfns =
122         "http://www.w3.org/1999/02/22-rdf-syntax-ns#".intern();
123     static final String JavaDoc xmlns = "http://www.w3.org/XML/1998/namespace".intern();
124     static final Map rdfnames = new HashMap();
125     static {
126         rdfnames.put("Description", new Integer JavaDoc(E_DESCRIPTION));
127         rdfnames.put("RDF", new Integer JavaDoc(E_RDF));
128         rdfnames.put("li", new Integer JavaDoc(E_LI));
129     }
130     static final Set knownRDFProperties = new HashSet();
131     static final Set knownRDFTypes = knownRDFProperties;
132     // WG decision makes this distinction spurious.
133
//new HashSet();
134
static {
135         knownRDFTypes.add("Bag");
136         knownRDFTypes.add("Seq");
137         knownRDFTypes.add("Alt");
138         knownRDFTypes.add("List");
139         knownRDFTypes.add("XMLLiteral");
140         knownRDFTypes.add("Property");
141         knownRDFProperties.add("type");
142         knownRDFTypes.add("Statement");
143         knownRDFProperties.add("subject");
144         knownRDFProperties.add("predicate");
145         knownRDFProperties.add("object");
146         knownRDFProperties.add("value");
147         knownRDFProperties.add("first");
148         knownRDFProperties.add("rest");
149         // not strictly true.
150
knownRDFProperties.add("nil");
151     }
152     static final Set knownBadRDFNames = new HashSet();
153     static {
154         knownBadRDFNames.add("ID");
155         knownBadRDFNames.add("about");
156         knownBadRDFNames.add("aboutEach");
157         knownBadRDFNames.add("aboutEachPrefix");
158         knownBadRDFNames.add("resource");
159         knownBadRDFNames.add("bagID");
160         knownBadRDFNames.add("parseType");
161         knownBadRDFNames.add("datatype");
162         knownBadRDFNames.add("li");
163         knownBadRDFNames.add("type");
164         knownBadRDFNames.add("Description");
165         knownBadRDFNames.add("nodeID");
166     }
167     // The order of these must match their occurrence in grammar rules.
168
static private String JavaDoc specialAtts[] =
169         { "base", "lang", "space", "ID", "about", "nodeID", "resource",
170         // "bagID",
171
"parseType", "datatype", "type" };
172     static private String JavaDoc specialNameSpaces[] =
173         { xmlns, xmlns, xmlns, rdfns, rdfns, rdfns,
174         // rdfns,
175
rdfns, rdfns, rdfns, rdfns };
176     // static private int A_XMLSPACE = -1;
177
static private int specialAttValues[] =
178         {
179             A_XMLBASE,
180             A_XMLLANG,
181             A_XMLSPACE,
182             A_ID,
183             A_ABOUT,
184             A_NODEID,
185             A_RESOURCE,
186         // A_BAGID,
187
A_PARSETYPE, A_DATATYPE, A_TYPE, };
188
189     void warning(int id, String JavaDoc s) {
190         try {
191             switch (options.getErrorMode()[id]) {
192                 case EM_IGNORE :
193                     break;
194                 case EM_WARNING :
195                     handlers.getErrorHandler().warning(new ParseException(id, s));
196                     break;
197                 case EM_ERROR :
198                     handlers.getErrorHandler().error(new ParseException(id, s));
199                     break;
200                 case EM_FATAL :
201                     handlers.getErrorHandler().fatalError(new ParseException(id, s));
202                     break;
203             }
204
205         } catch (SAXException JavaDoc e) {
206             throw new WrappedException(e);
207         }
208     }
209     
210     private ARPOptions options = new ARPOptions();
211     private ARPHandlers handlers = new ARPHandlers();
212     
213     void parseWarning(int id, Location where, String JavaDoc s) throws ParseException {
214         parseWarning(id, where, s, null);
215     }
216     void parseWarning(int id, Location where, String JavaDoc s, SAXParseException JavaDoc saxe)
217         throws ParseException {
218         int mode = options.getErrorMode()[id];
219         if (mode == EM_IGNORE)
220             return;
221         ParseException pe = new ParseException(id, where, s, saxe);
222         if (mode == EM_FATAL) {
223             pe.setFatal(true);
224             mode = EM_ERROR;
225         }
226         if (mode == EM_ERROR)
227             throw pe;
228
229         try {
230             userWarning(pe);
231             return;
232         } catch (ParseException rethrown) {
233             if (rethrown == pe)
234                 throw rethrown;
235             throw new WrappedException(pe);
236         } catch (SAXException JavaDoc e) {
237             throw new WrappedException(e);
238         }
239     }
240     void parseWarning(Warn w) throws ParseException {
241         parseWarning(w.number, w.location, w.msg);
242     }
243     void putWarning(int no, Location where, String JavaDoc msg) throws SAXParseException JavaDoc {
244         pipe.putNextToken(new Warn(no, where, msg));
245     }
246
247     void setUserData(String JavaDoc nodeId, Object JavaDoc v) {
248         nodeIdUserData.put(nodeId, v);
249     }
250
251     Object JavaDoc getUserData(String JavaDoc nodeId) {
252         return nodeIdUserData.get(nodeId);
253     }
254     public void setDocumentLocator(Locator JavaDoc locator) {
255         this.locator = locator;
256     }
257
258     private void doSpecialAtt(
259         int ix,
260         int attName,
261         String JavaDoc ns,
262         BitSet attsDone,
263         Attributes JavaDoc atts,
264         Location where)
265         throws SAXException JavaDoc {
266
267         attsDone.set(ix);
268
269         if (attName == A_XMLSPACE)
270             return;
271
272         pipe.putNextToken(
273             new ARPQname(attName, where, ns, null, atts.getQName(ix)));
274         String JavaDoc val = atts.getValue(ix);
275
276         if (attName == A_PARSETYPE) {
277             if (val.equals("Resource")) {
278                 pipe.putNextToken(new StrToken(AV_RESOURCE, where, val));
279             } else if (val.equals("Collection")) {
280                 pipe.putNextToken(new StrToken(AV_COLLECTION, where, val));
281             } else if (
282                 val.equals("daml:collection")
283                     && options.getErrorMode()[WARN_IN_STRICT_MODE] != EM_ERROR) {
284                 pipe.putNextToken(new StrToken(AV_DAMLCOLLECTION, where, val));
285                 putWarning(
286                     IGN_DAML_COLLECTION,
287                     where,
288                     "Illegal parseType: " + val);
289             } else {
290                 pipe.putNextToken(new StrToken(AV_LITERAL, where, val));
291                 if (!val.equals("Literal")) {
292                     putWarning(
293                         WARN_UNKNOWN_PARSETYPE,
294                         where,
295                         "Unknown parseType: " + val);
296                 }
297             }
298         } else {
299             pipe.putNextToken(new StrToken(AV_STRING, where, val));
300         }
301     }
302     public void startElement(
303         String JavaDoc uri,
304         String JavaDoc localName,
305         String JavaDoc rawName,
306         Attributes JavaDoc atts)
307         throws SAXException JavaDoc {
308         Location where = new Location(locator);
309         putElementQname(uri, localName, rawName, where);
310         BitSet attsDone = new BitSet();
311
312         for (int i = 0; i < atts.getLength(); i++) {
313             String JavaDoc qn = atts.getQName(i);
314             String JavaDoc prefix;
315             if (qn.startsWith("xmlns")) {
316                 prefix = "";
317                 if (qn.equals("xmlns")) {
318                 } else if (qn.charAt(5) == ':') {
319                     prefix = qn.substring(6);
320                     // atts.getLocalName(i);
321
} else {
322                     continue;
323                 }
324
325                 attsDone.set(i);
326                 pipe.putNextToken(new StrToken(A_XMLNS, where, prefix));
327                 String JavaDoc nsuri = atts.getValue(i);
328                 pipe.putNextToken(new StrToken(AV_STRING, where, nsuri));
329                 // System.err.println(prefix + " => " + atts.getValue(i));
330
if (nsuri.startsWith(rdfns) && !nsuri.equals(rdfns))
331                     putWarning(
332                         WARN_BAD_RDF_NAMESPACE_URI,
333                         where,
334                         "Namespace URI ref "
335                             + nsuri
336                             + " may not be used in RDF/XML.");
337                 if (nsuri.startsWith(xmlns) && !nsuri.equals(xmlns))
338                     putWarning(
339                         WARN_BAD_XML_NAMESPACE_URI,
340                         where,
341                         "Namespace URI ref "
342                             + nsuri
343                             + " may not be used in RDF/XML.");
344
345             }
346         }
347         for (int i = 0; i < specialAtts.length; i++) {
348             int ix = atts.getIndex(specialNameSpaces[i], specialAtts[i]);
349             if (ix != -1) {
350                 doSpecialAtt(
351                     ix,
352                     specialAttValues[i],
353                     specialNameSpaces[i],
354                     attsDone,
355                     atts,
356                     where);
357             }
358             if (specialNameSpaces[i] == rdfns) {
359                 ix = atts.getIndex("", specialAtts[i]);
360                 if (ix != -1) {
361                     putWarning(
362                         WARN_UNQUALIFIED_RDF_ATTRIBUTE,
363                         where,
364                         "Unqualified use of rdf:"
365                             + atts.getLocalName(ix)
366                             + " has been deprecated.");
367                     doSpecialAtt(
368                         ix,
369                         specialAttValues[i],
370                         "",
371                         attsDone,
372                         atts,
373                         where);
374                 }
375             }
376         }
377         for (int i = 0; i < atts.getLength(); i++) {
378             if (!attsDone.get(i)) {
379                 String JavaDoc ns = atts.getURI(i);
380                 String JavaDoc qn = atts.getQName(i);
381                 if (qn.length() >= 3
382                     && qn.substring(0, 3).toLowerCase().equals("xml")) {
383                     putWarning(
384                         WARN_UNKNOWN_XML_ATTRIBUTE,
385                         where,
386                         "XML attribute: "
387                             + atts.getQName(i)
388                             + " is not known and is being discarded.");
389                     continue;
390                 }
391                 if (ns.equals("")) {
392                     putWarning(
393                         WARN_UNQUALIFIED_ATTRIBUTE,
394                         where,
395                         "Attribute: "
396                             + atts.getLocalName(i)
397                             + ". Unqualified use is deprecated. Assuming namespace: "
398                             + uri);
399                     ns = uri;
400                 }
401                 putAttributeQname(ns, atts.getLocalName(i), qn, where);
402                 pipe.putNextToken(
403                     new StrToken(AV_STRING, where, atts.getValue(i)));
404             }
405         }
406     }
407
408     public void endElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc rawName)
409         throws SAXException JavaDoc {
410         Location loc = new Location(locator);
411         pipe.putNextToken(new Token(E_END, loc));
412     }
413     public void characters(char ch[], int start, int length)
414         throws SAXException JavaDoc {
415         Location loc = new Location(locator);
416         pipe.putNextToken(
417             new StrToken(CD_STRING, loc, new String JavaDoc(ch, start, length)));
418     }
419     public void ignorableWhitespace(char ch[], int start, int length)
420         throws SAXException JavaDoc { // Never called.
421
characters(ch, start, length);
422     }
423     private boolean isMemberProperty(String JavaDoc name) {
424         if (name.startsWith("_")) {
425             String JavaDoc number = name.substring(1);
426             if (number.startsWith("-") || number.startsWith("0"))
427                 return false;
428             try {
429                 Integer.parseInt(number);
430                 return true;
431             } catch (NumberFormatException JavaDoc e) {
432                 try {
433                     // It might be > Integer.MAX_VALUE
434
new java.math.BigInteger JavaDoc(number);
435                     return true;
436                 } catch (NumberFormatException JavaDoc ee) {
437                     return false;
438                 }
439             }
440         }
441         return false;
442     }
443     private boolean isKnownRDFProperty(String JavaDoc name) {
444         return knownRDFProperties.contains(name);
445     }
446     private void putElementQname(
447         String JavaDoc uri,
448         String JavaDoc localName,
449         String JavaDoc q,
450         Location where)
451         throws SAXException JavaDoc {
452         Token warn = null;
453         if (uri.equals(rdfns)) {
454             Integer JavaDoc val = (Integer JavaDoc) rdfnames.get(localName);
455             if (val == null) {
456                 if (isMemberProperty(localName)) {
457                     pipe.putNextToken(
458                         new ARPQname(E_RDF_N, where, uri, localName, q));
459                     return;
460                 } else if (
461                     !(knownRDFTypes.contains(localName)
462                         || isKnownRDFProperty(localName))) {
463                     if (knownBadRDFNames.contains(localName))
464                         warn =
465                             new Warn(
466                                 ERR_BAD_RDF_ELEMENT,
467                                 where,
468                                 "Creating statement(s) for syntactic RDF element: '<rdf:"
469                                     + localName
470                                     + "'.");
471                     else
472                         warn =
473                             new Warn(
474                                 WARN_UNKNOWN_RDF_ELEMENT,
475                                 where,
476                                 "Creating statement(s) for unknown RDF element: '<rdf:"
477                                     + localName
478                                     + "'.");
479                 }
480             } else {
481                 pipe.putNextToken(
482                     new ARPQname(val.intValue(), where, uri, localName, q));
483                 return;
484             }
485         }
486         pipe.putNextToken(new ARPQname(E_OTHER, where, uri, localName, q));
487         if (warn != null)
488             pipe.putNextToken(warn);
489     }
490
491     private void putAttributeQname(
492         String JavaDoc ns,
493         String JavaDoc local,
494         String JavaDoc q,
495         Location where)
496         throws SAXException JavaDoc {
497         if (ns.equals(rdfns)) {
498             if (isMemberProperty(local)) {
499                 pipe.putNextToken(new ARPQname(A_RDF_N, where, ns, local, q));
500                 return;
501             } else if (!isKnownRDFProperty(local)) {
502                 if (knownBadRDFNames.contains(local))
503                     putWarning(
504                         ERR_BAD_RDF_ATTRIBUTE,
505                         where,
506                         "Inappropriate or removed RDF attribute: 'rdf:"
507                             + local
508                             + "'.");
509                 else
510                     putWarning(
511                         WARN_UNKNOWN_RDF_ATTRIBUTE,
512                         where,
513                         "Creating statement for unknown RDF property: 'rdf:"
514                             + local
515                             + "'.");
516             }
517         }
518         pipe.putNextToken(new ARPQname(A_OTHER, where, ns, local, q));
519     }
520
521
522
523
524     public void comment(char[] ch, int start, int length) throws SAXParseException JavaDoc {
525         Location where = new Location(locator);
526         pipe.putNextToken(
527             new StrToken(COMMENT, where, new String JavaDoc(ch, start, length)));
528     }
529
530     public void processingInstruction(String JavaDoc target, String JavaDoc data)
531         throws SAXException JavaDoc {
532         Location where = new Location(locator);
533         pipe.putNextToken(
534             new StrToken(
535                 PROCESSING_INSTRUCTION,
536                 where,
537                 (data == null ? target : target + " " + data)));
538         // pipe.putNextToken( new ARPQname(E_RDF_N,where,uri,localName, q) );
539
}
540
541     public void error(SAXParseException JavaDoc e) throws SAXParseException JavaDoc {
542         saxError(ERR_SAX_ERROR, e);
543     }
544     public void warning(SAXParseException JavaDoc e) throws SAXParseException JavaDoc {
545         saxError(WARN_SAX_WARNING, e);
546     }
547     public void fatalError(SAXParseException JavaDoc e) throws SAXException JavaDoc {
548         saxError(ERR_SAX_FATAL_ERROR, e);
549         throw new FatalParsingErrorException();
550     }
551     void generalError(int i, Exception JavaDoc e) throws SAXParseException JavaDoc {
552         Location where = new Location(locator);
553         // System.err.println(e.getMessage());
554
pipe.putNextToken(new ExceptionToken(i, where, e));
555
556     }
557     private void saxError(int i, SAXParseException JavaDoc e) throws SAXParseException JavaDoc {
558         Location where =
559             new Location(
560                 e.getSystemId(),
561                 e.getLineNumber(),
562                 e.getColumnNumber());
563
564         pipe.putNextToken(new ExceptionToken(i, where, e));
565
566     }
567
568     /**
569      * @param v
570      */

571     void endLocalScope(Object JavaDoc v) {
572         
573         if (handlers.getExtendedHandler() != ARPHandlers.nullScopeHandler
574           && v != null
575           && v instanceof ARPResource) {
576             ARPResource bn = (ARPResource) v;
577             if (!bn.isAnonymous())
578                 return;
579           if (!bn.getHasBeenUsed())
580             return;
581             if (bn.hasNodeID()) {
582                 // save for later end scope
583
if ( handlers.getExtendedHandler().discardNodesWithNodeID())
584                   return;
585                   
586                 String JavaDoc bnodeID = bn.nodeID;
587                 if (!nodeIdUserData.containsKey(bnodeID))
588                     nodeIdUserData.put(bnodeID, null);
589             } else {
590                 handlers.getExtendedHandler().endBNodeScope(bn);
591                 
592             }
593         }
594     }
595
596     void endRDF() {
597         handlers.getExtendedHandler().endRDF();
598     }
599     void startRDF() {
600         handlers.getExtendedHandler().startRDF();
601     }
602
603     boolean ignoring(int eCode) {
604         return options.getErrorMode()[eCode]==EM_IGNORE;
605     }
606     protected void initParse(String JavaDoc base) throws MalformedURIException {
607         nodeIdUserData = new HashMap();
608         //String base = input.getSystemId();
609
if (base == null) {
610             warning(
611                 IGN_NO_BASE_URI_SPECIFIED,
612                 "Base URI not specified for input file; local URI references will be in error.");
613             documentContext =
614                 new XMLNullContext(this, ERR_RESOLVING_URI_AGAINST_NULL_BASE);
615     
616         } else if (base.equals("")) {
617             warning(
618                 IGN_NO_BASE_URI_SPECIFIED,
619                 "Base URI specified as \"\"; local URI references will not be resolved.");
620             documentContext =
621                 new XMLNullContext(this, WARN_RESOLVING_URI_AGAINST_EMPTY_BASE);
622         } else {
623             base = ParserSupport.truncateXMLBase(base);
624     
625             documentContext = new XMLContext(base);
626         }
627     }
628     void endBnodeScope() {
629         if ( getHandlers().getExtendedHandler() != ARPHandlers.nullScopeHandler ) {
630             Iterator it = nodeIdUserData.keySet().iterator();
631             while (it.hasNext()) {
632                 String JavaDoc nodeId = (String JavaDoc)it.next();
633                 ARPResource bn = new ARPResource(this);
634                 bn.setNodeId(nodeId);
635                 getHandlers().getExtendedHandler().endBNodeScope(bn);
636             }
637         }
638     }
639     
640
641 }
642
Popular Tags