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"