KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > internal > filebuffers > DocumentInputStream


1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.core.internal.filebuffers;
12
13 import java.io.IOException JavaDoc;
14 import java.io.InputStream JavaDoc;
15
16 import org.eclipse.jface.text.Assert;
17 import org.eclipse.jface.text.BadLocationException;
18 import org.eclipse.jface.text.DocumentEvent;
19 import org.eclipse.jface.text.IDocument;
20 import org.eclipse.jface.text.IDocumentListener;
21
22
23 /**
24  * An <code>InputStream</code> that reads from an <code>IDocument</code>.
25  * The input stream ensures that its content is the same as the document
26  * content when the stream was created.
27  * <p>
28  * Note that {@link #close()} must be called to release any acquired
29  * resources.
30  * </p>
31  *
32  * @since 3.1
33  */

34 class DocumentInputStream extends InputStream JavaDoc {
35
36     /**
37      * Document based character sequence.
38      */

39     private static class DocumentCharSequence implements CharSequence JavaDoc {
40
41         /** Document */
42         private IDocument fDocument;
43
44         /**
45          * Initialize with the sequence of characters in the given
46          * document.
47          *
48          * @param document the document
49          */

50         public DocumentCharSequence(IDocument document) {
51             fDocument= document;
52         }
53
54         /*
55          * @see java.lang.CharSequence#length()
56          */

57         public int length() {
58             return fDocument.getLength();
59         }
60
61         /*
62          * @see java.lang.CharSequence#charAt(int)
63          */

64         public char charAt(int index) {
65             try {
66                 return fDocument.getChar(index);
67             } catch (BadLocationException x) {
68                 throw new IndexOutOfBoundsException JavaDoc(x.getLocalizedMessage());
69             }
70         }
71
72         /*
73          * @see java.lang.CharSequence#subSequence(int, int)
74          */

75         public CharSequence JavaDoc subSequence(int start, int end) {
76             try {
77                 return fDocument.get(start, end - start);
78             } catch (BadLocationException x) {
79                 throw new IndexOutOfBoundsException JavaDoc(x.getLocalizedMessage());
80             }
81         }
82     }
83
84     /**
85      * Internal document listener.
86      */

87     private class InternalDocumentListener implements IDocumentListener {
88
89         /*
90          * @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent)
91          */

92         public void documentAboutToBeChanged(DocumentEvent event) {
93             handleDocumentAboutToBeChanged();
94         }
95
96         /*
97          * @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent)
98          */

99         public void documentChanged(DocumentEvent event) {
100         }
101     }
102
103     /** The character sequence. */
104     private volatile CharSequence JavaDoc fCharSequence;
105
106     /** Document length. */
107     private int fLength;
108
109     /** The current offset. */
110     private int fOffset= 0;
111
112     /** The document. */
113     private IDocument fDocument;
114
115     /** The document listener. */
116     private IDocumentListener fDocumentListener= new InternalDocumentListener();
117
118     /**
119      * Creates a new document input stream and initializes
120      * the stream to read from the given document.
121      *
122      * @param document the document
123      */

124     public DocumentInputStream(IDocument document) {
125         Assert.isNotNull(document);
126         fDocument= document;
127         fCharSequence= new DocumentCharSequence(fDocument);
128         fDocument.addDocumentListener(fDocumentListener);
129         fLength= fCharSequence.length();
130     }
131
132     /*
133      * @see java.io.InputStream#read()
134      */

135     public int read() throws IOException JavaDoc {
136         try {
137             return fOffset < fLength ? fCharSequence.charAt(fOffset++) : -1;
138         } catch (NullPointerException JavaDoc x) {
139             throw new IOException JavaDoc(FileBuffersMessages.DocumentInputStream_error_streamClosed);
140         } catch (IndexOutOfBoundsException JavaDoc x) {
141             throw new IOException JavaDoc(NLSUtility.format(FileBuffersMessages.DocumentInputStream_error_read, x.getLocalizedMessage()));
142         }
143     }
144
145     /*
146      * @see java.io.InputStream#close()
147      */

148     public void close() throws IOException JavaDoc {
149         synchronized (this) {
150             fCharSequence= null;
151         }
152         releaseDocument();
153     }
154
155     /**
156      * Copies the document prior to modification and removes the document listener.
157      */

158     private void handleDocumentAboutToBeChanged() {
159         IDocument document= fDocument;
160         if (fCharSequence == null || document == null)
161             return;
162         String JavaDoc content= document.get();
163         synchronized (this) {
164             if (fCharSequence == null)
165                 return;
166             fCharSequence= content;
167         }
168         releaseDocument();
169     }
170
171     /**
172      * Removes the document listener.
173      */

174     private synchronized void releaseDocument() {
175         if (fDocument != null)
176             fDocument.removeDocumentListener(fDocumentListener);
177         fDocument= null;
178         fDocumentListener= null;
179     }
180 }
181
Popular Tags