001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Alexey A. Ivanov
019: * @version $Revision$
020: */package javax.swing.text;
021:
022: import java.util.List;
023: import javax.swing.event.DocumentEvent.ElementChange;
024: import javax.swing.event.DocumentEvent.EventType;
025: import javax.swing.text.AbstractDocument.BranchElement;
026: import javax.swing.text.AbstractDocument.Content;
027: import javax.swing.text.AbstractDocument.DefaultDocumentEvent;
028: import javax.swing.text.DefaultStyledDocument.ElementBuffer;
029: import javax.swing.text.DefaultStyledDocument.ElementSpec;
030: import junit.framework.TestCase;
031:
032: /**
033: * Tests DefaultStyledDocument.ElementBuffer.insert() method with
034: * ElementSpec array that was obtained from real-life text insertions.
035: * The text contains no new line characters.
036: *
037: */
038: public class DefaultStyledDocument_ElementBuffer_InsertTextTest extends
039: TestCase {
040: private DefaultStyledDocument doc;
041:
042: private ElementBuffer buf;
043:
044: private Element root;
045:
046: private Element paragraph;
047:
048: private int insertOffset;
049:
050: private Content content;
051:
052: private DefaultDocumentEvent event;
053:
054: private static final AttributeSet bold = DefStyledDoc_Helpers.bold;
055:
056: private static final AttributeSet italic = DefStyledDoc_Helpers.italic;
057:
058: private static final String caps = "^^^";
059:
060: private static final int capsLen = caps.length();
061:
062: @Override
063: protected void setUp() throws Exception {
064: super .setUp();
065: doc = new DefaultStyledDocument();
066: root = doc.getDefaultRootElement();
067: buf = new DefStyledDoc_Helpers.ElementBufferWithLogging(doc,
068: root);
069: doc.buffer = buf;
070: paragraph = root.getElement(0);
071: content = doc.getContent();
072: paragraph = root.getElement(0);
073: content.insertString(0, "plainbolditalic\ntext");
074: // Create the structure equivalent to this sequence:
075: //doc.insertString(doc.getLength(), "plain", null); // 5 chars
076: //doc.insertString(doc.getLength(), "bold", bold); // 4 chars
077: //doc.insertString(doc.getLength(), "italic", italic); // 6 chars
078: //doc.insertString(doc.getLength(), "\ntext", null); // 5 chars
079: doc.writeLock(); // Write lock needed to modify document structure
080: Element[] leaves = new Element[4];
081: leaves[0] = doc.createLeafElement(paragraph, null, 0, 5);
082: leaves[1] = doc.createLeafElement(paragraph, bold, 5, 9);
083: leaves[2] = doc.createLeafElement(paragraph, italic, 9, 15);
084: leaves[3] = doc.createLeafElement(paragraph, null, 15, 16);
085: ((BranchElement) paragraph).replace(0, 1, leaves);
086: BranchElement branch = (BranchElement) doc.createBranchElement(
087: root, null);
088: leaves = new Element[1];
089: leaves[0] = doc.createLeafElement(branch, null, 16, 21);
090: branch.replace(0, 0, leaves);
091: // Add this branch to the root
092: ((BranchElement) root).replace(1, 0, new Element[] { branch });
093: insertOffset = 5 + 2;
094: }
095:
096: @Override
097: protected void tearDown() throws Exception {
098: super .tearDown();
099: doc.writeUnlock();
100: }
101:
102: /**
103: * Inserting text with the same attributes into the beginning of
104: * the document.
105: * <p>
106: * This test is equivalent to
107: * <code>doc.insertString(insertOffset, caps, null)</code>,
108: * where <code>insertOffset = 0</code>.
109: */
110: public void testInsertSameAttrsDocStart() throws Exception {
111: insertOffset = 0;
112: // doc.insertString(insertOffset, caps, null);
113: content.insertString(insertOffset, caps);
114: event = doc.new DefaultDocumentEvent(insertOffset, capsLen,
115: EventType.INSERT);
116: ElementSpec spec = new ElementSpec(null,
117: ElementSpec.ContentType, capsLen);
118: spec.setDirection(ElementSpec.JoinPreviousDirection);
119: buf.insert(insertOffset, capsLen, new ElementSpec[] { spec },
120: event);
121: List<?> edits = getEdits(event);
122: assertEquals(0, edits.size());
123: assertEquals("^^^plain", getText(doc
124: .getCharacterElement(insertOffset)));
125: }
126:
127: /**
128: * Inserting text with different attributes into the beginning of
129: * the document.
130: * <p>
131: * This test is equivalent to
132: * <code>doc.insertString(insertOffset, caps, italic)</code>,
133: * where <code>insertOffset = 0</code>.
134: */
135: public void testInsertDiffAttrsDocStart() throws Exception {
136: insertOffset = 0;
137: // doc.insertString(insertOffset, caps, italic);
138: content.insertString(insertOffset, caps);
139: event = doc.new DefaultDocumentEvent(insertOffset, capsLen,
140: EventType.INSERT);
141: ElementSpec spec = new ElementSpec(null,
142: ElementSpec.ContentType, capsLen);
143: buf.insert(insertOffset, capsLen, new ElementSpec[] { spec },
144: event);
145: List<?> edits = getEdits(event);
146: assertEquals(1, edits.size());
147: assertChange(edits.get(0), new int[] { 0, 8 }, new int[] { 0,
148: 3, 3, 8 });
149: assertEquals("^^^", getText(doc
150: .getCharacterElement(insertOffset)));
151: assertEquals("plain", getText(doc
152: .getCharacterElement(insertOffset + capsLen)));
153: }
154:
155: /**
156: * Inserting text into middle of an element with the same attributes.
157: * <p>
158: * This test is equivalent to
159: * <code>doc.insertString(insertOffset, caps, bold)</code>,
160: * where <code>insertOffset</code> has default value from
161: * <code>setUp()</code>.
162: */
163: public void testInsertSameAttrsMiddle() throws Exception {
164: // doc.insertString(insertOffset, caps, bold);
165: content.insertString(insertOffset, caps);
166: event = doc.new DefaultDocumentEvent(insertOffset, capsLen,
167: EventType.INSERT);
168: ElementSpec spec = new ElementSpec(null,
169: ElementSpec.ContentType, capsLen);
170: spec.setDirection(ElementSpec.JoinPreviousDirection);
171: buf.insert(insertOffset, capsLen, new ElementSpec[] { spec },
172: event);
173: List<?> edits = getEdits(event);
174: assertEquals(0, edits.size());
175: assertEquals("bo^^^ld", getText(doc
176: .getCharacterElement(insertOffset)));
177: }
178:
179: /**
180: * Inserting text into end of the an element with the same attributes;
181: * the following element has different attributes.
182: * <p>
183: * This test is equivalent to
184: * <code>doc.insertString(insertOffset, caps, bold)</code>,
185: * where 2 is added to default value of <code>insertOffset</code>.
186: */
187: public void testInsertSameAttrsEnd() throws Exception {
188: insertOffset += 2;
189: // doc.insertString(insertOffset, caps, bold);
190: content.insertString(insertOffset, caps);
191: event = doc.new DefaultDocumentEvent(insertOffset, capsLen,
192: EventType.INSERT);
193: ElementSpec spec = new ElementSpec(null,
194: ElementSpec.ContentType, capsLen);
195: spec.setDirection(ElementSpec.JoinPreviousDirection);
196: buf.insert(insertOffset, capsLen, new ElementSpec[] { spec },
197: event);
198: List<?> edits = getEdits(event);
199: assertEquals(0, edits.size());
200: assertEquals("bold^^^", getText(doc
201: .getCharacterElement(insertOffset)));
202: }
203:
204: /**
205: * Inserting text into the middle of an element with different attributes.
206: * <p>
207: * This test is equivalent to
208: * <code>doc.insertString(insertOffset, caps, null)</code>,
209: * where <code>insertOffset</code> has default value from
210: * <code>setUp()</code>.
211: */
212: public void testInsertDiffAttrsMiddle() throws Exception {
213: // doc.insertString(insertOffset, caps, null);
214: content.insertString(insertOffset, caps);
215: event = doc.new DefaultDocumentEvent(insertOffset, capsLen,
216: EventType.INSERT);
217: ElementSpec spec = new ElementSpec(null,
218: ElementSpec.ContentType, capsLen);
219: buf.insert(insertOffset, capsLen, new ElementSpec[] { spec },
220: event);
221: List<?> edits = getEdits(event);
222: assertEquals(1, edits.size());
223: assertChange(edits.get(0), new int[] { 5, 12 }, new int[] { 5,
224: 7, 7, 10, 10, 12 });
225: assertEquals("bo", getText(doc
226: .getCharacterElement(insertOffset - 1)));
227: assertEquals("^^^", getText(doc
228: .getCharacterElement(insertOffset)));
229: assertEquals("ld", getText(doc.getCharacterElement(insertOffset
230: + capsLen)));
231: }
232:
233: /**
234: * Inserting text into element boundary; the text and both elements have
235: * different attributes.
236: * <p>
237: * This test is equivalent to
238: * <code>doc.insertString(insertOffset, caps, null)</code>,
239: * where 2 is added to default value of <code>insertOffset</code>.
240: */
241: public void testInsertDiffAttrsEnd() throws Exception {
242: insertOffset += 2;
243: // doc.insertString(insertOffset, caps, null);
244: content.insertString(insertOffset, caps);
245: event = doc.new DefaultDocumentEvent(insertOffset, capsLen,
246: EventType.INSERT);
247: ElementSpec spec = new ElementSpec(null,
248: ElementSpec.ContentType, capsLen);
249: buf.insert(insertOffset, capsLen, new ElementSpec[] { spec },
250: event);
251: List<?> edits = getEdits(event);
252: assertEquals(1, edits.size());
253: assertChange(edits.get(0), new int[] { 5, 12 }, new int[] { 5,
254: 9, 9, 12 });
255: assertEquals("bold", getText(doc
256: .getCharacterElement(insertOffset - 1)));
257: assertEquals("^^^", getText(doc
258: .getCharacterElement(insertOffset)));
259: assertEquals("italic", getText(doc
260: .getCharacterElement(insertOffset + capsLen)));
261: }
262:
263: /**
264: * Inserting text into element boundary; the attributes of the text and
265: * the following element are the same, the attributes of the previous
266: * element are different.
267: * <p>
268: * This test is equivalent to
269: * <code>doc.insertString(insertOffset, caps, italic)</code>,
270: * where 2 is added to default value of <code>insertOffset</code>.
271: */
272: public void testInsertDiffSameAttrsEnd() throws Exception {
273: insertOffset += 2;
274: // doc.insertString(insertOffset, caps, italic);
275: content.insertString(insertOffset, caps);
276: event = doc.new DefaultDocumentEvent(insertOffset, capsLen,
277: EventType.INSERT);
278: ElementSpec spec = new ElementSpec(italic,
279: ElementSpec.ContentType, capsLen);
280: spec.setDirection(ElementSpec.JoinNextDirection);
281: buf.insert(insertOffset, capsLen, new ElementSpec[] { spec },
282: event);
283: List<?> edits = getEdits(event);
284: assertEquals(1, edits.size());
285: assertChange(edits.get(0), new int[] { 5, 12, 12, 18 },
286: new int[] { 5, 9, 9, 18 });
287: assertEquals("bold", getText(doc
288: .getCharacterElement(insertOffset - 1)));
289: assertEquals("^^^italic", getText(doc
290: .getCharacterElement(insertOffset)));
291: }
292:
293: /**
294: * Inserting text into the start of a paragraph with the same attributes.
295: * <p>
296: * This test is equivalent to
297: * <code>doc.insertString(insertOffset, caps, null)</code>,
298: * where <code>insertOffset = paragraph.getEndOffset()</code>.
299: */
300: public void testInsertSameAttrsParStart() throws Exception {
301: insertOffset = paragraph.getEndOffset();
302: // doc.insertString(insertOffset, caps, null);
303: content.insertString(insertOffset, caps);
304: event = doc.new DefaultDocumentEvent(insertOffset, capsLen,
305: EventType.INSERT);
306: ElementSpec[] specs = {
307: new ElementSpec(null, ElementSpec.EndTagType),
308: new ElementSpec(null, ElementSpec.StartTagType),
309: new ElementSpec(null, ElementSpec.ContentType, capsLen), };
310: specs[1].setDirection(ElementSpec.JoinNextDirection);
311: specs[2].setDirection(ElementSpec.JoinNextDirection);
312: buf.insert(insertOffset, capsLen, specs, event);
313: List<?> edits = getEdits(event);
314: assertEquals(2, edits.size());
315: assertChange(edits.get(0), new int[] { 15, 19 }, new int[] {
316: 15, 16 });
317: assertChange(edits.get(1), new int[] { 19, 24 }, new int[] {
318: 16, 24 });
319: assertChildren(paragraph,
320: new int[] { 0, 5, 5, 9, 9, 15, 15, 16 },
321: new AttributeSet[] { null, bold, italic, null });
322: assertChildren(root.getElement(1), new int[] { 16, 24 },
323: new AttributeSet[] { null });
324: assertEquals("^^^text\n", getText(doc
325: .getCharacterElement(insertOffset)));
326: }
327:
328: /**
329: * Inserting text into the start of a paragraph with different attributes.
330: * <p>
331: * This test is equivalent to
332: * <code>doc.insertString(insertOffset, caps, italic)</code>,
333: * where <code>insertOffset = paragraph.getEndOffset()</code>.
334: */
335: public void testInsertDiffAttrsParStart() throws Exception {
336: insertOffset = paragraph.getEndOffset();
337: // doc.insertString(insertOffset, caps, italic);
338: content.insertString(insertOffset, caps);
339: event = doc.new DefaultDocumentEvent(insertOffset, capsLen,
340: EventType.INSERT);
341: ElementSpec[] specs = {
342: new ElementSpec(null, ElementSpec.EndTagType),
343: new ElementSpec(null, ElementSpec.StartTagType),
344: new ElementSpec(italic, ElementSpec.ContentType,
345: capsLen), };
346: specs[1].setDirection(ElementSpec.JoinNextDirection);
347: buf.insert(insertOffset, capsLen, specs, event);
348: List<?> edits = getEdits(event);
349: assertEquals(2, edits.size());
350: assertChange(edits.get(0), new int[] { 15, 19 }, new int[] {
351: 15, 16 });
352: assertChange(edits.get(1), new int[] {}, new int[] { 16, 19 });
353: assertChildren(paragraph,
354: new int[] { 0, 5, 5, 9, 9, 15, 15, 16 },
355: new AttributeSet[] { null, bold, italic, null });
356: assertChildren(root.getElement(1),
357: new int[] { 16, 19, 19, 24 }, new AttributeSet[] {
358: italic, null });
359: assertEquals("^^^", getText(doc
360: .getCharacterElement(insertOffset)));
361: assertEquals("text\n", getText(doc
362: .getCharacterElement(insertOffset + capsLen)));
363: }
364:
365: /**
366: * Inserting text into the end of the document with the same attributes.
367: * <p>
368: * This test is equivalent to
369: * <code>doc.insertString(insertOffset, caps, null)</code>,
370: * where <code>insertOffset = doc.getLength()</code>.
371: */
372: public void testInsertSameAttrsDocEnd() throws Exception {
373: insertOffset = doc.getLength();
374: // doc.insertString(insertOffset, caps, null);
375: content.insertString(insertOffset, caps);
376: event = doc.new DefaultDocumentEvent(insertOffset, capsLen,
377: EventType.INSERT);
378: ElementSpec spec = new ElementSpec(null,
379: ElementSpec.ContentType, capsLen);
380: spec.setDirection(ElementSpec.JoinPreviousDirection);
381: buf.insert(insertOffset, capsLen, new ElementSpec[] { spec },
382: event);
383: List<?> edits = getEdits(event);
384: assertEquals(0, edits.size());
385: assertChildren(root.getElement(1), new int[] { 16, 24 },
386: new AttributeSet[] { null });
387: assertEquals("text^^^\n", getText(doc
388: .getCharacterElement(insertOffset)));
389: }
390:
391: /**
392: * Inserting text into the end of the document with different attributes.
393: * <p>
394: * This test is equivalent to
395: * <code>doc.insertString(insertOffset, caps, italic)</code>,
396: * where <code>insertOffset = doc.getLength()</code>.
397: */
398: public void testInsertDiffAttrsDocEnd() throws Exception {
399: insertOffset = doc.getLength();
400: // doc.insertString(insertOffset, caps, italic);
401: content.insertString(insertOffset, caps);
402: event = doc.new DefaultDocumentEvent(insertOffset, capsLen,
403: EventType.INSERT);
404: ElementSpec spec = new ElementSpec(italic,
405: ElementSpec.ContentType, capsLen);
406: buf.insert(insertOffset, capsLen, new ElementSpec[] { spec },
407: event);
408: List<?> edits = getEdits(event);
409: assertEquals(1, edits.size());
410: assertChange(edits.get(0), new int[] { 16, 24 }, new int[] {
411: 16, 20, 20, 23, 23, 24 });
412: assertChildren(root.getElement(1), new int[] { 16, 20, 20, 23,
413: 23, 24 }, new AttributeSet[] { null, italic, null });
414: assertEquals("text", getText(doc
415: .getCharacterElement(insertOffset - 1)));
416: assertEquals("^^^", getText(doc
417: .getCharacterElement(insertOffset)));
418: assertEquals("\n", getText(doc.getCharacterElement(insertOffset
419: + capsLen)));
420: }
421:
422: private String getText(final int offset, final int length)
423: throws BadLocationException {
424: return doc.getText(offset, length);
425: }
426:
427: private String getText(final Element element)
428: throws BadLocationException {
429: return getText(element.getStartOffset(), element.getEndOffset()
430: - element.getStartOffset());
431: }
432:
433: private static void assertChange(final Object change,
434: final int[] removedOffsets, final int[] addedOffsets) {
435: DefStyledDoc_Helpers.assertChange((ElementChange) change,
436: removedOffsets, addedOffsets);
437: }
438:
439: private static void assertChildren(final Element element,
440: final int[] offsets, final AttributeSet[] attributes) {
441: DefStyledDoc_Helpers.assertChildren(element, offsets,
442: attributes);
443: }
444:
445: private static List<?> getEdits(final DefaultDocumentEvent event) {
446: return DefStyledDoc_Helpers.getEdits(event);
447: }
448: }
449: /*
450: The dump of the document after the initial set up.
451:
452: <section>
453: <paragraph
454: resolver=NamedStyle:default {name=default,}
455: >
456: <content>
457: [0,5][plain]
458: <content
459: bold=true
460: >
461: [5,9][bold]
462: <content
463: italic=true
464: >
465: [9,15][italic]
466: <content>
467: [15,16][
468: ]
469: <paragraph>
470: <content>
471: [16,21][text
472: ]
473: <bidi root>
474: <bidi level
475: bidiLevel=0
476: >
477: [0,21][plainbolditalic
478: text
479: ]
480: */
|