Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. /*
  2. * $Id: FObj.java,v 1.40 2003/03/05 21:48:02 jeremias Exp $
  3. * ============================================================================
  4. * The Apache Software License, Version 1.1
  5. * ============================================================================
  6. *
  7. * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
  8. *
  9. * Redistribution and use in source and binary forms, with or without modifica-
  10. * tion, are permitted provided that the following conditions are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright notice,
  13. * this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright notice,
  16. * this list of conditions and the following disclaimer in the documentation
  17. * and/or other materials provided with the distribution.
  18. *
  19. * 3. The end-user documentation included with the redistribution, if any, must
  20. * include the following acknowledgment: "This product includes software
  21. * developed by the Apache Software Foundation (http://www.apache.org/)."
  22. * Alternately, this acknowledgment may appear in the software itself, if
  23. * and wherever such third-party acknowledgments normally appear.
  24. *
  25. * 4. The names "FOP" and "Apache Software Foundation" must not be used to
  26. * endorse or promote products derived from this software without prior
  27. * written permission. For written permission, please contact
  28. * apache@apache.org.
  29. *
  30. * 5. Products derived from this software may not be called "Apache", nor may
  31. * "Apache" appear in their name, without prior written permission of the
  32. * Apache Software Foundation.
  33. *
  34. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  35. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  36. * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  37. * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  38. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
  39. * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  40. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  41. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  42. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  43. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  44. * ============================================================================
  45. *
  46. * This software consists of voluntary contributions made by many individuals
  47. * on behalf of the Apache Software Foundation and was originally created by
  48. * James Tauber <jtauber@jtauber.com>. For more information on the Apache
  49. * Software Foundation, please see <http://www.apache.org/>.
  50. */
  51. package org.apache.fop.fo;
  52. // Java
  53. import java.util.Iterator;
  54. import java.util.ListIterator;
  55. import java.util.ArrayList;
  56. import java.util.List;
  57. import java.util.HashMap;
  58. import java.util.Set;
  59. import java.util.Map;
  60. import org.xml.sax.Attributes;
  61. // FOP
  62. import org.apache.fop.apps.FOPException;
  63. import org.apache.fop.apps.StructureHandler;
  64. import org.apache.fop.fo.properties.FOPropertyMapping;
  65. import org.apache.fop.fo.flow.Marker;
  66. /**
  67. * base class for representation of formatting objects and their processing
  68. */
  69. public class FObj extends FONode {
  70. private static final String FO_URI = "http://www.w3.org/1999/XSL/Format";
  71. /**
  72. * Static property list builder that converts xml attributes
  73. * into fo properties. This is static since the underlying
  74. * property mappings for fo are also static.
  75. */
  76. protected static PropertyListBuilder plb = null;
  77. /**
  78. * Structure handler used to notify structure events
  79. * such as start end element.
  80. */
  81. protected StructureHandler structHandler;
  82. /**
  83. * Formatting properties for this fo element.
  84. */
  85. public PropertyList properties;
  86. /**
  87. * Property manager for handler some common properties.
  88. */
  89. protected PropertyManager propMgr;
  90. /**
  91. * Id of this fo element of null if no id.
  92. */
  93. protected String id = null;
  94. /**
  95. * The children of this node.
  96. */
  97. protected ArrayList children = null;
  98. /**
  99. * Markers added to this element.
  100. */
  101. protected Map markers = null;
  102. /**
  103. * Create a new formatting object.
  104. * All formatting object classes extend this class.
  105. *
  106. * @param parent the parent node
  107. */
  108. public FObj(FONode parent) {
  109. super(parent);
  110. }
  111. /**
  112. * Set the name of this element.
  113. * The prepends "fo:" to the name to indicate it is in the fo namespace.
  114. *
  115. * @param str the xml element name
  116. */
  117. public void setName(String str) {
  118. name = "fo:" + str;
  119. }
  120. protected PropertyListBuilder getListBuilder() {
  121. if (plb == null) {
  122. plb = new PropertyListBuilder();
  123. plb.addList(FOPropertyMapping.getGenericMappings());
  124. for (Iterator iter =
  125. FOPropertyMapping.getElementMappings().iterator();
  126. iter.hasNext();) {
  127. String elem = (String) iter.next();
  128. plb.addElementList(elem,
  129. FOPropertyMapping.getElementMapping(elem));
  130. }
  131. }
  132. return plb;
  133. }
  134. /**
  135. * Handle the attributes for this element.
  136. * The attributes must be used immediately as the sax attributes
  137. * will be altered for the next element.
  138. */
  139. public void handleAttrs(Attributes attlist) throws FOPException {
  140. FONode par = parent;
  141. while (par != null && !(par instanceof FObj)) {
  142. par = par.parent;
  143. }
  144. PropertyList props = null;
  145. if (par != null) {
  146. props = ((FObj) par).properties;
  147. }
  148. properties = getListBuilder().makeList(FO_URI, name, attlist, props,
  149. (FObj) par);
  150. properties.setFObj(this);
  151. this.propMgr = makePropertyManager(properties);
  152. setWritingMode();
  153. }
  154. protected PropertyManager makePropertyManager(
  155. PropertyList propertyList) {
  156. return new PropertyManager(propertyList);
  157. }
  158. /**
  159. * Add the child to this object.
  160. *
  161. * @param child the child node to add
  162. */
  163. protected void addChild(FONode child) {
  164. if (containsMarkers() && child.isMarker()) {
  165. addMarker((Marker)child);
  166. } else {
  167. if (children == null) {
  168. children = new ArrayList();
  169. }
  170. children.add(child);
  171. }
  172. }
  173. /**
  174. * Set the structure handler for handling structure events.
  175. *
  176. * @param st the structure handler
  177. */
  178. public void setStructHandler(StructureHandler st) {
  179. structHandler = st;
  180. }
  181. /**
  182. * lets outside sources access the property list
  183. * first used by PageNumberCitation to find the "id" property
  184. * @param name - the name of the desired property to obtain
  185. * @return the property
  186. */
  187. public Property getProperty(String name) {
  188. return (properties.get(name));
  189. }
  190. /**
  191. * Setup the id for this formatting object.
  192. * Most formatting objects can have an id that can be referenced.
  193. * This methods checks that the id isn't already used by another
  194. * fo and sets the id attribute of this object.
  195. */
  196. protected void setupID() {
  197. Property prop = this.properties.get("id");
  198. if (prop != null) {
  199. String str = prop.getString();
  200. if (str != null && !str.equals("")) {
  201. Set idrefs = structHandler.getIDReferences();
  202. if (!idrefs.contains(str)) {
  203. id = str;
  204. idrefs.add(id);
  205. } else {
  206. getLogger().warn("duplicate id:" + str + " ignored");
  207. }
  208. }
  209. }
  210. }
  211. /**
  212. * Get the id string for this formatting object.
  213. * This will be unique for the fo document.
  214. *
  215. * @return the id string or null if not set
  216. */
  217. public String getID() {
  218. return id;
  219. }
  220. /**
  221. * Check if this formatting object generates reference areas.
  222. *
  223. * @return true if generates reference areas
  224. */
  225. public boolean generatesReferenceAreas() {
  226. return false;
  227. }
  228. /**
  229. * Check if this formatting object generates inline areas.
  230. *
  231. * @return true if generates inline areas
  232. */
  233. public boolean generatesInlineAreas() {
  234. return true;
  235. }
  236. /**
  237. * Check if this formatting object may contain markers.
  238. *
  239. * @return true if this can contian markers
  240. */
  241. protected boolean containsMarkers() {
  242. return false;
  243. }
  244. /**
  245. * Set writing mode for this FO.
  246. * Find nearest ancestor, including self, which generates
  247. * reference areas and use the value of its writing-mode property.
  248. * If no such ancestor is found, use the value on the root FO.
  249. */
  250. protected void setWritingMode() {
  251. FObj p;
  252. FONode parent;
  253. for (p = this; !p.generatesReferenceAreas()
  254. && (parent = p.getParent()) != null
  255. && (parent instanceof FObj); p = (FObj) parent) {
  256. }
  257. this.properties.setWritingMode(
  258. p.getProperty("writing-mode").getEnum());
  259. }
  260. /**
  261. * Return a LayoutManager responsible for laying out this FObj's content.
  262. * Must override in subclasses if their content can be laid out.
  263. * @param list the list to add the layout manager(s) to
  264. */
  265. public void addLayoutManager(List list) {
  266. }
  267. /**
  268. * Return an iterator over all the children of this FObj.
  269. * @return A ListIterator.
  270. */
  271. public ListIterator getChildren() {
  272. if (children != null) {
  273. return children.listIterator();
  274. }
  275. return null;
  276. }
  277. /**
  278. * Return an iterator over the object's children starting
  279. * at the pased node.
  280. * @param childNode First node in the iterator
  281. * @return A ListIterator or null if childNode isn't a child of
  282. * this FObj.
  283. */
  284. public ListIterator getChildren(FONode childNode) {
  285. if (children != null) {
  286. int i = children.indexOf(childNode);
  287. if (i >= 0) {
  288. return children.listIterator(i);
  289. }
  290. }
  291. return null;
  292. }
  293. /**
  294. * Add the marker to this formatting object.
  295. * If this object can contain markers it checks that the marker
  296. * has a unique class-name for this object and that it is
  297. * the first child.
  298. */
  299. public void addMarker(Marker marker) {
  300. String mcname = marker.getMarkerClassName();
  301. if (children != null) {
  302. // check for empty children
  303. for (Iterator iter = children.iterator(); iter.hasNext();) {
  304. FONode node = (FONode)iter.next();
  305. if (node instanceof FOText) {
  306. FOText text = (FOText)node;
  307. if (text.willCreateArea()) {
  308. getLogger().error("fo:marker must be an initial child: " + mcname);
  309. return;
  310. } else {
  311. iter.remove();
  312. }
  313. } else {
  314. getLogger().error("fo:marker must be an initial child: " + mcname);
  315. return;
  316. }
  317. }
  318. }
  319. if (markers == null) {
  320. markers = new HashMap();
  321. }
  322. if (!markers.containsKey(mcname)) {
  323. markers.put(mcname, marker);
  324. } else {
  325. getLogger().error("fo:marker 'marker-class-name' "
  326. + "must be unique for same parent: " + mcname);
  327. }
  328. }
  329. public boolean hasMarkers() {
  330. return markers != null && !markers.isEmpty();
  331. }
  332. public Map getMarkers() {
  333. return markers;
  334. }
  335. /**
  336. * lets layout managers access FO properties via PropertyManager
  337. * @return the property manager for this FO
  338. */
  339. public PropertyManager getPropertyManager() {
  340. return this.propMgr;
  341. }
  342. }