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: package javax.swing.text;
018:
019: import java.util.Enumeration;
020: import javax.swing.BasicSwingTestCase;
021: import javax.swing.text.AbstractDocument.BranchElement;
022: import javax.swing.text.AbstractDocument.LeafElement;
023:
024: /**
025: * Tests AbstractDocument.BranchElement class.
026: */
027: public class AbstractDocument_BranchElementTest extends
028: BasicSwingTestCase {
029: protected AbstractDocument doc;
030:
031: protected BranchElement bidi;
032:
033: protected BranchElement par;
034:
035: protected Element leaf1;
036:
037: protected Element leaf2;
038:
039: protected Element leaf3;
040:
041: protected AttributeSet[] as;
042:
043: protected static final String RTL = "\u05DC\u05DD";
044:
045: protected static final String LTR = "\u0061\u0062";
046:
047: @Override
048: protected void setUp() throws Exception {
049: super .setUp();
050: StyleContextTest.sc = StyleContext.getDefaultStyleContext();
051: as = new AttributeSet[] { StyleContextTest.addAttribute(1),
052: StyleContextTest.addAttribute(2),
053: StyleContextTest.addAttribute(null, 3, 2) };
054: doc = new PlainDocument();
055: doc.insertString(0, LTR + RTL + LTR + RTL + "\n01234", as[0]);
056: bidi = (BranchElement) doc.getBidiRootElement();
057: leaf1 = bidi.getElement(0).getElement(0);
058: par = (BranchElement) doc.getDefaultRootElement();
059: leaf2 = par.getElement(0);
060: leaf3 = par.getElement(1);
061: }
062:
063: public void testGetElement() {
064: if (BasicSwingTestCase.isHarmony()) {
065: assertNull(par.getElement(-1));
066: }
067: assertEquals(leaf2, par.getElement(0));
068: assertEquals(leaf3, par.getElement(1));
069: assertNull(par.getElement(2));
070: }
071:
072: public void testChildren() {
073: Enumeration<?> elements = par.children();
074: Element[] children = new Element[] { par.getElement(0),
075: par.getElement(1) };
076: int index = 0;
077: while (elements.hasMoreElements()) {
078: Object child = elements.nextElement();
079: assertSame(children[index++], child);
080: }
081: }
082:
083: public void testGetName() {
084: assertEquals("bidi root", bidi.getName());
085: assertEquals("paragraph", par.getName());
086: assertSame(AbstractDocument.ParagraphElementName, par.getName());
087: }
088:
089: /**
090: * Test getElementIndex with default set of elements.
091: */
092: public void testGetElementIndex01() {
093: assertEquals(0, par.getElementIndex(-1));
094: assertEquals(0, par.getElementIndex(7));
095: assertEquals(0, par.getElementIndex(8));
096: assertEquals(1, par.getElementIndex(9));
097: assertEquals(1, par.getElementIndex(10));
098: assertEquals(1, par.getElementIndex(11));
099: assertEquals(1, par.getElementIndex(20));
100: }
101:
102: /**
103: * Test getElementIndex behavior if some elements are zero-length,
104: * i.e. start and end offsets are the same.
105: */
106: public void testGetElementIndex02() {
107: BranchElement root = doc.new BranchElement(null, null);
108: LeafElement[] leaves = { doc.new LeafElement(root, null, 0, 0), // [0]
109: doc.new LeafElement(root, null, 0, 1), // [1]
110: doc.new LeafElement(root, null, 0, 1), // [2]
111: doc.new LeafElement(root, null, 1, 1), // [3]
112: doc.new LeafElement(root, null, 1, 1), // [4]
113: doc.new LeafElement(root, null, 1, 2), // [5]
114: doc.new LeafElement(root, null, 2, 3) // [6]
115: };
116: root.replace(0, 0, leaves);
117: assertEquals(0, root.getElementIndex(-1));
118: assertEquals(1, root.getElementIndex(0));
119: assertEquals(5 /*2*/, root.getElementIndex(1));
120: assertEquals(6, root.getElementIndex(2));
121: assertEquals(6, root.getElementIndex(3));
122: assertEquals(6, root.getElementIndex(4));
123: }
124:
125: /**
126: * Tests getElementIndex behavior when there are no children in the
127: * BranchElement.
128: */
129: public void testGetElementIndex03() {
130: BranchElement root = doc.new BranchElement(null, null);
131: try {
132: assertEquals(0, root.getElementIndex(-1));
133: if (!BasicSwingTestCase.isHarmony()) {
134: fail("NullPointerException should be thrown");
135: }
136: } catch (NullPointerException e) {
137: }
138: try {
139: assertEquals(0, root.getElementIndex(0));
140: if (!BasicSwingTestCase.isHarmony()) {
141: fail("NullPointerException should be thrown");
142: }
143: } catch (NullPointerException e) {
144: }
145: }
146:
147: /**
148: * Tests getElementIndex behavior when there are "gaps" between children.
149: * The document has default length.
150: */
151: public void testGetElementIndex04() throws BadLocationException {
152: final Element[] leaves = new Element[] { createLeaf(1, 2),
153: createLeaf(3, 5), createLeaf(5, 8), createLeaf(15, 20) };
154: assertEquals(14, doc.getLength());
155: par.replace(0, par.getElementCount(), leaves);
156: final int[] indexes = new int[] { 0, 0, 0, 0, 1, // [ 0] - [ 4]
157: 1, 1, 2, 2, 2, // [ 5] - [ 9]
158: 3, 3, 3, 3, 3, // [10] - [14]
159: 3, 3, 3, 3, 3, // [15] - [19]
160: 3, 3, 3, 3, 3 }; // [20] - [24]
161: for (int offset = -2, i = 0; offset < 23; offset++, i++) {
162: assertEquals("offset = " + offset + ", i = " + i,
163: indexes[i], par.getElementIndex(offset));
164: }
165: }
166:
167: /**
168: * Tests getElementIndex behavior when there are "gaps" between children.
169: * The document has zero length.
170: */
171: public void testGetElementIndex05() throws BadLocationException {
172: doc.getContent().remove(0, doc.getLength());
173: assertEquals(0, doc.getLength());
174: final Element[] leaves = new Element[] { createLeaf(1, 2),
175: createLeaf(3, 5), createLeaf(5, 8), createLeaf(15, 20) };
176: par.replace(0, par.getElementCount(), leaves);
177: final int[] indexes = new int[] { 0, 0, 0, 0, 1, // [ 0] - [ 4]
178: 1, 1, 2, 2, 2, // [ 5] - [ 9]
179: 3, 3, 3, 3, 3, // [10] - [14]
180: 3, 3, 3, 3, 3, // [15] - [19]
181: 3, 3, 3, 3, 3 }; // [20] - [24]
182: for (int offset = -2, i = 0; offset < 23; offset++, i++) {
183: assertEquals("offset = " + offset + ", i = " + i,
184: indexes[i], par.getElementIndex(offset));
185: }
186: }
187:
188: /**
189: * Tests getElementIndex behavior when there are no child elements, but
190: * <code>getStartOffset</code> and <code>getEndOffset</code> are overridden
191: * to prevent <code>{@link NullPointerException}</code>.
192: */
193: // Regression for HARMONY-2756
194: public void testGetElementIndex06() {
195: par = doc.new BranchElement(null, null) {
196: private static final long serialVersionUID = 1L;
197:
198: @Override
199: public int getStartOffset() {
200: return 10;
201: }
202:
203: @Override
204: public int getEndOffset() {
205: return 20;
206: }
207: };
208: assertEquals(0, par.getElementIndex(-1));
209: assertEquals(0, par.getElementIndex(0));
210: assertEquals(0, par.getElementIndex(10));
211: assertEquals(0, par.getElementIndex(15));
212: assertEquals(0, par.getElementIndex(20));
213: assertEquals(0, par.getElementIndex(25));
214: }
215:
216: /**
217: * Tests getElementIndex behavior when this BranchElement doesn't span
218: * all the document, it has child elements.
219: */
220: // Regression for HARMONY-2756
221: public void testGetElementIndex07() throws BadLocationException {
222: par = createBranchElement();
223:
224: assertEquals(0, par.getElementIndex(-1));
225: assertEquals(0, par.getElementIndex(0));
226: assertEquals(0, par.getElementIndex(7));
227: assertEquals(1, par.getElementIndex(10));
228: assertEquals(2, par.getElementIndex(13));
229: assertEquals(3, par.getElementIndex(18));
230: assertEquals(3, par.getElementIndex(19));
231: assertEquals(3, par.getElementIndex(20));
232: }
233:
234: public void testIsLeaf() {
235: assertFalse(bidi.isLeaf());
236: assertFalse(par.isLeaf());
237: }
238:
239: public void testGetAllowsChildren() {
240: assertTrue(bidi.getAllowsChildren());
241: assertTrue(par.getAllowsChildren());
242: }
243:
244: public void testGetStartOffset() {
245: assertEquals(0, bidi.getStartOffset());
246: assertEquals(0, par.getStartOffset());
247: }
248:
249: // Regression for HARMONY-2777
250: public void testGetStartOffsetNoChildren() {
251: par = doc.new BranchElement(null, null);
252: try {
253: par.getStartOffset();
254: fail("NullPointerException is expected");
255: } catch (NullPointerException e) {
256: // expected
257: }
258: }
259:
260: public void testGetEndOffset() {
261: assertEquals(15, bidi.getEndOffset());
262: assertEquals(15, par.getEndOffset());
263: }
264:
265: // Regression for HARMONY-2777
266: public void testGetEndOffsetNoChildren() {
267: par = doc.new BranchElement(null, null);
268: try {
269: par.getEndOffset();
270: fail("NullPointerException is expected");
271: } catch (NullPointerException e) {
272: // expected
273: }
274: }
275:
276: public void testGetElementCount() {
277: assertEquals(5, bidi.getElementCount());
278: assertEquals(2, par.getElementCount());
279: }
280:
281: public void testBranchElement() {
282: doc.writeLock();
283: bidi = doc.new BranchElement(par, as[2]);
284: doc.writeUnlock();
285: assertNotSame(as[2], bidi.getAttributes());
286: assertEquals(as[2], bidi.getAttributes());
287: assertSame(par, bidi.getParentElement());
288: assertEquals(0, bidi.getElementCount());
289: assertNull(bidi.getElement(0));
290: Enumeration<?> elements = bidi.children();
291: assertNull(elements);
292: }
293:
294: /**
295: * Generic checks.
296: */
297: public void testReplace01() {
298: assertEquals(5, bidi.getElementCount());
299: bidi.replace(0, bidi.getElementCount(), new Element[] {});
300: assertEquals(0, bidi.getElementCount());
301: assertNull(bidi.children());
302: bidi.replace(0, 0, new Element[] { leaf1, leaf2, leaf3 });
303: assertEquals(3, bidi.getElementCount());
304: bidi = doc.new BranchElement(null, null);
305: assertEquals(0, bidi.getElementCount());
306: bidi.replace(0, 0, new Element[] { leaf2 });
307: }
308:
309: /**
310: * Copy checks.
311: */
312: public void testReplace02() {
313: assertEquals(5, bidi.getElementCount());
314: Element[] copy = new Element[] { bidi.getElement(0),
315: bidi.getElement(1), bidi.getElement(2),
316: bidi.getElement(3), bidi.getElement(4), };
317: bidi.replace(1, 3, new Element[] { leaf2 });
318: assertEquals(3, bidi.getElementCount());
319: assertSame(copy[0], bidi.getElement(0));
320: assertSame(leaf2, bidi.getElement(1));
321: assertSame(copy[4], bidi.getElement(2));
322: }
323:
324: /**
325: * Replace with null.
326: */
327: public void testReplace03() throws Exception {
328: assertEquals(5, bidi.getElementCount());
329: try {
330: bidi.replace(0, 2, null);
331: fail("NPE exception expected");
332: } catch (NullPointerException e) {
333: }
334: /*
335: // When NPE isn't thrown, the following assertion must be true
336: assertEquals(3, bidi.getElementCount());
337: */
338: }
339:
340: // Regression for HARMONY-2459
341: public void testReplace04() {
342: PlainDocument document = new PlainDocument();
343: Element elem = new DummyElement();
344: AbstractDocument.BranchElement branchElem = document.new BranchElement(
345: elem, (AttributeSet) null);
346: Element[] arr0 = new Element[] { null, null, null };
347:
348: try {
349: branchElem.replace(Integer.MIN_VALUE, 5, arr0);
350: fail("ArrayIndexOutOfBoundsException is expected");
351: } catch (ArrayIndexOutOfBoundsException ex) {
352: // valid
353: }
354:
355: try {
356: branchElem.replace(0, -1, arr0);
357: fail("ArrayIndexOutOfBoundsException is expected");
358: } catch (ArrayIndexOutOfBoundsException ex) {
359: // valid
360: }
361:
362: try {
363: branchElem.replace(1, 5, arr0);
364: fail("ArrayIndexOutOfBoundsException is expected");
365: } catch (ArrayIndexOutOfBoundsException ex) {
366: // valid
367: }
368:
369: try {
370: branchElem.replace(0, 2, arr0);
371: fail("ArrayIndexOutOfBoundsException is expected");
372: } catch (ArrayIndexOutOfBoundsException ex) {
373: // valid
374: }
375: }
376:
377: public void testPositionToElement() {
378: assertNull(par.positionToElement(-1));
379: assertSame(leaf2, par.positionToElement(7));
380: assertSame(leaf2, par.positionToElement(8));
381: assertSame(leaf3, par.positionToElement(9));
382: assertSame(leaf3, par.positionToElement(10));
383: assertSame(leaf3, par.positionToElement(11));
384: assertNull(par.positionToElement(20));
385: }
386:
387: /**
388: * Tests <code>positionToElement</code> where the <code>BranchElement</code>
389: * tested doesn't span over the whole document.
390: */
391: public void testPositionToElement_PartialBranch()
392: throws BadLocationException {
393: par = createBranchElement();
394:
395: assertNull(par.positionToElement(6));
396: assertSame(par.getElement(0), par.positionToElement(7));
397: assertSame(par.getElement(1), par.positionToElement(10));
398: assertSame(par.getElement(2), par.positionToElement(13));
399: assertSame(par.getElement(3), par.positionToElement(18));
400: assertNull(par.positionToElement(19));
401: }
402:
403: public void testToString() {
404: assertEquals("BranchElement(bidi root) 0,15\n", bidi.toString());
405: assertEquals("BranchElement(paragraph) 0,15\n", par.toString());
406: }
407:
408: private Element createLeaf(final int start, final int end) {
409: return doc.new LeafElement(par, null, start, end);
410: }
411:
412: /**
413: * Creates <code>BranchElement</code> which doesn't span over the whole document.
414: * <code>DefaultStyledDocument</code> is used to prepare the structure.
415: */
416: private BranchElement createBranchElement()
417: throws BadLocationException {
418: final DefaultStyledDocument styledDoc = new DefaultStyledDocument();
419: doc = styledDoc;
420: doc.insertString(doc.getLength(),
421: "1 line\nonetwothree\n3 line", null);
422: // 0123456 789012345678 901234
423: // 0 1 2
424: styledDoc.setCharacterAttributes(7, 3,
425: SimpleAttributeSet.EMPTY, false);
426: styledDoc.setCharacterAttributes(10, 3,
427: SimpleAttributeSet.EMPTY, false);
428: styledDoc.setCharacterAttributes(13, 5,
429: SimpleAttributeSet.EMPTY, false);
430: return (BranchElement) doc.getDefaultRootElement()
431: .getElement(1);
432: }
433:
434: /**
435: * This class is used by testReplace04
436: */
437: class DummyElement implements Element {
438: public AttributeSet getAttributes() {
439: return null;
440: }
441:
442: public Document getDocument() {
443: return null;
444: }
445:
446: public Element getElement(int p0) {
447: return null;
448: }
449:
450: public int getElementCount() {
451: return 0;
452: }
453:
454: public int getElementIndex(int p0) {
455: return 0;
456: }
457:
458: public int getEndOffset() {
459: return 0;
460: }
461:
462: public String getName() {
463: return "AA";
464: }
465:
466: public Element getParentElement() {
467: return null;
468: }
469:
470: public int getStartOffset() {
471: return 0;
472: }
473:
474: public boolean isLeaf() {
475: return false;
476: }
477: }
478:
479: }
|