/* * #! * Ontopia Engine * #- * Copyright (C) 2001 - 2013 The Ontopia Project * #- * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * !# */ package net.ontopia.topicmaps.xml; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Stack; import net.ontopia.infoset.core.LocatorIF; import net.ontopia.topicmaps.core.ScopedIF; import net.ontopia.topicmaps.core.TopicIF; import net.ontopia.xml.Slf4jSaxErrorHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xml.sax.ErrorHandler; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.DefaultHandler; /** * INTERNAL: Abstract SAX2 content handler used for reading various * kinds of topic map documents.</p> */ public abstract class AbstractTopicMapContentHandler extends DefaultHandler { protected Collection propagated_themes; // The list of processed documents passed on to the current // document. Note that each document may contain multiple topic // maps. protected Collection processed_documents_current; // The list of processed retrieved from the parent. Note that this // collection does not change until the endDocument event is // reached. protected Collection processed_documents_from_parent; // The list of documents processed up til the current document. The // processed documents for each topic map in the document is added // to this list. protected Collection processed_documents_accumulated; // Parse state info protected Stack parents; protected Map info; /* current base uri, as modified by xml:base, is in the stack */ /** document base uri, used for intra-document references. see RFC 2396, section 4.2 */ protected LocatorIF doc_address; protected Locator locator; protected ErrorHandler ehandler; // Define a logging category. static Logger log = LoggerFactory.getLogger(AbstractTopicMapContentHandler.class.getName()); public AbstractTopicMapContentHandler(LocatorIF base_address) { this(base_address, new HashSet()); } public AbstractTopicMapContentHandler(LocatorIF base_address, Collection processed_documents_from_parent) { this.doc_address = base_address; parents = new Stack(); info = new HashMap(); this.processed_documents_from_parent = processed_documents_from_parent; } public Collection getPropagatedThemes() { return propagated_themes; } public void setPropagatedThemes(Collection propagated_themes) { this.propagated_themes = propagated_themes; } protected void propagateThemes(ScopedIF scoped) { if (propagated_themes != null) { Iterator iter = propagated_themes.iterator(); while(iter.hasNext()) scoped.addTheme((TopicIF)iter.next()); } } public void setDocumentLocator(Locator locator) { this.locator = locator; } /** * INTERNAL: Registers the content handler with the given XML reader * object.</p> * * The content handler will register itself as the content handler of * the XML reader. It will also attempt to set the SAX core features * 'http://xml.org/sax/features/string-interning' to 'true' and * 'http://xml.org/sax/features/external-parameter-entities' to * 'false'. */ public void register(XMLReader parser) { // Set required parser features try { // Use interned strings for names. parser.setFeature("http://xml.org/sax/features/string-interning", true); } catch (SAXException e) { log.warn("SAX string-interning feature not supported."); } try { // Don't read the DTD (document type definition) parser.setFeature("http://xml.org/sax/features/external-parameter-entities", false); } catch (SAXException e) { // this one isn't important enough for us to warn about log.debug("SAX external-parameter-entities feature not supported."); } // Register handlers with parser parser.setContentHandler(this); ErrorHandler _ehandler = parser.getErrorHandler(); if (_ehandler == null || (_ehandler instanceof org.xml.sax.helpers.DefaultHandler)) parser.setErrorHandler(getDefaultErrorHandler()); // Get hold of actual error handler ehandler = parser.getErrorHandler(); } protected String getLocationInfo() { if (locator == null) return ""; return "(resource '" + locator.getSystemId() + "' line " + locator.getLineNumber() + " col " + locator.getColumnNumber() + ")"; } protected ErrorHandler getDefaultErrorHandler() { return new Slf4jSaxErrorHandler(log); } }