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