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.AbstractElement;
026: import javax.swing.text.AbstractDocument.BranchElement;
027: import javax.swing.text.AbstractDocument.Content;
028: import javax.swing.text.AbstractDocument.DefaultDocumentEvent;
029: import javax.swing.text.DefaultStyledDocument.ElementBuffer;
030: import javax.swing.text.DefaultStyledDocument.ElementSpec;
031: import junit.framework.TestCase;
032:
033: /**
034: * Tests DefaultStyledDocument.ElementBuffer.insert() method with
035: * ElementSpec array that was obtained from real-life text insertions.
036: * The text contains several new line characters as well as other characters
037: * too.
038: *
039: */
040: public class DefaultStyledDocument_ElementBuffer_InsertSeveralNewLinesTest
041: extends TestCase {
042: private DefaultStyledDocument doc;
043:
044: private ElementBuffer buf;
045:
046: private Element root;
047:
048: private Element paragraph;
049:
050: private int insertOffset;
051:
052: private Content content;
053:
054: private DefaultDocumentEvent event;
055:
056: private static final AttributeSet bold = DefStyledDoc_Helpers.bold;
057:
058: private static final AttributeSet italic = DefStyledDoc_Helpers.italic;
059:
060: private static final String newLine = "\n";
061:
062: private static final int newLineLen = newLine.length();
063:
064: private static final String newLines2 = "\n\n";
065:
066: private static final int newLines2Len = newLines2.length();
067:
068: private static final String newLines3 = "\n\n\n";
069:
070: private static final int newLines3Len = newLines3.length();
071:
072: private static final String newLines2Text = "0\n1\n";
073:
074: private static final String newLines3Text = "0\n1\n2\n";
075:
076: @Override
077: protected void setUp() throws Exception {
078: super .setUp();
079: doc = new DefaultStyledDocument();
080: root = doc.getDefaultRootElement();
081: buf = new DefStyledDoc_Helpers.ElementBufferWithLogging(doc,
082: root);
083: doc.buffer = buf;
084: paragraph = root.getElement(0);
085: content = doc.getContent();
086: paragraph = root.getElement(0);
087: content.insertString(0, "plainbolditalic\ntext");
088: // Create the structure equivalent to this sequence:
089: //doc.insertString(doc.getLength(), "plain", null); // 5 chars
090: //doc.insertString(doc.getLength(), "bold", bold); // 4 chars
091: //doc.insertString(doc.getLength(), "italic", italic); // 6 chars
092: //doc.insertString(doc.getLength(), "\ntext", null); // 5 chars
093: doc.writeLock(); // Write lock needed to modify document structure
094: Element[] leaves = new Element[4];
095: leaves[0] = doc.createLeafElement(paragraph, null, 0, 5);
096: leaves[1] = doc.createLeafElement(paragraph, bold, 5, 9);
097: leaves[2] = doc.createLeafElement(paragraph, italic, 9, 15);
098: leaves[3] = doc.createLeafElement(paragraph, null, 15, 16);
099: ((BranchElement) paragraph).replace(0, 1, leaves);
100: BranchElement branch = (BranchElement) doc.createBranchElement(
101: root, null);
102: leaves = new Element[1];
103: leaves[0] = doc.createLeafElement(branch, null, 16, 21);
104: branch.replace(0, 0, leaves);
105: // Add this branch to the root
106: ((BranchElement) root).replace(1, 0, new Element[] { branch });
107: insertOffset = 5 + 2;
108: }
109:
110: @Override
111: protected void tearDown() throws Exception {
112: super .tearDown();
113: doc.writeUnlock();
114: }
115:
116: /**
117: * Inserting text with the same attributes into the beginning of
118: * the document. The text contains <i>two</i> new line characters only.
119: * <p>
120: * This test is equivalent to
121: * <code>doc.insertString(insertOffset, newLines2, null)</code>,
122: * where <code>insertOffset = 0</code>.
123: */
124: public void testInsertSameAttrsDocStart2NewLines() throws Exception {
125: insertOffset = 0;
126: // doc.insertString(insertOffset, newLines2, null);
127: content.insertString(insertOffset, newLines2);
128: event = doc.new DefaultDocumentEvent(insertOffset,
129: newLines2Len, EventType.INSERT);
130: ElementSpec[] specs = {
131: new ElementSpec(null, ElementSpec.ContentType,
132: newLineLen),
133: new ElementSpec(null, ElementSpec.EndTagType),
134: new ElementSpec(null, ElementSpec.StartTagType),
135: new ElementSpec(null, ElementSpec.ContentType,
136: newLineLen),
137: new ElementSpec(null, ElementSpec.EndTagType),
138: new ElementSpec(null, ElementSpec.StartTagType) };
139: specs[0].setDirection(ElementSpec.JoinPreviousDirection);
140: specs[specs.length - 1]
141: .setDirection(ElementSpec.JoinFractureDirection);
142: buf.insert(insertOffset, newLines2Len, specs, event);
143: List<?> edits = getEdits(event);
144: assertEquals(3, edits.size());
145: assertChange(edits.get(0), 0, new int[] { 0, 7, 7, 11, 11, 17,
146: 17, 18 }, new int[] { 0, 1 });
147: assertChange(edits.get(1), 0, new int[] {}, new int[] { 1, 2 });
148: assertChange(edits.get(2), 1, new int[] {}, new int[] { 1, 2,
149: 2, 18 });
150: assertChildren(root.getElement(0), new int[] { 0, 1 },
151: new AttributeSet[] { null });
152: assertChildren(root.getElement(1), new int[] { 1, 2 },
153: new AttributeSet[] { null });
154: assertChildren(root.getElement(2), new int[] { 2, 7, 7, 11, 11,
155: 17, 17, 18 }, new AttributeSet[] { null, bold, italic,
156: null });
157: assertEquals("\n", getText(doc
158: .getCharacterElement(insertOffset)));
159: assertEquals("\n", getText(doc.getCharacterElement(insertOffset
160: + newLineLen)));
161: assertEquals("plain", getText(doc
162: .getCharacterElement(insertOffset + newLines2Len)));
163: }
164:
165: /**
166: * Inserting text with the same attributes into the beginning of
167: * the document. The text contains <i>three</i> new line characters only.
168: * <p>
169: * This test is equivalent to
170: * <code>doc.insertString(insertOffset, newLines3, null)</code>,
171: * where <code>insertOffset = 0</code>.
172: */
173: public void testInsertSameAttrsDocStart3NewLines() throws Exception {
174: insertOffset = 0;
175: // doc.insertString(insertOffset, newLines3, null);
176: content.insertString(insertOffset, newLines3);
177: event = doc.new DefaultDocumentEvent(insertOffset,
178: newLines3Len, EventType.INSERT);
179: ElementSpec[] specs = {
180: new ElementSpec(null, ElementSpec.ContentType,
181: newLineLen),
182: new ElementSpec(null, ElementSpec.EndTagType),
183: new ElementSpec(null, ElementSpec.StartTagType),
184: new ElementSpec(null, ElementSpec.ContentType,
185: newLineLen),
186: new ElementSpec(null, ElementSpec.EndTagType),
187: new ElementSpec(null, ElementSpec.StartTagType),
188: new ElementSpec(null, ElementSpec.ContentType,
189: newLineLen),
190: new ElementSpec(null, ElementSpec.EndTagType),
191: new ElementSpec(null, ElementSpec.StartTagType) };
192: specs[0].setDirection(ElementSpec.JoinPreviousDirection);
193: specs[specs.length - 1]
194: .setDirection(ElementSpec.JoinFractureDirection);
195: buf.insert(insertOffset, newLines3Len, specs, event);
196: List<?> edits = getEdits(event);
197: assertEquals(4, edits.size());
198: assertChange(edits.get(0), 0, new int[] { 0, 8, 8, 12, 12, 18,
199: 18, 19 }, new int[] { 0, 1 });
200: assertChange(edits.get(1), 0, new int[] {}, new int[] { 1, 2 });
201: assertChange(edits.get(2), 0, new int[] {}, new int[] { 2, 3 });
202: assertChange(edits.get(3), 1, new int[] {}, new int[] { 1, 2,
203: 2, 3, 3, 19 });
204: assertChildren(root.getElement(0), new int[] { 0, 1 },
205: new AttributeSet[] { null });
206: assertChildren(root.getElement(1), new int[] { 1, 2 },
207: new AttributeSet[] { null });
208: assertChildren(root.getElement(2), new int[] { 2, 3 },
209: new AttributeSet[] { null });
210: assertChildren(root.getElement(3), new int[] { 3, 8, 8, 12, 12,
211: 18, 18, 19 }, new AttributeSet[] { null, bold, italic,
212: null });
213: assertEquals("\n", getText(doc
214: .getCharacterElement(insertOffset)));
215: assertEquals("\n", getText(doc.getCharacterElement(insertOffset
216: + newLineLen)));
217: assertEquals("\n", getText(doc.getCharacterElement(insertOffset
218: + newLines2Len)));
219: assertEquals("plain", getText(doc
220: .getCharacterElement(insertOffset + newLines3Len)));
221: }
222:
223: /**
224: * Inserting text with the same attributes into the beginning of
225: * the document. The text contains <i>two</i> new line characters and
226: * one digit before each of them.
227: * <p>
228: * This test is equivalent to
229: * <code>doc.insertString(insertOffset, newLines2Text, null)</code>,
230: * where <code>insertOffset = 0</code>.
231: */
232: public void testInsertSameAttrsDocStart2NewLinesText()
233: throws Exception {
234: insertOffset = 0;
235: // doc.insertString(insertOffset, newLines2Text, null);
236: content.insertString(insertOffset, newLines2Text);
237: event = doc.new DefaultDocumentEvent(insertOffset,
238: newLines2Len * 2, EventType.INSERT);
239: ElementSpec[] specs = {
240: new ElementSpec(null, ElementSpec.ContentType,
241: newLineLen * 2),
242: new ElementSpec(null, ElementSpec.EndTagType),
243: new ElementSpec(null, ElementSpec.StartTagType),
244: new ElementSpec(null, ElementSpec.ContentType,
245: newLineLen * 2),
246: new ElementSpec(null, ElementSpec.EndTagType),
247: new ElementSpec(null, ElementSpec.StartTagType) };
248: specs[0].setDirection(ElementSpec.JoinPreviousDirection);
249: specs[specs.length - 1]
250: .setDirection(ElementSpec.JoinFractureDirection);
251: buf.insert(insertOffset, newLines2Len * 2, specs, event);
252: List<?> edits = getEdits(event);
253: assertEquals(3, edits.size());
254: assertChange(edits.get(0), 0, new int[] { 0, 9, 9, 13, 13, 19,
255: 19, 20 }, new int[] { 0, 2 });
256: assertChange(edits.get(1), 0, new int[] {}, new int[] { 2, 4 });
257: assertChange(edits.get(2), 1, new int[] {}, new int[] { 2, 4,
258: 4, 20 });
259: assertChildren(root.getElement(0), new int[] { 0, 2 },
260: new AttributeSet[] { null });
261: assertChildren(root.getElement(1), new int[] { 2, 4 },
262: new AttributeSet[] { null });
263: assertChildren(root.getElement(2), new int[] { 4, 9, 9, 13, 13,
264: 19, 19, 20 }, new AttributeSet[] { null, bold, italic,
265: null });
266: assertEquals("0\n", getText(doc
267: .getCharacterElement(insertOffset)));
268: assertEquals("1\n", getText(doc
269: .getCharacterElement(insertOffset + newLineLen * 2)));
270: assertEquals("plain", getText(doc
271: .getCharacterElement(insertOffset + newLines2Len * 2)));
272: }
273:
274: /**
275: * Inserting text with the same attributes into the beginning of
276: * the document. The text contains <i>three</i> new line characters and
277: * one digit before each of them.
278: * <p>
279: * This test is equivalent to
280: * <code>doc.insertString(insertOffset, newLines3Text, null)</code>,
281: * where <code>insertOffset = 0</code>.
282: */
283: public void testInsertSameAttrsDocStart3NewLinesText()
284: throws Exception {
285: insertOffset = 0;
286: // doc.insertString(insertOffset, newLines3Text, null);
287: content.insertString(insertOffset, newLines3Text);
288: event = doc.new DefaultDocumentEvent(insertOffset,
289: newLines3Len * 2, EventType.INSERT);
290: ElementSpec[] specs = {
291: new ElementSpec(null, ElementSpec.ContentType,
292: newLineLen * 2),
293: new ElementSpec(null, ElementSpec.EndTagType),
294: new ElementSpec(bold, ElementSpec.StartTagType),
295: new ElementSpec(null, ElementSpec.ContentType,
296: newLineLen * 2),
297: new ElementSpec(null, ElementSpec.EndTagType),
298: new ElementSpec(italic, ElementSpec.StartTagType),
299: new ElementSpec(null, ElementSpec.ContentType,
300: newLineLen * 2),
301: new ElementSpec(null, ElementSpec.EndTagType),
302: new ElementSpec(italic, ElementSpec.StartTagType) };
303: specs[0].setDirection(ElementSpec.JoinPreviousDirection);
304: specs[specs.length - 1]
305: .setDirection(ElementSpec.JoinFractureDirection);
306: ((AbstractElement) root.getElement(0)).addAttributes(bold);
307: ((AbstractElement) root.getElement(0)).addAttributes(italic);
308: buf.insert(insertOffset, newLines3Len * 2, specs, event);
309: List<?> edits = getEdits(event);
310: assertEquals(4, edits.size());
311: assertChange(edits.get(0), 0, new int[] { 0, 11, 11, 15, 15,
312: 21, 21, 22 }, new int[] { 0, 2 });
313: assertChange(edits.get(1), 0, new int[] {}, new int[] { 2, 4 });
314: assertChange(edits.get(2), 0, new int[] {}, new int[] { 4, 6 });
315: assertChange(edits.get(3), 1, new int[] {}, new int[] { 2, 4,
316: 4, 6, 6, 22 });
317: assertChildren(root.getElement(0), new int[] { 0, 2 },
318: new AttributeSet[] { null });
319: assertChildren(root.getElement(1), new int[] { 2, 4 },
320: new AttributeSet[] { null });
321: assertChildren(root.getElement(2), new int[] { 4, 6 },
322: new AttributeSet[] { null });
323: assertChildren(root.getElement(3), new int[] { 6, 11, 11, 15,
324: 15, 21, 21, 22 }, new AttributeSet[] { null, bold,
325: italic, null });
326: // Assert attributes of the paragraph
327: Element paragraph = root.getElement(0);
328: assertEquals(3, paragraph.getAttributes().getAttributeCount());
329: assertTrue(paragraph.getAttributes().isDefined(
330: AttributeSet.ResolveAttribute));
331: assertTrue(paragraph.getAttributes().containsAttributes(bold));
332: assertTrue(paragraph.getAttributes().containsAttributes(italic));
333: paragraph = root.getElement(1);
334: assertTrue(paragraph.getAttributes().isEqual(bold));
335: paragraph = root.getElement(2);
336: assertTrue(paragraph.getAttributes().isEqual(italic));
337: paragraph = root.getElement(3);
338: assertEquals(3, paragraph.getAttributes().getAttributeCount());
339: assertTrue(paragraph.getAttributes().isDefined(
340: AttributeSet.ResolveAttribute));
341: assertTrue(paragraph.getAttributes().containsAttributes(bold));
342: assertTrue(paragraph.getAttributes().containsAttributes(italic));
343: assertEquals("0\n", getText(doc
344: .getCharacterElement(insertOffset)));
345: assertEquals("1\n", getText(doc
346: .getCharacterElement(insertOffset + newLineLen * 2)));
347: assertEquals("2\n", getText(doc
348: .getCharacterElement(insertOffset + newLines2Len * 2)));
349: assertEquals("plain", getText(doc
350: .getCharacterElement(insertOffset + newLines3Len * 2)));
351: }
352:
353: private String getText(final int offset, final int length)
354: throws BadLocationException {
355: return doc.getText(offset, length);
356: }
357:
358: private String getText(final Element element)
359: throws BadLocationException {
360: return getText(element.getStartOffset(), element.getEndOffset()
361: - element.getStartOffset());
362: }
363:
364: private static void assertChange(final Object change,
365: final int index, final int[] removedOffsets,
366: final int[] addedOffsets) {
367: assertEquals("Change index", index, ((ElementChange) change)
368: .getIndex());
369: DefStyledDoc_Helpers.assertChange((ElementChange) change,
370: removedOffsets, addedOffsets);
371: }
372:
373: private static void assertChildren(final Element element,
374: final int[] offsets, final AttributeSet[] attributes) {
375: DefStyledDoc_Helpers.assertChildren(element, offsets,
376: attributes);
377: }
378:
379: private static List<?> getEdits(final DefaultDocumentEvent event) {
380: return DefStyledDoc_Helpers.getEdits(event);
381: }
382: }
|