/* This file is part of Cyclos (www.cyclos.org). A project of the Social Trade Organisation (www.socialtrade.org). Cyclos is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Cyclos is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Cyclos; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package nl.strohalm.cyclos.http; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.collections.iterators.IteratorEnumeration; /** * An {@link AttributeHolder} which has another {@link AttributeHolder} as base, and keeps a local copy of the attributes. It allows resetting to the * original state and applying the local attribute modifications to the original {@link AttributeHolder} * @author luis */ public class ResettableAttributeHolder implements AttributeHolder, Resettable { /** * Determines an operation over attributes * @author luis */ private abstract static class AttributeOperation { /** * Creates an operation for removing an attribute */ private static AttributeOperation remove(final String name) { return new AttributeOperation() { @Override public void apply(final AttributeHolder holder) { holder.removeAttribute(name); } }; } /** * Creates an operation for setting an attribute */ private static AttributeOperation set(final String name, final Object value) { return new AttributeOperation() { @Override public void apply(final AttributeHolder holder) { holder.setAttribute(name, value); } }; } /** * Applies this operation over the given {@link AttributeHolder} */ public abstract void apply(AttributeHolder holder); } private AttributeHolder holder; private Map<String, Object> attributes; private List<AttributeOperation> operations; public ResettableAttributeHolder(final AttributeHolder holder) { this.holder = holder; attributes = new HashMap<String, Object>(); operations = new ArrayList<AttributeOperation>(); resetState(); } /** * Apply any pending operation to the original state */ @Override public void applyState() { for (final AttributeOperation operation : operations) { operation.apply(holder); } operations.clear(); } @Override public Object getAttribute(final String name) { return attributes.get(name); } @Override @SuppressWarnings("unchecked") public Enumeration<String> getAttributeNames() { return new IteratorEnumeration(attributes.keySet().iterator()); } @Override public void removeAttribute(final String name) { operations.add(AttributeOperation.remove(name)); attributes.remove(name); } /** * Resets this object to the original state */ @Override public void resetState() { attributes.clear(); operations.clear(); // Copy each original attribute final Enumeration<String> attributeNames = holder.getAttributeNames(); while (attributeNames.hasMoreElements()) { final String key = attributeNames.nextElement(); attributes.put(key, holder.getAttribute(key)); } } @Override public void setAttribute(final String name, final Object value) { operations.add(AttributeOperation.set(name, value)); attributes.put(name, value); } }