| /* |
| * 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$ */ |
| |
| package org.apache.fop.layoutmgr; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| |
| import org.apache.fop.apps.FOUserAgent; |
| import org.apache.fop.area.AreaTreeHandler; |
| import org.apache.fop.fo.FOElementMapping; |
| import org.apache.fop.fo.FONode; |
| import org.apache.fop.fo.FONode.FONodeIterator; |
| import org.apache.fop.fo.FOText; |
| import org.apache.fop.fo.FObjMixed; |
| import org.apache.fop.fo.extensions.ExternalDocument; |
| import org.apache.fop.fo.flow.BasicLink; |
| import org.apache.fop.fo.flow.BidiOverride; |
| import org.apache.fop.fo.flow.Block; |
| import org.apache.fop.fo.flow.BlockContainer; |
| import org.apache.fop.fo.flow.ChangeBarBegin; |
| import org.apache.fop.fo.flow.ChangeBarEnd; |
| import org.apache.fop.fo.flow.Character; |
| import org.apache.fop.fo.flow.ExternalGraphic; |
| import org.apache.fop.fo.flow.Float; |
| import org.apache.fop.fo.flow.Footnote; |
| import org.apache.fop.fo.flow.Inline; |
| import org.apache.fop.fo.flow.InlineContainer; |
| import org.apache.fop.fo.flow.InlineLevel; |
| import org.apache.fop.fo.flow.InstreamForeignObject; |
| import org.apache.fop.fo.flow.Leader; |
| import org.apache.fop.fo.flow.ListBlock; |
| import org.apache.fop.fo.flow.ListItem; |
| import org.apache.fop.fo.flow.MultiCase; |
| import org.apache.fop.fo.flow.MultiSwitch; |
| import org.apache.fop.fo.flow.PageNumber; |
| import org.apache.fop.fo.flow.PageNumberCitation; |
| import org.apache.fop.fo.flow.PageNumberCitationLast; |
| import org.apache.fop.fo.flow.RetrieveMarker; |
| import org.apache.fop.fo.flow.RetrieveTableMarker; |
| import org.apache.fop.fo.flow.Wrapper; |
| import org.apache.fop.fo.flow.table.Table; |
| import org.apache.fop.fo.flow.table.TableBody; |
| import org.apache.fop.fo.flow.table.TableCell; |
| import org.apache.fop.fo.flow.table.TableColumn; |
| import org.apache.fop.fo.flow.table.TableFooter; |
| import org.apache.fop.fo.flow.table.TableHeader; |
| import org.apache.fop.fo.flow.table.TableRow; |
| import org.apache.fop.fo.pagination.Flow; |
| import org.apache.fop.fo.pagination.PageSequence; |
| import org.apache.fop.fo.pagination.SideRegion; |
| import org.apache.fop.fo.pagination.StaticContent; |
| import org.apache.fop.fo.pagination.Title; |
| import org.apache.fop.layoutmgr.inline.BasicLinkLayoutManager; |
| import org.apache.fop.layoutmgr.inline.BidiLayoutManager; |
| import org.apache.fop.layoutmgr.inline.CharacterLayoutManager; |
| import org.apache.fop.layoutmgr.inline.ContentLayoutManager; |
| import org.apache.fop.layoutmgr.inline.ExternalGraphicLayoutManager; |
| import org.apache.fop.layoutmgr.inline.FloatLayoutManager; |
| import org.apache.fop.layoutmgr.inline.FootnoteLayoutManager; |
| import org.apache.fop.layoutmgr.inline.InlineContainerLayoutManager; |
| import org.apache.fop.layoutmgr.inline.InlineLayoutManager; |
| import org.apache.fop.layoutmgr.inline.InstreamForeignObjectLM; |
| import org.apache.fop.layoutmgr.inline.LeaderLayoutManager; |
| import org.apache.fop.layoutmgr.inline.PageNumberCitationLastLayoutManager; |
| import org.apache.fop.layoutmgr.inline.PageNumberCitationLayoutManager; |
| import org.apache.fop.layoutmgr.inline.PageNumberLayoutManager; |
| import org.apache.fop.layoutmgr.inline.TextLayoutManager; |
| import org.apache.fop.layoutmgr.inline.WrapperLayoutManager; |
| import org.apache.fop.layoutmgr.list.ListBlockLayoutManager; |
| import org.apache.fop.layoutmgr.list.ListItemLayoutManager; |
| import org.apache.fop.layoutmgr.table.TableLayoutManager; |
| import org.apache.fop.util.CharUtilities; |
| |
| /** |
| * The default LayoutManager maker class |
| */ |
| public class LayoutManagerMapping implements LayoutManagerMaker { |
| |
| /** logging instance */ |
| private static final Log LOG = LogFactory.getLog(LayoutManagerMapping.class); |
| |
| /** The map of LayoutManagerMakers */ |
| private final Map makers = new HashMap(); |
| |
| private FOUserAgent userAgent; |
| |
| /** default constructor */ |
| public LayoutManagerMapping(FOUserAgent userAgent) { |
| this.userAgent = userAgent; |
| initialize(); |
| } |
| |
| /** |
| * Initializes the set of maker objects associated with this LayoutManagerMapping |
| */ |
| protected void initialize() { |
| registerMaker(FOText.class, new FOTextLayoutManagerMaker()); |
| registerMaker(FObjMixed.class, new Maker()); |
| registerMaker(BidiOverride.class, new BidiOverrideLayoutManagerMaker()); |
| registerMaker(Inline.class, new InlineLayoutManagerMaker()); |
| registerMaker(Footnote.class, new FootnoteLayoutManagerMaker()); |
| registerMaker(InlineContainer.class, |
| new InlineContainerLayoutManagerMaker()); |
| registerMaker(BasicLink.class, new BasicLinkLayoutManagerMaker()); |
| registerMaker(Block.class, new BlockLayoutManagerMaker()); |
| registerMaker(Leader.class, new LeaderLayoutManagerMaker()); |
| registerMaker(RetrieveMarker.class, new RetrieveMarkerLayoutManagerMaker()); |
| registerMaker(RetrieveTableMarker.class, new RetrieveTableMarkerLayoutManagerMaker()); |
| registerMaker(Character.class, new CharacterLayoutManagerMaker()); |
| registerMaker(ExternalGraphic.class, |
| new ExternalGraphicLayoutManagerMaker()); |
| registerMaker(BlockContainer.class, |
| new BlockContainerLayoutManagerMaker()); |
| registerMaker(ListItem.class, new ListItemLayoutManagerMaker()); |
| registerMaker(ListBlock.class, new ListBlockLayoutManagerMaker()); |
| registerMaker(InstreamForeignObject.class, |
| new InstreamForeignObjectLayoutManagerMaker()); |
| registerMaker(PageNumber.class, new PageNumberLayoutManagerMaker()); |
| registerMaker(PageNumberCitation.class, |
| new PageNumberCitationLayoutManagerMaker()); |
| registerMaker(PageNumberCitationLast.class, |
| new PageNumberCitationLastLayoutManagerMaker()); |
| registerMaker(Table.class, new TableLayoutManagerMaker()); |
| registerMaker(TableBody.class, new Maker()); |
| registerMaker(TableColumn.class, new Maker()); |
| registerMaker(TableRow.class, new Maker()); |
| registerMaker(TableCell.class, new Maker()); |
| registerMaker(TableFooter.class, new Maker()); |
| registerMaker(TableHeader.class, new Maker()); |
| registerMaker(Wrapper.class, new WrapperLayoutManagerMaker()); |
| registerMaker(Title.class, new InlineLayoutManagerMaker()); |
| registerMaker(ChangeBarBegin.class, new Maker()); |
| registerMaker(ChangeBarEnd.class, new Maker()); |
| registerMaker(MultiCase.class, new MultiCaseLayoutManagerMaker()); |
| registerMaker(MultiSwitch.class, new MultiSwitchLayoutManagerMaker()); |
| registerMaker(Float.class, new FloatLayoutManagerMaker()); |
| } |
| |
| /** |
| * Registers a Maker class for a specific formatting object. |
| * @param clazz the formatting object class |
| * @param maker the maker for the layout manager |
| */ |
| protected void registerMaker(Class clazz, Maker maker) { |
| makers.put(clazz, maker); |
| } |
| |
| /** {@inheritDoc} */ |
| public void makeLayoutManagers(FONode node, List lms) { |
| Maker maker = (Maker) makers.get(node.getClass()); |
| if (maker == null) { |
| if (FOElementMapping.URI.equals(node.getNamespaceURI())) { |
| LOG.error("No LayoutManager maker for class " + node.getClass()); |
| } else { |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("Skipping the creation of a layout manager for " + node.getClass()); |
| } |
| } |
| } else { |
| maker.make(node, lms, userAgent); |
| } |
| } |
| |
| /** {@inheritDoc} */ |
| public LayoutManager makeLayoutManager(FONode node) { |
| List lms = new ArrayList(); |
| makeLayoutManagers(node, lms); |
| if (lms.size() == 0) { |
| throw new IllegalStateException("LayoutManager for class " |
| + node.getClass() |
| + " is missing."); |
| } else if (lms.size() > 1) { |
| throw new IllegalStateException("Duplicate LayoutManagers for class " |
| + node.getClass() |
| + " found, only one may be declared."); |
| } |
| return (LayoutManager) lms.get(0); |
| } |
| |
| /** {@inheritDoc} */ |
| public PageSequenceLayoutManager makePageSequenceLayoutManager( |
| AreaTreeHandler ath, PageSequence ps) { |
| return new PageSequenceLayoutManager(ath, ps); |
| } |
| |
| /** {@inheritDoc} */ |
| public ExternalDocumentLayoutManager makeExternalDocumentLayoutManager( |
| AreaTreeHandler ath, ExternalDocument ed) { |
| return new ExternalDocumentLayoutManager(ath, ed); |
| } |
| |
| /** {@inheritDoc} */ |
| public FlowLayoutManager makeFlowLayoutManager( |
| PageSequenceLayoutManager pslm, Flow flow) { |
| return new FlowLayoutManager(pslm, flow); |
| } |
| |
| /** {@inheritDoc} */ |
| public ContentLayoutManager makeContentLayoutManager(PageSequenceLayoutManager pslm, |
| Title title) { |
| return new ContentLayoutManager(pslm, title); |
| } |
| |
| /** {@inheritDoc} */ |
| public StaticContentLayoutManager makeStaticContentLayoutManager( |
| PageSequenceLayoutManager pslm, StaticContent sc, SideRegion reg) { |
| return new StaticContentLayoutManager(pslm, sc, reg); |
| } |
| |
| /** {@inheritDoc} */ |
| public StaticContentLayoutManager makeStaticContentLayoutManager( |
| PageSequenceLayoutManager pslm, StaticContent sc, org.apache.fop.area.Block block) { |
| return new StaticContentLayoutManager(pslm, sc, block); |
| } |
| |
| /** a layout manager maker base class */ |
| public static class Maker { |
| /** |
| * Create a layout manager. |
| * @param node the associated FO node |
| * @param lms a list of layout managers to which new manager is to be added |
| */ |
| public void make(FONode node, List lms, FOUserAgent userAgent) { |
| // no layout manager |
| } |
| } |
| |
| /** a layout manager maker */ |
| public static class FOTextLayoutManagerMaker extends Maker { |
| /** {@inheritDoc} */ |
| public void make(FONode node, List lms, FOUserAgent userAgent) { |
| FOText foText = (FOText) node; |
| if (foText.length() > 0) { |
| lms.add(new TextLayoutManager(foText, userAgent)); |
| } |
| } |
| } |
| |
| /** a layout manager maker */ |
| public static class BidiOverrideLayoutManagerMaker extends Maker { |
| /** {@inheritDoc} */ |
| public void make(FONode node, List lms, FOUserAgent userAgent) { |
| if (node instanceof BidiOverride) { |
| lms.add(new BidiLayoutManager((BidiOverride) node)); |
| } |
| } |
| } |
| |
| /** a layout manager maker */ |
| public static class InlineLayoutManagerMaker extends Maker { |
| /** {@inheritDoc} */ |
| public void make(FONode node, List lms, FOUserAgent userAgent) { |
| lms.add(new InlineLayoutManager((InlineLevel) node)); |
| } |
| } |
| |
| /** a layout manager maker */ |
| public static class FootnoteLayoutManagerMaker extends Maker { |
| /** {@inheritDoc} */ |
| public void make(FONode node, List lms, FOUserAgent userAgent) { |
| lms.add(new FootnoteLayoutManager((Footnote) node)); |
| } |
| } |
| |
| /** a layout manager maker */ |
| public static class InlineContainerLayoutManagerMaker extends Maker { |
| /** {@inheritDoc} */ |
| public void make(FONode node, List lms, FOUserAgent userAgent) { |
| lms.add(new InlineContainerLayoutManager((InlineContainer) node)); |
| } |
| } |
| |
| /** a layout manager maker */ |
| public static class BasicLinkLayoutManagerMaker extends Maker { |
| /** {@inheritDoc} */ |
| public void make(FONode node, List lms, FOUserAgent userAgent) { |
| lms.add(new BasicLinkLayoutManager((BasicLink) node)); |
| } |
| } |
| |
| /** a layout manager maker */ |
| public static class BlockLayoutManagerMaker extends Maker { |
| /** {@inheritDoc} */ |
| public void make(FONode node, List lms, FOUserAgent userAgent) { |
| lms.add(new BlockLayoutManager((Block) node)); |
| } |
| } |
| |
| /** a layout manager maker */ |
| public static class LeaderLayoutManagerMaker extends Maker { |
| /** {@inheritDoc} */ |
| public void make(FONode node, List lms, FOUserAgent userAgent) { |
| lms.add(new LeaderLayoutManager((Leader) node)); |
| } |
| } |
| |
| /** a layout manager maker */ |
| public static class CharacterLayoutManagerMaker extends Maker { |
| /** {@inheritDoc} */ |
| public void make(FONode node, List lms, FOUserAgent userAgent) { |
| Character foCharacter = (Character) node; |
| if (foCharacter.getCharacter() != CharUtilities.CODE_EOT) { |
| lms.add(new CharacterLayoutManager(foCharacter)); |
| } |
| } |
| } |
| |
| /** a layout manager maker */ |
| public static class ExternalGraphicLayoutManagerMaker extends Maker { |
| /** {@inheritDoc} */ |
| public void make(FONode node, List lms, FOUserAgent userAgent) { |
| ExternalGraphic eg = (ExternalGraphic) node; |
| if (!eg.getSrc().equals("")) { |
| lms.add(new ExternalGraphicLayoutManager(eg)); |
| } |
| } |
| } |
| |
| /** a layout manager maker */ |
| public static class BlockContainerLayoutManagerMaker extends Maker { |
| /** {@inheritDoc} */ |
| public void make(FONode node, List lms, FOUserAgent userAgent) { |
| lms.add(new BlockContainerLayoutManager((BlockContainer) node)); |
| } |
| } |
| |
| /** a layout manager maker */ |
| public static class ListItemLayoutManagerMaker extends Maker { |
| /** {@inheritDoc} */ |
| public void make(FONode node, List lms, FOUserAgent userAgent) { |
| lms.add(new ListItemLayoutManager((ListItem) node)); |
| } |
| } |
| |
| /** a layout manager maker */ |
| public static class ListBlockLayoutManagerMaker extends Maker { |
| /** {@inheritDoc} */ |
| public void make(FONode node, List lms, FOUserAgent userAgent) { |
| lms.add(new ListBlockLayoutManager((ListBlock) node)); |
| } |
| } |
| |
| /** a layout manager maker */ |
| public static class InstreamForeignObjectLayoutManagerMaker extends Maker { |
| /** {@inheritDoc} */ |
| public void make(FONode node, List lms, FOUserAgent userAgent) { |
| lms.add(new InstreamForeignObjectLM((InstreamForeignObject) node)); |
| } |
| } |
| |
| /** a layout manager maker */ |
| public static class PageNumberLayoutManagerMaker extends Maker { |
| /** {@inheritDoc} */ |
| public void make(FONode node, List lms, FOUserAgent userAgent) { |
| lms.add(new PageNumberLayoutManager((PageNumber) node)); |
| } |
| } |
| |
| /** a layout manager maker */ |
| public static class PageNumberCitationLayoutManagerMaker extends Maker { |
| /** {@inheritDoc} */ |
| public void make(FONode node, List lms, FOUserAgent userAgent) { |
| lms.add(new PageNumberCitationLayoutManager((PageNumberCitation) node)); |
| } |
| } |
| |
| /** a layout manager maker */ |
| public static class PageNumberCitationLastLayoutManagerMaker extends Maker { |
| /** {@inheritDoc} */ |
| public void make(FONode node, List lms, FOUserAgent userAgent) { |
| lms.add(new PageNumberCitationLastLayoutManager((PageNumberCitationLast) node)); |
| } |
| } |
| |
| /** a layout manager maker */ |
| public static class TableLayoutManagerMaker extends Maker { |
| /** {@inheritDoc} */ |
| public void make(FONode node, List lms, FOUserAgent userAgent) { |
| Table table = (Table) node; |
| TableLayoutManager tlm = new TableLayoutManager(table); |
| lms.add(tlm); |
| } |
| } |
| |
| /** a layout manager maker */ |
| public class RetrieveMarkerLayoutManagerMaker extends Maker { |
| /** {@inheritDoc} */ |
| public void make(FONode node, List lms, FOUserAgent userAgent) { |
| Iterator baseIter; |
| baseIter = node.getChildNodes(); |
| if (baseIter == null) { |
| return; |
| } |
| while (baseIter.hasNext()) { |
| FONode child = (FONode) baseIter.next(); |
| makeLayoutManagers(child, lms); |
| } |
| } |
| } |
| |
| public class RetrieveTableMarkerLayoutManagerMaker extends Maker { |
| public void make(FONode node, List lms, FOUserAgent userAgent) { |
| FONodeIterator baseIter = node.getChildNodes(); |
| if (baseIter == null) { |
| // this happens when the retrieve-table-marker cannot be resolved yet |
| RetrieveTableMarker rtm = (RetrieveTableMarker) node; |
| RetrieveTableMarkerLayoutManager rtmlm = new RetrieveTableMarkerLayoutManager(rtm); |
| lms.add(rtmlm); |
| return; |
| } |
| while (baseIter.hasNext()) { |
| // this happens when the retrieve-table-marker has been resolved |
| FONode child = baseIter.next(); |
| makeLayoutManagers(child, lms); |
| } |
| } |
| } |
| |
| /** a layout manager maker */ |
| public class WrapperLayoutManagerMaker extends Maker { |
| /** {@inheritDoc} */ |
| public void make(FONode node, List lms, FOUserAgent userAgent) { |
| //We insert the wrapper LM before it's children so an ID |
| //on the node can be registered on a page. |
| lms.add(new WrapperLayoutManager((Wrapper)node)); |
| Iterator baseIter; |
| baseIter = node.getChildNodes(); |
| if (baseIter == null) { |
| return; |
| } |
| while (baseIter.hasNext()) { |
| FONode child = (FONode) baseIter.next(); |
| makeLayoutManagers(child, lms); |
| } |
| } |
| } |
| |
| public class MultiSwitchLayoutManagerMaker extends Maker { |
| |
| @Override |
| public void make(FONode node, List lms, FOUserAgent userAgent) { |
| lms.add(new MultiSwitchLayoutManager((MultiSwitch) node)); |
| } |
| } |
| |
| public class MultiCaseLayoutManagerMaker extends Maker { |
| |
| @Override |
| public void make(FONode node, List lms, FOUserAgent userAgent) { |
| lms.add(new MultiCaseLayoutManager((MultiCase) node)); |
| } |
| } |
| |
| public static class FloatLayoutManagerMaker extends Maker { |
| public void make(FONode node, List lms, FOUserAgent userAgent) { |
| lms.add(new FloatLayoutManager((Float) node)); |
| } |
| } |
| |
| } |