You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  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.render.rtf.rtflib.rtfdoc;
  19. /*
  20. * This file is part of the RTF library of the FOP project, which was originally
  21. * created by Bertrand Delacretaz bdelacretaz@codeconsult.ch and by other
  22. * contributors to the jfor project (www.jfor.org), who agreed to donate jfor to
  23. * the FOP project.
  24. */
  25. import java.io.IOException;
  26. import java.io.Writer;
  27. import java.util.LinkedList;
  28. import java.util.List;
  29. import org.apache.fop.render.rtf.rtflib.exceptions.RtfStructureException;
  30. /**
  31. * <p>An RtfElement that can contain other elements.</p>
  32. *
  33. * <p>This work was authored by Bertrand Delacretaz (bdelacretaz@codeconsult.ch).</p>
  34. */
  35. public class RtfContainer extends RtfElement {
  36. private LinkedList children; // 'final' removed by Boris Poudérous on 07/22/2002
  37. private RtfOptions options = new RtfOptions();
  38. private RtfElement lastChild;
  39. /** Create an RTF container as a child of given container */
  40. RtfContainer(RtfContainer parent, Writer w) throws IOException {
  41. this(parent, w, null);
  42. }
  43. /** Create an RTF container as a child of given container with given attributes */
  44. RtfContainer(RtfContainer parent, Writer w, RtfAttributes attr) throws IOException {
  45. super(parent, w, attr);
  46. children = new LinkedList();
  47. }
  48. /**
  49. * set options
  50. * @param opt options to set
  51. */
  52. public void setOptions(RtfOptions opt) {
  53. options = opt;
  54. }
  55. /**
  56. * add a child element to this
  57. * @param e child element to add
  58. * @throws RtfStructureException for trying to add an invalid child (??)
  59. */
  60. protected void addChild(RtfElement e)
  61. throws RtfStructureException {
  62. if (isClosed()) {
  63. // No childs should be added to a container that has been closed
  64. final StringBuffer sb = new StringBuffer();
  65. sb.append("addChild: container already closed (parent=");
  66. sb.append(this.getClass().getName());
  67. sb.append(" child=");
  68. sb.append(e.getClass().getName());
  69. sb.append(")");
  70. final String msg = sb.toString();
  71. // warn of this problem
  72. final RtfFile rf = getRtfFile();
  73. // if(rf.getLog() != null) {
  74. // rf.getLog().logWarning(msg);
  75. // }
  76. // TODO this should be activated to help detect XSL-FO constructs
  77. // that we do not handle properly.
  78. /*
  79. throw new RtfStructureException(msg);
  80. */
  81. }
  82. children.add(e);
  83. lastChild = e;
  84. }
  85. /**
  86. * @return a copy of our children's list
  87. */
  88. public List getChildren() {
  89. return (List)children.clone();
  90. }
  91. /**
  92. * @return the number of children
  93. */
  94. public int getChildCount() {
  95. return children.size();
  96. }
  97. private int findChildren(RtfElement aChild, int iStart) {
  98. for (Object o : this.getChildren()) {
  99. final RtfElement e = (RtfElement) o;
  100. if (aChild == e) {
  101. return iStart;
  102. } else if (e instanceof RtfContainer) {
  103. int iFound = ((RtfContainer) e).findChildren(aChild, (iStart + 1));
  104. if (iFound != -1) {
  105. return iFound;
  106. }
  107. }
  108. }
  109. return -1;
  110. }
  111. /**
  112. * Find the passed child in the current container
  113. * @param aChild the child element
  114. * @return the depth (nested level) inside the current container
  115. */
  116. public int findChildren(RtfElement aChild) {
  117. return findChildren(aChild, 0);
  118. }
  119. /**
  120. * Add by Boris Poudérous on 07/22/2002
  121. * Set the children list
  122. * @param list list of child objects
  123. * @return true if process succeeded
  124. */
  125. public boolean setChildren(List list) {
  126. if (list instanceof LinkedList) {
  127. this.children = (LinkedList) list;
  128. return true;
  129. }
  130. return false;
  131. }
  132. /**
  133. * write RTF code of all our children
  134. * @throws IOException for I/O problems
  135. */
  136. protected void writeRtfContent()
  137. throws IOException {
  138. for (Object aChildren : children) {
  139. final RtfElement e = (RtfElement) aChildren;
  140. e.writeRtf();
  141. }
  142. }
  143. /** return our options */
  144. RtfOptions getOptions() {
  145. return options;
  146. }
  147. /** true if this (recursively) contains at least one RtfText object */
  148. boolean containsText() {
  149. boolean result = false;
  150. for (Object aChildren : children) {
  151. final RtfElement e = (RtfElement) aChildren;
  152. if (e instanceof RtfText) {
  153. result = !e.isEmpty();
  154. } else if (e instanceof RtfContainer) {
  155. if (((RtfContainer) e).containsText()) {
  156. result = true;
  157. }
  158. }
  159. if (result) {
  160. break;
  161. }
  162. }
  163. return result;
  164. }
  165. /** debugging to given Writer */
  166. void dump(Writer w, int indent)
  167. throws IOException {
  168. super.dump(w, indent);
  169. for (Object aChildren : children) {
  170. final RtfElement e = (RtfElement) aChildren;
  171. e.dump(w, indent + 1);
  172. }
  173. }
  174. /**
  175. * minimal debugging display
  176. * @return String representation of object contents
  177. */
  178. public String toString() {
  179. return super.toString() + " (" + getChildCount() + " children)";
  180. }
  181. /**
  182. * @return false if empty or if our options block writing
  183. */
  184. protected boolean okToWriteRtf() {
  185. boolean result = super.okToWriteRtf() && !isEmpty();
  186. if (result && !options.renderContainer(this)) {
  187. result = false;
  188. }
  189. return result;
  190. }
  191. /**
  192. * @return true if this element would generate no "useful" RTF content,
  193. * i.e. (for RtfContainer) true if it has no children where isEmpty() is false
  194. */
  195. public boolean isEmpty() {
  196. boolean result = true;
  197. for (Object aChildren : children) {
  198. final RtfElement e = (RtfElement) aChildren;
  199. if (!e.isEmpty()) {
  200. result = false;
  201. break;
  202. }
  203. }
  204. return result;
  205. }
  206. }