KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > corext > textmanipulation > TextBuffer


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.jdt.internal.corext.textmanipulation;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.List JavaDoc;
15
16 import org.eclipse.core.runtime.CoreException;
17 import org.eclipse.core.runtime.IProgressMonitor;
18 import org.eclipse.core.runtime.IStatus;
19 import org.eclipse.core.runtime.Status;
20
21 import org.eclipse.core.resources.IFile;
22
23 import org.eclipse.jface.util.Assert;
24
25 import org.eclipse.jface.text.BadLocationException;
26 import org.eclipse.jface.text.DefaultLineTracker;
27 import org.eclipse.jface.text.IDocument;
28 import org.eclipse.jface.text.ILineTracker;
29 import org.eclipse.jface.text.IRegion;
30
31 import org.eclipse.jdt.internal.corext.util.Messages;
32 import org.eclipse.jdt.internal.corext.util.Strings;
33
34 import org.eclipse.jdt.internal.ui.IJavaStatusConstants;
35 import org.eclipse.jdt.internal.ui.JavaPlugin;
36
37 /**
38  * An implementation of a <code>TextBuffer</code> that is based on <code>ITextSelection</code>
39  * and <code>IDocument</code>.
40  *
41  * @deprecated Use file buffers instead
42  */

43 public class TextBuffer {
44     
45     /**
46      * @deprecated Use file buffers instead
47      */

48     private static class DocumentRegion extends TextRegion {
49         IRegion fRegion;
50         public DocumentRegion(IRegion region) {
51             fRegion= region;
52         }
53         public int getOffset() {
54             return fRegion.getOffset();
55         }
56         public int getLength() {
57             return fRegion.getLength();
58         }
59     }
60     
61     /**
62      * @deprecated Use file buffers instead
63      */

64     public class Block {
65         public String JavaDoc content;
66         public int offsetDelta;
67     }
68     
69     private IDocument fDocument;
70     
71     private static final TextBufferFactory fgFactory= new TextBufferFactory();
72     
73     public TextBuffer(IDocument document) {
74         fDocument= document;
75         Assert.isNotNull(fDocument);
76     }
77     
78     public IDocument getDocument() {
79         return fDocument;
80     }
81     
82     /**
83      * Returns the number of characters in this text buffer.
84      *
85      * @return the number of characters in this text buffer
86      */

87     public int getLength() {
88         return fDocument.getLength();
89     }
90     
91     /**
92      * Returns the number of lines in this text buffer.
93      *
94      * @return the number of lines in this text buffer
95      */

96     public int getNumberOfLines() {
97         return fDocument.getNumberOfLines();
98     }
99     
100     /**
101      * Returns the character at the given offset in this text buffer.
102      *
103      * @param offset a text buffer offset
104      * @return the character at the offset
105      * @exception IndexOutOfBoundsException if the <code>offset</code>
106      * argument is negative or not less than the length of this text buffer.
107      */

108     public char getChar(int offset) {
109         try {
110             return fDocument.getChar(offset);
111         } catch (BadLocationException e) {
112             throw new ArrayIndexOutOfBoundsException JavaDoc(e.getMessage());
113         }
114     }
115     
116     /**
117      * Returns the whole content of the text buffer.
118      *
119      * @return the whole content of the text buffer
120      */

121     public String JavaDoc getContent() {
122         return fDocument.get();
123     }
124     
125     /**
126      * Returns length characters starting from the specified position.
127      *
128      * @return the characters specified by the given text region. Returns <code>
129      * null</code> if text range is illegal
130      */

131     public String JavaDoc getContent(int start, int length) {
132         try {
133             return fDocument.get(start, length);
134         } catch (BadLocationException e) {
135             return null;
136         }
137     }
138     
139     public Block getBlockContent(int start, int length, int tabWidth) {
140         Block result= new Block();
141         StringBuffer JavaDoc buffer= new StringBuffer JavaDoc();
142         int lineOffset= getLineInformationOfOffset(start).getOffset();
143         if (start > lineOffset) {
144             String JavaDoc line= getContent(lineOffset, start - lineOffset);
145             String JavaDoc indent= Strings.getIndentString(line, tabWidth);
146             result.offsetDelta= -indent.length();
147             buffer.append(indent);
148         }
149         final int end= start + length;
150         TextRegion region= getLineInformationOfOffset(end);
151         lineOffset= region.getOffset();
152         // Cursor is at beginning of next line
153
if (lineOffset == end) {
154             int lineNumber= getLineOfOffset(lineOffset);
155             if (lineNumber > 0) {
156                 length= length - getLineDelimiter(lineNumber - 1).length();
157             }
158         }
159         if (buffer.length() == 0) {
160             result.content= getContent(start, length);
161         } else {
162             buffer.append(getContent(start, length));
163             result.content= buffer.toString();
164         }
165         return result;
166     }
167     
168     /**
169      * Returns the preferred line delimiter to be used for this text buffer.
170      *
171      * @return the preferred line delimiter
172      */

173     public String JavaDoc getLineDelimiter() {
174         String JavaDoc lineDelimiter= getLineDelimiter(0);
175         if (lineDelimiter == null)
176             lineDelimiter= System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
177
return lineDelimiter;
178     }
179     
180     /**
181      * Returns the line delimiter used for the given line number. Returns <code>
182      * null</code> if the line number is out of range.
183      *
184      * @return the line delimiter used by the given line number or <code>null</code>
185      */

186     public String JavaDoc getLineDelimiter(int line) {
187         try {
188             return fDocument.getLineDelimiter(line);
189         } catch (BadLocationException e) {
190             return null;
191         }
192     }
193     
194     /**
195      * Returns the line for the given line number. If there isn't any line for
196      * the given line number, <code>null</code> is returned. The return string
197      * doesn't contain any line delimiters.
198      *
199      * @return the line for the given line number or <code>null</code>
200      */

201     public String JavaDoc getLineContent(int line) {
202         try {
203             IRegion region= fDocument.getLineInformation(line);
204             return fDocument.get(region.getOffset(), region.getLength());
205         } catch (BadLocationException e) {
206             return null;
207         }
208     }
209     
210     /**
211      * Returns the line indent for the given line. If there isn't any line for the
212      * given line number, <code>-1</code> is returned.
213      *
214      * @return the line indent for the given line number or <code>-1</code>
215      */

216     public int getLineIndent(int lineNumber, int tabWidth) {
217         String JavaDoc lineContent= getLineContent(lineNumber);
218         if (lineContent == null)
219             return -1;
220         return Strings.computeIndent(lineContent, tabWidth);
221     }
222     
223     /**
224      * Returns a region of the specified line. The region contains the offset and the
225      * length of the line excluding the line's delimiter. Returns <code>null</code>
226      * if the line doesn't exist.
227      *
228      * @param line the line of interest
229      * @return a line description or <code>null</code> if the given line doesn't
230      * exist
231      */

232     public TextRegion getLineInformation(int line) {
233         try {
234             return new DocumentRegion(fDocument.getLineInformation(line));
235         } catch (BadLocationException e) {
236             return null;
237         }
238     }
239     
240     /**
241      * Returns a line region of the specified offset. The region contains the offset and
242      * the length of the line excluding the line's delimiter. Returns <code>null</code>
243      * if the line doesn't exist.
244      *
245      * @param offset an offset into a line
246      * @return a line description or <code>null</code> if the given line doesn't
247      * exist
248      */

249     public TextRegion getLineInformationOfOffset(int offset) {
250         try {
251             return new DocumentRegion(fDocument.getLineInformationOfOffset(offset));
252         } catch (BadLocationException e) {
253             return null;
254         }
255     }
256     
257     /**
258      * Returns the line number that contains the given position. If there isn't any
259      * line that contains the position, <code>null</code> is returned. The returned
260      * string is a copy and doesn't contain the line delimiter.
261      *
262      * @return the line that contains the given offset or <code>null</code> if line
263      * doesn't exist
264      */

265     public int getLineOfOffset(int offset) {
266         try {
267             return fDocument.getLineOfOffset(offset);
268         } catch (BadLocationException e) {
269             return -1;
270         }
271     }
272
273     /**
274      * Returns the line that contains the given position. If there isn't any
275      * line that contains the position, <code>null</code> is returned. The returned
276      * string is a copy and doesn't contain the line delimiter.
277      *
278      * @return the line that contains the given offset or <code>null</code> if line
279      * doesn't exist
280      */

281     public String JavaDoc getLineContentOfOffset(int offset) {
282         try {
283             IRegion region= fDocument.getLineInformationOfOffset(offset);
284             return fDocument.get(region.getOffset(), region.getLength());
285         } catch (BadLocationException e) {
286             return null;
287         }
288     }
289
290     /**
291      * Converts the text determined by the region [offset, length] into an array of lines.
292      * The lines are copies of the original lines and don't contain any line delimiter
293      * characters.
294      *
295      * @return the text converted into an array of strings. Returns <code>null</code> if the
296      * region lies outside the source.
297      */

298     public String JavaDoc[] convertIntoLines(int offset, int length, boolean lastNewLineCreateEmptyLine) {
299         try {
300             String JavaDoc text= fDocument.get(offset, length);
301             ILineTracker tracker= new DefaultLineTracker();
302             tracker.set(text);
303             int size= tracker.getNumberOfLines();
304             int lastLine= size - 1;
305             List JavaDoc result= new ArrayList JavaDoc(size);
306             for (int i= 0; i < size; i++) {
307                 IRegion region= tracker.getLineInformation(i);
308                 String JavaDoc line= getContent(offset + region.getOffset(), region.getLength());
309                 if (i < lastLine || !"".equals(line) || lastNewLineCreateEmptyLine) //$NON-NLS-1$
310
result.add(line);
311             }
312             return (String JavaDoc[]) result.toArray(new String JavaDoc[result.size()]);
313         } catch (BadLocationException e) {
314             return null;
315         }
316     }
317     
318     /**
319      * Subsitutes the given text for the specified text position
320      *
321      * @param offset the starting offset of the text to be replaced
322      * @param length the length of the text to be replaced
323      * @param text the substitution text
324      * @exception CoreException if the text position [offset, length] is invalid.
325      */

326     public void replace(int offset, int length, String JavaDoc text) throws CoreException {
327         try {
328             fDocument.replace(offset, length, text);
329         } catch (BadLocationException e) {
330             IStatus s= new Status(IStatus.ERROR, JavaPlugin.getPluginId(), IJavaStatusConstants.INTERNAL_ERROR,
331                 Messages.format(
332                     TextManipulationMessages.TextBuffer_wrongRange, //$NON-NLS-1$
333
new Object JavaDoc[] {new Integer JavaDoc(offset), new Integer JavaDoc(length) } ), e);
334             throw new CoreException(s);
335         }
336     }
337     
338     public void replace(IRegion range, String JavaDoc text) throws CoreException {
339         replace(range.getOffset(), range.getLength(), text);
340     }
341
342     //---- Method to validate edit support
343

344     /**
345      * Verifies that the changes applied to this text buffer can be committed to
346      * the underlying file system. For buffers allocated via the create methods
347      * this method always succeeds. For buffer allocated via the
348      * <code>acquire</code> method the <code>validateEdit</code> method provided
349      * by <tt>IWorkspace</tt> is used to ensure that the content can be
350      * committed to the disk.
351      *
352      * @param context the <code>org.eclipse.swt.widgets.Shell</code> that is to
353      * be used to parent any dialogs with the user, or <code>null</code> if
354      * there is no UI context (declared as an <code>Object</code> to avoid
355      * any direct references on the SWT component)
356      * @return if <code>status.isOK()</code> returns <code>true</code> then the
357      * buffer can be committed to the underlying file system. Otherwise it is
358      * not commitable
359      *
360      * @see org.eclipse.core.resources.IWorkspace#validateEdit(org.eclipse.core.resources.IFile[], java.lang.Object)
361      */

362     public IStatus makeCommittable(Object JavaDoc context) {
363         return fgFactory.makeCommittable(this, context);
364     }
365     
366     //---- Debugging methods ----------------------------------------
367

368     /* (non-Javadoc)
369      * @see java.lang.Object#toString()
370      */

371     public String JavaDoc toString() {
372         return fDocument.get();
373     }
374     
375     //---- Special methods used by the <code>TextBufferEditor</code>
376

377     /**
378      * Releases this text buffer.
379      */

380     /* package */ void release() {
381     }
382     
383     //---- Factory methods ----------------------------------------------------------------
384

385     /**
386      * Acquires a text buffer for the given file. If a text buffer for the given
387      * file already exists, then that one is returned.
388      *
389      * @param file the file for which a text buffer is requested
390      * @return a managed text buffer for the given file
391      * @exception CoreException if it was not possible to acquire the
392      * text buffer
393      */

394     public static TextBuffer acquire(IFile file) throws CoreException {
395         return fgFactory.acquire(file);
396     }
397     
398     /**
399      * Releases the given text buffer.
400      *
401      * @param buffer the text buffer to be released
402      */

403     public static void release(TextBuffer buffer) {
404         fgFactory.release(buffer);
405     }
406
407     /**
408      * Commits the changes made to the given text buffer to the underlying
409      * storage system.
410      *
411      * @param buffer the text buffer containing the changes to be committed.
412      * @param force if <code>true</code> the text buffer is committed in any case.
413      * If <code>false</code> the text buffer is <b>ONLY</b> committed if the client
414      * is the last one that holds a reference to the text buffer. Clients of this
415      * method must make sure that they don't call this method from within an <code>
416      * IWorkspaceRunnable</code>.
417      * @param pm the progress monitor used to report progress if committing is
418      * necessary
419      */

420     public static void commitChanges(TextBuffer buffer, boolean force, IProgressMonitor pm) throws CoreException {
421         fgFactory.commitChanges(buffer, force, pm);
422     }
423     
424     /**
425      * Creates a new <code>TextBuffer</code> for the given file. The returned
426      * buffer will not be managed. Any subsequent call to <code>create</code>
427      * with the same file will return a different text buffer.
428      * <p>
429      * If the file is currently open in a text editor, the editors content is copied into
430      * the returned <code>TextBuffer</code>. Otherwise the content is read from
431      * disk.
432      *
433      * @param file the file for which a text buffer is to be created
434      * @return a new unmanaged text buffer
435      * @exception CoreException if it was not possible to create the text buffer
436      */

437     public static TextBuffer create(IFile file) throws CoreException {
438         return fgFactory.create(file);
439     }
440     
441     /**
442      * Creates a new <code>TextBuffer</code> for the string. The returned
443      * buffer will not be managed. Any subsequent call to <code>create</code>
444      * with the identical string will return a different text buffer.
445      *
446      * @param content the text buffer's content
447      * @return a new unmanaged text buffer
448      */

449     public static TextBuffer create(String JavaDoc content) {
450         return fgFactory.create(content);
451     }
452     
453     // Unclear which methods are needed if we get the new save model. If optimal no
454
// save is needed at all.
455

456     public static void save(TextBuffer buffer, IProgressMonitor pm) throws CoreException {
457         fgFactory.save(buffer, pm);
458     }
459     
460     public static void aboutToChange(TextBuffer buffer) throws CoreException {
461         fgFactory.aboutToChange(buffer);
462     }
463     
464     public static void changed(TextBuffer buffer) throws CoreException {
465         fgFactory.changed(buffer);
466     }
467 }
468
Popular Tags