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 implements AbstractDocument.Content, Serializable
58: {
59:
60: private static final long serialVersionUID = 4755994433709540381L;
61:
62:
63: char[] content;
64:
65: private int count;
66:
67: private Vector positions = new Vector();
68:
69: private class InsertUndo extends AbstractUndoableEdit
70: {
71: private int start;
72:
73: private int length;
74:
75: private String redoContent;
76:
77: public InsertUndo(int start, int length)
78: {
79: super();
80: this.start = start;
81: this.length = length;
82: }
83:
84: public void undo()
85: {
86: super.undo();
87: try
88: {
89: StringContent.this.checkLocation(this.start, this.length);
90: this.redoContent = new String(StringContent.this.content, this.start, this.length);
91: StringContent.this.remove(this.start, this.length);
92: }
93: catch (BadLocationException b)
94: {
95: throw new CannotUndoException();
96: }
97: }
98:
99: public void redo()
100: {
101: super.redo();
102: try
103: {
104: StringContent.this.insertString(this.start, this.redoContent);
105: }
106: catch (BadLocationException b)
107: {
108: throw new CannotRedoException();
109: }
110: }
111: }
112:
113: private class RemoveUndo extends AbstractUndoableEdit
114: {
115: private int start;
116:
117: private String undoString;
118:
119: public RemoveUndo(int start, String str)
120: {
121: super();
122: this.start = start;
123: this.undoString = str;
124: }
125:
126: public void undo()
127: {
128: super.undo();
129: try
130: {
131: StringContent.this.insertString(this.start, this.undoString);
132: }
133: catch (BadLocationException bad)
134: {
135: throw new CannotUndoException();
136: }
137: }
138:
139: public void redo()
140: {
141: super.redo();
142: try
143: {
144: int end = this.undoString.length();
145: StringContent.this.remove(this.start, end);
146: }
147: catch (BadLocationException bad)
148: {
149: throw new CannotRedoException();
150: }
151: }
152: }
153:
154: private class StickyPosition implements Position
155: {
156: private int offset = -1;
157:
158: public StickyPosition(int offset)
159: {
160: this.offset = offset;
161: }
162:
163:
164: void setOffset(int offset)
165: {
166: this.offset = this.offset >= 0 ? offset : -1;
167: }
168:
169:
172: public int getOffset()
173: {
174: return offset < 0 ? 0 : offset;
175: }
176: }
177:
178: public StringContent()
179: {
180: this(1);
181: }
182:
183: public StringContent(int initialLength)
184: {
185: super();
186: if (initialLength < 1)
187: initialLength = 1;
188: this.content = new char[initialLength];
189: this.content[0] = '\n';
190: this.count = 1;
191: }
192:
193: protected Vector getPositionsInRange(Vector v,
194: int offset,
195: int length)
196: {
197: Vector refPos = new Vector();
198: Iterator iter = this.positions.iterator();
199: while(iter.hasNext())
200: {
201: Position p = (Position)iter.next();
202: if ((offset <= p.getOffset())
203: && (p.getOffset() <= (offset + length)))
204: refPos.add(p);
205: }
206: return refPos;
207: }
208:
209: public Position createPosition(int offset) throws BadLocationException
210: {
211: if (offset < this.count || offset > this.count)
212: checkLocation(offset, 0);
213: StickyPosition sp = new StickyPosition(offset);
214: this.positions.add(sp);
215: return sp;
216: }
217:
218: public int length()
219: {
220: return this.count;
221: }
222:
223: public UndoableEdit insertString(int where, String str)
224: throws BadLocationException
225: {
226: checkLocation(where, 0);
227: if (where == this.count)
228: throw new BadLocationException("Invalid location", 1);
229: if (str == null)
230: throw new NullPointerException();
231: char[] insert = str.toCharArray();
232: char[] temp = new char[this.content.length + insert.length];
233: this.count += insert.length;
234:
235: if (where > 0)
236: System.arraycopy(this.content, 0, temp, 0, where);
237: System.arraycopy(insert, 0, temp, where, insert.length);
238: System.arraycopy(this.content, where, temp, (where + insert.length), (temp.length - where - insert.length));
239: if (this.content.length < temp.length)
240: this.content = new char[temp.length];
241:
242: System.arraycopy(temp, 0, this.content, 0, temp.length);
243:
244: Vector refPos = getPositionsInRange(this.positions, where, temp.length - where);
245: Iterator iter = refPos.iterator();
246: while (iter.hasNext())
247: {
248: StickyPosition p = (StickyPosition)iter.next();
249: p.setOffset(p.getOffset() + str.length());
250: }
251: InsertUndo iundo = new InsertUndo(where, insert.length);
252: return iundo;
253: }
254:
255: public UndoableEdit remove(int where, int nitems) throws BadLocationException
256: {
257: checkLocation(where, nitems);
258: char[] temp = new char[(this.content.length - nitems)];
259: this.count = this.count - nitems;
260: RemoveUndo rundo = new RemoveUndo(where, new String(this.content, where, nitems));
261:
262: System.arraycopy(this.content, 0, temp, 0, where);
263: System.arraycopy(this.content, where + nitems, temp, where, this.content.length - where - nitems);
264: this.content = new char[temp.length];
265:
266: System.arraycopy(temp, 0, this.content, 0, this.content.length);
267:
268: Vector refPos = getPositionsInRange(this.positions, where, this.content.length + nitems - where);
269: Iterator iter = refPos.iterator();
270: while (iter.hasNext())
271: {
272: StickyPosition p = (StickyPosition)iter.next();
273: int result = p.getOffset() - nitems;
274: p.setOffset(result);
275: if (result < 0)
276: this.positions.remove(p);
277: }
278: return rundo;
279: }
280:
281: public String getString(int where, int len) throws BadLocationException
282: {
283: checkLocation(where, len);
284: return new String (this.content, where, len);
285: }
286:
287: public void getChars(int where, int len, Segment txt) throws BadLocationException
288: {
289: checkLocation(where, len);
290: if (txt != null)
291: {
292: txt.array = this.content;
293: txt.offset = where;
294: txt.count = len;
295: }
296: }
297:
298:
299: void checkLocation(int where, int len) throws BadLocationException
300: {
301: if (where < 0)
302: throw new BadLocationException("Invalid location", 1);
303: else if (where > this.count)
304: throw new BadLocationException("Invalid location", this.count);
305: else if ((where + len)>this.count)
306: throw new BadLocationException("Invalid range", this.count);
307: }
308:
309: }