001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.util;
029
030import java.io.Serializable;
031import java.util.Comparator;
032import java.util.LinkedHashMap;
033import java.util.List;
034import java.util.Map;
035
036import com.google.common.base.Objects;
037
038/**
039 * Generic pair class.<p>
040 *
041 * @param <A> type of the first component of the pair
042 * @param <B> type of the second component of the pair
043 *
044 * @since 8.0.0
045 */
046public class CmsPair<A, B> implements Serializable {
047
048    /** Serial version id. */
049    private static final long serialVersionUID = 1185676847810113664L;
050
051    /** First component of the pair. */
052    private A m_first;
053
054    /** Second component of the pair. */
055    private B m_second;
056
057    /**
058     * Serialization constructor.<p>
059     */
060    public CmsPair() {
061
062        // do nothing
063    }
064
065    /**
066     * Creates a new pair containing two objects.<p>
067     *
068     * @param a the first component
069     * @param b the second component
070     */
071    public CmsPair(A a, B b) {
072
073        m_first = a;
074        m_second = b;
075    }
076
077    /**
078     * Helper method for constructing a pair which avoids having to explicitly write the generic type parameters.<p>
079     *
080     * @param <A> the type for the first component
081     * @param <B> the type for the second component
082     *
083     * @param a the first component
084     * @param b the second component
085     *
086     * @return the pair (a, b)
087     */
088    public static <A, B> CmsPair<A, B> create(A a, B b) {
089
090        return new CmsPair<A, B>(a, b);
091    }
092
093    /**
094     * Utility method which creates a new comparator for lexically ordering pairs.<p>
095     *
096     * Lexical ordering means that a pair is considered "less" than another if either its
097     * first component is less than that of the other one, or their first components are equal
098     * and the second component of the first pair is less than that of the other one.<p>
099     *
100     * @param <A> the type parameter for the first pair component
101     * @param <B> the type parameter for the second pair component
102     *
103     * @return a new comparator for lexically ordering pairs
104     */
105    public static <A extends Comparable<A>, B extends Comparable<B>> Comparator<CmsPair<A, B>> getLexicalComparator() {
106
107        return new Comparator<CmsPair<A, B>>() {
108
109            /**
110             * @see java.util.Comparator#compare(Object,Object)
111             */
112            public int compare(CmsPair<A, B> pair1, CmsPair<A, B> pair2) {
113
114                int c = pair1.getFirst().compareTo(pair2.getFirst());
115                if (c != 0) {
116                    return c;
117                }
118                return pair1.getSecond().compareTo(pair2.getSecond());
119            }
120        };
121    }
122
123    /**
124     * Helper method for converting a list of string pairs to a string map.<p>
125     *
126     * The first component of each pair is used as a map key, the second component as the
127     * value for the key.
128     *
129     * @param pairs the list of pairs
130     *
131     * @return a string map
132     */
133    public static Map<String, String> pairsToMap(List<CmsPair<String, String>> pairs) {
134
135        LinkedHashMap<String, String> result = new LinkedHashMap<String, String>();
136        for (CmsPair<String, String> pair : pairs) {
137            result.put(pair.getFirst(), pair.getSecond());
138        }
139        return result;
140    }
141
142    /**
143     * @see java.lang.Object#equals(java.lang.Object)
144     */
145    @SuppressWarnings("rawtypes")
146    @Override
147    public boolean equals(Object o) {
148
149        if ((o == null) || !(o instanceof CmsPair)) {
150            return false;
151        }
152        CmsPair otherPair = (CmsPair)o;
153        return getFirst().equals(otherPair.getFirst()) && getSecond().equals(otherPair.getSecond());
154    }
155
156    /**
157     * Returns the first component of the pair.<p>
158     *
159     * @return the first component of the pair
160     */
161    public A getFirst() {
162
163        return m_first;
164    }
165
166    /**
167     * Returns the second component of the pair.<p>
168     *
169     * @return the second component of the pair
170     */
171    public B getSecond() {
172
173        return m_second;
174    }
175
176    /**
177     * @see java.lang.Object#hashCode()
178     */
179    @Override
180    public int hashCode() {
181
182        return Objects.hashCode(getFirst(), getSecond());
183    }
184
185}