KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > editor > lib2 > highlighting > CompoundHighlightsContainerTest


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 /*
21  * ProxyHighlightLayerTest.java
22  * JUnit based test
23  *
24  * Created on June 28, 2006, 5:44 PM
25  */

26
27 package org.netbeans.modules.editor.lib2.highlighting;
28
29 import java.lang.reflect.InvocationTargetException JavaDoc;
30 import java.lang.reflect.Method JavaDoc;
31 import java.util.ArrayList JavaDoc;
32 import java.util.ConcurrentModificationException JavaDoc;
33 import java.util.Enumeration JavaDoc;
34 import java.util.Random JavaDoc;
35 import javax.swing.text.AttributeSet JavaDoc;
36 import javax.swing.text.Document JavaDoc;
37 import javax.swing.text.PlainDocument JavaDoc;
38 import javax.swing.text.Position JavaDoc;
39 import javax.swing.text.SimpleAttributeSet JavaDoc;
40 import org.netbeans.api.editor.settings.AttributesUtilities;
41 import org.netbeans.spi.editor.highlighting.support.PositionsBag;
42 import org.netbeans.spi.editor.highlighting.HighlightsContainer;
43 import org.netbeans.spi.editor.highlighting.HighlightsChangeEvent;
44 import org.netbeans.spi.editor.highlighting.HighlightsChangeListener;
45 import org.netbeans.spi.editor.highlighting.HighlightsSequence;
46 import org.netbeans.junit.NbTestCase;
47
48 /**
49  *
50  * @author vita
51  */

