001/* 002 * Copyright 2015 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.program; 017 018import java.util.HashMap; 019import java.util.Map; 020import java.util.Map.Entry; 021 022import org.apache.avalon.framework.component.Component; 023import org.apache.avalon.framework.service.ServiceException; 024import org.apache.avalon.framework.service.ServiceManager; 025import org.apache.avalon.framework.service.Serviceable; 026 027import org.ametys.cms.ObservationConstants; 028import org.ametys.cms.repository.ModifiableContent; 029import org.ametys.core.observation.Event; 030import org.ametys.core.observation.ObservationManager; 031import org.ametys.core.ui.Callable; 032import org.ametys.core.user.CurrentUserProvider; 033import org.ametys.core.user.UserIdentity; 034import org.ametys.odf.ODFHelper; 035import org.ametys.odf.observation.OdfObservationConstants; 036import org.ametys.odf.translation.TranslationHelper; 037import org.ametys.plugins.repository.AmetysObjectResolver; 038import org.ametys.plugins.repository.UnknownAmetysObjectException; 039 040/** 041 * DAO for manipulating ODF programs. 042 * 043 */ 044public class ProgramDAO implements Serviceable, Component 045{ 046 /** The Avalon role */ 047 public static final String ROLE = ProgramDAO.class.getName(); 048 049 /** The ametys object resolver */ 050 protected AmetysObjectResolver _resolver; 051 /** Observer manager. */ 052 protected ObservationManager _observationManager; 053 /** The current user provider. */ 054 protected CurrentUserProvider _currentUserProvider; 055 /** ODF helper */ 056 protected ODFHelper _odfHelper; 057 058 @Override 059 public void service(ServiceManager manager) throws ServiceException 060 { 061 _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE); 062 _observationManager = (ObservationManager) manager.lookup(ObservationManager.ROLE); 063 _currentUserProvider = (CurrentUserProvider) manager.lookup(CurrentUserProvider.ROLE); 064 _odfHelper = (ODFHelper) manager.lookup(ODFHelper.ROLE); 065 } 066 067 /** 068 * Translates a given program in a language 069 * @param contentId The program id 070 * @param language The language in which to translate 071 * @param fullCopy True if full copy 072 * @return A Map with id of translated program or an error message 073 * @throws Exception if an error occurs 074 */ 075 @Callable 076 public Map<String, String> translateProgram (String contentId, String language, boolean fullCopy) throws Exception 077 { 078 Map<String, String> result = new HashMap<>(); 079 080 Program program = _resolver.resolveById(contentId); 081 082 if (program.getLanguage().equals(language)) 083 { 084 result.put("error", "same-language"); 085 return result; 086 } 087 088 Map<String, String> translatedContents = new HashMap<>(); 089 090 String translatedProgramId = null; 091 092 // Get existing translations 093 Map<String, String> translations = TranslationHelper.getTranslations(program); 094 095 if (!translations.containsKey(language)) 096 { 097 ModifiableContent translatedProgram = _odfHelper.copyProgramItem(program, null, language, null, fullCopy, translatedContents, translatedContents, translatedContents, translatedContents, translatedContents); 098 translatedProgramId = translatedProgram.getId(); 099 } 100 else 101 { 102 translatedProgramId = translations.get(language); 103 // Check if content exists 104 try 105 { 106 _resolver.resolveById(translatedProgramId); 107 result.put("error", "already-exists"); 108 } 109 catch (UnknownAmetysObjectException e) 110 { 111 ModifiableContent translatedProgram = _odfHelper.copyProgramItem(program, null, language, null, fullCopy, translatedContents, translatedContents, translatedContents, translatedContents, translatedContents); 112 translatedProgramId = translatedProgram.getId(); 113 } 114 } 115 116 linkTranslations(translatedContents); 117 118 result.put("translated-program-id", translatedProgramId); 119 120 return result; 121 } 122 123 /** 124 * Store links to the other translations for all copied contents 125 * @param translatedContents The translated contents 126 */ 127 protected void linkTranslations(Map<String, String> translatedContents) 128 { 129 for (Entry<String, String> entry : translatedContents.entrySet()) 130 { 131 ModifiableContent originalContent = _resolver.resolveById(entry.getKey()); 132 ModifiableContent translatedContent = _resolver.resolveById(entry.getValue()); 133 134 linkTranslations(originalContent, translatedContent); 135 136 originalContent.saveChanges(); 137 translatedContent.saveChanges(); 138 139 Map<String, Object> eventParams = new HashMap<>(); 140 eventParams.put(ObservationConstants.ARGS_CONTENT, originalContent); 141 142 _observationManager.notify(new Event(OdfObservationConstants.ODF_CONTENT_TRANSLATED, _getCurrentUser(), eventParams)); 143 } 144 } 145 146 /** 147 * Store links to the other translations in all the translated objects. 148 * @param originalContent The original content 149 * @param translatedContent The translated content 150 */ 151 protected void linkTranslations(ModifiableContent originalContent, ModifiableContent translatedContent) 152 { 153 Map<String, String> translations = TranslationHelper.getTranslations(originalContent); 154 155 // Add the original and translated references. 156 translations.put(originalContent.getLanguage(), originalContent.getId()); 157 translations.put(translatedContent.getLanguage(), translatedContent.getId()); 158 159 for (String contentId : translations.values()) 160 { 161 ModifiableContent content = _resolver.resolveById(contentId); 162 163 Map<String, String> otherTranslations = new HashMap<>(translations); 164 otherTranslations.remove(content.getLanguage()); 165 166 TranslationHelper.setTranslations(content, otherTranslations); 167 } 168 } 169 170 /** 171 * Provides the current user. 172 * @return the identity which cannot be <code>null</code>. 173 */ 174 protected UserIdentity _getCurrentUser() 175 { 176 return _currentUserProvider.getUser(); 177 } 178 179}