KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jface > text > SequentialRewriteTextStore


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.jface.text;
12
13
14 import java.util.Iterator JavaDoc;
15 import java.util.LinkedList JavaDoc;
16
17
18 /**
19  * A text store that optimizes a given source text store for sequential rewriting.
20  * While rewritten it keeps a list of replace command that serve as patches for
21  * the source store. Only on request, the source store is indeed manipulated
22  * by applying the patch commands to the source text store.
23  *
24  * @since 2.0
25  * @deprecated since 3.3 as {@link GapTextStore} performs better even for sequential rewrite scenarios
26  */

27 public class SequentialRewriteTextStore implements ITextStore {
28
29     /**
30      * A buffered replace command.
31      */

32     private static class Replace {
33         public int newOffset;
34         public final int offset;
35         public final int length;
36         public final String JavaDoc text;
37
38         public Replace(int offset, int newOffset, int length, String JavaDoc text) {
39             this.newOffset= newOffset;
40             this.offset= offset;
41             this.length= length;
42             this.text= text;
43         }
44     }
45
46     /** The list of buffered replacements. */
47     private LinkedList JavaDoc fReplaceList;
48     /** The source text store */
49     private ITextStore fSource;
50     /** A flag to enforce sequential access. */
51     private static final boolean ASSERT_SEQUENTIALITY= false;
52
53
54     /**
55      * Creates a new sequential rewrite store for the given source store.
56      *
57      * @param source the source text store
58      */

59     public SequentialRewriteTextStore(ITextStore source) {
60         fReplaceList= new LinkedList JavaDoc();
61         fSource= source;
62     }
63
64     /**
65      * Returns the source store of this rewrite store.
66      *
67      * @return the source store of this rewrite store
68      */

69     public ITextStore getSourceStore() {
70         commit();
71         return fSource;
72     }
73
74     /*
75      * @see org.eclipse.jface.text.ITextStore#replace(int, int, java.lang.String)
76      */

77     public void replace(int offset, int length, String JavaDoc text) {
78         if (text == null)
79             text= ""; //$NON-NLS-1$
80

81         if (fReplaceList.size() == 0) {
82             fReplaceList.add(new Replace(offset, offset, length, text));
83
84         } else {
85             Replace firstReplace= (Replace) fReplaceList.getFirst();
86             Replace lastReplace= (Replace) fReplaceList.getLast();
87
88             // backward
89
if (offset + length <= firstReplace.newOffset) {
90                 int delta= text.length() - length;
91                 if (delta != 0) {
92                     for (Iterator JavaDoc i= fReplaceList.iterator(); i.hasNext(); ) {
93                         Replace replace= (Replace) i.next();
94                         replace.newOffset += delta;
95                     }
96                 }
97
98                 fReplaceList.addFirst(new Replace(offset, offset, length, text));
99
100             // forward
101
} else if (offset >= lastReplace.newOffset + lastReplace.text.length()) {
102                 int delta= getDelta(lastReplace);
103                 fReplaceList.add(new Replace(offset - delta, offset, length, text));
104
105             } else if (ASSERT_SEQUENTIALITY) {
106                 throw new IllegalArgumentException JavaDoc();
107
108             } else {
109                 commit();
110                 fSource.replace(offset, length, text);
111             }
112         }
113     }
114
115     /*
116      * @see org.eclipse.jface.text.ITextStore#set(java.lang.String)
117      */

118     public void set(String JavaDoc text) {
119         fSource.set(text);
120         fReplaceList.clear();
121     }
122
123     /*
124      * @see org.eclipse.jface.text.ITextStore#get(int, int)
125      */

126     public String JavaDoc get(int offset, int length) {
127
128         if (fReplaceList.isEmpty())
129             return fSource.get(offset, length);
130
131
132         Replace firstReplace= (Replace) fReplaceList.getFirst();
133         Replace lastReplace= (Replace) fReplaceList.getLast();
134
135         // before
136
if (offset + length <= firstReplace.newOffset) {
137             return fSource.get(offset, length);
138
139             // after
140
} else if (offset >= lastReplace.newOffset + lastReplace.text.length()) {
141             int delta= getDelta(lastReplace);
142             return fSource.get(offset - delta, length);
143
144         } else if (ASSERT_SEQUENTIALITY) {
145             throw new IllegalArgumentException JavaDoc();
146
147         } else {
148
149             int delta= 0;
150             for (Iterator JavaDoc i= fReplaceList.iterator(); i.hasNext(); ) {
151                 Replace replace= (Replace) i.next();
152
153                 if (offset + length < replace.newOffset) {
154                     return fSource.get(offset - delta, length);
155
156                 } else if (offset >= replace.newOffset && offset + length <= replace.newOffset + replace.text.length()) {
157                     return replace.text.substring(offset - replace.newOffset, offset - replace.newOffset + length);
158
159                 } else if (offset >= replace.newOffset + replace.text.length()) {
160                     delta= getDelta(replace);
161                     continue;
162
163                 } else {
164                     commit();
165                     return fSource.get(offset, length);
166                 }
167             }
168
169             return fSource.get(offset - delta, length);
170         }
171
172     }
173
174     /**
175      * Returns the difference between the offset in the source store and the "same" offset in the
176      * rewrite store after the replace operation.
177      *
178      * @param replace the replace command
179      * @return the difference
180      */

181     private static final int getDelta(Replace replace) {
182         return replace.newOffset - replace.offset + replace.text.length() - replace.length;
183     }
184
185     /*
186      * @see org.eclipse.jface.text.ITextStore#get(int)
187      */

188     public char get(int offset) {
189         if (fReplaceList.isEmpty())
190             return fSource.get(offset);
191
192         Replace firstReplace= (Replace) fReplaceList.getFirst();
193         Replace lastReplace= (Replace) fReplaceList.getLast();
194
195         // before
196
if (offset < firstReplace.newOffset) {
197             return fSource.get(offset);
198
199             // after
200
} else if (offset >= lastReplace.newOffset + lastReplace.text.length()) {
201             int delta= getDelta(lastReplace);
202             return fSource.get(offset - delta);
203
204         } else if (ASSERT_SEQUENTIALITY) {
205             throw new IllegalArgumentException JavaDoc();
206
207         } else {
208
209             int delta= 0;
210             for (Iterator JavaDoc i= fReplaceList.iterator(); i.hasNext(); ) {
211                 Replace replace= (Replace) i.next();
212
213                 if (offset < replace.newOffset)
214                     return fSource.get(offset - delta);
215
216                 else if (offset < replace.newOffset + replace.text.length())
217                     return replace.text.charAt(offset - replace.newOffset);
218
219                 delta= getDelta(replace);
220             }
221
222             return fSource.get(offset - delta);
223         }
224     }
225
226     /*
227      * @see org.eclipse.jface.text.ITextStore#getLength()
228      */

229     public int getLength() {
230         if (fReplaceList.isEmpty())
231             return fSource.getLength();
232
233         Replace lastReplace= (Replace) fReplaceList.getLast();
234         return fSource.getLength() + getDelta(lastReplace);
235     }
236
237     /**
238      * Disposes this rewrite store.
239      */

240     public void dispose() {
241         fReplaceList= null;
242         fSource= null;
243     }
244
245     /**
246      * Commits all buffered replace commands.
247      */

248     private void commit() {
249
250         if (fReplaceList.isEmpty())
251             return;
252
253         StringBuffer JavaDoc buffer= new StringBuffer JavaDoc();
254
255         int delta= 0;
256         for (Iterator JavaDoc i= fReplaceList.iterator(); i.hasNext(); ) {
257             Replace replace= (Replace) i.next();
258
259             int offset= buffer.length() - delta;
260             buffer.append(fSource.get(offset, replace.offset - offset));
261             buffer.append(replace.text);
262             delta= getDelta(replace);
263         }
264
265         int offset= buffer.length() - delta;
266         buffer.append(fSource.get(offset, fSource.getLength() - offset));
267
268         fSource.set(buffer.toString());
269         fReplaceList.clear();
270     }
271 }
272
Popular Tags