📄 contenthandlerimpl.java
字号:
package org.xbrlapi.SAXHandlers;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Stack;
import org.apache.log4j.Logger;
import org.apache.xerces.parsers.XMLGrammarPreparser;
import org.apache.xerces.util.XMLResourceIdentifierImpl;
import org.apache.xerces.xni.XMLResourceIdentifier;
import org.apache.xerces.xni.grammars.XMLGrammarDescription;
import org.apache.xerces.xni.grammars.XSGrammar;
import org.apache.xerces.xni.parser.XMLEntityResolver;
import org.apache.xerces.xni.parser.XMLInputSource;
import org.apache.xerces.xs.StringList;
import org.apache.xerces.xs.XSElementDeclaration;
import org.apache.xerces.xs.XSModel;
import org.apache.xerces.xs.XSNamespaceItem;
import org.apache.xerces.xs.XSNamespaceItemList;
import org.xbrlapi.Fragment;
import org.xbrlapi.impl.ArcroleTypeImpl;
import org.xbrlapi.impl.ConceptImpl;
import org.xbrlapi.impl.ContextImpl;
import org.xbrlapi.impl.ElementDeclarationImpl;
import org.xbrlapi.impl.EntityImpl;
import org.xbrlapi.impl.FragmentImpl;
import org.xbrlapi.impl.InstanceImpl;
import org.xbrlapi.impl.LanguageImpl;
import org.xbrlapi.impl.LinkbaseImpl;
import org.xbrlapi.impl.NonNumericItemImpl;
import org.xbrlapi.impl.PeriodImpl;
import org.xbrlapi.impl.ReferencePartDeclarationImpl;
import org.xbrlapi.impl.ReferencePartImpl;
import org.xbrlapi.impl.RoleTypeImpl;
import org.xbrlapi.impl.ScenarioImpl;
import org.xbrlapi.impl.SchemaImpl;
import org.xbrlapi.impl.SegmentImpl;
import org.xbrlapi.impl.SimpleNumericItemImpl;
import org.xbrlapi.impl.TupleImpl;
import org.xbrlapi.impl.UnitImpl;
import org.xbrlapi.impl.UsedOnImpl;
import org.xbrlapi.impl.XlinkDocumentationImpl;
import org.xbrlapi.loader.Loader;
import org.xbrlapi.utilities.Constants;
import org.xbrlapi.utilities.GrammarCacheImpl;
import org.xbrlapi.utilities.XBRLException;
import org.xbrlapi.xlink.XLinkException;
import org.xbrlapi.xlink.handler.XBRLXLinkHandlerImpl;
import org.xbrlapi.xmlbase.BaseURLSAXResolver;
import org.xbrlapi.xmlbase.BaseURLSAXResolverImpl;
import org.xbrlapi.xmlbase.XMLBaseException;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
/**
* SAX content handler used in construction of an XBRL
* Discoverable Taxonomy Set (DTS).
* The content handler is responsible for building up the XBRL
* XML fragments as they are parsed and then passing them over
* to the underlying data representation for storage.
*
* The content handler needs to be supplied with a variety of helpers
* to assist with data storage and XLink processing. These are
* supplied to the constructor by the loader.
*
* @author Geoffrey Shuetrim (geoff@galexy.net)
*/
public class ContentHandlerImpl extends DefaultHandler {
protected static Logger logger = Logger.getLogger(ContentHandlerImpl.class);
/**
* The DTS loader that uses this content handler
* to process discovered XML
*/
private Loader loader = null;
/**
* The XML Schema model if parsing an XML Schema.
*/
private XSModel model = null;
/**
* The URL of the document being parsed. This is used to
* recover the XML Schema model for the document if required.
*/
private URL url = null;
/**
* The target namespace of an XML Schema.
*/
private String targetNamespace = null;
/**
* State information to help find tuples in XBRL instances.
*/
private boolean parsingAnXBRLInstance = false;
private boolean canBeATuple = false;
/**
* State information to help find reference parts.
* TODO Find reference parts using XML Schema substitution group information.
*/
private boolean parsingAReferenceResource = false;
/**
* SAX parsing locator - providing information for use in
* error reporting.
*/
Locator locator = null;
/**
* Element depth of the tree being parsed. This is used to
* ensure that the loader knows when a fragment has finished
* being built. This starts at 0 and is incremented for each
* startElement event and decremented for each end element
* event.
* TODO eliminate depth from the SAX content handler in favour of the ElementState.
*/
long depth = 0;
/**
* Data required to track the element scheme XPointer
* expressions that can be used to identify XBRL fragments.
*/
ElementState state = new ElementState();
/**
* String representation of the XML document - for documents supplied as such.
*/
String xml = null;
/**
* The namespace map stack for tracking namespaces.
*/
Stack<HashMap<String,String>> nsStack = new Stack<HashMap<String,String>>();
/**
* Creates the content handler, starting out by
* identifying the DTS structure that the content
* handler is discovering.
* @param loader The DTS loader that is using this content handler.
* @param url The URL of the document being parsed.
* @throws XBRLException if any of the parameters
* are null.
*/
public ContentHandlerImpl(Loader loader, URL url) throws XBRLException {
super();
if (loader == null) {
throw new XBRLException("The loader must not be null.");
}
if (url == null) {
throw new XBRLException("The url must not be null.");
}
this.loader = loader;
this.url = url;
nsStack.push(new HashMap<String,String>());
}
/**
* Creates the content handler, starting out by
* identifying the data structure that the content
* handler is discovering.
* @param loader The data loader that is using this content handler.
* @param url The URL of the document being parsed.
* @param xml The string representation of the document being parsed.
* @throws XBRLException if any of the parameters
* are null.
*/
public ContentHandlerImpl(Loader loader, URL url, String xml) throws XBRLException {
this(loader, url);
this.xml = xml;
}
private Loader getLoader() {
return loader;
}
private long getDepth() {
return depth;
}
private ElementState getState() {
return state;
}
/**
* The locator for a document is stored as part of the DTSImpl object
* to facilitate resolution of CacheURLImpl's relative to that location.
*/
public void setDocumentLocator(Locator l)
{
this.locator = l;
}
private XBRLXLinkHandlerImpl getXLinkHandler() throws SAXException {
try {
return (XBRLXLinkHandlerImpl) this.getLoader().getXlinkProcessor().getXLinkHandler();
} catch (ClassCastException e) {
throw new SAXException("The XBRL API is not using the XBRL XLink Handler implementation.");
}
}
BaseURLSAXResolver baseURLSAXResolver = null;
/**
* On starting to parse a document the Base URL resolver is set up with the document's system ID;
*/
public void startDocument() throws SAXException
{
// Get the XLink handler
XBRLXLinkHandlerImpl xbrlXlinkHandler = getXLinkHandler();
// Set the base URL resolver for this document
try {
// TODO Can we use the url property of the content handler instead of the loader document URL?
String thisDocumentURL = this.getLoader().getDocumentURL();
this.baseURLSAXResolver = new BaseURLSAXResolverImpl(new URL(thisDocumentURL));
xbrlXlinkHandler.setBaseURLSAXResolver(this.baseURLSAXResolver);
} catch (MalformedURLException e) {
throw new SAXException("The docment has a malformed URL specified by the locator's System ID.");
}
}
/**
* The end of the document triggers stepping out of the document's
* container element
*/
public void endDocument() throws SAXException
{
}
/**
* All element processing is done by the DTSImpl object.
* The only activities specific to this content handler relate
* to the specific treatment of extended links, locators and arcs.
*/
@SuppressWarnings("unchecked")
public void startElement( String namespaceURI, String lName, String qName, Attributes attrs) throws SAXException
{
// Update element depth and child count.
depth++;
try {
getLoader().incrementChildren();
} catch (XBRLException e) {
throw new SAXException("Could not record a new child for the fragment being parsed.",e);
}
// Update the information about the state of the current element
state = new ElementState(state);
// Stash new URLs in xsi:schemaLocation attributes if desired
if (getLoader().useSchemaLocationAttributes()) {
String schemaLocations = attrs.getValue(Constants.XMLSchemaInstanceNamespace,"schemaLocation");
if (schemaLocations != null) {
logger.debug("Processing schema locations: " + schemaLocations);
String[] fields = schemaLocations.trim().split("\\s+");
for (int i=1; i<fields.length; i=i+2) {
try {
URL url = new URL(this.baseURLSAXResolver.getBaseURL(),fields[i]);
logger.debug("Working on: " + url);
getLoader().stashURL(url);
} catch (MalformedURLException e) {
logger.warn("Ignoring malformed XSI schemaLocation URL in: " + schemaLocations);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -