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.lang.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.RepositoryConstants;
027import org.ametys.plugins.repository.data.repositorydata.ModifiableRepositoryData;
028import org.ametys.plugins.repository.data.repositorydata.RepositoryData;
029import org.ametys.plugins.repository.data.repositorydata.impl.JCRRepositoryData;
030import org.ametys.plugins.repository.jcr.SimpleAmetysObject;
031import org.ametys.plugins.repository.lock.LockableAmetysObject;
032
033/**
034 * Translation helper: get and set translations for a content.
035 */
036public final class TranslationHelper
037{
038
039    /** The translations metadata name. */
040    public static final String TRANSLATIONS_METADATA = "translations";
041    
042    private TranslationHelper()
043    {
044        // Hide the default constructor.
045    }
046    
047    /**
048     * Get the translations of a content.
049     * @param content the Content.
050     * @return the translations as a Map of language -> content ID.
051     * FIXME CMS-9941: Use the DataHolder Internal API
052     */
053    public static Map<String, String> getTranslations(Content content)
054    {
055        Map<String, String> translations = new HashMap<>();
056        
057        RepositoryData repositoryData = _getContentRepositoryData(content);
058        if (repositoryData.hasValue(TRANSLATIONS_METADATA))
059        {
060            try
061            {
062                RepositoryData translationsRepositoryData = repositoryData.getRepositoryData(TRANSLATIONS_METADATA);
063                for (String language : translationsRepositoryData.getDataNames())
064                {
065                    String contentId = translationsRepositoryData.getString(language);
066                    if (StringUtils.isNotBlank(contentId))
067                    {
068                        translations.put(language, contentId);
069                    }
070                }
071            }
072            catch (AmetysRepositoryException e)
073            {
074                throw new AmetysRepositoryException("Error while getting translations for content " + content.getId(), e);
075            }
076        }
077        
078        return translations;
079    }
080    
081    /**
082     * Set the translations on a content.
083     * @param content the Content.
084     * @param translations the translations to set, as a Map of language -&gt; content ID.
085     * FIXME CMS-9941: Use the DataHolder Internal API
086     */
087    public static void setTranslations(ModifiableContent content, Map<String, String> translations)
088    {
089        ModifiableRepositoryData repositoryData = _getContentRepositoryData(content);
090        ModifiableRepositoryData translationsRepositoryData;
091        if (repositoryData.hasValue(TRANSLATIONS_METADATA))
092        {
093            translationsRepositoryData = repositoryData.getRepositoryData(TRANSLATIONS_METADATA);
094        }
095        else
096        {
097            _addLockToken(content);
098            translationsRepositoryData = repositoryData.addRepositoryData(TRANSLATIONS_METADATA, RepositoryConstants.COMPOSITE_METADTA_NODETYPE);
099        }
100        
101        for (String language : translationsRepositoryData.getDataNames())
102        {
103            _addLockToken(content);
104            translationsRepositoryData.removeValue(language);
105        }
106        
107        for (String language : translations.keySet())
108        {
109            _addLockToken(content);
110            
111            String contentId = translations.get(language);
112            translationsRepositoryData.setValue(language, contentId);
113        }
114            
115        content.saveChanges();
116    }
117    
118    private static ModifiableRepositoryData _getContentRepositoryData(Content content)
119    {
120        if (content instanceof SimpleAmetysObject)
121        {
122            return new JCRRepositoryData(((SimpleAmetysObject) content).getNode());
123        }
124        else
125        {
126            throw new IllegalArgumentException("Unable to acces to the translation of the content '" + content.getId() + "'.");
127        }
128    }
129
130    private static void _addLockToken(ModifiableContent content)
131    {
132        if (content instanceof LockableAmetysObject lockableContent)
133        {
134            lockableContent.setLockInfoOnCurrentContext();
135        }
136    }
137}