1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44:
45: import ;
46: import ;
47: import ;
48: import ;
49:
50:
57: public final class StringContent
58: implements AbstractDocument.Content, Serializable
59: {
60:
61: private static final long serialVersionUID = 4755994433709540381L;
62:
63:
64: char[] content;
65:
66: private int count;
67:
68: private Vector positions = new Vector();
69:
70: private class InsertUndo extends AbstractUndoableEdit
71: {
72: private int start;
73:
74: private int length;
75:
76: private String redoContent;
77:
78: public InsertUndo(int start, int length)
79: {
80: super();
81: this.start = start;
82: this.length = length;
83: }
84:
85: public void undo()
86: {
87: super.undo();
88: try
89: {
90: StringContent.this.checkLocation(this.start, this.length);
91: this.redoContent = new String(StringContent.this.content, this.start,
92: this.length);
93: StringContent.this.remove(this.start, this.length);
94: }
95: catch (BadLocationException b)
96: {
97: throw new CannotUndoException();
98: }
99: }
100:
101: public void redo()
102: {
103: super.redo();
104: try
105: {
106: StringContent.this.insertString(this.start, this.redoContent);
107: }
108: catch (BadLocationException b)
109: {
110: throw new CannotRedoException();
111: }
112: }
113: }
114:
115: private class RemoveUndo extends AbstractUndoableEdit
116: {
117: private int start;
118:
119: private String undoString;
120:
121: public RemoveUndo(int start, String str)
122: {
123: super();
124: this.start = start;
125: this.undoString = str;
126: }
127:
128: public void undo()
129: {
130: super.undo();
131: try
132: {
133: StringContent.this.insertString(this.start, this.undoString);
134: }
135: catch (BadLocationException bad)
136: {
137: throw new CannotUndoException();
138: }
139: }
140:
141: public void redo()
142: {
143: super.redo();
144: try
145: {
146: int end = this.undoString.length();
147: StringContent.this.remove(this.start, end);
148: }
149: catch (BadLocationException bad)
150: {
151: throw new CannotRedoException();
152: }
153: }
154: }
155:
156: private class StickyPosition implements Position
157: {
158: private int offset = -1;
159:
160: public StickyPosition(int offset)
161: {
162: this.offset = offset;
163: }
164:
165:
166: void setOffset(int offset)
167: {
168: this.offset = this.offset >= 0 ? offset : -1;
169: }
170:
171:
174: public int getOffset()
175: {
176: return offset < 0 ? 0 : offset;
177: }
178: }
179:
180:
185: public StringContent()
186: {
187: this(10);
188: }
189:
190:
196: public StringContent(int initialLength)
197: {
198: super();
199: if (initialLength < 1)
200: initialLength = 1;
201: this.content = new char[initialLength];
202: this.content[0] = '\n';
203: this.count = 1;
204: }
205:
206: protected Vector getPositionsInRange(Vector v,
207: int offset,
208: int length)
209: {
210: Vector refPos = new Vector();
211: Iterator iter = this.positions.iterator();
212: while(iter.hasNext())
213: {
214: Position p = (Position) iter.next();
215: if ((offset <= p.getOffset())
216: && (p.getOffset() <= (offset + length)))
217: refPos.add(p);
218: }
219: return refPos;
220: }
221:
222:
232: public Position createPosition(int offset) throws BadLocationException
233: {
234: if (offset < this.count || offset > this.count)
235: checkLocation(offset, 0);
236: StickyPosition sp = new StickyPosition(offset);
237: this.positions.add(sp);
238: return sp;
239: }
240:
241:
247: public int length()
248: {
249: return this.count;
250: }
251:
252:
262: public UndoableEdit insertString(int where, String str)
263: throws BadLocationException
264: {
265: checkLocation(where, 0);
266: if (where == this.count)
267: throw new BadLocationException("Invalid location", 1);
268: if (str == null)
269: throw new NullPointerException();
270: char[] insert = str.toCharArray();
271: char[] temp = new char[this.content.length + insert.length];
272: this.count += insert.length;
273:
274: if (where > 0)
275: System.arraycopy(this.content, 0, temp, 0, where);
276: System.arraycopy(insert, 0, temp, where, insert.length);
277: System.arraycopy(this.content, where, temp, (where + insert.length),
278: (temp.length - where - insert.length));
279: if (this.content.length < temp.length)
280: this.content = new char[temp.length];
281:
282: System.arraycopy(temp, 0, this.content, 0, temp.length);
283:
284: Vector refPos = getPositionsInRange(this.positions, where,
285: temp.length - where);
286: Iterator iter = refPos.iterator();
287: while (iter.hasNext())
288: {
289: StickyPosition p = (StickyPosition)iter.next();
290: p.setOffset(p.getOffset() + str.length());
291: }
292: InsertUndo iundo = new InsertUndo(where, insert.length);
293: return iundo;
294: }
295:
296:
308: public UndoableEdit remove(int where, int nitems) throws BadLocationException
309: {
310: checkLocation(where, nitems + 1);
311: char[] temp = new char[(this.content.length - nitems)];
312: this.count = this.count - nitems;
313: RemoveUndo rundo = new RemoveUndo(where, new String(this.content, where,
314: nitems));
315:
316: System.arraycopy(this.content, 0, temp, 0, where);
317: System.arraycopy(this.content, where + nitems, temp, where,
318: this.content.length - where - nitems);
319: this.content = new char[temp.length];
320:
321: System.arraycopy(temp, 0, this.content, 0, this.content.length);
322:
323: Vector refPos = getPositionsInRange(this.positions, where,
324: this.content.length + nitems - where);
325: Iterator iter = refPos.iterator();
326: while (iter.hasNext())
327: {
328: StickyPosition p = (StickyPosition)iter.next();
329: int result = p.getOffset() - nitems;
330: p.setOffset(result);
331: if (result < 0)
332: this.positions.remove(p);
333: }
334: return rundo;
335: }
336:
337:
349: public String getString(int where, int len) throws BadLocationException
350: {
351: checkLocation(where, len);
352: return new String(this.content, where, len);
353: }
354:
355:
368: public void getChars(int where, int len, Segment txt)
369: throws BadLocationException
370: {
371: checkLocation(where, len);
372: txt.array = this.content;
373: txt.offset = where;
374: txt.count = len;
375: }
376:
377:
378:
384: protected void updateUndoPositions(Vector positions)
385: {
386:
387: }
388:
389:
399: void checkLocation(int where, int len) throws BadLocationException
400: {
401: if (where < 0)
402: throw new BadLocationException("Invalid location", 1);
403: else if (where > this.count)
404: throw new BadLocationException("Invalid location", this.count);
405: else if ((where + len) > this.count)
406: throw new BadLocationException("Invalid range", this.count);
407: }
408:
409: }