Author: ltheussl
Date: Sat Mar 28 20:54:39 2009
New Revision: 759584

URL: http://svn.apache.org/viewvc?rev=759584&view=rev
Log:
Fix some problems in SinkEventAttributeSet:
 o make it Cloneable
 o add a method to make it unmodifiable
 o make all static fields unmodifiable
 o add attribute values as Objects, not Strings
 o fix potential NPEs in clone() and hashCode()

Added:
    
maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/SinkEventAttributeSetTest.java
   (with props)
Modified:
    
maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/SinkEventAttributeSet.java

Modified: 
maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/SinkEventAttributeSet.java
URL: 
http://svn.apache.org/viewvc/maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/SinkEventAttributeSet.java?rev=759584&r1=759583&r2=759584&view=diff
==============================================================================
--- 
maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/SinkEventAttributeSet.java
 (original)
+++ 
maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/SinkEventAttributeSet.java
 Sat Mar 28 20:54:39 2009
@@ -22,6 +22,7 @@
 import java.util.Collections;
 import java.util.Enumeration;
 import java.util.LinkedHashMap;
+import java.util.Map;
 
 import javax.swing.text.AttributeSet;
 
@@ -33,82 +34,82 @@
  * @since 1.1
  */
 public class SinkEventAttributeSet
-    implements SinkEventAttributes
+    implements SinkEventAttributes, Cloneable
 {
     /**
-     * An attribute set containing only an underline attribute.
+     * An unmodifiable attribute set containing only an underline attribute.
      */
     public static final SinkEventAttributes UNDERLINE;
 
     /**
-     * An attribute set containing only an overline attribute.
+     * An unmodifiable attribute set containing only an overline attribute.
      */
     public static final SinkEventAttributes OVERLINE;
 
     /**
-     * An attribute set containing only a linethrough attribute.
+     * An unmodifiable attribute set containing only a linethrough attribute.
      */
     public static final SinkEventAttributes LINETHROUGH;
 
     /**
-     * An attribute set containing only a boxed attribute.
+     * An unmodifiable attribute set containing only a boxed attribute.
      */
     public static final SinkEventAttributes BOXED;
 
     /**
-     * An attribute set containing only a bold attribute.
+     * An unmodifiable attribute set containing only a bold attribute.
      */
     public static final SinkEventAttributes BOLD;
 
     /**
-     * An attribute set containing only an italic attribute.
+     * An unmodifiable attribute set containing only an italic attribute.
      */
     public static final SinkEventAttributes ITALIC;
 
     /**
-     * An attribute set containing only a monospaced attribute.
+     * An unmodifiable attribute set containing only a monospaced attribute.
      */
     public static final SinkEventAttributes MONOSPACED;
 
     /**
-     * An attribute set containing only a left attribute.
+     * An unmodifiable attribute set containing only a left attribute.
      */
     public static final SinkEventAttributes LEFT;
 
     /**
-     * An attribute set containing only a right attribute.
+     * An unmodifiable attribute set containing only a right attribute.
      */
     public static final SinkEventAttributes RIGHT;
 
     /**
-     * An attribute set containing only a center attribute.
+     * An unmodifiable attribute set containing only a center attribute.
      */
     public static final SinkEventAttributes CENTER;
 
     /**
-     * An attribute set containing only a justify attribute.
+     * An unmodifiable attribute set containing only a justify attribute.
      */
     public static final SinkEventAttributes JUSTIFY;
 
 
     static
     {
-        UNDERLINE = new SinkEventAttributeSet( new String[] {DECORATION, 
"underline"} );
-        OVERLINE = new SinkEventAttributeSet( new String[] {DECORATION, 
"overline"} );
-        LINETHROUGH = new SinkEventAttributeSet( new String[] {DECORATION, 
"line-through"} );
-        BOXED = new SinkEventAttributeSet( new String[] {DECORATION, "boxed"} 
);
-
-        BOLD = new SinkEventAttributeSet( new String[] {STYLE, "bold"} );
-        ITALIC = new SinkEventAttributeSet( new String[] {STYLE, "italic"} );
-        MONOSPACED = new SinkEventAttributeSet( new String[] {STYLE, 
"monospaced"} );
-
-        LEFT = new SinkEventAttributeSet( new String[] {ALIGN, "left"} );
-        RIGHT = new SinkEventAttributeSet( new String[] {ALIGN, "right"} );
-        CENTER = new SinkEventAttributeSet( new String[] {ALIGN, "center"} );
-        JUSTIFY = new SinkEventAttributeSet( new String[] {ALIGN, "justify"} );
+        UNDERLINE = new SinkEventAttributeSet( new String[] {DECORATION, 
"underline"} ).unmodifiable();
+        OVERLINE = new SinkEventAttributeSet( new String[] {DECORATION, 
"overline"} ).unmodifiable();
+        LINETHROUGH = new SinkEventAttributeSet( new String[] {DECORATION, 
"line-through"} ).unmodifiable();
+        BOXED = new SinkEventAttributeSet( new String[] {DECORATION, "boxed"} 
).unmodifiable();
+
+        BOLD = new SinkEventAttributeSet( new String[] {STYLE, "bold"} 
).unmodifiable();
+        ITALIC = new SinkEventAttributeSet( new String[] {STYLE, "italic"} 
).unmodifiable();
+        MONOSPACED = new SinkEventAttributeSet( new String[] {STYLE, 
"monospaced"} ).unmodifiable();
+
+        LEFT = new SinkEventAttributeSet( new String[] {ALIGN, "left"} 
).unmodifiable();
+        RIGHT = new SinkEventAttributeSet( new String[] {ALIGN, "right"} 
).unmodifiable();
+        CENTER = new SinkEventAttributeSet( new String[] {ALIGN, "center"} 
).unmodifiable();
+        JUSTIFY = new SinkEventAttributeSet( new String[] {ALIGN, "justify"} 
).unmodifiable();
     }
 
-    private LinkedHashMap attribs;
+    private Map attribs;
 
     private AttributeSet resolveParent;
 
@@ -175,6 +176,20 @@
     }
 
     /**
+     * Replace this AttributeSet by an unmodifiable view of itself.
+     * Any subsequent attempt to add, remove or modify the underlying mapping
+     * will result in an UnsupportedOperationException.
+     *
+     * @return an unmodifiable view of this AttributeSet.
+     */
+    public SinkEventAttributeSet unmodifiable()
+    {
+        this.attribs = Collections.unmodifiableMap( attribs );
+
+        return this;
+    }
+
+    /**
      * Checks whether the set of attribs is empty.
      *
      * @return true if the set is empty.
@@ -262,7 +277,7 @@
      */
     public void addAttribute( Object name, Object value )
     {
-        attribs.put( name.toString(), value.toString() );
+        attribs.put( name.toString(), value );
     }
 
     /** {...@inheritdoc} */
@@ -341,18 +356,13 @@
     /** {...@inheritdoc} */
     public Object clone()
     {
-        SinkEventAttributeSet attr;
+        SinkEventAttributeSet attr = new SinkEventAttributeSet( attribs.size() 
);
+        attr.attribs = new LinkedHashMap( attribs );
 
-        try
+        if ( resolveParent != null )
         {
-            attr = (SinkEventAttributeSet) super.clone();
-            attr.attribs = (LinkedHashMap) attribs.clone();
             attr.resolveParent = resolveParent.copyAttributes();
         }
-        catch ( CloneNotSupportedException e )
-        {
-            attr = null;
-        }
 
         return attr;
     }
@@ -360,7 +370,9 @@
     /** {...@inheritdoc} */
     public int hashCode()
     {
-        return attribs.hashCode() + resolveParent.hashCode();
+        final int parentHash = ( resolveParent == null ? 0 : 
resolveParent.hashCode() );
+
+        return attribs.hashCode() + parentHash;
     }
 
     /** {...@inheritdoc} */

