/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

/* $Id: IFParser.java 1733431 2016-03-03 09:40:50Z gadams $ */

package org.apache.fop.render.intermediate;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.SAXTransformerFactory;

import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import org.xml.sax.helpers.DefaultHandler;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.xmlgraphics.util.QName;

import org.apache.fop.accessibility.AccessibilityEventProducer;
import org.apache.fop.accessibility.StructureTreeElement;
import org.apache.fop.accessibility.StructureTreeEventHandler;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.fo.ElementMapping;
import org.apache.fop.fo.ElementMappingRegistry;
import org.apache.fop.fo.expr.PropertyException;
import org.apache.fop.fo.extensions.InternalElementMapping;
import org.apache.fop.render.intermediate.extensions.DocumentNavigationExtensionConstants;
import org.apache.fop.render.intermediate.extensions.DocumentNavigationHandler;
import org.apache.fop.traits.BorderProps;
import org.apache.fop.traits.RuleStyle;
import org.apache.fop.util.ColorUtil;
import org.apache.fop.util.ContentHandlerFactory;
import org.apache.fop.util.ContentHandlerFactoryRegistry;
import org.apache.fop.util.DOMBuilderContentHandlerFactory;
import org.apache.fop.util.DefaultErrorListener;
import org.apache.fop.util.LanguageTags;
import org.apache.fop.util.XMLUtil;

