001/* 002 * Copyright 2018 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.translationflagging; 017 018import java.util.ArrayList; 019import java.util.HashMap; 020import java.util.HashSet; 021import java.util.List; 022import java.util.Map; 023import java.util.Map.Entry; 024import java.util.Set; 025 026import org.apache.avalon.framework.component.Component; 027import org.apache.avalon.framework.logger.AbstractLogEnabled; 028import org.apache.avalon.framework.service.ServiceException; 029import org.apache.avalon.framework.service.ServiceManager; 030import org.apache.avalon.framework.service.Serviceable; 031 032import org.ametys.core.observation.Event; 033import org.ametys.core.observation.ObservationManager; 034import org.ametys.core.user.CurrentUserProvider; 035import org.ametys.plugins.repository.AmetysObjectResolver; 036import org.ametys.plugins.repository.UnknownAmetysObjectException; 037import org.ametys.plugins.repository.metadata.CompositeMetadata; 038import org.ametys.plugins.repository.metadata.ModifiableCompositeMetadata; 039import org.ametys.plugins.repository.metadata.UnknownMetadataException; 040import org.ametys.web.ObservationConstants; 041import org.ametys.web.repository.page.ModifiablePage; 042import org.ametys.web.repository.page.Page; 043 044/** 045 * Translation page DAO 046 */ 047public class TranslationPageDAO extends AbstractLogEnabled implements Serviceable, Component 048{ 049 /** Avalon Role */ 050 public static final String ROLE = TranslationPageDAO.class.getName(); 051 052 private AmetysObjectResolver _resolver; 053 private CurrentUserProvider _currentUserProvider; 054 private ObservationManager _observationManager; 055 056 @Override 057 public void service(ServiceManager smanager) throws ServiceException 058 { 059 _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE); 060 _currentUserProvider = (CurrentUserProvider) smanager.lookup(CurrentUserProvider.ROLE); 061 _observationManager = (ObservationManager) smanager.lookup(ObservationManager.ROLE); 062 } 063 064 /** 065 * Set the translations for a specific page 066 * @param pageId The current page id 067 * @param pages the map of translated page 068 * @return The list of updated pages. 069 */ 070 public List<String> setTranslations(String pageId, Map<String, Page> pages) 071 { 072 Page currentPage = _resolver.resolveById(pageId); 073 074 // Get the collection of pages to clean. 075 Set<Page> pagesToClean = new HashSet<>(getTranslations(currentPage).values()); 076 077 // Compute all modified pages to notify the observer. 078 Set<Page> modifiedPages = new HashSet<>(pagesToClean); 079 modifiedPages.addAll(pages.values()); 080 081 // The old pages minus the new ones will be the pages to clean. 082 pagesToClean.removeAll(pages.values()); 083 084 // Clean the old pages: remove the translations metadata. 085 for (Page page : pagesToClean) 086 { 087 if (page instanceof ModifiablePage) 088 { 089 _cleanPage((ModifiablePage) page); 090 } 091 } 092 093 // Set the translations. 094 for (Page page : pages.values()) 095 { 096 if (page instanceof ModifiablePage) 097 { 098 _setTranslations((ModifiablePage) page, pages); 099 } 100 } 101 102 // Notify observers that page data has been changed 103 104 List<String> modifiedPageIds = new ArrayList<>(); 105 for (Page modifiedPage : modifiedPages) 106 { 107 if (modifiedPage != null) 108 { 109 modifiedPageIds.add(modifiedPage.getId()); 110 111 Map<String, Object> eventParams = new HashMap<>(); 112 eventParams.put(ObservationConstants.ARGS_PAGE, modifiedPage); 113 114 _observationManager.notify(new Event(ObservationConstants.EVENT_PAGE_UPDATED, _currentUserProvider.getUser(), eventParams)); 115 } 116 } 117 118 return modifiedPageIds; 119 } 120 121 /** 122 * Get the translation of a given page. 123 * @param page the page. 124 * @return the translated pages as a Map of pages, indexed by sitemap name (language). 125 */ 126 public Map<String, Page> getTranslations(Page page) 127 { 128 Map<String, Page> translations = new HashMap<>(); 129 130 CompositeMetadata meta = page.getMetadataHolder(); 131 132 try 133 { 134 CompositeMetadata transMeta = meta.getCompositeMetadata(TranslationFlaggingClientSideElement.TRANSLATIONS_META); 135 for (String lang : transMeta.getMetadataNames()) 136 { 137 String translatedPageId = transMeta.getString(lang); 138 139 try 140 { 141 Page translatedPage = _resolver.resolveById(translatedPageId); 142 translations.put(lang, translatedPage); 143 } 144 catch (UnknownAmetysObjectException e) 145 { 146 // Ignore : a removed page should be ignored 147 } 148 } 149 } 150 catch (UnknownMetadataException e) 151 { 152 // Ignore : the translations composite metadata doesn't exist, just return an empty map. 153 } 154 155 return translations; 156 } 157 158 /** 159 * Set the translations of a page in its metadata. 160 * @param page the page. 161 * @param pages the translated pages to set. 162 */ 163 protected void _setTranslations(ModifiablePage page, Map<String, Page> pages) 164 { 165 ModifiableCompositeMetadata meta = page.getMetadataHolder(); 166 167 ModifiableCompositeMetadata transMeta = meta.getCompositeMetadata(TranslationFlaggingClientSideElement.TRANSLATIONS_META, true); 168 169 for (Entry<String, Page> entry : pages.entrySet()) 170 { 171 if (!entry.getKey().equals(page.getSitemapName())) 172 { 173 if (entry.getValue() == null) 174 { 175 // Remove metadata. 176 if (transMeta.hasMetadata(entry.getKey())) 177 { 178 transMeta.removeMetadata(entry.getKey()); 179 } 180 } 181 else 182 { 183 transMeta.setMetadata(entry.getKey(), entry.getValue().getId()); 184 } 185 } 186 } 187 188 page.saveChanges(); 189 } 190 191 /** 192 * Clean a page of its translations metadata. 193 * @param page the page to clean. 194 */ 195 protected void _cleanPage(ModifiablePage page) 196 { 197 ModifiableCompositeMetadata meta = page.getMetadataHolder(); 198 199 if (meta.hasMetadata(TranslationFlaggingClientSideElement.TRANSLATIONS_META)) 200 { 201 meta.removeMetadata(TranslationFlaggingClientSideElement.TRANSLATIONS_META); 202 page.saveChanges(); 203 } 204 } 205}