You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by lu...@apache.org on 2022/11/27 08:24:56 UTC

[struts] 13/23: WW-5233 Addresses bugs reported by Sonar

This is an automated email from the ASF dual-hosted git repository.

lukaszlenart pushed a commit to branch WW-5233-tiles
in repository https://gitbox.apache.org/repos/asf/struts.git

commit 69e5efc84009057ad7191fb92f9995227c169ab2
Author: Lukasz Lenart <lu...@apache.org>
AuthorDate: Mon Oct 3 07:49:27 2022 +0200

    WW-5233 Addresses bugs reported by Sonar
---
 .../main/java/org/apache/tiles/api/Attribute.java  | 13 +--
 .../apache/tiles/api/BasicAttributeContext.java    | 22 +++--
 .../main/java/org/apache/tiles/api/Definition.java |  6 ++
 .../main/java/org/apache/tiles/api/Expression.java |  6 ++
 .../java/org/apache/tiles/api/ListAttribute.java   |  6 ++
 .../autotag/core/runtime/AbstractModelBody.java    | 11 +--
 .../definition/dao/BaseLocaleUrlDefinitionDAO.java | 13 +--
 .../tiles/request/collection/HeaderValuesMap.java  | 94 +++++++++++++++-------
 .../apache/tiles/request/collection/KeySet.java    | 13 ++-
 .../request/collection/ReadOnlyEnumerationMap.java | 93 ++++++++++++++-------
 .../java/org/apache/tiles/api/AttributeTest.java   |  4 +-
 .../autotag/runtime/AbstractModelBodyTest.java     |  7 --
 12 files changed, 190 insertions(+), 98 deletions(-)

diff --git a/plugins/tiles/src/main/java/org/apache/tiles/api/Attribute.java b/plugins/tiles/src/main/java/org/apache/tiles/api/Attribute.java
index e84039c73..69209e5d4 100644
--- a/plugins/tiles/src/main/java/org/apache/tiles/api/Attribute.java
+++ b/plugins/tiles/src/main/java/org/apache/tiles/api/Attribute.java
@@ -23,8 +23,6 @@ import com.opensymphony.xwork2.util.TextParseUtil;
 import org.apache.tiles.request.Request;
 
 import java.io.Serializable;
-import java.util.Collections;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Objects;
 import java.util.Set;
