Author: apetrelli
Date: Wed Jun 24 16:05:28 2009
New Revision: 788065
URL: http://svn.apache.org/viewvc?rev=788065&view=rev
Log:
TILES-429
Now attributes are deep copied in the BasicAttributeContext copy constructor.
Modified:
tiles/framework/trunk/tiles-api/src/main/java/org/apache/tiles/Attribute.java
tiles/framework/trunk/tiles-api/src/main/java/org/apache/tiles/BasicAttributeContext.java
tiles/framework/trunk/tiles-api/src/main/java/org/apache/tiles/ListAttribute.java
tiles/framework/trunk/tiles-api/src/test/java/org/apache/tiles/BasicAttributeContextTest.java
Modified:
tiles/framework/trunk/tiles-api/src/main/java/org/apache/tiles/Attribute.java
URL:
http://svn.apache.org/viewvc/tiles/framework/trunk/tiles-api/src/main/java/org/apache/tiles/Attribute.java?rev=788065&r1=788064&r2=788065&view=diff
==============================================================================
---
tiles/framework/trunk/tiles-api/src/main/java/org/apache/tiles/Attribute.java
(original)
+++
tiles/framework/trunk/tiles-api/src/main/java/org/apache/tiles/Attribute.java
Wed Jun 24 16:05:28 2009
@@ -34,7 +34,7 @@
*
* @version $Rev$ $Date$
*/
-public class Attribute implements Serializable {
+public class Attribute implements Serializable, Cloneable {
/**
* The name of the template renderer.
@@ -572,4 +572,10 @@
return nullSafeHashCode(value) + nullSafeHashCode(renderer)
+ nullSafeHashCode(roles) + nullSafeHashCode(expressionObject);
}
+
+ /** {...@inheritdoc} */
+ @Override
+ public Attribute clone() {
+ return new Attribute(this);
+ }
}
Modified:
tiles/framework/trunk/tiles-api/src/main/java/org/apache/tiles/BasicAttributeContext.java
URL:
http://svn.apache.org/viewvc/tiles/framework/trunk/tiles-api/src/main/java/org/apache/tiles/BasicAttributeContext.java?rev=788065&r1=788064&r2=788065&view=diff
==============================================================================
---
tiles/framework/trunk/tiles-api/src/main/java/org/apache/tiles/BasicAttributeContext.java
(original)
+++
tiles/framework/trunk/tiles-api/src/main/java/org/apache/tiles/BasicAttributeContext.java
Wed Jun 24 16:05:28 2009
@@ -82,7 +82,7 @@
*/
public BasicAttributeContext(Map<String, Attribute> attributes) {
if (attributes != null) {
- this.attributes = new HashMap<String, Attribute>(attributes);
+ this.attributes = deepCopyAttributeMap(attributes);
}
}
@@ -103,7 +103,7 @@
this.preparer = context.getPreparer();
this.attributes = new HashMap<String, Attribute>();
for (String name : context.getLocalAttributeNames()) {
- attributes.put(name, context.getLocalAttribute(name));
+ attributes.put(name, new
Attribute(context.getLocalAttribute(name)));
}
inheritCascadedAttributes(context);
}
@@ -146,8 +146,8 @@
} else {
this.cascadedAttributes = new HashMap<String, Attribute>();
for (String name : context.getCascadedAttributeNames()) {
- cascadedAttributes
- .put(name, context.getCascadedAttribute(name));
+ cascadedAttributes.put(name, new Attribute(context
+ .getCascadedAttribute(name)));
}
}
}
@@ -405,7 +405,7 @@
}
preparer = context.preparer;
if (context.attributes != null && !context.attributes.isEmpty()) {
- attributes = new HashMap<String, Attribute>(context.attributes);
+ attributes = deepCopyAttributeMap(context.attributes);
}
copyCascadedAttributes(context);
}
@@ -418,8 +418,7 @@
private void copyCascadedAttributes(BasicAttributeContext context) {
if (context.cascadedAttributes != null
&& !context.cascadedAttributes.isEmpty()) {
- cascadedAttributes = new HashMap<String, Attribute>(
- context.cascadedAttributes);
+ cascadedAttributes =
deepCopyAttributeMap(context.cascadedAttributes);
}
}
@@ -452,4 +451,23 @@
return destination;
}
+
+ /**
+ * Deep copies the attribute map, by creating clones (using copy
+ * constructors) of the attributes.
+ *
+ * @param attributes The attribute map to copy.
+ * @return The copied map.
+ */
+ private Map<String, Attribute> deepCopyAttributeMap(
+ Map<String, Attribute> attributes) {
+ Map<String, Attribute> retValue = new HashMap<String,
Attribute>(attributes.size());
+ for (Map.Entry<String, Attribute> entry : attributes.entrySet()) {
+ Attribute toCopy = entry.getValue();
+ if (toCopy != null) {
+ retValue.put(entry.getKey(), toCopy.clone());
+ }
+ }
+ return retValue;
+ }
}
Modified:
tiles/framework/trunk/tiles-api/src/main/java/org/apache/tiles/ListAttribute.java
URL:
http://svn.apache.org/viewvc/tiles/framework/trunk/tiles-api/src/main/java/org/apache/tiles/ListAttribute.java?rev=788065&r1=788064&r2=788065&view=diff
==============================================================================
---
tiles/framework/trunk/tiles-api/src/main/java/org/apache/tiles/ListAttribute.java
(original)
+++
tiles/framework/trunk/tiles-api/src/main/java/org/apache/tiles/ListAttribute.java
Wed Jun 24 16:05:28 2009
@@ -64,6 +64,17 @@
}
/**
+ * Copy constructor.
+ *
+ * @param toCopy The list attribute to copy.
+ * @since 2.1.3
+ */
+ public ListAttribute(ListAttribute toCopy) {
+ super(toCopy);
+ this.inherit = toCopy.inherit;
+ }
+
+ /**
* Add an element in list.
* We use a property to avoid rewriting a new class.
*
@@ -142,4 +153,23 @@
tempList.addAll((List<Object>) value);
setValue(tempList);
}
+
+ /** {...@inheritdoc} */
+ @Override
+ public boolean equals(Object obj) {
+ ListAttribute attribute = (ListAttribute) obj;
+ return super.equals(attribute) && this.inherit == attribute.inherit;
+ }
+
+ /** {...@inheritdoc} */
+ @Override
+ public int hashCode() {
+ return super.hashCode() + Boolean.valueOf(inherit).hashCode();
+ }
+
+ /** {...@inheritdoc} */
+ @Override
+ public ListAttribute clone() {
+ return new ListAttribute(this);
+ }
}
Modified:
tiles/framework/trunk/tiles-api/src/test/java/org/apache/tiles/BasicAttributeContextTest.java
URL:
http://svn.apache.org/viewvc/tiles/framework/trunk/tiles-api/src/test/java/org/apache/tiles/BasicAttributeContextTest.java?rev=788065&r1=788064&r2=788065&view=diff
==============================================================================
---
tiles/framework/trunk/tiles-api/src/test/java/org/apache/tiles/BasicAttributeContextTest.java
(original)
+++
tiles/framework/trunk/tiles-api/src/test/java/org/apache/tiles/BasicAttributeContextTest.java
Wed Jun 24 16:05:28 2009
@@ -20,6 +20,7 @@
*/
package org.apache.tiles;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
@@ -443,4 +444,36 @@
assertTrue("There are cascaded attributes", names == null
|| names.isEmpty());
}
+
+ /**
+ * Tests {...@link BasicAttributeContext} for the TILES-429 bug.
+ */
+ public void testTiles429() {
+ AttributeContext toCopy = new BasicAttributeContext();
+ toCopy.putAttribute("name1", new Attribute("value1"), false);
+ toCopy.putAttribute("name2", new Attribute("value2"), true);
+ List<Object> listOfObjects = new ArrayList<Object>();
+ listOfObjects.add(1);
+ ListAttribute listAttribute = new ListAttribute(listOfObjects);
+ listAttribute.setInherit(true);
+ toCopy.putAttribute("name3", listAttribute);
+ Attribute templateAttribute = Attribute
+ .createTemplateAttribute("/template.jsp");
+ Set<String> roles = new HashSet<String>();
+ roles.add("role1");
+ roles.add("role2");
+ templateAttribute.setRoles(roles);
+ toCopy.setTemplateAttribute(templateAttribute);
+ toCopy.setPreparer("my.preparer.Preparer");
+ AttributeContext context = new BasicAttributeContext(toCopy);
+ Attribute attribute = context.getAttribute("name1");
+ attribute.setValue("newValue1");
+ attribute = context.getAttribute("name1");
+ assertEquals("newValue1", attribute.getValue());
+ attribute = toCopy.getAttribute("name1");
+ assertEquals("value1", attribute.getValue());
+ attribute = context.getAttribute("name3");
+ assertTrue(attribute instanceof ListAttribute);
+ assertTrue(((ListAttribute) attribute).isInherit());
+ }
}