001: /*
002: * (C) Copyright IBM Corp. 1998-2004. All Rights Reserved.
003: *
004: * The program is provided "as is" without any warranty express or
005: * implied, including the warranty of non-infringement and the implied
006: * warranties of merchantibility and fitness for a particular purpose.
007: * IBM will not be liable for any damages suffered by you as a result
008: * of using the Program. In no event will IBM be liable for any
009: * special, indirect or consequential damages or lost profits even if
010: * IBM has been advised of the possibility of their occurrence. IBM
011: * will not be liable for any third party claims against you.
012: */
013: package com.ibm.richtext.demo;
014:
015: import java.io.*;
016:
017: import com.ibm.richtext.styledtext.MConstText;
018: import com.ibm.richtext.styledtext.MText;
019: import com.ibm.richtext.styledtext.StyledText;
020: import com.ibm.richtext.textpanel.MTextPanel;
021: import com.ibm.richtext.textlayout.attributes.AttributeMap;
022:
023: /**
024: * A TextDocument handles the association between a file on disk
025: * and a TextPanel.
026: */
027: public final class TextDocument {
028:
029: static final String COPYRIGHT = "(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
030: private static final int BUF_SIZE = 1024;
031:
032: private String fTitle;
033: private MConstText fText;
034: private File fFile;
035: private MTextPanel fTextPanel = null;
036: private boolean isModified = false;
037: private int fFormat = STYLED_TEXT;
038:
039: private TextDocument(String title, MConstText text, File file,
040: int format) {
041:
042: fTitle = title;
043: fText = text;
044: fFile = file;
045: setFormat(format);
046: }
047:
048: public static final int STYLED_TEXT = 0;
049: public static final int PLAIN_TEXT = 1;
050:
051: /**
052: * Return a new TextDocument with no associated file and
053: * empty text.
054: */
055: public static TextDocument createEmpty(String title, int format) {
056:
057: return new TextDocument(title, new StyledText(), null, format);
058: }
059:
060: /**
061: * Return a TextDocument created from the contents of the given
062: * file. This method may throw an exception if the file cannot
063: * be read. In particular, if the format is given as STYLED_TEXT
064: * but the file does not contain a serialized MConstText,
065: * this method will throw StreamCorruptedException.
066: */
067: public static TextDocument createFromFile(File file, int format)
068: throws Exception {
069:
070: if (format != STYLED_TEXT && format != PLAIN_TEXT) {
071: throw new IllegalArgumentException("Invalid format");
072: }
073:
074: MConstText text;
075: if (format == STYLED_TEXT) {
076: text = readMText(file);
077: } else {
078: text = readMTextFromTextFile(file);
079: }
080:
081: TextDocument document = new TextDocument(file.getName(), text,
082: file, format);
083: return document;
084: }
085:
086: /**
087: * Return true if this document's text differs from the contents
088: * of its file.
089: */
090: public boolean isModified() {
091:
092: if (fTextPanel == null) {
093: return isModified;
094: } else {
095: return fTextPanel.isModified();
096: }
097: }
098:
099: /**
100: * Set the MTextPanel that will be used to edit the document's
101: * text. The document's text becomes the contents of the
102: * MTextPanel.
103: */
104: public void setTextPanel(MTextPanel textPanel) {
105:
106: if (fTextPanel != null) {
107: fText = fTextPanel.getText();
108: isModified = fTextPanel.isModified();
109: }
110:
111: fTextPanel = textPanel;
112:
113: if (fTextPanel != null) {
114: fTextPanel.setText(fText);
115: fText = null;
116: fTextPanel.setModified(isModified);
117: fTextPanel.clearCommandLog();
118: }
119: }
120:
121: public File getFile() {
122:
123: return fFile;
124: }
125:
126: /**
127: * Set this document's file. The document's title will
128: * change to the file name. The file cannot be null.
129: */
130: public void setFile(File file) {
131:
132: fFile = file;
133: fTitle = file.getName();
134: }
135:
136: /**
137: * Set the format of this document. The format determines
138: * whether the document will be written to files as styled
139: * text or plain characters.
140: */
141: public void setFormat(int format) {
142:
143: if (format != STYLED_TEXT && format != PLAIN_TEXT) {
144: throw new IllegalArgumentException("Invalid format");
145: }
146: fFormat = format;
147: }
148:
149: /**
150: * Return the format of this document.
151: */
152: public int getFormat() {
153:
154: return fFormat;
155: }
156:
157: /**
158: * Write the document's text to its file. If the document does
159: * not have an associated file then this method is equivalent to
160: * saveAs. This method returns true if the save operation succeeds.
161: */
162: public boolean save() {
163:
164: if (fFile == null) {
165: throw new RuntimeException("Can't save without a file.");
166: }
167:
168: MConstText text = getText();
169: boolean success = fFormat == STYLED_TEXT ? writeMText(fFile,
170: text) : writePlainMText(fFile, text);
171: if (success && fTextPanel != null) {
172: fTextPanel.setModified(false);
173: }
174: return success;
175: }
176:
177: /**
178: * Return this document's styled text.
179: */
180: public MConstText getText() {
181:
182: if (fTextPanel == null) {
183: return fText;
184: } else {
185: return fTextPanel.getText();
186: }
187: }
188:
189: /**
190: * Return the title of this document.
191: */
192: public String getTitle() {
193:
194: return fTitle;
195: }
196:
197: /**
198: * Return the MText serialized in the given file.
199: * In case of an error return null.
200: */
201: private static MConstText readMText(File file) throws Exception {
202:
203: FileInputStream inStream = null;
204:
205: try {
206: inStream = new FileInputStream(file);
207: ObjectInputStream objStream = new ObjectInputStream(
208: inStream);
209:
210: return (MConstText) objStream.readObject();
211: } finally {
212: if (inStream != null) {
213: try {
214: inStream.close();
215: } catch (IOException e) {
216: System.out.print("");
217: }
218: }
219: }
220: }
221:
222: /**
223: * Read the given file as a plain text file, and return its
224: * contents as an MConstText. The character and paragraph styles in
225: * the returned text will be EMPTY_ATTRIBUTE_MAP.
226: */
227: private static MConstText readMTextFromTextFile(File file)
228: throws Exception {
229:
230: InputStreamReader in = null;
231:
232: try {
233: in = new FileReader(file);
234:
235: MText text = new StyledText();
236:
237: char[] buf = new char[BUF_SIZE];
238: int read;
239: while ((read = in.read(buf, 0, buf.length)) != -1) {
240: int len = text.length();
241: text.replace(len, len, buf, 0, read,
242: AttributeMap.EMPTY_ATTRIBUTE_MAP);
243: }
244: return text;
245: } finally {
246: if (in != null) {
247: try {
248: in.close();
249: } catch (IOException e) {
250: System.out.print("");
251: }
252: }
253: }
254: }
255:
256: /**
257: * Attempt to save the given text in the given file.
258: * @return true if the operation succeeded
259: */
260: private static boolean writeMText(File file, MConstText text) {
261:
262: Throwable error = null;
263: OutputStream outStream = null;
264:
265: try {
266: outStream = new FileOutputStream(file);
267: ObjectOutputStream objStream = new ObjectOutputStream(
268: outStream);
269:
270: objStream.writeObject(text);
271: } catch (IOException e) {
272: error = e;
273: } catch (ClassCastException e) {
274: error = e;
275: } finally {
276: if (outStream != null) {
277: try {
278: outStream.close();
279: } catch (IOException e) {
280: System.out.print("");
281: }
282: }
283: }
284:
285: if (error != null) {
286: error.printStackTrace();
287: return false;
288: } else {
289: return true;
290: }
291: }
292:
293: /**
294: * Write the given MConstText to the given file as plain text.
295: */
296: private static boolean writePlainMText(File file, MConstText text) {
297:
298: Throwable error = null;
299: OutputStreamWriter outStream = null;
300:
301: try {
302: outStream = new FileWriter(file);
303: char[] buf = new char[BUF_SIZE];
304: int length = text.length();
305: int start = 0;
306: do {
307: int count = Math.min(length - start, buf.length);
308: text.extractChars(start, start + count, buf, 0);
309: outStream.write(buf, 0, count);
310: start += count;
311: } while (start < length);
312: } catch (IOException e) {
313: error = e;
314: } finally {
315: if (outStream != null) {
316: try {
317: outStream.close();
318: } catch (IOException e) {
319: System.out.print("");
320: }
321: }
322: }
323:
324: if (error != null) {
325: error.printStackTrace();
326: return false;
327: } else {
328: return true;
329: }
330: }
331: }
|