KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 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.Reader JavaDoc;
15
16 import org.eclipse.core.runtime.Assert;
17
18 import org.eclipse.jface.text.BadLocationException;
19 import org.eclipse.jface.text.DocumentEvent;
20 import org.eclipse.jface.text.IDocument;
21 import org.eclipse.jface.text.IDocumentListener;
22
23
24 /**
25  * A <code>Reader</code> that reads from an <code>IDocument</code>.
26  * The reader ensures that its content is the same as the document
27  * content when the stream was created.
28  * <p>
29  * Note that {@link #close()} must be called to release any acquired
30  * resources.
31  * </p>
32  *
33  * @since 3.1
34  */

35 class DocumentReader extends Reader JavaDoc {
36
37     /**
38      * Document based character sequence.
39      */

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

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

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

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

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

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

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

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

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

136     public void close() throws IOException JavaDoc {
137         synchronized (this) {
138             fCharSequence= null;
139         }
140         releaseDocument();
141     }
142
143     /**
144      * Copies the document prior to modification and removes the document listener.
145      */

146     private void handleDocumentAboutToBeChanged() {
147         IDocument document= fDocument;
148         if (fCharSequence == null || document == null)
149             return;
150         String JavaDoc content= document.get();
151         synchronized (this) {
152             if (fCharSequence == null)
153                 return;
154             fCharSequence= content;
155         }
156         releaseDocument();
157     }
158
159     /**
160      * Removes the document listener.
161      */

162     private synchronized void releaseDocument() {
163         if (fDocument != null)
164             fDocument.removeDocumentListener(fDocumentListener);
165         fDocument= null;
166         fDocumentListener= null;
167     }
168
169     /*
170      * @see java.io.Reader#read(char[], int, int)
171      * @since 3.1
172      */

173     public int read(char[] cbuf, int off, int len) throws IOException JavaDoc {
174         int i= 0;
175         try {
176             for (; i < len && fOffset < fLength; i++)
177                 cbuf[off + i]= fCharSequence.charAt(fOffset++);
178             if (i > 0)
179                 return i;
180
181             return -1;
182         } catch (NullPointerException JavaDoc x) {
183             throw new IOException JavaDoc(FileBuffersMessages.DocumentInputStream_error_streamClosed);
184         } catch (IndexOutOfBoundsException JavaDoc x) {
185             return i-1;
186         }
187     }
188 }
189
Popular Tags