52 public class CompoundHighlightsContainerTest extends NbTestCase {
53     
54     public CompoundHighlightsContainerTest(String JavaDoc testName) {
55         super(testName);
56     }
57
58     public void testSimple() {
59         PlainDocument JavaDoc doc = new PlainDocument JavaDoc();
60         HighlightsContainer layer = createRandomBag(doc, "layer");
61         HighlightsSequence highlights = layer.getHighlights(0, 100);
62         
63         CompoundHighlightsContainer proxyLayer = new CompoundHighlightsContainer(doc, new HighlightsContainer [] { layer });
64         HighlightsSequence proxyHighlights = proxyLayer.getHighlights(0, 100);
65
66         for ( ; highlights.moveNext(); ) {
67             // Ignore empty highlights
68
if (highlights.getStartOffset() == highlights.getEndOffset()) {
69                 continue;
70             }
71
72             assertTrue("Wrong number of proxy highlights", proxyHighlights.moveNext());
73
74             assertEquals("Start offset does not match", highlights.getStartOffset(), proxyHighlights.getStartOffset());
75             assertEquals("End offset does not match", highlights.getEndOffset(), proxyHighlights.getEndOffset());
76             assertTrue("Attributes do not match", highlights.getAttributes().isEqual(proxyHighlights.getAttributes()));
77         }
78     }
79
80     public void testOrdering() {
81         PlainDocument JavaDoc doc = new PlainDocument JavaDoc();
82         PositionsBag hsA = new PositionsBag(doc);
83         PositionsBag hsB = new PositionsBag(doc);
84
85         SimpleAttributeSet JavaDoc attribsA = new SimpleAttributeSet JavaDoc();
86         SimpleAttributeSet JavaDoc attribsB = new SimpleAttributeSet JavaDoc();
87         
88         attribsA.addAttribute("attribute", "value-A");
89         attribsB.addAttribute("attribute", "value-B");
90         
91         hsA.addHighlight(new SimplePosition(5), new SimplePosition(15), attribsA);
92         hsB.addHighlight(new SimplePosition(10), new SimplePosition(20), attribsB);
93         
94         CompoundHighlightsContainer chc = new CompoundHighlightsContainer(doc, new HighlightsContainer [] { hsA, hsB });
95         HighlightsSequence highlights = chc.getHighlights(0, Integer.MAX_VALUE);
96
97         assertTrue("Wrong number of highlights", highlights.moveNext());
98         assertEquals("1. highlight - wrong attribs", "value-A", highlights.getAttributes().getAttribute("attribute"));
99
100         assertTrue("Wrong number of highlights", highlights.moveNext());
101         assertEquals("2. highlight - wrong attribs", "value-B", highlights.getAttributes().getAttribute("attribute"));
102
103         assertTrue("Wrong number of highlights", highlights.moveNext());
104         assertEquals("3. highlight - wrong attribs", "value-B", highlights.getAttributes().getAttribute("attribute"));
105     }
106
107     public void testConcurrentModification() throws Exception JavaDoc {
108         checkConcurrentModificationOnMethod("moveNext");
109         checkConcurrentModificationOnMethod("getStartOffset");
110         checkConcurrentModificationOnMethod("getEndOffset");
111         checkConcurrentModificationOnMethod("getAttributes");
112     }
113
114     private void checkConcurrentModificationOnMethod(String JavaDoc methodName) throws Exception JavaDoc {
115         PlainDocument JavaDoc doc = new PlainDocument JavaDoc();
116         PositionsBag bag = createRandomBag(doc, "layer");
117         HighlightsContainer [] layers = new HighlightsContainer [] { bag };
118         
119         {
120             CompoundHighlightsContainer hb = new CompoundHighlightsContainer(doc, layers);
121             HighlightsSequence hs = hb.getHighlights(0, Integer.MAX_VALUE);
122
123             // Change the layers
124
hb.setLayers(doc, layers);
125
126             Throwable JavaDoc exc = null;
127             try {
128                 Method JavaDoc m = hs.getClass().getMethod(methodName);
129                 m.invoke(hs);
130             } catch (InvocationTargetException JavaDoc e) {
131                 exc = e.getCause();
132             }
133
134             assertTrue("ConcurrentModificationException has not been thrown from " +
135                 methodName + "() after setLayers", exc instanceof ConcurrentModificationException JavaDoc);
136         }
137         {
138             CompoundHighlightsContainer hb = new CompoundHighlightsContainer(doc, layers);
139             HighlightsSequence hs = hb.getHighlights(0, Integer.MAX_VALUE);
140
141             // Modify the bag
142
bag.addHighlight(new SimplePosition(20), new SimplePosition(30), SimpleAttributeSet.EMPTY);
143
144             Throwable JavaDoc exc = null;
145             try {
146                 Method JavaDoc m = hs.getClass().getMethod(methodName);
147                 m.invoke(hs);
148             } catch (InvocationTargetException JavaDoc e) {
149                 exc = e.getCause();
150             }
151             
152             assertTrue("ConcurrentModificationException has not been thrown from " +
153                 methodName + "() after changing the original bag",
154                 exc instanceof ConcurrentModificationException JavaDoc);
155         }
156     }
157     
158     public void testRandomMerging() {
159         String JavaDoc [] layerNames = new String JavaDoc [] {
160             "layer-1",
161             "layer-2",
162             "layer-3",
163         };
164         
165         PlainDocument JavaDoc doc = new PlainDocument JavaDoc();
166         HighlightsContainer [] layers = new HighlightsContainer [layerNames.length];
167         for(int i = 0; i < layers.length; i++) {
168             layers[i] = createRandomBag(doc, layerNames[i]);
169         };
170         
171         CompoundHighlightsContainer proxyLayer = new CompoundHighlightsContainer(doc, layers);
172         
173         for (int pointer = 0; pointer <= 100; pointer++) {
174             
175             // Check the highlights
176
String JavaDoc failMsg = null;
177             Highlight [] highestPair = new Highlight [] { null, null };
178             Highlight [] proxyPair = new Highlight [] { null, null };
179             
180             
181             try {
182                 highestPair = new Highlight [] { null, null };
183                 proxyPair = new Highlight [] { null, null };
184                 
185                 // Find all highlights at the position
186
ArrayList JavaDoc<AttributeSet JavaDoc> leftHighlights = new ArrayList JavaDoc<AttributeSet JavaDoc>();
187                 ArrayList JavaDoc<AttributeSet JavaDoc> rightHighlights = new ArrayList JavaDoc<AttributeSet JavaDoc>();
188                 for (int i = 0; i < layers.length; i++) {
189                     Highlight [] layerPair = findPair(pointer, layers[i].getHighlights(0, 100));
190                     if (layerPair[0] != null) {
191                         leftHighlights.add(layerPair[0].getAttributes());
192                     }
193                     if (layerPair[1] != null) {
194                         rightHighlights.add(layerPair[1].getAttributes());
195                     }
196                 }
197                 
198                 if (!leftHighlights.isEmpty()) {
199                     highestPair[0] = new Highlight(pointer, pointer, AttributesUtilities.createComposite(
200                         leftHighlights.toArray(new AttributeSet JavaDoc[leftHighlights.size()])));
201                 }
202                 if (!rightHighlights.isEmpty()) {
203                     highestPair[1] = new Highlight(pointer, pointer, AttributesUtilities.createComposite(
204                         rightHighlights.toArray(new AttributeSet JavaDoc[rightHighlights.size()])));
205                 }
206                 
207                 // Find the proxy layer highlight at the position
208
proxyPair = findPair(pointer, proxyLayer.getHighlights(0, 100));
209
210                 for (int i = 0; i < 2; i++) {
211                     if (highestPair[i] != null && proxyPair[i] != null) {
212                         // Both highlights exist -> check they are the same
213
if (!highestPair[i].getAttributes().isEqual(proxyPair[i].getAttributes())) {
214                             failMsg = (i == 0 ? "Left" : "Right") + "pair attributes do not match";
215                         }
216                     } else if (highestPair[i] != null || proxyPair[i] != null) {
217                         // Both highlights should be null otherwise they would not match
218
failMsg = (i == 0 ? "Left" : "Right") + " highlight doesn't match";
219                     }
220                 }
221             } catch (Throwable JavaDoc e) {
222                 failMsg = e.getMessage();
223             }
224             
225             if (failMsg != null) {
226                 // Dump the layers
227
System.out.println("Dumping layers:");
228                 for (int i = 0; i < layers.length; i++) {
229                     System.out.println(" layer[" + i + "] = " + layerNames[i] + "{");
230                     for (HighlightsSequence highlights = layers[i].getHighlights(0, 100); highlights.moveNext(); ) {
231                         Highlight h = copyCurrentHighlight(highlights);
232                         System.out.println(" " + dumpHighlight(h));
233                     }
234                     System.out.println(" } End of layer[" + i + "] -----------------");
235                 }
236                 System.out.println("Dumping proxy layer: {");
237                 for (HighlightsSequence proxyHighlights = proxyLayer.getHighlights(0, 100); proxyHighlights.moveNext(); ) {
238                     Highlight h = copyCurrentHighlight(proxyHighlights);
239                     System.out.println(" " + dumpHighlight(h));
240                 }
241                 System.out.println("} End of proxy layer -----------------------");
242
243                 // Dump the pair that failed
244
System.out.println("highest pair (pos = " + pointer + ") : " + dumpHighlight(highestPair[0]) + ", " + dumpHighlight(highestPair[1]));
245                 System.out.println(" proxy pair (pos = " + pointer + ") : " + dumpHighlight(proxyPair[0]) + ", " + dumpHighlight(proxyPair[1]));
246
247                 fail(failMsg + " (position = " + pointer + ")");
248             }
249         }
250     }
251
252     public void testEvents() {
253         PlainDocument JavaDoc doc = new PlainDocument JavaDoc();
254         PositionsBag hsA = new PositionsBag(doc);
255         PositionsBag hsB = new PositionsBag(doc);
256         
257         CompoundHighlightsContainer chc = new CompoundHighlightsContainer(doc, new HighlightsContainer [] { hsA, hsB });
258         Listener listener = new Listener();
259         chc.addHighlightsChangeListener(listener);
260         
261         hsA.addHighlight(new SimplePosition(10), new SimplePosition(20), new SimpleAttributeSet JavaDoc());
262         assertEquals("Wrong number of events", 1, listener.eventsCnt);
263         assertEquals("Wrong change start offset", 10, listener.lastEventStartOffset);
264         assertEquals("Wrong change end offset", 20, listener.lastEventEndOffset);
265
266         listener.reset();
267         hsB.addHighlight(new SimplePosition(11), new SimplePosition(12), new SimpleAttributeSet JavaDoc());
268         assertEquals("Wrong number of events", 1, listener.eventsCnt);
269         assertEquals("Wrong change start offset", 11, listener.lastEventStartOffset);
270         assertEquals("Wrong change end offset", 12, listener.lastEventEndOffset);
271     }
272
273     public void testEvents2() {
274         PlainDocument JavaDoc doc = new PlainDocument JavaDoc();
275         PositionsBag hsA = new PositionsBag(doc);
276         PositionsBag hsB = new PositionsBag(doc);
277
278         hsA.addHighlight(new SimplePosition(10), new SimplePosition(20), new SimpleAttributeSet JavaDoc());
279         hsB.addHighlight(new SimplePosition(11), new SimplePosition(12), new SimpleAttributeSet JavaDoc());
280
281         CompoundHighlightsContainer chc = new CompoundHighlightsContainer();
282         Listener listener = new Listener();
283         chc.addHighlightsChangeListener(listener);
284
285         // changing delegate layers fires event covering 'all' offsets
286
chc.setLayers(doc, new HighlightsContainer [] { hsA, hsB });
287         assertEquals("Wrong number of events", 1, listener.eventsCnt);
288         assertEquals("Wrong change start offset", 0, listener.lastEventStartOffset);
289         assertEquals("Wrong change end offset", Integer.MAX_VALUE, listener.lastEventEndOffset);
290     }
291     
292     private Highlight [] findPair(int offset, HighlightsSequence highlights) {
293         Highlight left = null;
294         Highlight right = null;
295         
296         for ( ; highlights.moveNext(); ) {
297             if (highlights.getStartOffset() == highlights.getEndOffset()) {
298                 // ignore empty offsets
299
continue;
300             }
301             
302             if (offset > highlights.getStartOffset() && offset < highlights.getEndOffset()) {
303                 left = right = copyCurrentHighlight(highlights);
304             } else if (offset == highlights.getEndOffset()) {
305                 left = copyCurrentHighlight(highlights);
306             } else if (offset == highlights.getStartOffset()) {
307                 right = copyCurrentHighlight(highlights);
308             }
309         }
310         
311         return new Highlight [] { left, right };
312     }
313
314     private Highlight copyCurrentHighlight(HighlightsSequence iterator) {
315         return new Highlight(
316             iterator.getStartOffset(),
317             iterator.getEndOffset(),
318             iterator.getAttributes()
319         );
320     }
321     
322     private String JavaDoc dumpHighlight(Highlight h) {
323         if (h == null) {
324             return "< , , >";
325         } else {
326             StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
327
328             sb.append("<");
329             sb.append(h.getStartOffset());
330             sb.append(",");
331             sb.append(h.getEndOffset());
332             sb.append(",");
333             
334             Enumeration JavaDoc en = h.getAttributes().getAttributeNames();
335             while (en.hasMoreElements()) {
336                 Object JavaDoc attrName = en.nextElement();
337                 Object JavaDoc attrValue = h.getAttributes().getAttribute(attrName);
338
339                 sb.append("'");
340                 sb.append(attrName.toString());
341                 sb.append("' = '");
342                 sb.append(attrValue == null ? "null" : attrValue.toString());
343                 sb.append("'");
344                 if (en.hasMoreElements()) {
345                     sb.append(", ");
346                 }
347             }
348
349             sb.append(">");
350             
351             return sb.toString();
352         }
353     }
354     
355     private PositionsBag createRandomBag(Document JavaDoc doc, String JavaDoc bagId) {
356
357         PositionsBag bag = new PositionsBag(doc, false);
358
359         Random JavaDoc rand = new Random JavaDoc(System.currentTimeMillis());
360         int attrIdx = 0;
361         int startOffset = 0;
362         int endOffset = 100;
363
364         int maxGapSize = Math.max((int) (endOffset - startOffset) / 10, 1);
365         int maxHighlightSize = Math.max((int) (endOffset - startOffset) / 2, 1);
366
367         for (int pointer = startOffset + rand.nextInt(maxGapSize); pointer <= endOffset; ) {
368             int highlightSize = rand.nextInt(maxHighlightSize);
369             SimpleAttributeSet JavaDoc attributes = new SimpleAttributeSet JavaDoc();
370             attributes.addAttribute("AttrName-" + bagId + "-" + attrIdx, "AttrValue");
371             attrIdx++;
372
373             if (pointer + highlightSize < endOffset) {
374                 bag.addHighlight(
375                     new SimplePosition(pointer), new SimplePosition(pointer + highlightSize), attributes);
376             } else {
377                 bag.addHighlight(
378                     new SimplePosition(pointer), new SimplePosition(endOffset), attributes);
379             }
380
381             // move the pointer
382
pointer += highlightSize + rand.nextInt(maxGapSize);
383         }
384         
385         return bag;
386     }
387
388     private static final class Highlight {
389         private int startOffset;
390         private int endOffset;
391         private AttributeSet JavaDoc attributes;
392         
393         public Highlight(int startOffset, int endOffset, AttributeSet JavaDoc attributes) {
394             this.startOffset = startOffset;
395             this.endOffset = endOffset;
396             this.attributes = attributes;
397         }
398
399         public int getStartOffset() {
400             return startOffset;
401         }
402
403         public void setStartOffset(int startOffset) {
404             this.startOffset = startOffset;
405         }
406
407         public int getEndOffset() {
408             return endOffset;
409         }
410
411         public void setEndOffset(int endOffset) {
412             this.endOffset = endOffset;
413         }
414
415         public AttributeSet JavaDoc getAttributes() {
416             return attributes;
417         }
418
419         public void setAttributes(AttributeSet JavaDoc attributes) {
420             this.attributes = attributes;
421         }
422         
423     } // End of H class
424

425     private static final class Listener implements HighlightsChangeListener {
426         public int eventsCnt = 0;
427         public int lastEventStartOffset = 0;
428         public int lastEventEndOffset = 0;
429         
430         public void highlightChanged(HighlightsChangeEvent event) {
431             eventsCnt++;
432             lastEventStartOffset = event.getStartOffset();
433             lastEventEndOffset = event.getEndOffset();
434         }
435         
436         public void reset() {
437             eventsCnt = 0;
438             lastEventStartOffset = 0;
439             lastEventEndOffset = 0;
440         }
441     } // End of Listener class
442

443     private static final class SimplePosition implements Position JavaDoc {
444         private int offset;
445         
446         public SimplePosition(int offset) {
447             this.offset = offset;
448         }
449         
450         public int getOffset() {
451             return offset;
452         }
453     } // End of SimplePosition class
454

455     private void dumpHighlights(HighlightsSequence seq) {
456         System.out.println("Dumping highlights from: " + seq + "{");
457         while(seq.moveNext()) {
458             System.out.println("<" + seq.getStartOffset() + ", " + seq.getEndOffset() + ", " + seq.getAttributes() + ">");
459         }
460         System.out.println("} --- End of Dumping highlights from: " + seq + " ---------------------");
461     }
462 }
463
Popular Tags