Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

Root.java 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. /* $Id$ */
  18. package org.apache.fop.fo.pagination;
  19. // java
  20. import java.util.List;
  21. import java.util.Locale;
  22. import org.xml.sax.Locator;
  23. import org.apache.fop.apps.FOPException;
  24. import org.apache.fop.fo.FOEventHandler;
  25. import org.apache.fop.fo.FONode;
  26. import org.apache.fop.fo.FOTreeBuilderContext;
  27. import org.apache.fop.fo.FObj;
  28. import org.apache.fop.fo.PropertyList;
  29. import org.apache.fop.fo.ValidationException;
  30. import org.apache.fop.fo.extensions.destination.Destination;
  31. import org.apache.fop.fo.pagination.bookmarks.BookmarkTree;
  32. import org.apache.fop.fo.properties.CommonAccessibility;
  33. import org.apache.fop.fo.properties.CommonAccessibilityHolder;
  34. import org.apache.fop.fo.properties.CommonHyphenation;
  35. /**
  36. * Class modeling the <a href="http://www.w3.org/TR/xsl/#fo_root">
  37. * <code>fo:root</code></a> formatting object.
  38. * Contains page masters, page-sequences.
  39. */
  40. public class Root extends FObj implements CommonAccessibilityHolder {
  41. private CommonAccessibility commonAccessibility;
  42. private int mediaUsage;
  43. private LayoutMasterSet layoutMasterSet;
  44. private Declarations declarations;
  45. private BookmarkTree bookmarkTree = null;
  46. private List<Destination> destinationList;
  47. private List<PageSequence> pageSequences;
  48. private Locale locale;
  49. // temporary until above list populated
  50. private boolean pageSequenceFound = false;
  51. /**
  52. * Keeps count of page number from over PageSequence instances
  53. */
  54. private int endingPageNumberOfPreviousSequence = 0;
  55. private int totalPagesGenerated = 0;
  56. /**
  57. * Context class used while building the FO tree.
  58. */
  59. private FOTreeBuilderContext builderContext;
  60. /**
  61. * FOEventHandler object for this FO Tree
  62. */
  63. private FOEventHandler foEventHandler = null;
  64. /**
  65. * Base constructor
  66. *
  67. * @param parent {@link FONode} that is the parent of this object
  68. * Note: parent should be null for the fo:root.
  69. */
  70. public Root(FONode parent) {
  71. super(parent);
  72. pageSequences = new java.util.ArrayList<PageSequence>();
  73. }
  74. /** {@inheritDoc} */
  75. public void bind(PropertyList pList) throws FOPException {
  76. super.bind(pList);
  77. commonAccessibility = CommonAccessibility.getInstance(pList);
  78. mediaUsage = pList.get(PR_MEDIA_USAGE).getEnum();
  79. String language = pList.get(PR_LANGUAGE).getString();
  80. String country = pList.get(PR_COUNTRY).getString();
  81. locale = CommonHyphenation.toLocale(language, country);
  82. }
  83. /** {@inheritDoc} */
  84. protected void startOfNode() throws FOPException {
  85. foEventHandler.startRoot(this);
  86. }
  87. /** {@inheritDoc} */
  88. protected void endOfNode() throws FOPException {
  89. if (!pageSequenceFound || layoutMasterSet == null) {
  90. missingChildElementError("(layout-master-set, declarations?, "
  91. + "bookmark-tree?, (page-sequence|fox:external-document)+)");
  92. }
  93. foEventHandler.endRoot(this);
  94. }
  95. /**
  96. * {@inheritDoc}
  97. * <br>XSL 1.0 Spec: (layout-master-set,declarations?,page-sequence+)
  98. * <br>FOP: (layout-master-set, declarations?, fox:bookmarks?, page-sequence+)
  99. */
  100. protected void validateChildNode(Locator loc, String nsURI, String localName)
  101. throws ValidationException {
  102. if (FO_URI.equals(nsURI)) {
  103. if (localName.equals("layout-master-set")) {
  104. if (layoutMasterSet != null) {
  105. tooManyNodesError(loc, "fo:layout-master-set");
  106. }
  107. } else if (localName.equals("declarations")) {
  108. if (layoutMasterSet == null) {
  109. nodesOutOfOrderError(loc, "fo:layout-master-set", "fo:declarations");
  110. } else if (declarations != null) {
  111. tooManyNodesError(loc, "fo:declarations");
  112. } else if (bookmarkTree != null) {
  113. nodesOutOfOrderError(loc, "fo:declarations", "fo:bookmark-tree");
  114. } else if (pageSequenceFound) {
  115. nodesOutOfOrderError(loc, "fo:declarations", "fo:page-sequence");
  116. }
  117. } else if (localName.equals("bookmark-tree")) {
  118. if (layoutMasterSet == null) {
  119. nodesOutOfOrderError(loc, "fo:layout-master-set", "fo:bookmark-tree");
  120. } else if (bookmarkTree != null) {
  121. tooManyNodesError(loc, "fo:bookmark-tree");
  122. } else if (pageSequenceFound) {
  123. nodesOutOfOrderError(loc, "fo:bookmark-tree", "fo:page-sequence");
  124. }
  125. } else if (localName.equals("page-sequence")) {
  126. if (layoutMasterSet == null) {
  127. nodesOutOfOrderError(loc, "fo:layout-master-set", "fo:page-sequence");
  128. } else {
  129. pageSequenceFound = true;
  130. }
  131. } else {
  132. invalidChildError(loc, nsURI, localName);
  133. }
  134. } else {
  135. if (FOX_URI.equals(nsURI)) {
  136. if ("external-document".equals(localName)) {
  137. pageSequenceFound = true;
  138. }
  139. }
  140. //invalidChildError(loc, nsURI, localName);
  141. //Ignore non-FO elements under root
  142. }
  143. }
  144. /**
  145. * @param loc location in the source file
  146. * @param child the {@link FONode} to validate against
  147. * @throws ValidationException if the incoming node is not a valid child for the given FO
  148. */
  149. protected void validateChildNode(Locator loc, FONode child) throws ValidationException {
  150. if (child instanceof AbstractPageSequence) {
  151. pageSequenceFound = true;
  152. }
  153. }
  154. /** {@inheritDoc} */
  155. public CommonAccessibility getCommonAccessibility() {
  156. return commonAccessibility;
  157. }
  158. /**
  159. * Sets the FOEventHandler object that this Root is attached to
  160. * @param foEventHandler the FOEventHandler object
  161. */
  162. public void setFOEventHandler(FOEventHandler foEventHandler) {
  163. this.foEventHandler = foEventHandler;
  164. }
  165. /**
  166. * This method overrides the FONode version. The FONode version calls the
  167. * method by the same name for the parent object. Since Root is at the top
  168. * of the tree, it returns the actual FOEventHandler object. Thus, any FONode
  169. * can use this chain to find which FOEventHandler it is being built for.
  170. * @return the FOEventHandler implementation that this Root is attached to
  171. */
  172. public FOEventHandler getFOEventHandler() {
  173. return foEventHandler;
  174. }
  175. /**
  176. * Sets the builder context for this FO tree.
  177. * @param context the builder context to be used
  178. */
  179. public void setBuilderContext(FOTreeBuilderContext context) {
  180. this.builderContext = context;
  181. }
  182. /** {@inheritDoc} */
  183. public FOTreeBuilderContext getBuilderContext() {
  184. return this.builderContext;
  185. }
  186. /**
  187. * Gets the last page number generated by the previous page-sequence
  188. * @return the last page number, 0 if no page sequences yet generated
  189. */
  190. public int getEndingPageNumberOfPreviousSequence() {
  191. return endingPageNumberOfPreviousSequence;
  192. }
  193. /**
  194. * Returns the total number of pages generated by FOP
  195. * (May not equal endingPageNumberOfPreviousSequence due to
  196. * initial-page-number property on fo:page-sequences.)
  197. * @return the last page number, 0 if no page sequences yet generated
  198. */
  199. public int getTotalPagesGenerated() {
  200. return totalPagesGenerated;
  201. }
  202. /**
  203. * Notify additional pages generated to increase the totalPagesGenerated counter
  204. * @param lastPageNumber the last page number generated by the sequence
  205. * @param additionalPages the total pages generated by the sequence (for statistics)
  206. * @throws IllegalArgumentException for negative additional page counts
  207. */
  208. public void notifyPageSequenceFinished(int lastPageNumber, int additionalPages)
  209. throws IllegalArgumentException {
  210. if (additionalPages >= 0) {
  211. totalPagesGenerated += additionalPages;
  212. endingPageNumberOfPreviousSequence = lastPageNumber;
  213. } else {
  214. throw new IllegalArgumentException(
  215. "Number of additional pages must be zero or greater.");
  216. }
  217. }
  218. /**
  219. * Returns the number of PageSequence instances.
  220. * @return the number of PageSequence instances
  221. */
  222. public int getPageSequenceCount() {
  223. return pageSequences.size();
  224. }
  225. /**
  226. * Some properties, such as 'force-page-count', require a
  227. * page-sequence to know about some properties of the next.
  228. * @param current the current PageSequence
  229. * @return succeeding PageSequence; null if none
  230. */
  231. public PageSequence getSucceedingPageSequence(PageSequence current) {
  232. int currentIndex = pageSequences.indexOf(current);
  233. if (currentIndex == -1) {
  234. return null;
  235. }
  236. if (currentIndex < (pageSequences.size() - 1)) {
  237. return pageSequences.get(currentIndex + 1);
  238. } else {
  239. return null;
  240. }
  241. }
  242. /**
  243. * Returns the associated LayoutMasterSet.
  244. * @return the LayoutMasterSet instance
  245. */
  246. public LayoutMasterSet getLayoutMasterSet() {
  247. return this.layoutMasterSet;
  248. }
  249. /**
  250. * Sets the associated LayoutMasterSet.
  251. * @param layoutMasterSet the LayoutMasterSet to use
  252. */
  253. public void setLayoutMasterSet(LayoutMasterSet layoutMasterSet) {
  254. this.layoutMasterSet = layoutMasterSet;
  255. }
  256. /**
  257. * Returns the associated Declarations.
  258. * @return the Declarations instance
  259. */
  260. public Declarations getDeclarations() {
  261. return this.declarations;
  262. }
  263. /**
  264. * Sets the associated Declarations.
  265. * @param declarations the Declarations to use
  266. */
  267. public void setDeclarations(Declarations declarations) {
  268. this.declarations = declarations;
  269. }
  270. /**
  271. * Set the BookmarkTree object for this FO
  272. * @param bookmarkTree the BookmarkTree object
  273. */
  274. public void setBookmarkTree(BookmarkTree bookmarkTree) {
  275. this.bookmarkTree = bookmarkTree;
  276. }
  277. /**
  278. * Add a Destination object to this FO
  279. * @param destination the Destination object to add
  280. */
  281. public void addDestination(Destination destination) {
  282. if (destinationList == null) {
  283. destinationList = new java.util.ArrayList<Destination>();
  284. }
  285. destinationList.add(destination);
  286. }
  287. /**
  288. * Public accessor for the list of Destination objects for this FO
  289. * @return the Destination object
  290. */
  291. public List getDestinationList() {
  292. return destinationList;
  293. }
  294. /**
  295. * Public accessor for the BookmarkTree object for this FO
  296. * @return the BookmarkTree object
  297. */
  298. public BookmarkTree getBookmarkTree() {
  299. return bookmarkTree;
  300. }
  301. /** {@inheritDoc} */
  302. public Root getRoot() {
  303. return this;
  304. }
  305. /** {@inheritDoc} */
  306. public String getLocalName() {
  307. return "root";
  308. }
  309. /**
  310. * {@inheritDoc}
  311. * @return {@link org.apache.fop.fo.Constants#FO_ROOT}
  312. */
  313. public int getNameId() {
  314. return FO_ROOT;
  315. }
  316. /** @return locale proprty. */
  317. public Locale getLocale() {
  318. return locale;
  319. }
  320. }