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