001/*
002 *  Copyright 2011 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.odf.translation;
017
018import java.util.HashMap;
019import java.util.Map;
020
021import org.apache.commons.lang3.StringUtils;
022
023import org.ametys.cms.repository.Content;
024import org.ametys.cms.repository.ModifiableContent;
025import org.ametys.plugins.repository.AmetysRepositoryException;
026import org.ametys.plugins.repository.data.holder.ModifiableDataHolder;
027import org.ametys.plugins.repository.data.holder.group.Composite;
028import org.ametys.plugins.repository.data.holder.group.ModifiableComposite;
029import org.ametys.plugins.repository.lock.LockableAmetysObject;
030
031/**
032 * Translation helper: get and set translations for a content.
033 */
034public final class TranslationHelper
035{
036
037    /** The translations metadata name. */
038    public static final String TRANSLATIONS_METADATA = "translations";
039    
040    private TranslationHelper()
041    {
042        // Hide the default constructor.
043    }
044    
045    /**
046     * Get the translations of a content.
047     * @param content the Content.
048     * @return the translations as a Map of language -> content ID.
049     * FIXME CMS-9941: Use the DataHolder Internal API
050     */
051    public static Map<String, String> getTranslations(Content content)
052    {
053        Map<String, String> translations = new HashMap<>();
054        
055        ModifiableDataHolder internalDataHolder = content.getInternalDataHolder();
056        if (internalDataHolder.hasValue(TRANSLATIONS_METADATA))
057        {
058            try
059            {
060                Composite translationsComposite = internalDataHolder.getComposite(TRANSLATIONS_METADATA);
061                for (String language : translationsComposite.getDataNames())
062                {
063                    String contentId = translationsComposite.getValue(language);
064                    if (StringUtils.isNotBlank(contentId))
065                    {
066                        translations.put(language, contentId);
067                    }
068                }
069            }
070            catch (AmetysRepositoryException e)
071            {
072                throw new AmetysRepositoryException("Error while getting translations for content " + content.getId(), e);
073            }
074        }
075        
076        return translations;
077    }
078    
079    /**
080     * Set the translations on a content.
081     * @param content the Content.
082     * @param translations the translations to set, as a Map of language -&gt; content ID.
083     * FIXME CMS-9941: Use the DataHolder Internal API
084     */
085    public static void setTranslations(ModifiableContent content, Map<String, String> translations)
086    {
087        ModifiableDataHolder internalDataHolder = content.getInternalDataHolder();
088        if (!internalDataHolder.hasValue(TRANSLATIONS_METADATA))
089        {
090            _addLockToken(content);
091        }
092
093        ModifiableComposite translationsComposite = internalDataHolder.getComposite(TRANSLATIONS_METADATA, true);
094        
095        for (String language : translationsComposite.getDataNames())
096        {
097            _addLockToken(content);
098            translationsComposite.removeValue(language);
099        }
100        
101        for (String language : translations.keySet())
102        {
103            _addLockToken(content);
104            
105            String contentId = translations.get(language);
106            translationsComposite.setValue(language, contentId);
107        }
108            
109        content.saveChanges();
110    }
111    
112    private static void _addLockToken(ModifiableContent content)
113    {
114        if (content instanceof LockableAmetysObject lockableContent)
115        {
116            lockableContent.setLockInfoOnCurrentContext();
117        }
118    }
119}