1:
37:
38:
39: package ;
40:
41: import ;
42:
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51:
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60:
61: import ;
62: import ;
63:
64: import ;
65:
66:
128: public class XCat implements EntityResolver2
129: {
130: private Catalog catalogs [];
131: private boolean usingPublic = true;
132: private boolean loadingPermitted = true;
133: private boolean unified = true;
134: private String parserClass;
135: private ErrorHandler errorHandler;
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
159: public XCat () { }
160:
161:
171: public XCat (String uri)
172: throws SAXException, IOException
173: { loadCatalog (uri); }
174:
175:
176:
208: public synchronized void loadCatalog (String uri)
209: throws SAXException, IOException
210: {
211: Catalog catalog;
212: int index = -1;
213:
214: if (!loadingPermitted)
215: throw new IllegalStateException ();
216:
217: uri = normalizeURI (uri);
218: if (catalogs != null) {
219:
220: for (index = 0; index < catalogs.length; index++)
221: if (uri.equals (catalogs [index].catalogURI))
222: break;
223: }
224: catalog = loadCatalog (parserClass, errorHandler, uri, unified);
225:
226:
227: if (catalogs == null) {
228: index = 0;
229: catalogs = new Catalog [1];
230: } else if (index == catalogs.length) {
231: Catalog tmp [];
232:
233: tmp = new Catalog [index + 1];
234: System.arraycopy (catalogs, 0, tmp, 0, index);
235: catalogs = tmp;
236: }
237: catalogs [index] = catalog;
238: }
239:
240:
241:
262: public InputSource resolveEntity (
263: String name,
264: String publicId,
265: String baseURI,
266: String systemId
267: ) throws SAXException, IOException
268: {
269: if (loadingPermitted)
270: disableLoading ();
271:
272: try {
273:
274:
275: for (int i = 0; i < catalogs.length; i++) {
276: InputSource retval;
277: retval = catalogs [i].resolve (usingPublic, publicId, systemId);
278: if (retval != null)
279: return retval;
280: }
281: } catch (DoneDelegation x) {
282:
283: }
284:
285: return null;
286: }
287:
288:
289:
312: public InputSource getExternalSubset (String name, String baseURI)
313: throws SAXException, IOException
314: {
315: if (loadingPermitted)
316: disableLoading ();
317: try {
318: for (int i = 0; i < catalogs.length; i++) {
319: InputSource retval = catalogs [i].getExternalSubset (name);
320: if (retval != null)
321: return retval;
322: }
323: } catch (DoneDelegation x) {
324:
325: }
326: return null;
327: }
328:
329:
330:
371: final public InputSource resolveEntity (String publicId, String systemId)
372: throws SAXException, IOException
373: {
374: return resolveEntity (null, publicId, null, systemId);
375: }
376:
377:
378:
409: public InputSource resolveURI (String baseURI, String uri)
410: throws SAXException, IOException
411: {
412: if (loadingPermitted)
413: disableLoading ();
414:
415:
416:
417:
418:
419:
420: try {
421: for (int i = 0; i < catalogs.length; i++) {
422: InputSource tmp = catalogs [i].resolveURI (uri);
423: if (tmp != null)
424: return tmp;
425: }
426: } catch (DoneDelegation x) {
427:
428: }
429:
430: return null;
431: }
432:
433:
434:
441: public synchronized void disableLoading ()
442: {
443:
444:
445:
446:
447:
448: loadingPermitted = false;
449: }
450:
451:
452:
459: public ErrorHandler getErrorHandler ()
460: { return errorHandler; }
461:
462:
475: public void setErrorHandler (ErrorHandler handler)
476: { errorHandler = handler; }
477:
478:
479:
484: public String getParserClass ()
485: { return parserClass; }
486:
487:
503: public void setParserClass (String parser)
504: { parserClass = parser; }
505:
506:
507:
529: public boolean isUnified ()
530: { return unified; }
531:
532:
542: public void setUnified (boolean value)
543: { unified = value; }
544:
545:
546:
558: public boolean isUsingPublic ()
559: { return usingPublic; }
560:
561:
578: public void setUsingPublic (boolean value)
579: { usingPublic = value; }
580:
581:
582:
583:
584: private static Catalog loadCatalog (
585: String parserClass,
586: ErrorHandler eh,
587: String uri,
588: boolean unified
589: ) throws SAXException, IOException
590: {
591: XMLReader parser;
592: Loader loader;
593: boolean doesIntern = false;
594:
595: if (parserClass == null)
596: parser = XMLReaderFactory.createXMLReader ();
597: else
598: parser = XMLReaderFactory.createXMLReader (parserClass);
599: if (eh != null)
600: parser.setErrorHandler (eh);
601:
602:
603: try {
604: doesIntern = parser.getFeature (
605: "http://xml.org/sax/features/string-interning");
606: } catch (SAXNotRecognizedException e) { }
607:
608: loader = new Loader (doesIntern, eh, unified);
609: loader.cat.parserClass = parserClass;
610: loader.cat.catalogURI = uri;
611:
612: parser.setContentHandler (loader);
613: parser.setProperty (
614: "http://xml.org/sax/properties/declaration-handler",
615: loader);
616: parser.setProperty (
617: "http://xml.org/sax/properties/lexical-handler",
618: loader);
619: parser.parse (uri);
620:
621: return loader.cat;
622: }
623:
624:
625: private static String normalizePublicId (boolean full, String publicId)
626: {
627: if (publicId.startsWith ("urn:publicid:")) {
628: CPStringBuilder buf = new CPStringBuilder ();
629: char chars [] = publicId.toCharArray ();
630: boolean hasbug = false;
631:
632: for (int i = 13; i < chars.length; i++) {
633: switch (chars [i]) {
634: case '+': buf.append (' '); continue;
635: case ':': buf.append ("//"); continue;
636: case ';': buf.append ("::"); continue;
637: case '%':
638:
639: hasbug = true;
640: default: buf.append (chars [i]); continue;
641: }
642: }
643: publicId = buf.toString ();
644: if (hasbug)
645: System.err.println ("nyet unhexing public id: " + publicId);
646: full = true;
647: }
648:
649:
650:
651: if (full) {
652: StringTokenizer tokens;
653: String token;
654:
655: tokens = new StringTokenizer (publicId, " \r\n");
656: publicId = null;
657: while (tokens.hasMoreTokens ()) {
658: if (publicId == null)
659: publicId = tokens.nextToken ();
660: else
661: publicId += " " + tokens.nextToken ();
662: }
663: }
664: return publicId;
665: }
666:
667: private static boolean isUriExcluded (int c)
668: { return c <= 0x20 || c >= 0x7f || "\"<>^`{|}".indexOf (c) != -1; }
669:
670: private static int hexNibble (int c)
671: {
672: if (c < 10)
673: return c + '0';
674: return ('a' - 10) + c;
675: }
676:
677:
678: private static String normalizeURI (String systemId)
679: {
680: int length = systemId.length ();
681:
682: for (int i = 0; i < length; i++) {
683: char c = systemId.charAt (i);
684:
685:
686: if (isUriExcluded (c)) {
687: byte buf [];
688: ByteArrayOutputStream out;
689: int b;
690:
691:
692: try {
693: buf = systemId.getBytes ("UTF8");
694: out = new ByteArrayOutputStream (buf.length + 10);
695:
696: for (i = 0; i < buf.length; i++) {
697: b = buf [i] & 0x0ff;
698: if (isUriExcluded (b)) {
699: out.write ((int) '%');
700: out.write (hexNibble (b >> 4));
701: out.write (hexNibble (b & 0x0f));
702: } else
703: out.write (b);
704: }
705: return out.toString ("8859_1");
706: } catch (IOException e) {
707: throw new RuntimeException (
708: "can't normalize URI: " + e.getMessage ());
709: }
710: }
711: }
712: return systemId;
713: }
714:
715:
716: private static class DoneDelegation extends SAXException
717: {
718: DoneDelegation () { }
719: }
720:
721:
722:
726: private static class Catalog
727: {
728:
729: String catalogURI;
730: ErrorHandler eh;
731: boolean unified;
732: String parserClass;
733:
734:
735: boolean hasPreference;
736: boolean usingPublic;
737:
738: Hashtable publicIds;
739: Hashtable publicDelegations;
740:
741: Hashtable systemIds;
742: Hashtable systemRewrites;
743: Hashtable systemDelegations;
744:
745: Hashtable uris;
746: Hashtable uriRewrites;
747: Hashtable uriDelegations;
748:
749: Hashtable doctypes;
750:
751: Vector next;
752:
753:
754: Catalog () { }
755:
756:
757:
758: private InputSource locatePublicId (String publicId)
759: throws SAXException, IOException
760: {
761:
762: if (publicIds != null) {
763: String retval = (String) publicIds.get (publicId);
764: if (retval != null) {
765:
766: return new InputSource (retval);
767: }
768: }
769:
770:
771: if (publicDelegations != null)
772: return checkDelegations (publicDelegations, publicId,
773: publicId, null);
774:
775: return null;
776: }
777:
778:
779: private InputSource mapURI (
780: String uri,
781: Hashtable ids,
782: Hashtable rewrites,
783: Hashtable delegations
784: ) throws SAXException, IOException
785: {
786:
787:
788: if (ids != null) {
789: String retval = (String) ids.get (uri);
790: if (retval != null) {
791:
792: return new InputSource (retval);
793: }
794: }
795:
796:
797:
798: if (rewrites != null) {
799: String prefix = null;
800: String replace = null;
801: int prefixLen = -1;
802:
803: for (Enumeration e = rewrites.keys ();
804: e.hasMoreElements ();
805: ) {
806: String temp = (String) e.nextElement ();
807: int len = -1;
808:
809: if (!uri.startsWith (temp))
810: continue;
811: if (prefix != null
812: && (len = temp.length ()) < prefixLen)
813: continue;
814: prefix = temp;
815: prefixLen = len;
816: replace = (String) rewrites.get (temp);
817: }
818: if (prefix != null) {
819: CPStringBuilder buf = new CPStringBuilder (replace);
820: buf.append (uri.substring (prefixLen));
821:
822: return new InputSource (buf.toString ());
823: }
824: }
825:
826:
827:
828: if (delegations != null)
829: return checkDelegations (delegations, uri, null, uri);
830:
831: return null;
832: }
833:
834:
835:
838: public InputSource resolve (
839: boolean usingPublic,
840: String publicId,
841: String systemId
842: ) throws SAXException, IOException
843: {
844: boolean preferSystem;
845: InputSource retval;
846:
847: if (hasPreference)
848: preferSystem = !this.usingPublic;
849: else
850: preferSystem = !usingPublic;
851:
852: if (publicId != null)
853: publicId = normalizePublicId (false, publicId);
854:
855:
856: if (systemId != null) {
857: if (systemId.startsWith ("urn:publicid:")) {
858: String temp = normalizePublicId (true, systemId);
859: if (publicId == null) {
860: publicId = temp;
861: systemId = null;
862: } else if (!publicId.equals (temp)) {
863:
864: systemId = null;
865: }
866: } else
867: systemId = normalizeURI (systemId);
868: }
869:
870: if (systemId == null && publicId == null)
871: return null;
872:
873: if (systemId != null) {
874: retval = mapURI (systemId, systemIds, systemRewrites,
875: systemDelegations);
876: if (retval != null) {
877: retval.setPublicId (publicId);
878: return retval;
879: }
880: }
881:
882: if (publicId != null
883: && !(systemId != null && preferSystem)) {
884: retval = locatePublicId (publicId);
885: if (retval != null) {
886: retval.setPublicId (publicId);
887: return retval;
888: }
889: }
890:
891:
892: if (next != null) {
893: int length = next.size ();
894: for (int i = 0; i < length; i++) {
895: Catalog n = getNext (i);
896: retval = n.resolve (usingPublic, publicId, systemId);
897: if (retval != null)
898: return retval;
899: }
900: }
901:
902: return null;
903: }
904:
905:
909: public InputSource resolveURI (String uri)
910: throws SAXException, IOException
911: {
912: if (uri.startsWith ("urn:publicid:"))
913: return resolve (true, normalizePublicId (true, uri), null);
914:
915: InputSource retval;
916:
917: uri = normalizeURI (uri);
918:
919:
920: retval = mapURI (uri, uris, uriRewrites, uriDelegations);
921: if (retval != null)
922: return retval;
923:
924:
925: if (next != null) {
926: int length = next.size ();
927: for (int i = 0; i < length; i++) {
928: Catalog n = getNext (i);
929: retval = n.resolveURI (uri);
930: if (retval != null)
931: return retval;
932: }
933: }
934:
935: return null;
936: }
937:
938:
939:
942: public InputSource getExternalSubset (String name)
943: throws SAXException, IOException
944: {
945: if (doctypes != null) {
946: String value = (String) doctypes.get (name);
947: if (value != null) {
948:
949: return new InputSource (value);
950: }
951: }
952: if (next != null) {
953: int length = next.size ();
954: for (int i = 0; i < length; i++) {
955: Catalog n = getNext (i);
956: if (n == null)
957: continue;
958: InputSource retval = n.getExternalSubset (name);
959: if (retval != null)
960: return retval;
961: }
962: }
963: return null;
964: }
965:
966: private synchronized Catalog getNext (int i)
967: throws SAXException, IOException
968: {
969: Object obj;
970:
971: if (next == null || i < 0 || i >= next.size ())
972: return null;
973: obj = next.elementAt (i);
974: if (obj instanceof Catalog)
975: return (Catalog) obj;
976:
977:
978:
979: Catalog cat = null;
980:
981: try {
982: cat = loadCatalog (parserClass, eh, (String) obj, unified);
983: next.setElementAt (cat, i);
984: } catch (SAXException e) {
985:
986: } catch (IOException e) {
987:
988: }
989: return cat;
990: }
991:
992: private InputSource checkDelegations (
993: Hashtable delegations,
994: String id,
995: String publicId,
996: String systemId
997: ) throws SAXException, IOException
998: {
999: Vector matches = null;
1000: int length = 0;
1001:
1002:
1003: for (Enumeration e = delegations.keys ();
1004: e.hasMoreElements ();
1005: ) {
1006: String prefix = (String) e.nextElement ();
1007:
1008: if (!id.startsWith (prefix))
1009: continue;
1010: if (matches == null)
1011: matches = new Vector ();
1012:
1013:
1014:
1015: int index;
1016:
1017: for (index = 0; index < length; index++) {
1018: String temp = (String) matches.elementAt (index);
1019: if (prefix.length () > temp.length ()) {
1020: matches.insertElementAt (prefix, index);
1021: break;
1022: }
1023: }
1024: if (index == length)
1025: matches.addElement (prefix);
1026: length++;
1027: }
1028: if (matches == null)
1029: return null;
1030:
1031:
1032:
1033:
1034:
1035: for (int i = 0; i < length; i++) {
1036: Catalog catalog = null;
1037: InputSource result;
1038:
1039:
1040: synchronized (delegations) {
1041: Object prefix = matches.elementAt (i);
1042: Object cat = delegations.get (prefix);
1043:
1044: if (cat instanceof Catalog)
1045: catalog = (Catalog) cat;
1046: else {
1047: try {
1048:
1049: catalog = loadCatalog (parserClass, eh,
1050: (String) cat, unified);
1051: delegations.put (prefix, catalog);
1052: } catch (SAXException e) {
1053:
1054: } catch (IOException e) {
1055:
1056: }
1057: }
1058: }
1059:
1060:
1061: if (catalog == null)
1062: continue;
1063:
1064:
1065:
1066: result = catalog.resolve (true, publicId, systemId);
1067: if (result != null)
1068: return result;
1069: }
1070:
1071:
1072:
1073: throw new DoneDelegation ();
1074: }
1075: }
1076:
1077:
1078:
1079: private static final String catalogNamespace =
1080: "urn:oasis:names:tc:entity:xmlns:xml:catalog";
1081:
1082:
1083:
1086: private static class Loader extends DefaultHandler2
1087: {
1088: private boolean preInterned;
1089: private ErrorHandler handler;
1090: private boolean unified;
1091: private int ignoreDepth;
1092: private Locator locator;
1093: private boolean started;
1094: private Hashtable externals;
1095: private Stack bases;
1096:
1097: Catalog cat = new Catalog ();
1098:
1099:
1100:
1108: Loader (boolean flag, ErrorHandler eh, boolean unified)
1109: {
1110: preInterned = flag;
1111: handler = eh;
1112: this.unified = unified;
1113: cat.unified = unified;
1114: cat.eh = eh;
1115: }
1116:
1117:
1118:
1119: private String nofrag (String uri)
1120: throws SAXException
1121: {
1122: if (uri.indexOf ('#') != -1) {
1123: warn ("URI with fragment: " + uri);
1124: uri = uri.substring (0, uri.indexOf ('#'));
1125: }
1126: return uri;
1127: }
1128:
1129:
1130: private String absolutize (String uri)
1131: throws SAXException
1132: {
1133:
1134:
1135: if (uri.startsWith ("file:/")
1136: || uri.startsWith ("http:/")
1137: || uri.startsWith ("https:/")
1138: || uri.startsWith ("ftp:/")
1139: || uri.startsWith ("urn:")
1140: )
1141: return uri;
1142:
1143:
1144: try {
1145: URL base = (URL) bases.peek ();
1146: return new URL (base, uri).toString ();
1147: } catch (Exception e) {
1148: fatal ("can't absolutize URI: " + uri);
1149: return null;
1150: }
1151: }
1152:
1153:
1154: private void error (String message)
1155: throws SAXException
1156: {
1157: if (handler == null)
1158: return;
1159: handler.error (new SAXParseException (message, locator));
1160: }
1161:
1162:
1163: private void fatal (String message)
1164: throws SAXException
1165: {
1166: SAXParseException spe;
1167:
1168: spe = new SAXParseException (message, locator);
1169: if (handler != null)
1170: handler.fatalError (spe);
1171: throw spe;
1172: }
1173:
1174:
1175: private void warn (String message)
1176: throws SAXException
1177: {
1178: if (handler == null)
1179: return;
1180: handler.warning (new SAXParseException (message, locator));
1181: }
1182:
1183:
1184:
1185: public void setDocumentLocator (Locator l)
1186: { locator = l; }
1187:
1188: public void startDocument ()
1189: throws SAXException
1190: {
1191: if (locator == null)
1192: error ("no locator!");
1193: bases = new Stack ();
1194: String uri = locator.getSystemId ();
1195: try {
1196: bases.push (new URL (uri));
1197: } catch (IOException e) {
1198: fatal ("bad document base URI: " + uri);
1199: }
1200: }
1201:
1202: public void endDocument ()
1203: throws SAXException
1204: {
1205: try {
1206: if (!started)
1207: error ("not a catalog!");
1208: } finally {
1209: locator = null;
1210: handler = null;
1211: externals = null;
1212: bases = null;
1213: }
1214: }
1215:
1216:
1217:
1218:
1219: public void externalEntityDecl (String name, String pub, String sys)
1220: throws SAXException
1221: {
1222: if (externals == null)
1223: externals = new Hashtable ();
1224: if (externals.get (name) == null)
1225: externals.put (name, pub);
1226: }
1227:
1228: public void startEntity (String name)
1229: throws SAXException
1230: {
1231: if (externals == null)
1232: return;
1233: String uri = (String) externals.get (name);
1234:
1235:
1236:
1237: if (uri != null) {
1238: try {
1239: bases.push (new URL (uri));
1240: } catch (IOException e) {
1241: fatal ("entity '" + name + "', bad URI: " + uri);
1242: }
1243: }
1244: }
1245:
1246: public void endEntity (String name)
1247: {
1248: if (externals == null)
1249: return;
1250: String value = (String) externals.get (name);
1251:
1252: if (value != null)
1253: bases.pop ();
1254: }
1255:
1256:
1259: public void startElement (String namespace, String local,
1260: String qName, Attributes atts)
1261: throws SAXException
1262: {
1263:
1264: if (ignoreDepth != 0 || !catalogNamespace.equals (namespace)) {
1265: ignoreDepth++;
1266: return;
1267: }
1268:
1269:
1270: if (!preInterned)
1271: local = local.intern ();
1272: if (!started) {
1273: started = true;
1274: if ("catalog" != local)
1275: fatal ("root element not 'catalog': " + local);
1276: }
1277:
1278:
1279: String xmlbase = atts.getValue ("xml:base");
1280:
1281: if (xmlbase != null) {
1282: URL base = (URL) bases.peek ();
1283: try {
1284: base = new URL (base, xmlbase);
1285: } catch (IOException e) {
1286: fatal ("can't resolve xml:base attribute: " + xmlbase);
1287: }
1288: bases.push (base);
1289: } else
1290: bases.push (bases.peek ());
1291:
1292:
1293:
1294:
1295: String catalog = atts.getValue ("catalog");
1296: if (catalog != null)
1297: catalog = normalizeURI (absolutize (catalog));
1298:
1299: String rewritePrefix = atts.getValue ("rewritePrefix");
1300: if (rewritePrefix != null)
1301: rewritePrefix = normalizeURI (absolutize (rewritePrefix));
1302:
1303: String systemIdStartString;
1304: systemIdStartString = atts.getValue ("systemIdStartString");
1305: if (systemIdStartString != null) {
1306: systemIdStartString = normalizeURI (systemIdStartString);
1307:
1308: if (systemIdStartString.startsWith ("urn:publicid:")) {
1309: error ("systemIdStartString is really a publicId!!");
1310: return;
1311: }
1312: }
1313:
1314: String uri = atts.getValue ("uri");
1315: if (uri != null)
1316: uri = normalizeURI (absolutize (uri));
1317:
1318: String uriStartString;
1319: uriStartString = atts.getValue ("uriStartString");
1320: if (uriStartString != null) {
1321: uriStartString = normalizeURI (uriStartString);
1322:
1323: if (uriStartString.startsWith ("urn:publicid:")) {
1324: error ("uriStartString is really a publicId!!");
1325: return;
1326: }
1327: }
1328:
1329:
1330:
1331:
1332:
1333:
1334:
1335: if ("catalog" == local || "group" == local) {
1336: String prefer = atts.getValue ("prefer");
1337:
1338: if (prefer != null && !"public".equals (prefer)) {
1339: if (!"system".equals (prefer)) {
1340: error ("in <" + local + " ... prefer='...'>, "
1341: + "assuming 'public'");
1342: prefer = "public";
1343: }
1344: }
1345: if (prefer != null) {
1346: if ("catalog" == local) {
1347: cat.hasPreference = true;
1348: cat.usingPublic = "public".equals (prefer);
1349: } else {
1350: if (!cat.hasPreference || cat.usingPublic
1351: != "public".equals (prefer)) {
1352: fatal ("<group prefer=...> case not handled");
1353: }
1354: }
1355: } else if ("group" == local && cat.hasPreference) {
1356: fatal ("<group prefer=...> case not handled");
1357: }
1358:
1359:
1360:
1361:
1362: } else if ("public" == local) {
1363: String publicId = atts.getValue ("publicId");
1364: String value = null;
1365:
1366: if (publicId == null || uri == null) {
1367: error ("expecting <public publicId=... uri=.../>");
1368: return;
1369: }
1370: publicId = normalizePublicId (true, publicId);
1371: uri = nofrag (uri);
1372: if (cat.publicIds == null)
1373: cat.publicIds = new Hashtable ();
1374: else
1375: value = (String) cat.publicIds.get (publicId);
1376: if (value != null) {
1377: if (!value.equals (uri))
1378: warn ("ignoring <public...> entry for " + publicId);
1379: } else
1380: cat.publicIds.put (publicId, uri);
1381:
1382: } else if ("delegatePublic" == local) {
1383: String publicIdStartString;
1384: Object value = null;
1385:
1386: publicIdStartString = atts.getValue ("publicIdStartString");
1387: if (publicIdStartString == null || catalog == null) {
1388: error ("expecting <delegatePublic "
1389: + "publicIdStartString=... catalog=.../>");
1390: return;
1391: }
1392: publicIdStartString = normalizePublicId (true,
1393: publicIdStartString);
1394: if (cat.publicDelegations == null)
1395: cat.publicDelegations = new Hashtable ();
1396: else
1397: value = cat.publicDelegations.get (publicIdStartString);
1398: if (value != null) {
1399: if (!value.equals (catalog))
1400: warn ("ignoring <delegatePublic...> entry for "
1401: + uriStartString);
1402: } else
1403: cat.publicDelegations.put (publicIdStartString, catalog);
1404:
1405:
1406:
1407:
1408:
1409: } else if ("system" == local) {
1410: String systemId = atts.getValue ("systemId");
1411: String value = null;
1412:
1413: if (systemId == null || uri == null) {
1414: error ("expecting <system systemId=... uri=.../>");
1415: return;
1416: }
1417: systemId = normalizeURI (systemId);
1418: uri = nofrag (uri);
1419: if (systemId.startsWith ("urn:publicid:")) {
1420: error ("systemId is really a publicId!!");
1421: return;
1422: }
1423: if (cat.systemIds == null) {
1424: cat.systemIds = new Hashtable ();
1425: if (unified)
1426: cat.uris = cat.systemIds;
1427: } else
1428: value = (String) cat.systemIds.get (systemId);
1429: if (value != null) {
1430: if (!value.equals (uri))
1431: warn ("ignoring <system...> entry for " + systemId);
1432: } else
1433: cat.systemIds.put (systemId, uri);
1434:
1435: } else if ("rewriteSystem" == local) {
1436: String value = null;
1437:
1438: if (systemIdStartString == null || rewritePrefix == null
1439: || systemIdStartString.length () == 0
1440: || rewritePrefix.length () == 0
1441: ) {
1442: error ("expecting <rewriteSystem "
1443: + "systemIdStartString=... rewritePrefix=.../>");
1444: return;
1445: }
1446: if (cat.systemRewrites == null) {
1447: cat.systemRewrites = new Hashtable ();
1448: if (unified)
1449: cat.uriRewrites = cat.systemRewrites;
1450: } else
1451: value = (String) cat.systemRewrites.get (
1452: systemIdStartString);
1453: if (value != null) {
1454: if (!value.equals (rewritePrefix))
1455: warn ("ignoring <rewriteSystem...> entry for "
1456: + systemIdStartString);
1457: } else
1458: cat.systemRewrites.put (systemIdStartString,
1459: rewritePrefix);
1460:
1461: } else if ("delegateSystem" == local) {
1462: Object value = null;
1463:
1464: if (systemIdStartString == null || catalog == null) {
1465: error ("expecting <delegateSystem "
1466: + "systemIdStartString=... catalog=.../>");
1467: return;
1468: }
1469: if (cat.systemDelegations == null) {
1470: cat.systemDelegations = new Hashtable ();
1471: if (unified)
1472: cat.uriDelegations = cat.systemDelegations;
1473: } else
1474: value = cat.systemDelegations.get (systemIdStartString);
1475: if (value != null) {
1476: if (!value.equals (catalog))
1477: warn ("ignoring <delegateSystem...> entry for "
1478: + uriStartString);
1479: } else
1480: cat.systemDelegations.put (systemIdStartString, catalog);
1481:
1482:
1483:
1484:
1485:
1486:
1487: } else if ("uri" == local) {
1488: String name = atts.getValue ("name");
1489: String value = null;
1490:
1491: if (name == null || uri == null) {
1492: error ("expecting <uri name=... uri=.../>");
1493: return;
1494: }
1495: if (name.startsWith ("urn:publicid:")) {
1496: error ("name is really a publicId!!");
1497: return;
1498: }
1499: name = normalizeURI (name);
1500: if (cat.uris == null) {
1501: cat.uris = new Hashtable ();
1502: if (unified)
1503: cat.systemIds = cat.uris;
1504: } else
1505: value = (String) cat.uris.get (name);
1506: if (value != null) {
1507: if (!value.equals (uri))
1508: warn ("ignoring <uri...> entry for " + name);
1509: } else
1510: cat.uris.put (name, uri);
1511:
1512: } else if ("rewriteURI" == local) {
1513: String value = null;
1514:
1515: if (uriStartString == null || rewritePrefix == null
1516: || uriStartString.length () == 0
1517: || rewritePrefix.length () == 0
1518: ) {
1519: error ("expecting <rewriteURI "
1520: + "uriStartString=... rewritePrefix=.../>");
1521: return;
1522: }
1523: if (cat.uriRewrites == null) {
1524: cat.uriRewrites = new Hashtable ();
1525: if (unified)
1526: cat.systemRewrites = cat.uriRewrites;
1527: } else
1528: value = (String) cat.uriRewrites.get (uriStartString);
1529: if (value != null) {
1530: if (!value.equals (rewritePrefix))
1531: warn ("ignoring <rewriteURI...> entry for "
1532: + uriStartString);
1533: } else
1534: cat.uriRewrites.put (uriStartString, rewritePrefix);
1535:
1536: } else if ("delegateURI" == local) {
1537: Object value = null;
1538:
1539: if (uriStartString == null || catalog == null) {
1540: error ("expecting <delegateURI "
1541: + "uriStartString=... catalog=.../>");
1542: return;
1543: }
1544: if (cat.uriDelegations == null) {
1545: cat.uriDelegations = new Hashtable ();
1546: if (unified)
1547: cat.systemDelegations = cat.uriDelegations;
1548: } else
1549: value = cat.uriDelegations.get (uriStartString);
1550: if (value != null) {
1551: if (!value.equals (catalog))
1552: warn ("ignoring <delegateURI...> entry for "
1553: + uriStartString);
1554: } else
1555: cat.uriDelegations.put (uriStartString, catalog);
1556:
1557:
1558:
1559:
1560: } else if ("nextCatalog" == local) {
1561: if (catalog == null) {
1562: error ("expecting <nextCatalog catalog=.../>");
1563: return;
1564: }
1565: if (cat.next == null)
1566: cat.next = new Vector ();
1567: cat.next.addElement (catalog);
1568:
1569:
1570:
1571:
1572: } else if ("doctype" == local) {
1573: String name = atts.getValue ("name");
1574: String value = null;
1575:
1576: if (name == null || uri == null) {
1577: error ("expecting <doctype name=... uri=.../>");
1578: return;
1579: }
1580: name = normalizeURI (name);
1581: if (cat.doctypes == null)
1582: cat.doctypes = new Hashtable ();
1583: else
1584: value = (String) cat.doctypes.get (name);
1585: if (value != null) {
1586: if (!value.equals (uri))
1587: warn ("ignoring <doctype...> entry for "
1588: + uriStartString);
1589: } else
1590: cat.doctypes.put (name, uri);
1591:
1592:
1593:
1594:
1595:
1596: } else {
1597: warn ("ignoring unknown catalog element: " + local);
1598: ignoreDepth++;
1599: }
1600: }
1601:
1602: public void endElement (String uri, String local, String qName)
1603: throws SAXException
1604: {
1605: if (ignoreDepth != 0)
1606: ignoreDepth--;
1607: else
1608: bases.pop ();
1609: }
1610: }
1611: }