    001    // Copyright 2006 The Apache Software Foundation
    002    //
    003    // Licensed under the Apache License, Version 2.0 (the "License");
    004    // you may not use this file except in compliance with the License.
    005    // You may obtain a copy of the License at
    006    //
    007    //     http://www.apache.org/licenses/LICENSE-2.0
    008    //
    009    // Unless required by applicable law or agreed to in writing, software
    010    // distributed under the License is distributed on an "AS IS" BASIS,
    011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    012    // See the License for the specific language governing permissions and
    013    // limitations under the License.
    014
    015    package org.apache.tapestry5.internal.util;
    016
    017    import java.util.Arrays;
    018
    019    /**
    020     * Combines multiple values to form a single composite key. MultiKey can often be used as an alternative to nested
    021     * maps.
    022     */
    023    public final class MultiKey
    024    {
    025        private static final int PRIME = 31;
    026
    027        private final Object[] values;
    028
    029        private final int hashCode;
    030
    031        /**
    032         * Creates a new instance from the provided values. It is assumed that the values provided are good map keys
    033         * themselves -- immutable, with proper implementations of equals() and hashCode().
    034         *
    035         * @param values
    036         */
    037        public MultiKey(Object... values)
    038        {
    039            this.values = values;
    040
    041            hashCode = PRIME * Arrays.hashCode(this.values);
    042        }
    043
    044        @Override
    045        public int hashCode()
    046        {
    047            return hashCode;
    048        }
    049
    050        @Override
    051        public boolean equals(Object obj)
    052        {
    053            if (this == obj)
    054                return true;
    055            if (obj == null)
    056                return false;
    057            if (getClass() != obj.getClass())
    058                return false;
    059            final MultiKey other = (MultiKey) obj;
    060
    061            return Arrays.equals(values, other.values);
    062        }
    063
    064        @Override
    065        public String toString()
    066        {
    067            StringBuilder builder = new StringBuilder("MultiKey[");
    068
    069            boolean first = true;
    070
    071            for (Object o : values)
    072            {
    073                if (!first)
    074                    builder.append(", ");
    075
    076                builder.append(o);
    077
    078                first = false;
    079            }
    080
    081            builder.append("]");
    082
    083            return builder.toString();
    084        }
    085
    086    }