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: RtfFile.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 org.apache.fop.render.rtf.rtflib.exceptions.RtfStructureException;
030: import java.io.Writer;
031: import java.io.IOException;
032: import java.io.BufferedWriter;
033: import java.io.FileWriter;
034: import java.io.OutputStreamWriter;
035:
036: /**
037: * Models the top-level structure of an RTF file.
038: * @author Bertrand Delacretaz bdelacretaz@codeconsult.ch
039: * @author Andreas Putz a.putz@skynamics.com
040: * @author Christopher Scott scottc@westinghouse.com
041: */
042:
043: public class RtfFile extends RtfContainer {
044: private RtfHeader header;
045: private RtfPageArea pageArea;
046: private RtfListTable listTable;
047: private RtfDocumentArea docArea;
048: // private ConverterLogChannel m_log;
049: private RtfContainer listTableContainer;
050: private int listNum = 0;
051:
052: /**
053: * Create an RTF file that outputs to the given Writer
054: * @param w the Writer to write to
055: * @throws IOException for I/O problems
056: */
057: public RtfFile(Writer w) throws IOException {
058: super (null, w);
059: }
060:
061: /** optional log channel */
062: // public void setLogChannel(ConverterLogChannel log)
063: // {
064: // m_log = log;
065: // }
066: /**
067: * Gets the log channel.
068: * If logchannel not set, it will return a empty log channel.
069: * @return our log channel, it is never null */
070: // ConverterLogChannel getLog()
071: // {
072: // if (m_log == null)
073: // m_log = new ConverterLogChannel (null);
074: // return m_log;
075: // }
076: /**
077: * If called, must be called before startDocumentArea
078: * @return the new RtfHeader
079: * @throws IOException for I/O problems
080: */
081: public RtfHeader startHeader() throws IOException {
082: if (header != null) {
083: throw new RtfStructureException(
084: "startHeader called more than once");
085: }
086: header = new RtfHeader(this , writer);
087: listTableContainer = new RtfContainer(this , writer);
088: return header;
089: }
090:
091: /**
092: * Creates the list table.
093: * @param attr attributes for the RtfListTable
094: * @return the new RtfListTable
095: * @throws IOException for I/O problems
096: */
097: public RtfListTable startListTable(RtfAttributes attr)
098: throws IOException {
099: listNum++;
100: if (listTable != null) {
101: return listTable;
102: } else {
103: listTable = new RtfListTable(this , writer, new Integer(
104: listNum), attr);
105: listTableContainer.addChild(listTable);
106: }
107:
108: return listTable;
109: }
110:
111: /**
112: * Get the list table.
113: * @return the RtfListTable
114: */
115: public RtfListTable getListTable() {
116: return listTable;
117: }
118:
119: /**
120: * Closes the RtfHeader if not done yet, and starts the docment area.
121: * Like startDocumentArea, is only called once. This is not optimal,
122: * must be able to have multiple page definition, and corresponding
123: * Document areas
124: * @return the RtfPageArea
125: * @throws IOException for I/O problems
126: * @throws RtfStructureException for illegal RTF structure
127: */
128: public RtfPageArea startPageArea() throws IOException {
129: if (pageArea != null) {
130: throw new RtfStructureException(
131: "startPageArea called more than once");
132: }
133: // create an empty header if there was none
134: if (header == null) {
135: startHeader();
136: }
137: header.close();
138: pageArea = new RtfPageArea(this , writer);
139: addChild(pageArea);
140: return pageArea;
141: }
142:
143: /**
144: * Call startPageArea if needed and return the page area object.
145: * @return the RtfPageArea
146: * @throws IOException for I/O problems
147: * @throws RtfStructureException for illegal RTF structure
148: */
149: public RtfPageArea getPageArea() throws IOException {
150: if (pageArea == null) {
151: return startPageArea();
152: }
153: return pageArea;
154: }
155:
156: /**
157: * Closes the RtfHeader if not done yet, and starts the document area.
158: * Must be called once only.
159: * @return the RtfDocumentArea
160: * @throws IOException for I/O problems
161: * @throws RtfStructureException for illegal RTF structure
162: */
163: public RtfDocumentArea startDocumentArea() throws IOException {
164: if (docArea != null) {
165: throw new RtfStructureException(
166: "startDocumentArea called more than once");
167: }
168: // create an empty header if there was none
169: if (header == null) {
170: startHeader();
171: }
172: header.close();
173: docArea = new RtfDocumentArea(this , writer);
174: addChild(docArea);
175: return docArea;
176: }
177:
178: /**
179: * Call startDocumentArea if needed and return the document area object.
180: * @return the RtfDocumentArea
181: * @throws IOException for I/O problems
182: * @throws RtfStructureException for illegal RTF structure
183: */
184: public RtfDocumentArea getDocumentArea() throws IOException {
185: if (docArea == null) {
186: return startDocumentArea();
187: }
188: return docArea;
189: }
190:
191: /**
192: * overridden to write RTF prefix code, what comes before our children
193: * @throws IOException for I/O problems
194: */
195: protected void writeRtfPrefix() throws IOException {
196: writeGroupMark(true);
197: writeControlWord("rtf1");
198: }
199:
200: /**
201: * overridden to write RTF suffix code, what comes after our children
202: * @throws IOException for I/O problems
203: */
204: protected void writeRtfSuffix() throws IOException {
205: writeGroupMark(false);
206: }
207:
208: /**
209: * must be called when done creating the document
210: * @throws IOException for I/O problems
211: */
212: public synchronized void flush() throws IOException {
213: writeRtf();
214: writer.flush();
215: }
216:
217: /**
218: * minimal test and usage example
219: * @param args command-line arguments
220: * @throws Exception for problems
221: */
222: public static void main(String[] args) throws Exception {
223: Writer w = null;
224: if (args.length != 0) {
225: final String outFile = args[0];
226: System.err.println("Outputting RTF to file '" + outFile
227: + "'");
228: w = new BufferedWriter(new FileWriter(outFile));
229: } else {
230: System.err
231: .println("Outputting RTF code to standard output");
232: w = new BufferedWriter(new OutputStreamWriter(System.out));
233: }
234:
235: final RtfFile f = new RtfFile(w);
236: final RtfSection sect = f.startDocumentArea().newSection();
237:
238: final RtfParagraph p = sect.newParagraph();
239: p.newText("Hello, RTF world.\n", null);
240: final RtfAttributes attr = new RtfAttributes();
241: attr.set(RtfText.ATTR_BOLD);
242: attr.set(RtfText.ATTR_ITALIC);
243: attr.set(RtfText.ATTR_FONT_SIZE, 36);
244: p.newText("This is bold, italic, 36 points", attr);
245:
246: f.flush();
247: System.err.println("RtfFile test: all done.");
248: }
249: }
|