@@ -267,10 +265,7 @@ public class Attribute implements Serializable, Cloneable {
      */
     @Override
     public String toString() {
-        if (value != null) {
-            return value.toString();
-        }
-        return null;
+        return Objects.toString(value);
     }
 
     /**
@@ -323,6 +318,12 @@ public class Attribute implements Serializable, Cloneable {
      */
     @Override
     public boolean equals(Object obj) {
+        if (obj == null && value == null) {
+            return true;
+        }
+        if (!(obj instanceof Attribute)) {
+            return false;
+        }
         Attribute attribute = (Attribute) obj;
         return Objects.equals(value, attribute.value)
             && Objects.equals(renderer, attribute.renderer)
diff --git a/plugins/tiles/src/main/java/org/apache/tiles/api/BasicAttributeContext.java b/plugins/tiles/src/main/java/org/apache/tiles/api/BasicAttributeContext.java
index 8fdc5b8aa..9de064d6b 100644
--- a/plugins/tiles/src/main/java/org/apache/tiles/api/BasicAttributeContext.java
+++ b/plugins/tiles/src/main/java/org/apache/tiles/api/BasicAttributeContext.java
@@ -149,7 +149,9 @@ public class BasicAttributeContext implements AttributeContext, Serializable {
      */
     public void inheritCascadedAttributes(AttributeContext context) {
         if (context instanceof BasicAttributeContext) {
-            copyCascadedAttributes((BasicAttributeContext) context);
+            if (((BasicAttributeContext) context).cascadedAttributes != null && !((BasicAttributeContext) context).cascadedAttributes.isEmpty()) {
+                cascadedAttributes = deepCopyAttributeMap(((BasicAttributeContext) context).cascadedAttributes);
+            }
         } else {
             this.cascadedAttributes = new HashMap<>();
             Set<String> parentAttributeNames = context.getCascadedAttributeNames();
@@ -353,6 +355,12 @@ public class BasicAttributeContext implements AttributeContext, Serializable {
      */
     @Override
     public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof BasicAttributeContext)) {
+            return false;
+        }
         BasicAttributeContext bac = (BasicAttributeContext) obj;
         return Objects.equals(templateAttribute, bac.templateAttribute)
             && Objects.equals(preparer, bac.preparer)
@@ -400,17 +408,7 @@ public class BasicAttributeContext implements AttributeContext, Serializable {
         if (context.attributes != null && !context.attributes.isEmpty()) {
             attributes = deepCopyAttributeMap(context.attributes);
         }
-        copyCascadedAttributes(context);
-    }
-
-    /**
-     * Copies the cascaded attributes to the current context.
-     *
-     * @param context The context to copy from.
-     */
-    private void copyCascadedAttributes(BasicAttributeContext context) {
-        if (context.cascadedAttributes != null
-            && !context.cascadedAttributes.isEmpty()) {
+        if (context.cascadedAttributes != null && !context.cascadedAttributes.isEmpty()) {
             cascadedAttributes = deepCopyAttributeMap(context.cascadedAttributes);
         }
     }
diff --git a/plugins/tiles/src/main/java/org/apache/tiles/api/Definition.java b/plugins/tiles/src/main/java/org/apache/tiles/api/Definition.java
index 3cd217b1c..54ac5e035 100644
--- a/plugins/tiles/src/main/java/org/apache/tiles/api/Definition.java
+++ b/plugins/tiles/src/main/java/org/apache/tiles/api/Definition.java
@@ -116,6 +116,12 @@ public class Definition extends BasicAttributeContext {
      */
     @Override
     public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof Definition)) {
+            return false;
+        }
         Definition def = (Definition) obj;
         return Objects.equals(name, def.name) && Objects.equals(inherit, def.inherit) && super.equals(def);
     }
diff --git a/plugins/tiles/src/main/java/org/apache/tiles/api/Expression.java b/plugins/tiles/src/main/java/org/apache/tiles/api/Expression.java
index 6efe6ce1b..38d152ccb 100644
--- a/plugins/tiles/src/main/java/org/apache/tiles/api/Expression.java
+++ b/plugins/tiles/src/main/java/org/apache/tiles/api/Expression.java
@@ -137,6 +137,12 @@ public class Expression {
      */
     @Override
     public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof Expression)) {
+            return false;
+        }
         Expression exp = (Expression) obj;
         return Objects.equals(expression, exp.expression) && Objects.equals(language, exp.language);
     }
diff --git a/plugins/tiles/src/main/java/org/apache/tiles/api/ListAttribute.java b/plugins/tiles/src/main/java/org/apache/tiles/api/ListAttribute.java
index 3daeff4f5..227380af0 100644
--- a/plugins/tiles/src/main/java/org/apache/tiles/api/ListAttribute.java
+++ b/plugins/tiles/src/main/java/org/apache/tiles/api/ListAttribute.java
@@ -146,6 +146,12 @@ public class ListAttribute extends Attribute {
     /** {@inheritDoc} */
     @Override
     public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof ListAttribute)) {
+            return false;
+        }
         ListAttribute attribute = (ListAttribute) obj;
         return super.equals(attribute) && this.inherit == attribute.inherit;
     }
