    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
    015package org.apache.tapestry5.commons.util;
    016
    017import 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 */
    023public 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    /**
    087     * Returns a copy of the values array.
    088     * @since 5.8.3
    089     */
    090    public Object[] getValues() {
    091        return values.clone();
    092    }
    093
    094}