This is a parser for the intermediate format XML which converts the intermediate file into IFPainter events.
/** * This is a parser for the intermediate format XML which converts the intermediate file into * {@link IFPainter} events. */
public class IFParser implements IFConstants {
Logger instance
/** Logger instance */
protected static final Log log = LogFactory.getLog(IFParser.class); private static SAXTransformerFactory tFactory = (SAXTransformerFactory)SAXTransformerFactory.newInstance(); private static Set<String> handledNamespaces = new java.util.HashSet<String>(); static { handledNamespaces.add(XMLNS_NAMESPACE_URI); handledNamespaces.add(XML_NAMESPACE); handledNamespaces.add(NAMESPACE); handledNamespaces.add(XLINK_NAMESPACE); }
Parses an intermediate file and paints it.
Params:
  • src – the Source instance pointing to the intermediate file
  • documentHandler – the intermediate format document handler used to process the IF events
  • userAgent – the user agent
Throws:
  • TransformerException – if an error occurs while parsing the area tree XML
  • IFException – if an IF-related error occurs inside the target document handler
/** * Parses an intermediate file and paints it. * @param src the Source instance pointing to the intermediate file * @param documentHandler the intermediate format document handler used to process the IF events * @param userAgent the user agent * @throws TransformerException if an error occurs while parsing the area tree XML * @throws IFException if an IF-related error occurs inside the target document handler */
public void parse(Source src, IFDocumentHandler documentHandler, FOUserAgent userAgent) throws TransformerException, IFException { try { Transformer transformer = tFactory.newTransformer(); transformer.setErrorListener(new DefaultErrorListener(log)); SAXResult res = new SAXResult(getContentHandler(documentHandler, userAgent)); transformer.transform(src, res); } catch (TransformerException te) { Throwable cause = te.getCause(); //Unpack original IFException if applicable if (cause instanceof SAXException) { SAXException se = (SAXException) cause; cause = se.getCause(); if (cause instanceof IFException) { throw (IFException) cause; } } else if (cause instanceof IFException) { throw (IFException) cause; } throw te; } }
Creates a new ContentHandler instance that you can send the area tree XML to. The parsed pages are added to the AreaTreeModel instance you pass in as a parameter.
Params:
  • documentHandler – the intermediate format document handler used to process the IF events
  • userAgent – the user agent
Returns:the ContentHandler instance to receive the SAX stream from the area tree XML
/** * Creates a new ContentHandler instance that you can send the area tree XML to. The parsed * pages are added to the AreaTreeModel instance you pass in as a parameter. * @param documentHandler the intermediate format document handler used to process the IF events * @param userAgent the user agent * @return the ContentHandler instance to receive the SAX stream from the area tree XML */
public ContentHandler getContentHandler(IFDocumentHandler documentHandler, FOUserAgent userAgent) { ElementMappingRegistry elementMappingRegistry = userAgent.getElementMappingRegistry(); return new Handler(documentHandler, userAgent, elementMappingRegistry); } private static class Handler extends DefaultHandler { private Map<String, ElementHandler> elementHandlers = new HashMap<String, ElementHandler>(); private IFDocumentHandler documentHandler; private IFPainter painter; private FOUserAgent userAgent; private ElementMappingRegistry elementMappingRegistry; private Attributes lastAttributes; private StringBuffer content = new StringBuffer(); private boolean ignoreCharacters = true; //private Stack delegateStack = new Stack(); private int delegateDepth; private ContentHandler delegate; private boolean inForeignObject; private Document foreignObject; private ContentHandler navParser; private StructureTreeHandler structureTreeHandler; private Attributes pageSequenceAttributes; private Map<String, StructureTreeElement> structureTreeElements = new HashMap<String, StructureTreeElement>(); private class StructureTreeHandler extends DefaultHandler { protected final StructureTreeEventHandler structureTreeEventHandler; StructureTreeHandler(StructureTreeEventHandler structureTreeEventHandler) { this.structureTreeEventHandler = structureTreeEventHandler; } void startStructureTree(String type) { } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (!"structure-tree".equals(localName)) { if (localName.equals("marked-content")) { localName = "#PCDATA"; } StructureTreeElement parent = getStructureTreeElement(attributes); String structID = attributes.getValue(InternalElementMapping.URI, InternalElementMapping.STRUCT_ID); if (structID == null) { structureTreeEventHandler.startNode(localName, attributes, parent); } else if (localName.equals("external-graphic") || localName.equals("instream-foreign-object")) { StructureTreeElement structureTreeElement = structureTreeEventHandler.startImageNode(localName, attributes, parent); structureTreeElements.put(structID, structureTreeElement); } else { StructureTreeElement structureTreeElement = structureTreeEventHandler .startReferencedNode(localName, attributes, parent); structureTreeElements.put(structID, structureTreeElement); } } } @Override public void endElement(String uri, String localName, String arqNameg2) throws SAXException { if (!"structure-tree".equals(localName)) { structureTreeEventHandler.endNode(localName); } } } private class MainStructureTreeHandler extends StructureTreeHandler { private final Locale pageSequenceLanguage; MainStructureTreeHandler(StructureTreeEventHandler structureTreeEventHandler, Locale pageSequenceLanguage) throws SAXException { super(structureTreeEventHandler); this.pageSequenceLanguage = pageSequenceLanguage; } @Override void startStructureTree(String type) { structureTreeEventHandler.startPageSequence(pageSequenceLanguage, type); } public void endDocument() throws SAXException { startIFElement(EL_PAGE_SEQUENCE, pageSequenceAttributes); pageSequenceAttributes = null; } } public Handler(IFDocumentHandler documentHandler, FOUserAgent userAgent, ElementMappingRegistry elementMappingRegistry) { this.documentHandler = documentHandler; this.userAgent = userAgent; this.elementMappingRegistry = elementMappingRegistry; elementHandlers.put(EL_DOCUMENT, new DocumentHandler()); elementHandlers.put(EL_HEADER, new DocumentHeaderHandler()); elementHandlers.put(EL_LOCALE, new LocaleHandler()); elementHandlers.put(EL_TRAILER, new DocumentTrailerHandler()); elementHandlers.put(EL_PAGE_SEQUENCE, new PageSequenceHandler()); elementHandlers.put(EL_PAGE, new PageHandler()); elementHandlers.put(EL_PAGE_HEADER, new PageHeaderHandler()); elementHandlers.put(EL_PAGE_CONTENT, new PageContentHandler()); elementHandlers.put(EL_PAGE_TRAILER, new PageTrailerHandler()); //Page content elementHandlers.put(EL_VIEWPORT, new ViewportHandler()); elementHandlers.put(EL_GROUP, new GroupHandler()); elementHandlers.put(EL_ID, new IDHandler()); elementHandlers.put(EL_FONT, new FontHandler()); elementHandlers.put(EL_TEXT, new TextHandler()); elementHandlers.put(EL_CLIP_RECT, new ClipRectHandler()); elementHandlers.put(EL_RECT, new RectHandler()); elementHandlers.put(EL_LINE, new LineHandler()); elementHandlers.put(EL_BORDER_RECT, new BorderRectHandler()); elementHandlers.put(EL_IMAGE, new ImageHandler()); } private void establishForeignAttributes(Map<QName, String> foreignAttributes) { documentHandler.getContext().setForeignAttributes(foreignAttributes); } private void resetForeignAttributes() { documentHandler.getContext().resetForeignAttributes(); }
{@inheritDoc}
/** {@inheritDoc} */
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (delegate != null) { delegateDepth++; delegate.startElement(uri, localName, qName, attributes); } else { boolean handled = true; if (NAMESPACE.equals(uri)) { if (localName.equals(EL_PAGE_SEQUENCE) && userAgent.isAccessibilityEnabled()) { pageSequenceAttributes = new AttributesImpl(attributes); Locale language = getLanguage(attributes); structureTreeHandler = new MainStructureTreeHandler( userAgent.getStructureTreeEventHandler(), language); } else if (localName.equals(EL_STRUCTURE_TREE)) { if (userAgent.isAccessibilityEnabled()) { String type = attributes.getValue("type"); structureTreeHandler.startStructureTree(type); delegate = structureTreeHandler; } else { /* Delegate to a handler that does nothing */ delegate = new DefaultHandler(); } delegateDepth++; delegate.startDocument(); delegate.startElement(uri, localName, qName, attributes); } else { if (pageSequenceAttributes != null) { /* * This means that no structure-element tag was * found in the XML, otherwise a * StructureTreeBuilderWrapper object would have * been created, which would have reset the * pageSequenceAttributes field. */ AccessibilityEventProducer.Provider .get(userAgent.getEventBroadcaster()) .noStructureTreeInXML(this); } handled = startIFElement(localName, attributes); } } else if (DocumentNavigationExtensionConstants.NAMESPACE.equals(uri)) { if (this.navParser == null) { this.navParser = new DocumentNavigationHandler( this.documentHandler.getDocumentNavigationHandler(), structureTreeElements); } delegate = this.navParser; delegateDepth++; delegate.startDocument(); delegate.startElement(uri, localName, qName, attributes); } else { ContentHandlerFactoryRegistry registry = userAgent.getContentHandlerFactoryRegistry(); ContentHandlerFactory factory = registry.getFactory(uri); if (factory == null) { DOMImplementation domImplementation = elementMappingRegistry.getDOMImplementationForNamespace(uri); if (domImplementation == null) { domImplementation = ElementMapping.getDefaultDOMImplementation(); /* throw new SAXException("No DOMImplementation could be" + " identified to handle namespace: " + uri); */ } factory = new DOMBuilderContentHandlerFactory(uri, domImplementation); } delegate = factory.createContentHandler(); delegateDepth++; delegate.startDocument(); delegate.startElement(uri, localName, qName, attributes); } if (!handled) { if (uri == null || uri.length() == 0) { throw new SAXException("Unhandled element " + localName + " in namespace: " + uri); } else { log.warn("Unhandled element " + localName + " in namespace: " + uri); } } } } private static Locale getLanguage(Attributes attributes) { String xmllang = attributes.getValue(XML_NAMESPACE, "lang"); return (xmllang == null) ? null : LanguageTags.toLocale(xmllang); } private boolean startIFElement(String localName, Attributes attributes) throws SAXException { lastAttributes = new AttributesImpl(attributes); ElementHandler elementHandler = elementHandlers.get(localName); content.setLength(0); ignoreCharacters = true; if (elementHandler != null) { ignoreCharacters = elementHandler.ignoreCharacters(); try { elementHandler.startElement(attributes); } catch (IFException ife) { handleIFException(ife); } return true; } else { return false; } } private void handleIFException(IFException ife) throws SAXException { Throwable cause = ife.getCause(); if (cause instanceof SAXException) { //unwrap throw (SAXException) cause; } else { //wrap throw new SAXException(ife); } }
{@inheritDoc}
/** {@inheritDoc} */
public void endElement(String uri, String localName, String qName) throws SAXException { if (delegate != null) { delegate.endElement(uri, localName, qName); delegateDepth--; if (delegateDepth == 0) { delegate.endDocument(); if (delegate instanceof ContentHandlerFactory.ObjectSource) { Object obj = ((ContentHandlerFactory.ObjectSource)delegate).getObject(); if (inForeignObject) { this.foreignObject = (Document)obj; } else { handleExternallyGeneratedObject(obj); } } delegate = null; //Sub-document is processed, return to normal processing } } else { if (NAMESPACE.equals(uri)) { ElementHandler elementHandler = elementHandlers.get(localName); if (elementHandler != null) { try { elementHandler.endElement(); } catch (IFException ife) { handleIFException(ife); } content.setLength(0); } ignoreCharacters = true; } else { if (log.isTraceEnabled()) { log.trace("Ignoring " + localName + " in namespace: " + uri); } } } } // ============== Element handlers for the intermediate format ============= private interface ElementHandler { void startElement(Attributes attributes) throws IFException, SAXException; void endElement() throws IFException; boolean ignoreCharacters(); } private abstract class AbstractElementHandler implements ElementHandler { public void startElement(Attributes attributes) throws IFException, SAXException { //nop } public void endElement() throws IFException { //nop } public boolean ignoreCharacters() { return true; } } private class DocumentHandler extends AbstractElementHandler { public void startElement(Attributes attributes) throws IFException { documentHandler.startDocument(); } public void endElement() throws IFException { documentHandler.endDocument(); } } private class DocumentHeaderHandler extends AbstractElementHandler { public void startElement(Attributes attributes) throws IFException { documentHandler.startDocumentHeader(); } public void endElement() throws IFException { documentHandler.endDocumentHeader(); } } private class LocaleHandler extends AbstractElementHandler { public void startElement(Attributes attributes) throws IFException { documentHandler.setDocumentLocale(getLanguage(attributes)); } } private class DocumentTrailerHandler extends AbstractElementHandler { public void startElement(Attributes attributes) throws IFException { documentHandler.startDocumentTrailer(); } public void endElement() throws IFException { documentHandler.endDocumentTrailer(); } } private class PageSequenceHandler extends AbstractElementHandler { public void startElement(Attributes attributes) throws IFException { String id = attributes.getValue("id"); Locale language = getLanguage(attributes); if (language != null) { documentHandler.getContext().setLanguage(language); } Map<QName, String> foreignAttributes = getForeignAttributes(lastAttributes); establishForeignAttributes(foreignAttributes); documentHandler.startPageSequence(id); resetForeignAttributes(); } public void endElement() throws IFException { documentHandler.endPageSequence(); documentHandler.getContext().setLanguage(null); } } private class PageHandler extends AbstractElementHandler { public void startElement(Attributes attributes) throws IFException { int index = Integer.parseInt(attributes.getValue("index")); String name = attributes.getValue("name"); String pageMasterName = attributes.getValue("page-master-name"); int width = Integer.parseInt(attributes.getValue("width")); int height = Integer.parseInt(attributes.getValue("height")); Map<QName, String> foreignAttributes = getForeignAttributes(lastAttributes); establishForeignAttributes(foreignAttributes); documentHandler.startPage(index, name, pageMasterName, new Dimension(width, height)); documentHandler.getContext().setPageNumber(index + 1); resetForeignAttributes(); } public void endElement() throws IFException { documentHandler.endPage(); } } private class PageHeaderHandler extends AbstractElementHandler { public void startElement(Attributes attributes) throws IFException { documentHandler.startPageHeader(); structureTreeHandler = new StructureTreeHandler(userAgent.getStructureTreeEventHandler()); } public void endElement() throws IFException { documentHandler.endPageHeader(); } } private class PageContentHandler extends AbstractElementHandler { public void startElement(Attributes attributes) throws IFException { painter = documentHandler.startPageContent(); } public void endElement() throws IFException { painter = null; documentHandler.getContext().setID(""); documentHandler.endPageContent(); } } private class PageTrailerHandler extends AbstractElementHandler { public void startElement(Attributes attributes) throws IFException { documentHandler.startPageTrailer(); } public void endElement() throws IFException { documentHandler.endPageTrailer(); } } private class ViewportHandler extends AbstractElementHandler { public void startElement(Attributes attributes) throws IFException { String transform = attributes.getValue("transform"); AffineTransform[] transforms = AffineTransformArrayParser.createAffineTransform(transform); int width = Integer.parseInt(attributes.getValue("width")); int height = Integer.parseInt(attributes.getValue("height")); Rectangle clipRect = XMLUtil.getAttributeAsRectangle(attributes, "clip-rect"); painter.startViewport(transforms, new Dimension(width, height), clipRect); } public void endElement() throws IFException { painter.endViewport(); } } private class GroupHandler extends AbstractElementHandler { public void startElement(Attributes attributes) throws IFException { String transform = attributes.getValue("transform"); AffineTransform[] transforms = AffineTransformArrayParser.createAffineTransform(transform); String layer = attributes.getValue("layer"); painter.startGroup(transforms, layer); } public void endElement() throws IFException { painter.endGroup(); } } private class IDHandler extends AbstractElementHandler { @Override public void startElement(Attributes attributes) throws IFException, SAXException { String id = attributes.getValue("name"); documentHandler.getContext().setID(id); } } private class FontHandler extends AbstractElementHandler { public void startElement(Attributes attributes) throws IFException { String family = attributes.getValue("family"); String style = attributes.getValue("style"); Integer weight = XMLUtil.getAttributeAsInteger(attributes, "weight"); String variant = attributes.getValue("variant"); Integer size = XMLUtil.getAttributeAsInteger(attributes, "size"); Color color; try { color = getAttributeAsColor(attributes, "color"); } catch (PropertyException pe) { throw new IFException("Error parsing the color attribute", pe); } painter.setFont(family, style, weight, variant, size, color); } } private class TextHandler extends AbstractElementHandler { public void endElement() throws IFException { int x = Integer.parseInt(lastAttributes.getValue("x")); int y = Integer.parseInt(lastAttributes.getValue("y")); String s = lastAttributes.getValue("letter-spacing"); int letterSpacing = (s != null ? Integer.parseInt(s) : 0); s = lastAttributes.getValue("word-spacing"); int wordSpacing = (s != null ? Integer.parseInt(s) : 0); int[] dx = XMLUtil.getAttributeAsIntArray(lastAttributes, "dx"); int[][] dp = XMLUtil.getAttributeAsPositionAdjustments(lastAttributes, "dp"); // if only DX present, then convert DX to DP; otherwise use only DP, // effectively ignoring DX if ((dp == null) && (dx != null)) { dp = IFUtil.convertDXToDP(dx); } establishStructureTreeElement(lastAttributes); boolean isHyphenated = Boolean.valueOf(lastAttributes.getValue("hyphenated")); if (isHyphenated) { documentHandler.getContext().setHyphenated(isHyphenated); } painter.drawText(x, y, letterSpacing, wordSpacing, dp, content.toString()); documentHandler.getContext().setHyphenated(false); resetStructureTreeElement(); } public boolean ignoreCharacters() { return false; } } private class ClipRectHandler extends AbstractElementHandler { public void startElement(Attributes attributes) throws IFException { int x = Integer.parseInt(attributes.getValue("x")); int y = Integer.parseInt(attributes.getValue("y")); int width = Integer.parseInt(attributes.getValue("width")); int height = Integer.parseInt(attributes.getValue("height")); BorderProps[] borders = new BorderProps[4]; for (int i = 0; i < 4; i++) { String b = attributes.getValue(SIDES[i]); if (b != null) { borders[i] = BorderProps.valueOf(userAgent, b); } } if (!(borders[0] == null && borders[1] == null && borders[2] == null && borders[3] == null)) { painter.clipBackground(new Rectangle(x, y, width, height), borders[0], borders[1], borders[2], borders[3]); } painter.clipRect(new Rectangle(x, y, width, height)); } } private class RectHandler extends AbstractElementHandler { public void startElement(Attributes attributes) throws IFException { int x = Integer.parseInt(attributes.getValue("x")); int y = Integer.parseInt(attributes.getValue("y")); int width = Integer.parseInt(attributes.getValue("width")); int height = Integer.parseInt(attributes.getValue("height")); Color fillColor; try { fillColor = getAttributeAsColor(attributes, "fill"); } catch (PropertyException pe) { throw new IFException("Error parsing the fill attribute", pe); } Rectangle rectangularArea = new Rectangle(x, y, width, height); //TODO should rect be overloaded to include rounded corners // or should we introduce a new IF element? BorderProps[] borders = new BorderProps[4]; for (int i = 0; i < 4; i++) { String b = attributes.getValue(SIDES[i]); if (b != null) { borders[i] = BorderProps.valueOf(userAgent, b); } } if (!(borders[0] == null && borders[1] == null && borders[2] == null && borders[3] == null)) { painter.clipBackground(rectangularArea, borders[0], borders[1], borders[2], borders[3]); } painter.fillRect(rectangularArea , fillColor); } } private class LineHandler extends AbstractElementHandler { public void startElement(Attributes attributes) throws IFException { int x1 = Integer.parseInt(attributes.getValue("x1")); int y1 = Integer.parseInt(attributes.getValue("y1")); int x2 = Integer.parseInt(attributes.getValue("x2")); int y2 = Integer.parseInt(attributes.getValue("y2")); int width = Integer.parseInt(attributes.getValue("stroke-width")); Color color; try { color = getAttributeAsColor(attributes, "color"); } catch (PropertyException pe) { throw new IFException("Error parsing the fill attribute", pe); } RuleStyle style = RuleStyle.valueOf(attributes.getValue("style")); painter.drawLine(new Point(x1, y1), new Point(x2, y2), width, color, style); } } private static final String[] SIDES = new String[] {"top", "bottom", "left", "right"}; private class BorderRectHandler extends AbstractElementHandler { public void startElement(Attributes attributes) throws IFException { int x = Integer.parseInt(attributes.getValue("x")); int y = Integer.parseInt(attributes.getValue("y")); int width = Integer.parseInt(attributes.getValue("width")); int height = Integer.parseInt(attributes.getValue("height")); BorderProps[] borders = new BorderProps[4]; for (int i = 0; i < 4; i++) { String b = attributes.getValue(SIDES[i]); if (b != null) { borders[i] = BorderProps.valueOf(userAgent, b); } } Color backgroundColor; try { backgroundColor = getAttributeAsColor(attributes, "inner-background-color"); } catch (PropertyException pe) { throw new IFException("Error parsing the color attribute", pe); } painter.drawBorderRect(new Rectangle(x, y, width, height), borders[0], borders[1], borders[2], borders[3], backgroundColor); } } private class ImageHandler extends AbstractElementHandler { public void startElement(Attributes attributes) throws IFException { inForeignObject = true; } public void endElement() throws IFException { int x = Integer.parseInt(lastAttributes.getValue("x")); int y = Integer.parseInt(lastAttributes.getValue("y")); int width = Integer.parseInt(lastAttributes.getValue("width")); int height = Integer.parseInt(lastAttributes.getValue("height")); Map<QName, String> foreignAttributes = getForeignAttributes(lastAttributes); establishForeignAttributes(foreignAttributes); establishStructureTreeElement(lastAttributes); if (foreignObject != null) { painter.drawImage(foreignObject, new Rectangle(x, y, width, height)); foreignObject = null; } else { String uri = lastAttributes.getValue( XLINK_HREF.getNamespaceURI(), XLINK_HREF.getLocalName()); if (uri == null) { throw new IFException("xlink:href is missing on image", null); } painter.drawImage(uri, new Rectangle(x, y, width, height)); } resetStructureTreeElement(); resetForeignAttributes(); inForeignObject = false; } public boolean ignoreCharacters() { return false; } } // ====================================================================
Handles objects created by "sub-parsers" that implement the ObjectSource interface. An example of object handled here are ExtensionAttachments.
Params:
  • obj – the Object to be handled.
Throws:
  • SAXException – if an error occurs while handling the extension object
/** * Handles objects created by "sub-parsers" that implement the ObjectSource interface. * An example of object handled here are ExtensionAttachments. * @param obj the Object to be handled. * @throws SAXException if an error occurs while handling the extension object */
protected void handleExternallyGeneratedObject(Object obj) throws SAXException { try { documentHandler.handleExtensionObject(obj); } catch (IFException ife) { handleIFException(ife); } } private Color getAttributeAsColor(Attributes attributes, String name) throws PropertyException { String s = attributes.getValue(name); if (s == null) { return null; } else { return ColorUtil.parseColorString(userAgent, s); } } private static Map<QName, String> getForeignAttributes(Attributes atts) { Map<QName, String> foreignAttributes = null; for (int i = 0, c = atts.getLength(); i < c; i++) { String ns = atts.getURI(i); if (ns.length() > 0) { if (handledNamespaces.contains(ns)) { continue; } if (foreignAttributes == null) { foreignAttributes = new java.util.HashMap<QName, String>(); } QName qname = new QName(ns, atts.getQName(i)); foreignAttributes.put(qname, atts.getValue(i)); } } return foreignAttributes; } private void establishStructureTreeElement(Attributes attributes) { StructureTreeElement element = getStructureTreeElement(attributes); if (element != null) { documentHandler.getContext().setStructureTreeElement(element); } } private StructureTreeElement getStructureTreeElement(Attributes attributes) { String structRef = attributes.getValue(InternalElementMapping.URI, InternalElementMapping.STRUCT_REF); if (structRef != null && structRef.length() > 0) { assert structureTreeElements.containsKey(structRef); return structureTreeElements.get(structRef); } else { return null; } } private void resetStructureTreeElement() { documentHandler.getContext().resetStructureTreeElement(); }
{@inheritDoc}
/** {@inheritDoc} */
public void characters(char[] ch, int start, int length) throws SAXException { if (delegate != null) { delegate.characters(ch, start, length); } else if (!ignoreCharacters) { this.content.append(ch, start, length); } } } }