001/*
002 * Copyright 2002-2018 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.core;
018
019import java.io.Serializable;
020import java.util.LinkedHashMap;
021import java.util.Map;
022
023import org.springframework.util.Assert;
024import org.springframework.util.StringUtils;
025
026/**
027 * Support class for {@link AttributeAccessor AttributeAccessors}, providing
028 * a base implementation of all methods. To be extended by subclasses.
029 *
030 * <p>{@link Serializable} if subclasses and all attribute values are {@link Serializable}.
031 *
032 * @author Rob Harrop
033 * @author Juergen Hoeller
034 * @since 2.0
035 */
036@SuppressWarnings("serial")
037public abstract class AttributeAccessorSupport implements AttributeAccessor, Serializable {
038
039        /** Map with String keys and Object values */
040        private final Map<String, Object> attributes = new LinkedHashMap<String, Object>(0);
041
042
043        @Override
044        public void setAttribute(String name, Object value) {
045                Assert.notNull(name, "Name must not be null");
046                if (value != null) {
047                        this.attributes.put(name, value);
048                }
049                else {
050                        removeAttribute(name);
051                }
052        }
053
054        @Override
055        public Object getAttribute(String name) {
056                Assert.notNull(name, "Name must not be null");
057                return this.attributes.get(name);
058        }
059
060        @Override
061        public Object removeAttribute(String name) {
062                Assert.notNull(name, "Name must not be null");
063                return this.attributes.remove(name);
064        }
065
066        @Override
067        public boolean hasAttribute(String name) {
068                Assert.notNull(name, "Name must not be null");
069                return this.attributes.containsKey(name);
070        }
071
072        @Override
073        public String[] attributeNames() {
074                return StringUtils.toStringArray(this.attributes.keySet());
075        }
076
077
078        /**
079         * Copy the attributes from the supplied AttributeAccessor to this accessor.
080         * @param source the AttributeAccessor to copy from
081         */
082        protected void copyAttributesFrom(AttributeAccessor source) {
083                Assert.notNull(source, "Source must not be null");
084                String[] attributeNames = source.attributeNames();
085                for (String attributeName : attributeNames) {
086                        setAttribute(attributeName, source.getAttribute(attributeName));
087                }
088        }
089
090
091        @Override
092        public boolean equals(Object other) {
093                if (this == other) {
094                        return true;
095                }
096                if (!(other instanceof AttributeAccessorSupport)) {
097                        return false;
098                }
099                AttributeAccessorSupport that = (AttributeAccessorSupport) other;
100                return this.attributes.equals(that.attributes);
101        }
102
103        @Override
104        public int hashCode() {
105                return this.attributes.hashCode();
106        }
107
108}