1 /*
   2  * Licensed to the Apache Software Foundation (ASF) under one or more
   3  * contributor license agreements.  See the NOTICE file distributed with
   4  * this work for additional information regarding copyright ownership.
   5  * The ASF licenses this file to You under the Apache License, Version 2.0
   6  * (the "License"); you may not use this file except in compliance with
   7  * the License.  You may obtain a copy of the License at
   8  *
   9  *      http://www.apache.org/licenses/LICENSE-2.0
  10  *
  11  * Unless required by applicable law or agreed to in writing, software
  12  * distributed under the License is distributed on an "AS IS" BASIS,
  13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14  * See the License for the specific language governing permissions and
  15  * limitations under the License.
  16  */
  17 
  18 package com.sun.org.apache.xml.internal.resolver.readers;
  19 
  20 import java.util.Vector;
  21 import com.sun.org.apache.xml.internal.resolver.Catalog;
  22 import com.sun.org.apache.xml.internal.resolver.Resolver;
  23 import com.sun.org.apache.xml.internal.resolver.CatalogEntry;
  24 import com.sun.org.apache.xml.internal.resolver.CatalogException;
  25 
  26 import org.xml.sax.*;
  27 import org.w3c.dom.*;
  28 
  29 /**
  30  * Parse Extended OASIS Entity Resolution Technical Committee
  31  * XML Catalog files.
  32  *
  33  * @see Catalog
  34  *
  35  * @author Norman Walsh
  36  * <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
  37  *
  38  */
  39 public class ExtendedXMLCatalogReader extends OASISXMLCatalogReader {
  40   /** The namespace name of extended catalog elements */
  41   public static final String extendedNamespaceName = "http://nwalsh.com/xcatalog/1.0";
  42 
  43   /**
  44    * The SAX <code>startElement</code> method recognizes elements
  45    * from the plain catalog format and instantiates CatalogEntry
  46    * objects for them.
  47    *
  48    * @param namespaceURI The namespace name of the element.
  49    * @param localName The local name of the element.
  50    * @param qName The QName of the element.
  51    * @param atts The list of attributes on the element.
  52    *
  53    * @see CatalogEntry
  54    */
  55   public void startElement (String namespaceURI,
  56                             String localName,
  57                             String qName,
  58                             Attributes atts)
  59     throws SAXException {
  60 
  61     // Check before calling the super because super will report our
  62     // namespace as an extension namespace, but that doesn't count
  63     // for this element.
  64     boolean inExtension = inExtensionNamespace();
  65 
  66     super.startElement(namespaceURI, localName, qName, atts);
  67 
  68     int entryType = -1;
  69     Vector entryArgs = new Vector();
  70 
  71     if (namespaceURI != null && extendedNamespaceName.equals(namespaceURI)
  72         && !inExtension) {
  73       // This is an Extended XML Catalog entry
  74 
  75       if (atts.getValue("xml:base") != null) {
  76         String baseURI = atts.getValue("xml:base");
  77         entryType = Catalog.BASE;
  78         entryArgs.add(baseURI);
  79         baseURIStack.push(baseURI);
  80 
  81         debug.message(4, "xml:base", baseURI);
  82 
  83         try {
  84           CatalogEntry ce = new CatalogEntry(entryType, entryArgs);
  85           catalog.addEntry(ce);
  86         } catch (CatalogException cex) {
  87           if (cex.getExceptionType() == CatalogException.INVALID_ENTRY_TYPE) {
  88             debug.message(1, "Invalid catalog entry type", localName);
  89           } else if (cex.getExceptionType() == CatalogException.INVALID_ENTRY) {
  90             debug.message(1, "Invalid catalog entry (base)", localName);
  91           }
  92         }
  93 
  94         entryType = -1;
  95         entryArgs = new Vector();
  96       } else {
  97         baseURIStack.push(baseURIStack.peek());
  98       }
  99 
 100       if (localName.equals("uriSuffix")) {
 101         if (checkAttributes(atts, "suffix", "uri")) {
 102           entryType = Resolver.URISUFFIX;
 103           entryArgs.add(atts.getValue("suffix"));
 104           entryArgs.add(atts.getValue("uri"));
 105 
 106           debug.message(4, "uriSuffix",
 107                         atts.getValue("suffix"),
 108                         atts.getValue("uri"));
 109         }
 110       } else if (localName.equals("systemSuffix")) {
 111         if (checkAttributes(atts, "suffix", "uri")) {
 112           entryType = Resolver.SYSTEMSUFFIX;
 113           entryArgs.add(atts.getValue("suffix"));
 114           entryArgs.add(atts.getValue("uri"));
 115 
 116           debug.message(4, "systemSuffix",
 117                         atts.getValue("suffix"),
 118                         atts.getValue("uri"));
 119         }
 120       } else {
 121         // This is equivalent to an invalid catalog entry type
 122         debug.message(1, "Invalid catalog entry type", localName);
 123       }
 124 
 125       if (entryType >= 0) {
 126         try {
 127           CatalogEntry ce = new CatalogEntry(entryType, entryArgs);
 128           catalog.addEntry(ce);
 129         } catch (CatalogException cex) {
 130           if (cex.getExceptionType() == CatalogException.INVALID_ENTRY_TYPE) {
 131             debug.message(1, "Invalid catalog entry type", localName);
 132           } else if (cex.getExceptionType() == CatalogException.INVALID_ENTRY) {
 133             debug.message(1, "Invalid catalog entry", localName);
 134           }
 135         }
 136       }
 137     }
 138   }
 139 
 140   /** The SAX <code>endElement</code> method does nothing. */
 141   public void endElement (String namespaceURI,
 142                           String localName,
 143                           String qName)
 144     throws SAXException {
 145 
 146     super.endElement(namespaceURI, localName, qName);
 147 
 148     // Check after popping the stack so we don't erroneously think we
 149     // are our own extension namespace...
 150     boolean inExtension = inExtensionNamespace();
 151 
 152     int entryType = -1;
 153     Vector entryArgs = new Vector();
 154 
 155     if (namespaceURI != null
 156         && (extendedNamespaceName.equals(namespaceURI))
 157         && !inExtension) {
 158 
 159       String popURI = (String) baseURIStack.pop();
 160       String baseURI = (String) baseURIStack.peek();
 161 
 162       if (!baseURI.equals(popURI)) {
 163         entryType = Catalog.BASE;
 164         entryArgs.add(baseURI);
 165 
 166         debug.message(4, "(reset) xml:base", baseURI);
 167 
 168         try {
 169           CatalogEntry ce = new CatalogEntry(entryType, entryArgs);
 170           catalog.addEntry(ce);
 171         } catch (CatalogException cex) {
 172           if (cex.getExceptionType() == CatalogException.INVALID_ENTRY_TYPE) {
 173             debug.message(1, "Invalid catalog entry type", localName);
 174           } else if (cex.getExceptionType() == CatalogException.INVALID_ENTRY) {
 175             debug.message(1, "Invalid catalog entry (rbase)", localName);
 176           }
 177         }
 178       }
 179     }
 180   }
 181 }