diff --git a/plugins/tiles/src/main/java/org/apache/tiles/autotag/core/runtime/AbstractModelBody.java b/plugins/tiles/src/main/java/org/apache/tiles/autotag/core/runtime/AbstractModelBody.java
index 72b3a9938..b1a937e73 100644
--- a/plugins/tiles/src/main/java/org/apache/tiles/autotag/core/runtime/AbstractModelBody.java
+++ b/plugins/tiles/src/main/java/org/apache/tiles/autotag/core/runtime/AbstractModelBody.java
@@ -31,12 +31,12 @@ import java.util.regex.Pattern;
 public abstract class AbstractModelBody implements ModelBody {
 
     // precompiled the pattern to avoid compiling on every method call
-    private static final Pattern PATTERN = Pattern.compile("^\\s*|\\s*$");
+    private static final Pattern PATTERN = Pattern.compile("^\\s*$");
 
     /**
      * The default writer to use.
      */
-    private Writer defaultWriter;
+    private final Writer defaultWriter;
 
     /**
      * Constructor.
@@ -63,7 +63,7 @@ public abstract class AbstractModelBody implements ModelBody {
         String body = writer.toString();
         if (body != null) {
             body = PATTERN.matcher(body).replaceAll("");
-            if (body.length() <= 0) {
+            if (body.length() == 0) {
                 body = null;
             }
         }
@@ -72,11 +72,8 @@ public abstract class AbstractModelBody implements ModelBody {
 
     @Override
     public void evaluateWithoutWriting() throws IOException {
-        NullWriter writer = new NullWriter();
-        try {
+        try (NullWriter writer = new NullWriter()) {
             evaluate(writer);
-        } finally {
-            writer.close();
         }
     }
 
diff --git a/plugins/tiles/src/main/java/org/apache/tiles/core/definition/dao/BaseLocaleUrlDefinitionDAO.java b/plugins/tiles/src/main/java/org/apache/tiles/core/definition/dao/BaseLocaleUrlDefinitionDAO.java
index 45aa73840..cb01af434 100644
--- a/plugins/tiles/src/main/java/org/apache/tiles/core/definition/dao/BaseLocaleUrlDefinitionDAO.java
+++ b/plugins/tiles/src/main/java/org/apache/tiles/core/definition/dao/BaseLocaleUrlDefinitionDAO.java
@@ -89,8 +89,8 @@ public abstract class BaseLocaleUrlDefinitionDAO implements DefinitionDAO<Locale
     public void setSources(List<ApplicationResource> sources) {
         // filter out any sources that are already localized
         ArrayList<ApplicationResource> defaultSources = new ArrayList<>();
-        for(ApplicationResource source: sources) {
-            if(Locale.ROOT.equals(source.getLocale())) {
+        for (ApplicationResource source : sources) {
+            if (Locale.ROOT.equals(source.getLocale())) {
                 defaultSources.add(source);
             }
         }
@@ -101,7 +101,9 @@ public abstract class BaseLocaleUrlDefinitionDAO implements DefinitionDAO<Locale
         this.reader = reader;
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     public boolean refreshRequired() {
         boolean status = false;
 
@@ -136,7 +138,7 @@ public abstract class BaseLocaleUrlDefinitionDAO implements DefinitionDAO<Locale
         InputStream stream = null;
         try {
             lastModifiedDates.put(resource.getLocalePath(), resource
-                    .getLastModified());
+                .getLastModified());
 
             // Definition must be collected, starting from the base
             // source up to the last localized file.
@@ -152,8 +154,7 @@ public abstract class BaseLocaleUrlDefinitionDAO implements DefinitionDAO<Locale
                 if (stream != null) {
                     stream.close();
                 }
-            } catch (IOException e) {
-                throw new DefinitionsFactoryException("I/O error closing " + resource, e);
+            } catch (IOException ignore) {
             }
         }
 
diff --git a/plugins/tiles/src/main/java/org/apache/tiles/request/collection/HeaderValuesMap.java b/plugins/tiles/src/main/java/org/apache/tiles/request/collection/HeaderValuesMap.java
index 6c91895ad..fa50dbab9 100644
--- a/plugins/tiles/src/main/java/org/apache/tiles/request/collection/HeaderValuesMap.java
+++ b/plugins/tiles/src/main/java/org/apache/tiles/request/collection/HeaderValuesMap.java
@@ -18,7 +18,7 @@
  */
 package org.apache.tiles.request.collection;
 
-import static org.apache.tiles.request.collection.CollectionUtil.*;
+import org.apache.tiles.request.attribute.EnumeratedValuesExtractor;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -28,9 +28,11 @@ import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.NoSuchElementException;
 import java.util.Set;
 
-import org.apache.tiles.request.attribute.EnumeratedValuesExtractor;
+import static org.apache.tiles.request.collection.CollectionUtil.enumerationSize;
+import static org.apache.tiles.request.collection.CollectionUtil.key;
 
 /**
  * Exposes an {@link EnumeratedValuesExtractor} object as a read-only map.
@@ -52,19 +54,25 @@ public class HeaderValuesMap implements Map<String, String[]> {
     }
 
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     public void clear() {
         throw new UnsupportedOperationException();
     }
 
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     public boolean containsKey(Object key) {
         return (request.getValue(key(key)) != null);
     }
 
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     public boolean containsValue(Object value) {
         if (!(value instanceof String[])) {
             return (false);
@@ -81,18 +89,28 @@ public class HeaderValuesMap implements Map<String, String[]> {
     }
 
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     public Set<Entry<String, String[]>> entrySet() {
         return new HeadersEntrySet();
     }
 
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     @Override
-    public boolean equals(Object o) {
-        EnumeratedValuesExtractor otherRequest = ((HeaderValuesMap) o).request;
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof HeaderValuesMap)) {
+            return false;
+        }
+        EnumeratedValuesExtractor otherRequest = ((HeaderValuesMap) obj).request;
         boolean retValue = true;
-        for (Enumeration<String> attribs = request.getKeys(); attribs.hasMoreElements() && retValue;) {
+        for (Enumeration<String> attribs = request.getKeys(); attribs.hasMoreElements() && retValue; ) {
             String parameterName = attribs.nextElement();
             Set<String> valueSet = enumeration2set(otherRequest.getValues(parameterName));
             retValue = compareHeaders(parameterName, valueSet);
@@ -102,17 +120,21 @@ public class HeaderValuesMap implements Map<String, String[]> {
     }
 
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     public String[] get(Object key) {
         return getHeaderValues(key(key));
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public int hashCode() {
         int retValue = 0;
         for (Enumeration<String> attribs = request.getKeys(); attribs
-                .hasMoreElements();) {
+            .hasMoreElements(); ) {
             String parameterName = attribs.nextElement();
             Enumeration<String> values = request.getValues(parameterName);
             int valueHash = 0;
@@ -125,44 +147,57 @@ public class HeaderValuesMap implements Map<String, String[]> {
     }
 
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     public boolean isEmpty() {
         return !request.getKeys().hasMoreElements();
     }
 
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     public Set<String> keySet() {
         return new KeySet(request);
     }
 
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     public String[] put(String key, String[] value) {
         throw new UnsupportedOperationException();
     }
 
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     public void putAll(Map<? extends String, ? extends String[]> map) {
         throw new UnsupportedOperationException();
     }
 
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     public String[] remove(Object key) {
         throw new UnsupportedOperationException();
     }
 
 
-
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     public int size() {
         return enumerationSize(request.getKeys());
     }
 
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     public Collection<String[]> values() {
         return new HeaderValuesCollection();
     }
@@ -212,7 +247,7 @@ public class HeaderValuesMap implements Map<String, String[]> {
      * Checks if values of a header attribute are the same as the one passed in
      * the set.
      *
-     * @param name The name of the header.
+     * @param name    The name of the header.
      * @param testSet The set of values it must contain.
      * @return <code>true</code> if all the values, and only them, are present
      * in the header values.
@@ -240,7 +275,7 @@ public class HeaderValuesMap implements Map<String, String[]> {
 
         @Override
         public boolean addAll(
-                Collection<? extends Entry<String, String[]>> c) {
+            Collection<? extends Entry<String, String[]>> c) {
             throw new UnsupportedOperationException();
         }
 
@@ -346,8 +381,7 @@ public class HeaderValuesMap implements Map<String, String[]> {
          * @param names The enumeration to get the next name from..
          * @return The next map entry.
          */
-        private MapEntry<String, String[]> extractNextEntry(
-                Enumeration<String> names) {
+        private MapEntry<String, String[]> extractNextEntry(Enumeration<String> names) {
             String name = names.nextElement();
             return new MapEntryArrayValues<>(name, getHeaderValues(name), false);
         }
@@ -369,7 +403,10 @@ public class HeaderValuesMap implements Map<String, String[]> {
 
             @Override
             public Entry<String, String[]> next() {
-                return extractNextEntry(namesEnumeration);
+                if (namesEnumeration.hasMoreElements()) {
+                    return extractNextEntry(namesEnumeration);
+                }
+                throw new NoSuchElementException();
             }
 
             @Override
@@ -504,7 +541,10 @@ public class HeaderValuesMap implements Map<String, String[]> {
 
             @Override
             public String[] next() {
-                return enumeration2array(request.getValues(namesEnumeration.nextElement()));
+                if (namesEnumeration.hasMoreElements()) {
+                    return enumeration2array(request.getValues(namesEnumeration.nextElement()));
+                }
+                throw new NoSuchElementException();
             }
 
             @Override
diff --git a/plugins/tiles/src/main/java/org/apache/tiles/request/collection/KeySet.java b/plugins/tiles/src/main/java/org/apache/tiles/request/collection/KeySet.java
index e89d60bdc..f34688088 100644
--- a/plugins/tiles/src/main/java/org/apache/tiles/request/collection/KeySet.java
+++ b/plugins/tiles/src/main/java/org/apache/tiles/request/collection/KeySet.java
@@ -18,16 +18,18 @@
  */
 package org.apache.tiles.request.collection;
 
-import static org.apache.tiles.request.collection.CollectionUtil.*;
+import org.apache.tiles.request.attribute.HasKeys;
 
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Enumeration;
 import java.util.Iterator;
 import java.util.List;
+import java.util.NoSuchElementException;
 import java.util.Set;
 
-import org.apache.tiles.request.attribute.HasKeys;
+import static org.apache.tiles.request.collection.CollectionUtil.enumerationSize;
+import static org.apache.tiles.request.collection.CollectionUtil.key;
 
 /**
  * Exposes keys of a {@link HasKeys} object as a set.
@@ -142,7 +144,7 @@ public class KeySet implements Set<String> {
         /**
          * The key names enumeration.
          */
-        private Enumeration<String> namesEnumeration = request.getKeys();
+        private final Enumeration<String> namesEnumeration = request.getKeys();
 
         @Override
         public boolean hasNext() {
@@ -151,7 +153,10 @@ public class KeySet implements Set<String> {
 
         @Override
         public String next() {
-            return namesEnumeration.nextElement();
+            if (namesEnumeration.hasMoreElements()) {
+                return namesEnumeration.nextElement();
+            }
+            throw new NoSuchElementException();
         }
 
         @Override
diff --git a/plugins/tiles/src/main/java/org/apache/tiles/request/collection/ReadOnlyEnumerationMap.java b/plugins/tiles/src/main/java/org/apache/tiles/request/collection/ReadOnlyEnumerationMap.java
index 85c17b656..2db0e83ae 100644
--- a/plugins/tiles/src/main/java/org/apache/tiles/request/collection/ReadOnlyEnumerationMap.java
+++ b/plugins/tiles/src/main/java/org/apache/tiles/request/collection/ReadOnlyEnumerationMap.java
@@ -18,7 +18,7 @@
  */
 package org.apache.tiles.request.collection;
 
-import static org.apache.tiles.request.collection.CollectionUtil.*;
+import org.apache.tiles.request.attribute.HasKeys;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -27,9 +27,11 @@ import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.NoSuchElementException;
 import java.util.Set;
 
-import org.apache.tiles.request.attribute.HasKeys;
+import static org.apache.tiles.request.collection.CollectionUtil.enumerationSize;
+import static org.apache.tiles.request.collection.CollectionUtil.key;
 
 /**
  * Wraps an {@link HasKeys} object into a read-only map.
@@ -52,21 +54,27 @@ public class ReadOnlyEnumerationMap<V> implements Map<String, V> {
         this.request = request;
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     public void clear() {
         throw new UnsupportedOperationException();
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     public boolean containsKey(Object key) {
         return (request.getValue(key(key)) != null);
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     @SuppressWarnings("unchecked")
     public boolean containsValue(Object value) {
         V realValue = (V) value;
-        for (Enumeration<String> keysIt = request.getKeys(); keysIt.hasMoreElements();) {
+        for (Enumeration<String> keysIt = request.getKeys(); keysIt.hasMoreElements(); ) {
             if (realValue.equals(request.getValue(keysIt.nextElement()))) {
                 return true;
             }
@@ -74,63 +82,89 @@ public class ReadOnlyEnumerationMap<V> implements Map<String, V> {
         return false;
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     public Set<Entry<String, V>> entrySet() {
         return new ReadOnlyEnumerationMapEntrySet();
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     public V get(Object key) {
         return (request.getValue(key(key)));
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     public boolean isEmpty() {
         return !request.getKeys().hasMoreElements();
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     public Set<String> keySet() {
         return new KeySet(request);
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     public V put(String key, V value) {
         throw new UnsupportedOperationException();
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     public void putAll(Map<? extends String, ? extends V> map) {
         throw new UnsupportedOperationException();
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     public V remove(Object key) {
         throw new UnsupportedOperationException();
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     public int size() {
         return enumerationSize(request.getKeys());
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     public Collection<V> values() {
         return new ReadOnlyEnumerationMapValuesCollection();
     }
 
-    /** {@inheritDoc} */
-    @SuppressWarnings("unchecked")
+    /**
+     * {@inheritDoc}
+     */
     @Override
-    public boolean equals(Object o) {
-        HasKeys<V> otherRequest = ((ReadOnlyEnumerationMap<V>) o).request;
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof ReadOnlyEnumerationMap)) {
+            return false;
+        }
+        @SuppressWarnings("unchecked")
+        HasKeys<V> otherRequest = ((ReadOnlyEnumerationMap<V>) obj).request;
         boolean retValue = true;
         Set<String> otherKeys;
         otherKeys = new HashSet<>();
-        for (Enumeration<String> attribs = otherRequest.getKeys(); attribs.hasMoreElements();) {
+        for (Enumeration<String> attribs = otherRequest.getKeys(); attribs.hasMoreElements(); ) {
             otherKeys.add(attribs.nextElement());
         }
-        for (Enumeration<String> attribs = request.getKeys(); attribs.hasMoreElements() && retValue;) {
+        for (Enumeration<String> attribs = request.getKeys(); attribs.hasMoreElements() && retValue; ) {
             String parameterName = attribs.nextElement();
             retValue = request.getValue(parameterName).equals(otherRequest.getValue(parameterName));
             otherKeys.remove(parameterName);
@@ -139,12 +173,14 @@ public class ReadOnlyEnumerationMap<V> implements Map<String, V> {
         return retValue && otherKeys.isEmpty();
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public int hashCode() {
         int retValue = 0;
         for (Enumeration<String> attribs = request.getKeys(); attribs
-                .hasMoreElements();) {
+            .hasMoreElements(); ) {
             String parameterName = attribs.nextElement();
             V value = request.getValue(parameterName);
             retValue += parameterName.hashCode() ^ (value == null ? 0 : value.hashCode());
@@ -164,7 +200,7 @@ public class ReadOnlyEnumerationMap<V> implements Map<String, V> {
 
         @Override
         public boolean addAll(
-                Collection<? extends Entry<String, V>> c) {
+            Collection<? extends Entry<String, V>> c) {
             throw new UnsupportedOperationException();
         }
 
@@ -264,7 +300,7 @@ public class ReadOnlyEnumerationMap<V> implements Map<String, V> {
          * @return The next entry.
          */
         private MapEntry<String, V> extractNextEntry(
-                Enumeration<String> names) {
+            Enumeration<String> names) {
             String name = names.nextElement();
             return new MapEntry<>(name, request.getValue(name), false);
         }
@@ -327,7 +363,7 @@ public class ReadOnlyEnumerationMap<V> implements Map<String, V> {
         public boolean containsAll(Collection<?> c) {
             Collection<String> realCollection = (Collection<String>) c;
             List<String> valueList = new ArrayList<>(realCollection);
-            for (Enumeration<String> keysEnum = request.getKeys(); keysEnum.hasMoreElements();) {
+            for (Enumeration<String> keysEnum = request.getKeys(); keysEnum.hasMoreElements(); ) {
                 valueList.remove(request.getValue(keysEnum.nextElement()));
                 if (valueList.isEmpty()) {
                     return true;
@@ -407,7 +443,10 @@ public class ReadOnlyEnumerationMap<V> implements Map<String, V> {
 
             @Override
             public V next() {
-                return request.getValue(namesEnumeration.nextElement());
+                if (namesEnumeration.hasMoreElements()) {
+                    return request.getValue(namesEnumeration.nextElement());
+                }
+                throw new NoSuchElementException();
             }
 
             @Override
diff --git a/plugins/tiles/src/test/java/org/apache/tiles/api/AttributeTest.java b/plugins/tiles/src/test/java/org/apache/tiles/api/AttributeTest.java
index 875431c6f..5c46b42e0 100644
--- a/plugins/tiles/src/test/java/org/apache/tiles/api/AttributeTest.java
+++ b/plugins/tiles/src/test/java/org/apache/tiles/api/AttributeTest.java
@@ -33,6 +33,7 @@ import static org.easymock.EasyMock.verify;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
@@ -41,7 +42,6 @@ import static org.junit.Assert.assertTrue;
  */
 public class AttributeTest {
 
-
     /**
      * Tests {@link Attribute#createTemplateAttribute(String)}.
      */
@@ -193,7 +193,7 @@ public class AttributeTest {
         Attribute attribute = new Attribute("my.value", expression, "role1,role2", "myrenderer");
         assertEquals("my.value", attribute.toString());
         attribute.setValue(null);
-        assertNull(attribute.toString());
+        assertNotNull(attribute.toString());
     }
 
     @Test
diff --git a/plugins/tiles/src/test/java/org/apache/tiles/autotag/runtime/AbstractModelBodyTest.java b/plugins/tiles/src/test/java/org/apache/tiles/autotag/runtime/AbstractModelBodyTest.java
index 08e4d9011..3bfe89ff5 100644
--- a/plugins/tiles/src/test/java/org/apache/tiles/autotag/runtime/AbstractModelBodyTest.java
+++ b/plugins/tiles/src/test/java/org/apache/tiles/autotag/runtime/AbstractModelBodyTest.java
@@ -37,8 +37,6 @@ import static org.junit.Assert.assertNull;
 
 /**
  * Tests {@link AbstractModelBody}.
- *
- * @version $Rev$ $Date$
  */
 public class AbstractModelBodyTest {
 
@@ -132,11 +130,6 @@ public class AbstractModelBodyTest {
         }
     }
 
-    /**
-     * A mock model body.
-     *
-     * @version $Rev$ $Date$
-     */
     public static class MockModelBody extends AbstractModelBody {
 
         /**