Added: 
maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/SinkEventAttributeSetTest.java
URL: 
http://svn.apache.org/viewvc/maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/SinkEventAttributeSetTest.java?rev=759584&view=auto
==============================================================================
--- 
maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/SinkEventAttributeSetTest.java
 (added)
+++ 
maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/SinkEventAttributeSetTest.java
 Sat Mar 28 20:54:39 2009
@@ -0,0 +1,281 @@
+package org.apache.maven.doxia.sink;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Enumeration;
+
+import javax.swing.text.AttributeSet;
+
+import junit.framework.TestCase;
+
+/**
+ * Test SinkEventAttributeSet.
+ *
+ * @author ltheussl
+ */
+public class SinkEventAttributeSetTest extends TestCase
+{
+
+    private SinkEventAttributeSet sinkEventAttributeSet;
+
+    /**
+     * @throws java.lang.Exception if any.
+     */
+    protected void setUp()
+            throws Exception
+    {
+        super.setUp();
+        this.sinkEventAttributeSet = new SinkEventAttributeSet();
+    }
+
+    /**
+     * Test of constructors, of class SinkEventAttributeSet.
+     */
+    public void testConstructor()
+    {
+        try
+        {
+            SinkEventAttributeSet aset = new SinkEventAttributeSet( new 
String[] {"key"} );
+            fail( "missing attribute value!" );
+        }
+        catch ( IllegalArgumentException e )
+        {
+            assertNotNull( e );
+        }
+    }
+
+    /**
+     * Test of isEmpty method, of class SinkEventAttributeSet.
+     */
+    public void testIsEmpty()
+    {
+        assertTrue( sinkEventAttributeSet.isEmpty() );
+        sinkEventAttributeSet.addAttributes( SinkEventAttributeSet.BOLD );
+        assertFalse( sinkEventAttributeSet.isEmpty() );
+    }
+
+    /**
+     * Test of getAttributeCount method, of class SinkEventAttributeSet.
+     */
+    public void testGetAttributeCount()
+    {
+        assertEquals( 0, sinkEventAttributeSet.getAttributeCount() );
+        sinkEventAttributeSet.addAttribute( "name1", "value1" );
+        assertEquals( 1, sinkEventAttributeSet.getAttributeCount() );
+        sinkEventAttributeSet.removeAttribute( "name2" );
+        assertEquals( 1, sinkEventAttributeSet.getAttributeCount() );
+        sinkEventAttributeSet.removeAttribute( "name1" );
+        assertEquals( 0, sinkEventAttributeSet.getAttributeCount() );
+
+        sinkEventAttributeSet.addAttributes( SinkEventAttributeSet.BOLD );
+        assertEquals( 1, sinkEventAttributeSet.getAttributeCount() );
+        sinkEventAttributeSet.removeAttributes( SinkEventAttributeSet.BOXED );
+        assertEquals( 1, sinkEventAttributeSet.getAttributeCount() );
+        sinkEventAttributeSet.removeAttributes( SinkEventAttributeSet.BOLD );
+        assertEquals( 0, sinkEventAttributeSet.getAttributeCount() );
+    }
+
+    /**
+     * Test of isDefined method, of class SinkEventAttributeSet.
+     */
+    public void testIsDefined()
+    {
+        assertFalse( sinkEventAttributeSet.isDefined( 
SinkEventAttributes.DECORATION ) );
+        sinkEventAttributeSet.addAttributes( SinkEventAttributeSet.BOXED );
+        assertTrue( sinkEventAttributeSet.isDefined( 
SinkEventAttributes.DECORATION ) );
+    }
+
+    /**
+     * Test of isEqual method, of class SinkEventAttributeSet.
+     */
+    public void testIsEqual()
+    {
+        SinkEventAttributes instance = new SinkEventAttributeSet( 
SinkEventAttributeSet.BOLD );
+        sinkEventAttributeSet.addAttributes( SinkEventAttributeSet.BOLD );
+        assertTrue( instance.isEqual( sinkEventAttributeSet ) );
+        instance.addAttributes( SinkEventAttributeSet.BOXED );
+        assertFalse( instance.isEqual( sinkEventAttributeSet ) );
+    }
+
+    /**
+     * Test of equals method, of class SinkEventAttributeSet.
+     */
+    public void testEquals()
+    {
+        assertFalse( sinkEventAttributeSet.equals( null ) );
+        assertTrue( sinkEventAttributeSet.equals( sinkEventAttributeSet ) );
+
+        SinkEventAttributes instance = new SinkEventAttributeSet( 
SinkEventAttributeSet.BOLD );
+        sinkEventAttributeSet.addAttributes( SinkEventAttributeSet.BOLD );
+        assertTrue( instance.equals( sinkEventAttributeSet ) );
+        instance.addAttributes( SinkEventAttributeSet.BOXED );
+        assertFalse( instance.equals( sinkEventAttributeSet ) );
+    }
+
+    /**
+     * Test of copyAttributes method, of class SinkEventAttributeSet.
+     */
+    public void testCopyAttributes()
+    {
+        sinkEventAttributeSet.addAttributes( SinkEventAttributeSet.ITALIC );
+        AttributeSet instance = sinkEventAttributeSet.copyAttributes();
+        assertTrue( instance.isEqual( sinkEventAttributeSet ) );
+    }
+
+    /**
+     * Test of getAttributeNames method, of class SinkEventAttributeSet.
+     */
+    public void testGetAttributeNames()
+    {
+        sinkEventAttributeSet.addAttributes( SinkEventAttributeSet.UNDERLINE );
+        Enumeration result = sinkEventAttributeSet.getAttributeNames();
+        assertEquals( "decoration", result.nextElement() );
+        assertFalse( result.hasMoreElements() );
+    }
+
+    /**
+     * Test of getAttribute method, of class SinkEventAttributeSet.
+     */
+    public void testGetAttribute()
+    {
+        sinkEventAttributeSet.addAttribute( "key", "value" );
+        assertTrue( sinkEventAttributeSet.getAttribute( "key" ).equals( 
"value" ) );
+        assertNull( sinkEventAttributeSet.getAttribute( "bla" ) );
+    }
+
+    /**
+     * Test of containsAttribute method, of class SinkEventAttributeSet.
+     */
+    public void testContainsAttribute()
+    {
+        sinkEventAttributeSet.addAttribute( "key", "value" );
+        assertTrue( sinkEventAttributeSet.containsAttribute( "key", "value" ) 
);
+        assertFalse( sinkEventAttributeSet.containsAttribute( "key", "valu" ) 
);
+    }
+
+    /**
+     * Test of containsAttributes method, of class SinkEventAttributeSet.
+     */
+    public void testContainsAttributes()
+    {
+        sinkEventAttributeSet.addAttributes( SinkEventAttributeSet.JUSTIFY );
+        assertTrue( sinkEventAttributeSet.containsAttributes( 
SinkEventAttributeSet.JUSTIFY ) );
+        assertFalse( sinkEventAttributeSet.containsAttributes( 
SinkEventAttributeSet.BOXED ) );
+    }
+
+    /**
+     * Test of addAttribute method, of class SinkEventAttributeSet.
+     */
+    public void testAddAttribute()
+    {
+        assertFalse( sinkEventAttributeSet.containsAttribute( "key", "value" ) 
);
+        sinkEventAttributeSet.addAttribute( "key", "value" );
+        assertTrue( sinkEventAttributeSet.containsAttribute( "key", "value" ) 
);
+        sinkEventAttributeSet.removeAttribute( "key" );
+        assertFalse( sinkEventAttributeSet.containsAttribute( "key", "value" ) 
);
+    }
+
+    /**
+     * Test of add/removeAttributes methods, of class SinkEventAttributeSet.
+     */
+    public void testAddAttributes()
+    {
+        assertFalse( sinkEventAttributeSet.containsAttributes( 
SinkEventAttributeSet.JUSTIFY ) );
+        sinkEventAttributeSet.addAttributes( SinkEventAttributeSet.JUSTIFY );
+        assertTrue( sinkEventAttributeSet.containsAttributes( 
SinkEventAttributeSet.JUSTIFY ) );
+
+        sinkEventAttributeSet.removeAttributes( SinkEventAttributeSet.JUSTIFY 
);
+        assertFalse( sinkEventAttributeSet.containsAttributes( 
SinkEventAttributeSet.JUSTIFY ) );
+
+        sinkEventAttributeSet.addAttributes( SinkEventAttributeSet.JUSTIFY );
+        sinkEventAttributeSet.removeAttributes( 
SinkEventAttributeSet.JUSTIFY.getAttributeNames() );
+        assertFalse( sinkEventAttributeSet.containsAttributes( 
SinkEventAttributeSet.JUSTIFY ) );
+
+        sinkEventAttributeSet.setResolveParent( SinkEventAttributeSet.JUSTIFY 
);
+        assertTrue( sinkEventAttributeSet.containsAttributes( 
SinkEventAttributeSet.JUSTIFY ) );
+
+        sinkEventAttributeSet.removeAttributes( (AttributeSet) null ); // 
should do nothing
+    }
+
+    /**
+     * Test of getResolveParent method, of class SinkEventAttributeSet.
+     */
+    public void testGetResolveParent()
+    {
+        assertNull( sinkEventAttributeSet.getResolveParent() );
+        sinkEventAttributeSet.setResolveParent( SinkEventAttributeSet.CENTER );
+        assertNotNull( sinkEventAttributeSet.getResolveParent() );
+    }
+
+    /**
+     * Test of clone method, of class SinkEventAttributeSet.
+     */
+    public void testClone()
+    {
+        Object result = sinkEventAttributeSet.clone();
+        assertTrue( sinkEventAttributeSet.equals( result ) );
+
+        sinkEventAttributeSet.addAttributes( SinkEventAttributeSet.MONOSPACED 
);
+        assertFalse( sinkEventAttributeSet.equals( result ) );
+
+        result = sinkEventAttributeSet.clone();
+        assertTrue( sinkEventAttributeSet.equals( result ) );
+        sinkEventAttributeSet.setResolveParent( SinkEventAttributeSet.CENTER );
+        //assertFalse( sinkEventAttributeSet.equals( result ) );
+
+        result = sinkEventAttributeSet.clone();
+        assertTrue( sinkEventAttributeSet.equals( result ) );
+        sinkEventAttributeSet.setResolveParent( SinkEventAttributeSet.BOXED );
+        //assertFalse( sinkEventAttributeSet.equals( result ) );
+    }
+
+    /**
+     * Test of hashCode method, of class SinkEventAttributeSet.
+     */
+    public void testHashCode()
+    {
+        int oldValue = sinkEventAttributeSet.hashCode();
+        sinkEventAttributeSet.addAttributes( SinkEventAttributeSet.BOLD );
+        int newValue = sinkEventAttributeSet.hashCode();
+        assertFalse( oldValue == newValue );
+
+        oldValue = newValue;
+        sinkEventAttributeSet.setResolveParent( SinkEventAttributeSet.CENTER );
+        newValue = sinkEventAttributeSet.hashCode();
+        assertFalse( oldValue == newValue );
+    }
+
+    /**
+     * Test of toString method, of class SinkEventAttributeSet.
+     */
+    public void testToString()
+    {
+        String expected = "";
+        assertEquals( expected, sinkEventAttributeSet.toString() );
+
+        sinkEventAttributeSet.addAttributes( SinkEventAttributeSet.BOXED );
+        expected = " decoration=boxed";
+        assertEquals( expected, sinkEventAttributeSet.toString() );
+
+        sinkEventAttributeSet.addAttributes( SinkEventAttributeSet.CENTER );
+        expected = " decoration=boxed align=center";
+        assertEquals( expected, sinkEventAttributeSet.toString() );
+    }
+}

Propchange: 
maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/SinkEventAttributeSetTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/SinkEventAttributeSetTest.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"


Reply via email to