001/*
002 *  Copyright 2017 Anyware Services
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 *      http://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 */
016package org.ametys.plugins.repository.metadata;
017
018import java.util.Arrays;
019import java.util.HashMap;
020import java.util.List;
021import java.util.Locale;
022import java.util.Map;
023import java.util.Set;
024import java.util.stream.Collectors;
025
026import org.apache.commons.lang3.StringUtils;
027
028import org.ametys.plugins.repository.AmetysRepositoryException;
029
030/**
031 * Class representing a multilingual String
032 */
033public class MultilingualString
034{
035    private Map<Locale, String> _values;
036
037    /**
038     * Construct an empty multilingual string
039     */
040    public MultilingualString ()
041    {
042        _values = new HashMap<>();
043    }
044    
045    /**
046     * Construct an multilingual string
047     * @param values The values of each locale
048     */
049    public MultilingualString (Map<Locale, String> values)
050    {
051        _values = values;
052    }
053    
054    /**
055     * Add or replace value for a specific locale.
056     * @param locale The locale. Can not be null.
057     * @param value The value for this locale.
058     */
059    public void add(Locale locale, String value)
060    {
061        _values.put(locale, value);
062    }
063    
064    /**
065     * Returns the value in the given locale as String.<br> 
066     * @param locale the locale of value to retrieve
067     * @return the value as String or <code>null</code> if not found
068     */
069    public String getValue(Locale locale)
070    {
071        return _values.get(locale);
072    }
073    
074    /**
075     * Returns the existing {@link Locale}s
076     * @return the locales
077     */
078    public Set<Locale> getLocales()
079    {
080        return _values.keySet();
081    }
082    
083    /**
084     * Get all non-empty values
085     * @return the values
086     */
087    public List<String> getValues()
088    {
089        return _values.values().stream().filter(v -> StringUtils.isNotEmpty(v)).collect(Collectors.toList());
090    }
091    
092    /**
093     * Determines if this multilingual string has value for the given locale
094     * @param locale The locale to test
095     * @return <code>true</code> if a value exists for this locale
096     * @throws AmetysRepositoryException if an error occurs.
097     */
098    public boolean hasLocale(Locale locale)
099    {
100        return _values.containsKey(locale);
101    }
102    
103    
104    @Override
105    public boolean equals(Object obj)
106    {
107        if (this == obj)
108        {
109            return true;
110        }
111        if (obj == null)
112        {
113            return false;
114        }
115        if (!(obj instanceof MultilingualString))
116        {
117            return false;
118        }
119        
120        MultilingualString other = (MultilingualString) obj;
121        
122        Locale[] locales = getLocales().stream().toArray(Locale[]::new);
123        Locale[] otherLocales = other.getLocales().stream().toArray(Locale[]::new);
124        
125        if (!Arrays.deepEquals(locales, otherLocales))
126        {
127            return false;
128        }
129        
130        for (Locale locale : locales)
131        {
132            if (!getValue(locale).equals(other.getValue(locale)))
133            {
134                return false;
135            }
136        }
137        
138        return true;
139    }
140    
141    @Override
142    public int hashCode()
143    {
144        return _values.hashCode();
145    }
146}