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.awt.Color;
023: import javax.swing.BasicSwingTestCase;
024: import javax.swing.text.AbstractDocument.AbstractElement;
025: import junit.framework.TestCase;
026:
027: /**
028: * Tests methods of DefaultStyledDocument which deal with getting paragraph
029: * and character elements, setting their attributes and logical styles.
030: *
031: */
032: public class DefaultStyledDocument_ElementsAndAttributesTest extends
033: TestCase {
034: private DefaultStyledDocument doc;
035:
036: private Element root;
037:
038: private StyleContext styles;
039:
040: private AttributeSet plain;
041:
042: private AttributeSet bold;
043:
044: private AttributeSet italic;
045:
046: private AttributeSet boldItalic;
047:
048: private AttributeSet background;
049:
050: private AttributeSet foreground;
051:
052: private static final class StyledText {
053: public final String text;
054:
055: public final AttributeSet attr;
056:
057: public StyledText(final String text, final AttributeSet attr) {
058: this .text = text;
059: this .attr = attr;
060: }
061: }
062:
063: @Override
064: protected void setUp() throws Exception {
065: super .setUp();
066: styles = new StyleContext();
067: doc = new DefaultStyledDocument(styles);
068: root = doc.getDefaultRootElement();
069: initAttributes();
070: initText();
071: }
072:
073: private void initAttributes() {
074: plain = styles.getEmptySet();
075: bold = styles.addAttribute(plain, StyleConstants.Bold,
076: Boolean.TRUE);
077: italic = styles.addAttribute(plain, StyleConstants.Italic,
078: Boolean.TRUE);
079: boldItalic = styles.addAttribute(bold, StyleConstants.Italic,
080: Boolean.TRUE);
081: foreground = background = styles.getEmptySet();
082: foreground = styles.addAttribute(foreground,
083: StyleConstants.Foreground, Color.CYAN);
084: background = styles.addAttribute(background,
085: StyleConstants.Background, Color.BLUE);
086: }
087:
088: private void initText() throws BadLocationException {
089: final StyledText[] styledText = new StyledText[] {
090: // First paragraph
091: new StyledText("plain", plain),
092: new StyledText("bold", bold),
093: new StyledText("italic\n", italic),
094: // Second and Third
095: new StyledText("Bold & Italic", boldItalic),
096: new StyledText(" & Plain\n", plain),
097: new StyledText("The very plain text", null) };
098: int offset = 0;
099: for (int i = 0; i < styledText.length; i++) {
100: doc.insertString(offset, styledText[i].text,
101: styledText[i].attr);
102: offset += styledText[i].text.length();
103: }
104: }
105:
106: /**
107: * Tests getting the first paragraph.
108: */
109: public void testGetParagraphElement01() {
110: final Element par = doc.getParagraphElement(5);
111: assertSame(root.getElement(0), par);
112: assertFalse(par.isLeaf());
113: assertEquals(3, par.getElementCount());
114: assertEquals(0, par.getStartOffset());
115: assertEquals(16, par.getEndOffset());
116: }
117:
118: /**
119: * Tests getting the second paragraph by its start offset.
120: */
121: public void testGetParagraphElement02() {
122: final Element par = doc.getParagraphElement(16);
123: assertSame(root.getElement(1), par);
124: assertEquals(2, par.getElementCount());
125: }
126:
127: /**
128: * Tests getting paragraph at invalid offset (to the left).
129: */
130: public void testGetParagraphElement03() {
131: final Element par = doc.getParagraphElement(-1);
132: assertSame(root.getElement(0), par);
133: assertEquals(3, par.getElementCount());
134: }
135:
136: /**
137: * Tests getting paragraph at invalid offset (to the right).
138: */
139: public void testGetParagraphElement04() {
140: final Element par = doc
141: .getParagraphElement(doc.getLength() + 2);
142: assertSame(root.getElement(root.getElementCount() - 1), par);
143: assertEquals(BasicSwingTestCase.isHarmony() ? 1 : 2, par
144: .getElementCount());
145: }
146:
147: /**
148: * Tests method getCharacterElement on the first leaf
149: * of the first paragraph.
150: */
151: public void testGetCharacterElement01() {
152: final Element par = doc.getParagraphElement(0);
153: final Element chars = doc.getCharacterElement(2);
154: assertSame(par.getElement(0), chars);
155: assertTrue(chars.isLeaf());
156: assertEquals(0, chars.getStartOffset());
157: assertEquals(5, chars.getEndOffset());
158: }
159:
160: /**
161: * Tests method getCharacterElement on the second leaf
162: * of the first paragraph.
163: */
164: public void testGetCharacterElement02() {
165: final Element par = doc.getParagraphElement(0);
166: final Element chars = doc.getCharacterElement(5);
167: assertSame(par.getElement(1), chars);
168: assertEquals(5, chars.getStartOffset());
169: assertEquals(9, chars.getEndOffset());
170: }
171:
172: /**
173: * Tests method getCharacterElement on the third (last) leaf
174: * of the first paragraph.
175: */
176: public void testGetCharacterElement03() {
177: final Element par = doc.getParagraphElement(0);
178: final Element chars = doc.getCharacterElement(15);
179: assertSame(par.getElement(2), chars);
180: assertEquals(9, chars.getStartOffset());
181: assertEquals(16, chars.getEndOffset());
182: }
183:
184: /**
185: * Tests method getCharacterElement with invalid offset (-1).
186: */
187: public void testGetCharacterElement04() {
188: final Element par = root.getElement(0);
189: final Element chars = doc.getCharacterElement(-1);
190: assertSame(par.getElement(0), chars);
191: }
192:
193: /**
194: * Tests method getCharacterElement with invalid offset (length + 2).
195: */
196: public void testGetCharacterElement05() {
197: final Element par = root.getElement(root.getElementCount() - 1);
198: final Element chars = doc
199: .getCharacterElement(doc.getLength() + 2);
200: assertSame(par.getElement(par.getElementCount() - 1), chars);
201: }
202:
203: /**
204: * General checks for getLogicalStyle().
205: */
206: public void testGetLogicalStyle01() {
207: final StyleContext styles = (StyleContext) doc
208: .getAttributeContext();
209: assertSame(styles.getStyle(StyleContext.DEFAULT_STYLE), doc
210: .getLogicalStyle(5));
211: final Element par = doc.getParagraphElement(5);
212: final AttributeSet parAttrs = par.getAttributes();
213: assertSame(
214: parAttrs.getAttribute(AttributeSet.ResolveAttribute),
215: doc.getLogicalStyle(5));
216: }
217:
218: /**
219: * Checks that logical style is ResolveAttribute of paragraph.
220: */
221: public void testGetLogicalStyle02() {
222: final StyleContext context = new StyleContext();
223: final Style style = context.addStyle("aStyle", null);
224: final AbstractElement par = (AbstractElement) doc
225: .getParagraphElement(5);
226: doc.writeLock();
227: try {
228: par.addAttribute(AttributeSet.ResolveAttribute, style);
229: assertSame(style, doc.getLogicalStyle(5));
230: } finally {
231: doc.writeUnlock();
232: }
233: }
234:
235: /**
236: * Checks what happens when ResolveAttribute of a paragraph is set
237: * to non-Style object.
238: */
239: public void testGetLogicalStyle03() {
240: final AbstractElement par = (AbstractElement) doc
241: .getParagraphElement(5);
242: final MutableAttributeSet set = new SimpleAttributeSet();
243: StyleConstants.setForeground(set, Color.GREEN);
244: StyleConstants.setBackground(set, Color.YELLOW);
245: doc.writeLock();
246: try {
247: set.setResolveParent(boldItalic);
248: par.setResolveParent(set);
249: assertSame(set, par.getResolveParent());
250: assertNull(doc.getLogicalStyle(5));
251: } finally {
252: doc.writeUnlock();
253: }
254: }
255:
256: /**
257: * Checks what happens when getLogicalStyle is called with invalid offset.
258: */
259: public void testGetLogicalStyle04() {
260: final Style defaultStyle = doc
261: .getStyle(StyleContext.DEFAULT_STYLE);
262: assertSame(defaultStyle, doc.getLogicalStyle(-2));
263: assertSame(defaultStyle, doc
264: .getLogicalStyle(doc.getLength() + 2));
265: }
266:
267: /**
268: * Adding character attributes. Tests attribute sets of the elements.
269: */
270: public void testSetCharacterAttributes01() {
271: doc.setCharacterAttributes(3, 8, foreground, false);
272: final Element par = doc.getParagraphElement(0);
273: assertEquals(5, par.getElementCount());
274: assertEquals(plain, par.getElement(0).getAttributes());
275: assertEquals(foreground, par.getElement(1).getAttributes());
276: assertEquals(styles.addAttributes(bold, foreground), par
277: .getElement(2).getAttributes());
278: assertEquals(styles.addAttributes(italic, foreground), par
279: .getElement(3).getAttributes());
280: assertEquals(italic, par.getElement(4).getAttributes());
281: }
282:
283: /**
284: * Adding character attributes. Tests the resulting offsets of
285: * the elements.
286: */
287: public void testSetCharacterAttributes02() {
288: doc.setCharacterAttributes(3, 8, foreground, false);
289: final Element par = doc.getParagraphElement(0);
290: assertEquals(5, par.getElementCount());
291: Element span = par.getElement(0); // Plain (no attributes)
292: assertEquals(0, span.getStartOffset());
293: assertEquals(3, span.getEndOffset());
294: span = par.getElement(1); // Foreground only
295: assertEquals(3, span.getStartOffset());
296: assertEquals(5, span.getEndOffset());
297: span = par.getElement(2); // Bold + Foreground
298: assertEquals(5, span.getStartOffset());
299: assertEquals(9, span.getEndOffset());
300: span = par.getElement(3); // Italic + Foreground
301: assertEquals(9, span.getStartOffset());
302: assertEquals(11, span.getEndOffset());
303: span = par.getElement(4); // Italic only
304: assertEquals(11, span.getStartOffset());
305: assertEquals(16, span.getEndOffset());
306: }
307:
308: /**
309: * Replacing character attributes. Tests attribute sets of the elements.
310: *
311: * It seems like the elements with equal attribute sets should be combined.
312: */
313: public void testSetCharacterAttributes03() {
314: doc.setCharacterAttributes(3, 8, background, true);
315: final Element par = doc.getParagraphElement(0);
316: assertEquals(5, par.getElementCount());
317: assertEquals(plain, par.getElement(0).getAttributes());
318: assertEquals(background, par.getElement(1).getAttributes());
319: assertEquals(background, par.getElement(2).getAttributes());
320: assertEquals(background, par.getElement(3).getAttributes());
321: assertEquals(italic, par.getElement(4).getAttributes());
322: }
323:
324: /**
325: * Replacing character attributes. Tests the resulting offsets of
326: * the elements.
327: */
328: public void testSetCharacterAttributes04() {
329: doc.setCharacterAttributes(3, 8, background, true);
330: final Element par = doc.getParagraphElement(0);
331: assertEquals(5, par.getElementCount());
332: Element span = par.getElement(0); // Plain (no attributes)
333: assertEquals(0, span.getStartOffset());
334: assertEquals(3, span.getEndOffset());
335: span = par.getElement(1); // Background only
336: assertEquals(3, span.getStartOffset());
337: assertEquals(5, span.getEndOffset());
338: span = par.getElement(2); // Background only
339: assertEquals(5, span.getStartOffset());
340: assertEquals(9, span.getEndOffset());
341: span = par.getElement(3); // Background only
342: assertEquals(9, span.getStartOffset());
343: assertEquals(11, span.getEndOffset());
344: span = par.getElement(4); // Italic only
345: assertEquals(11, span.getStartOffset());
346: assertEquals(16, span.getEndOffset());
347: }
348:
349: /**
350: * Adds character attributes with <code>null</code> attributes.
351: * <code>replace</code> is <code>false</code>.
352: */
353: public void testSetCharacterAttributes05() {
354: try {
355: doc.setCharacterAttributes(3, 8, null, false);
356: fail("NullPointerException is expected.");
357: } catch (NullPointerException e) {
358: }
359: }
360:
361: /**
362: * Adds character attributes with <code>null</code> attributes.
363: * <code>replace</code> is <code>true</code>.
364: */
365: public void testSetCharacterAttributes06() {
366: try {
367: doc.setCharacterAttributes(3, 8, null, true);
368: fail("NullPointerException is expected.");
369: } catch (NullPointerException e) {
370: }
371: }
372:
373: public void testSetLogicalStyle() {
374: final StyleContext context = new StyleContext();
375: final Style logicalStyle = context.addStyle("aStyle", null);
376: logicalStyle
377: .addAttribute(StyleConstants.Foreground, Color.CYAN);
378: logicalStyle
379: .addAttribute(StyleConstants.Background, Color.BLUE);
380: doc.setLogicalStyle(16, logicalStyle);
381: assertNotSame(logicalStyle, doc.getLogicalStyle(15)); // 1st par end - 1
382: assertSame(logicalStyle, doc.getLogicalStyle(16)); // 2nd par start
383: assertSame(logicalStyle, doc.getLogicalStyle(37)); // 2nd par end - 1
384: assertNotSame(logicalStyle, doc.getLogicalStyle(38)); // 3rd par start
385: assertSame(doc.getStyle(StyleContext.DEFAULT_STYLE), doc
386: .getLogicalStyle(38));
387: }
388:
389: public void testSetLogicalStyleInvalid() {
390: final StyleContext context = new StyleContext();
391: final Style logicalStyle = context.addStyle("aStyle", null);
392: logicalStyle
393: .addAttribute(StyleConstants.Foreground, Color.CYAN);
394: logicalStyle
395: .addAttribute(StyleConstants.Background, Color.BLUE);
396: final Style defaultStyle = doc
397: .getStyle(StyleContext.DEFAULT_STYLE);
398: doc.setLogicalStyle(-2, logicalStyle);
399: assertSame(logicalStyle, doc.getLogicalStyle(0)); // 1st par end - 1
400: assertSame(defaultStyle, doc.getLogicalStyle(16)); // 2nd par start
401: assertSame(defaultStyle, doc.getLogicalStyle(37)); // 2nd par end - 1
402: assertSame(defaultStyle, doc.getLogicalStyle(38));
403: doc.setLogicalStyle(doc.getLength() + 2, logicalStyle);
404: assertSame(logicalStyle, doc.getLogicalStyle(doc.getLength()));
405: }
406:
407: /**
408: * Adds paragraph attributes to only one paragraph.
409: */
410: public void testSetParagraphAttributes01() {
411: doc.setParagraphAttributes(3, 13, foreground, false);
412: assertFalse(doc.getLogicalStyle(3).containsAttributes(
413: foreground));
414: // The paragraph itself contains attributes, but not its resolve parent
415: assertTrue(root.getElement(0).getAttributes()
416: .containsAttributes(foreground));
417: assertFalse(root.getElement(1).getAttributes()
418: .containsAttributes(foreground));
419: assertFalse(root.getElement(2).getAttributes()
420: .containsAttributes(foreground));
421: }
422:
423: /**
424: * Adds paragraph attributes to only one paragraph.
425: */
426: public void testSetParagraphAttributes02() {
427: doc.setParagraphAttributes(3, 14, foreground, false);
428: assertFalse(doc.getLogicalStyle(3).containsAttributes(
429: foreground));
430: assertFalse(doc.getLogicalStyle(3 + 14).containsAttributes(
431: foreground));
432: assertTrue(root.getElement(0).getAttributes()
433: .containsAttributes(foreground));
434: assertTrue(root.getElement(1).getAttributes()
435: .containsAttributes(foreground));
436: assertFalse(root.getElement(2).getAttributes()
437: .containsAttributes(foreground));
438: }
439:
440: /**
441: * Tests setParagraphAttributes when <code>replace</code> is
442: * <code>true</code>.
443: */
444: public void testSetParagraphAttributes03() {
445: doc.setParagraphAttributes(3, 1, foreground, false);
446: doc.setParagraphAttributes(3, 1, background, true);
447: // The attributes fully replaced including resolve parent
448: assertNull(doc.getLogicalStyle(3));
449: assertEquals(background, root.getElement(0).getAttributes());
450: final Style defaultStyle = doc
451: .getStyle(StyleContext.DEFAULT_STYLE);
452: assertSame(defaultStyle, doc.getLogicalStyle(16));
453: assertSame(defaultStyle, doc.getLogicalStyle(38));
454: }
455:
456: /**
457: * Tests setParagraphAttributes with null argument.
458: */
459: public void testSetParagraphAttributes04() {
460: try {
461: doc.setParagraphAttributes(3, 1, null, false);
462: fail("NullPointerException is expected");
463: } catch (NullPointerException e) {
464: }
465: }
466: }
467: /* The dump of the document used in these tests (after setUp()).
468:
469: <section>
470: <paragraph
471: resolver=NamedStyle:default {name=default,}
472: >
473: <content>
474: [0,5][plain]
475: <content
476: bold=true
477: >
478: [5,9][bold]
479: <content
480: italic=true
481: >
482: [9,16][italic
483: ]
484: <paragraph
485: resolver=NamedStyle:default {name=default,}
486: >
487: <content
488: bold=true
489: italic=true
490: >
491: [16,29][Bold & Italic]
492: <content>
493: [29,38][ & Plain
494: ]
495: <paragraph
496: resolver=NamedStyle:default {name=default,}
497: >
498: <content>
499: [38,57][The very plain text]
500: <content>
501: [57,58][
502: ]
503: <bidi root>
504: <bidi level
505: bidiLevel=0
506: >
507: [0,58][plainbolditalic
508: Bold & Italic & Plain
509: Th...]
510:
511: */
|