/** * Finds the Maker used to create node objects of a particular type * * @param namespaceURI URI for the namespace of the element * @param localName name of the Element * @param locator the Locator instance for context information * @return the ElementMapping.Maker that can create an FO object for this element * @throws FOPException if a Maker could not be found for a bound namespace. */ public Maker findFOMaker(String namespaceURI, String localName, Locator locator) throws FOPException { Map<String, Maker> table = fobjTable.get(namespaceURI); Maker fobjMaker = null; if (table != null) { fobjMaker = table.get(localName); // try default if (fobjMaker == null) { fobjMaker = table.get(ElementMapping.DEFAULT); } } if (fobjMaker == null) { if (namespaces.containsKey(namespaceURI.intern())) { throw new FOPException( FONode.errorText(locator) + "No element mapping definition found for " + FONode.getNodeString(namespaceURI, localName), locator); } else { fobjMaker = new UnknownXMLObj.Maker(namespaceURI); } } return fobjMaker; }
/** * Creates block-pointers between subsequent FOText nodes in the same Block. (used for handling * text-transform) * * <p>TODO: !! Revisit: does not take into account fo:characters !! * * @throws FOPException if there is a problem during processing */ private void flushText() throws FOPException { if (this.ft != null) { final FOText lft = this.ft; /* make sure nested calls to itself have no effect */ this.ft = null; if (getNameId() == FO_BLOCK) { lft.createBlockPointers((org.apache.fop.fo.flow.Block) this); this.lastFOTextProcessed = lft; } else if (getNameId() != FO_MARKER && getNameId() != FO_TITLE && getNameId() != FO_BOOKMARK_TITLE) { FONode fo = this.parent; int foNameId = fo.getNameId(); while (foNameId != FO_BLOCK && foNameId != FO_MARKER && foNameId != FO_TITLE && foNameId != FO_BOOKMARK_TITLE && foNameId != FO_PAGE_SEQUENCE) { fo = fo.getParent(); foNameId = fo.getNameId(); } if (foNameId == FO_BLOCK) { lft.createBlockPointers((org.apache.fop.fo.flow.Block) fo); ((FObjMixed) fo).lastFOTextProcessed = lft; } else if (foNameId == FO_PAGE_SEQUENCE && lft.willCreateArea()) { log.error("Could not create block pointers." + " FOText w/o Block ancestor."); } } addChildNode(lft); } }
private void sendCharacters() throws FOPException { if (this.currentTextNode != null) { final FONodeIterator nodeIter = this.getChildNodes(this.currentTextNode); FONode node; while (nodeIter.hasNext()) { node = nodeIter.nextNode(); assert node instanceof FOText || node.getNameId() == FO_CHARACTER; if (node.getNameId() == FO_CHARACTER) { node.startOfNode(); } node.endOfNode(); } } this.currentTextNode = null; }
/** {@inheritDoc} */ public void endElement(String uri, String localName, String rawName) throws SAXException { if (currentFObj == null) { throw new SAXException( "endElement() called for " + rawName + " where there is no current element."); } else if (!currentFObj.getLocalName().equals(localName) || !currentFObj.getNamespaceURI().equals(uri)) { throw new SAXException( "Mismatch: " + currentFObj.getLocalName() + " (" + currentFObj.getNamespaceURI() + ") vs. " + localName + " (" + uri + ")"); } // fo:characters can potentially be removed during // white-space handling. // Do not notify the FOEventHandler. if (currentFObj.getNameId() != Constants.FO_CHARACTER) { currentFObj.endOfNode(); } if (currentPropertyList != null && currentPropertyList.getFObj() == currentFObj && !builderContext.inMarker()) { currentPropertyList = currentPropertyList.getParentPropertyList(); } if (currentFObj.getNameId() == Constants.FO_MARKER) { if (nestedMarkerDepth == 0) { builderContext.switchMarkerContext(false); } else { nestedMarkerDepth--; } } if (currentFObj.getParent() == null) { log.debug("endElement for top-level " + currentFObj.getName()); } currentFObj = currentFObj.getParent(); }
/** * Finds the {@link Maker} used to create {@link FONode} objects of a particular type * * @param namespaceURI URI for the namespace of the element * @param localName name of the Element * @return the ElementMapping.Maker that can create an FO object for this element * @throws FOPException if a Maker could not be found for a bound namespace. */ private Maker findFOMaker(String namespaceURI, String localName) throws FOPException { Maker maker = elementMappingRegistry.findFOMaker(namespaceURI, localName, locator); if (maker instanceof UnknownXMLObj.Maker) { FOValidationEventProducer eventProducer = FOValidationEventProducer.Provider.get(userAgent.getEventBroadcaster()); eventProducer.unknownFormattingObject( this, currentFObj.getName(), new QName(namespaceURI, localName), getEffectiveLocator()); } return maker; }
/** {@inheritDoc} */ @Override protected void addChildNode(final FONode child) throws FOPException { flushText(); if (!inMarker()) { if (child instanceof FOText || child.getNameId() == FO_CHARACTER) { if (this.currentTextNode == null) { this.currentTextNode = child; } } else { // handle white-space for all text up to here handleWhiteSpaceFor(this, child); // send character[s]() events to the FOEventHandler sendCharacters(); } } super.addChildNode(child); }
/** {@inheritDoc} */ public void characters(char[] data, int start, int length) throws FOPException { if (currentFObj != null) { currentFObj.characters(data, start, length, currentPropertyList, getEffectiveLocator()); } }
/** {@inheritDoc} */ public void startElement( String namespaceURI, String localName, String rawName, Attributes attlist) throws SAXException { /* the node found in the FO document */ FONode foNode; PropertyList propertyList = null; // Check to ensure first node encountered is an fo:root if (rootFObj == null) { empty = false; if (!namespaceURI.equals(FOElementMapping.URI) || !localName.equals("root")) { FOValidationEventProducer eventProducer = FOValidationEventProducer.Provider.get(userAgent.getEventBroadcaster()); eventProducer.invalidFORoot( this, FONode.getNodeString(namespaceURI, localName), getEffectiveLocator()); } } else { // check that incoming node is valid for currentFObj if (currentFObj.getNamespaceURI().equals(FOElementMapping.URI) || currentFObj.getNamespaceURI().equals(ExtensionElementMapping.URI)) { currentFObj.validateChildNode(locator, namespaceURI, localName); } } ElementMapping.Maker fobjMaker = findFOMaker(namespaceURI, localName); try { foNode = fobjMaker.make(currentFObj); if (rootFObj == null) { rootFObj = (Root) foNode; rootFObj.setBuilderContext(builderContext); rootFObj.setFOEventHandler(foEventHandler); } propertyList = foNode.createPropertyList(currentPropertyList, foEventHandler); foNode.processNode(localName, getEffectiveLocator(), attlist, propertyList); if (foNode.getNameId() == Constants.FO_MARKER) { if (builderContext.inMarker()) { nestedMarkerDepth++; } else { builderContext.switchMarkerContext(true); } } if (foNode.getNameId() == Constants.FO_PAGE_SEQUENCE) { builderContext.getXMLWhiteSpaceHandler().reset(); } } catch (IllegalArgumentException e) { throw new SAXException(e); } ContentHandlerFactory chFactory = foNode.getContentHandlerFactory(); if (chFactory != null) { ContentHandler subHandler = chFactory.createContentHandler(); if (subHandler instanceof ObjectSource && foNode instanceof ObjectBuiltListener) { ((ObjectSource) subHandler).setObjectBuiltListener((ObjectBuiltListener) foNode); } subHandler.startDocument(); subHandler.startElement(namespaceURI, localName, rawName, attlist); depth = 1; delegate = subHandler; } if (currentFObj != null) { currentFObj.addChildNode(foNode); } currentFObj = foNode; if (propertyList != null && !builderContext.inMarker()) { currentPropertyList = propertyList; } // fo:characters can potentially be removed during // white-space handling. // Do not notify the FOEventHandler. if (currentFObj.getNameId() != Constants.FO_CHARACTER) { currentFObj.startOfNode(); } }