001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /* $Id: RtfContainer.java 426576 2006-07-28 15:44:37Z jeremias $ */
019:
020: package org.apache.fop.render.rtf.rtflib.rtfdoc;
021:
022: /*
023: * This file is part of the RTF library of the FOP project, which was originally
024: * created by Bertrand Delacretaz <bdelacretaz@codeconsult.ch> and by other
025: * contributors to the jfor project (www.jfor.org), who agreed to donate jfor to
026: * the FOP project.
027: */
028:
029: import java.io.Writer;
030: import java.util.LinkedList;
031: import java.util.List;
032: import java.util.Iterator;
033: import java.io.IOException;
034: import org.apache.fop.render.rtf.rtflib.exceptions.RtfStructureException;
035:
036: /** An RtfElement that can contain other elements.
037: * @author Bertrand Delacretaz bdelacretaz@codeconsult.ch
038: */
039:
040: public class RtfContainer extends RtfElement {
041: private LinkedList children; // 'final' removed by Boris Poudérous on 07/22/2002
042: private RtfOptions options = new RtfOptions();
043: private RtfElement lastChild;
044:
045: /** Create an RTF container as a child of given container */
046: RtfContainer(RtfContainer parent, Writer w) throws IOException {
047: this (parent, w, null);
048: }
049:
050: /** Create an RTF container as a child of given container with given attributes */
051: RtfContainer(RtfContainer parent, Writer w, RtfAttributes attr)
052: throws IOException {
053: super (parent, w, attr);
054: children = new LinkedList();
055: }
056:
057: /**
058: * set options
059: * @param opt options to set
060: */
061: public void setOptions(RtfOptions opt) {
062: options = opt;
063: }
064:
065: /**
066: * add a child element to this
067: * @param e child element to add
068: * @throws RtfStructureException for trying to add an invalid child (??)
069: */
070: protected void addChild(RtfElement e) throws RtfStructureException {
071: if (isClosed()) {
072: // No childs should be added to a container that has been closed
073: final StringBuffer sb = new StringBuffer();
074: sb.append("addChild: container already closed (parent=");
075: sb.append(this .getClass().getName());
076: sb.append(" child=");
077: sb.append(e.getClass().getName());
078: sb.append(")");
079: final String msg = sb.toString();
080:
081: // warn of this problem
082: final RtfFile rf = getRtfFile();
083: // if(rf.getLog() != null) {
084: // rf.getLog().logWarning(msg);
085: // }
086:
087: // TODO this should be activated to help detect XSL-FO constructs
088: // that we do not handle properly.
089: /*
090: throw new RtfStructureException(msg);
091: */
092: }
093:
094: children.add(e);
095: lastChild = e;
096: }
097:
098: /**
099: * @return a copy of our children's list
100: */
101: public List getChildren() {
102: return (List) children.clone();
103: }
104:
105: /**
106: * @return the number of children
107: */
108: public int getChildCount() {
109: return children.size();
110: }
111:
112: /**
113: * Add by Boris Poudérous on 07/22/2002
114: * Set the children list
115: * @param list list of child objects
116: * @return true if process succeeded
117: */
118: public boolean setChildren(List list) {
119: if (list instanceof LinkedList) {
120: this .children = (LinkedList) list;
121: return true;
122: }
123:
124: return false;
125: }
126:
127: /**
128: * write RTF code of all our children
129: * @throws IOException for I/O problems
130: */
131: protected void writeRtfContent() throws IOException {
132: for (Iterator it = children.iterator(); it.hasNext();) {
133: final RtfElement e = (RtfElement) it.next();
134: e.writeRtf();
135: }
136: }
137:
138: /** return our options */
139: RtfOptions getOptions() {
140: return options;
141: }
142:
143: /** true if this (recursively) contains at least one RtfText object */
144: boolean containsText() {
145: boolean result = false;
146: for (Iterator it = children.iterator(); it.hasNext();) {
147: final RtfElement e = (RtfElement) it.next();
148: if (e instanceof RtfText) {
149: result = !e.isEmpty();
150: } else if (e instanceof RtfContainer) {
151: if (((RtfContainer) e).containsText()) {
152: result = true;
153: }
154: }
155: if (result) {
156: break;
157: }
158: }
159: return result;
160: }
161:
162: /** debugging to given Writer */
163: void dump(Writer w, int indent) throws IOException {
164: super .dump(w, indent);
165: for (Iterator it = children.iterator(); it.hasNext();) {
166: final RtfElement e = (RtfElement) it.next();
167: e.dump(w, indent + 1);
168: }
169: }
170:
171: /**
172: * minimal debugging display
173: * @return String representation of object contents
174: */
175: public String toString() {
176: return super .toString() + " (" + getChildCount() + " children)";
177: }
178:
179: /**
180: * @return false if empty or if our options block writing
181: */
182: protected boolean okToWriteRtf() {
183: boolean result = super .okToWriteRtf() && !isEmpty();
184: if (result && !options.renderContainer(this )) {
185: result = false;
186: }
187: return result;
188: }
189:
190: /**
191: * @return true if this element would generate no "useful" RTF content,
192: * i.e. (for RtfContainer) true if it has no children where isEmpty() is false
193: */
194: public boolean isEmpty() {
195: boolean result = true;
196: for (Iterator it = children.iterator(); it.hasNext();) {
197: final RtfElement e = (RtfElement) it.next();
198: if (!e.isEmpty()) {
199: result = false;
200: break;
201: }
202: }
203: return result;
204: }
205: }
|