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.userdirectory.clientsideelement; 017 018import java.util.ArrayList; 019import java.util.Arrays; 020import java.util.HashMap; 021import java.util.List; 022import java.util.Map; 023import java.util.stream.Collectors; 024 025import javax.jcr.Node; 026import javax.jcr.RepositoryException; 027import javax.jcr.Value; 028 029import org.apache.avalon.framework.service.ServiceException; 030import org.apache.avalon.framework.service.ServiceManager; 031import org.apache.jackrabbit.value.StringValue; 032 033import org.ametys.core.observation.Event; 034import org.ametys.core.observation.ObservationManager; 035import org.ametys.core.ui.Callable; 036import org.ametys.core.util.LambdaUtils; 037import org.ametys.plugins.repository.AmetysObjectResolver; 038import org.ametys.plugins.repository.jcr.JCRAmetysObject; 039import org.ametys.plugins.userdirectory.OrganisationChartPageHandler; 040import org.ametys.plugins.userdirectory.observation.ObservationConstants; 041import org.ametys.plugins.userdirectory.page.VirtualOrganisationChartPageFactory; 042import org.ametys.runtime.i18n.I18nizableText; 043import org.ametys.web.clientsideelement.AbstractPageClientSideElement; 044import org.ametys.web.repository.page.Page; 045 046/** 047 * Client side element for a controller wich set/remove the organisation chart root page 048 */ 049public class SetOrganisationChartRootClientSideElement extends AbstractPageClientSideElement 050{ 051 /** Observer manager. */ 052 protected ObservationManager _observationManager; 053 054 /** The organisation chart page handler */ 055 protected OrganisationChartPageHandler _pageHandler; 056 057 @Override 058 public void service(ServiceManager smanager) throws ServiceException 059 { 060 super.service(smanager); 061 _observationManager = (ObservationManager) smanager.lookup(ObservationManager.ROLE); 062 _pageHandler = (OrganisationChartPageHandler) smanager.lookup(OrganisationChartPageHandler.ROLE); 063 } 064 065 /** 066 * Gets the status of the given page 067 * @param pageId The page id 068 * @return the status of the given page 069 */ 070 @Callable 071 public Map<String, Object> getStatus(String pageId) 072 { 073 Map<String, Object> result = new HashMap<>(); 074 075 Map<String, Object> parameters = this._script.getParameters(); 076 077 Page page = _resolver.resolveById(pageId); 078 079 if (page instanceof JCRAmetysObject) 080 { 081 if (_pageHandler.isOrganisationChartRootPage((JCRAmetysObject) page)) 082 { 083 List<String> i18nParameters = new ArrayList<>(); 084 i18nParameters.add(page.getTitle()); 085 086 I18nizableText ed = (I18nizableText) parameters.get("organisation-chart-page-description"); 087 I18nizableText msg = new I18nizableText(ed.getCatalogue(), ed.getKey(), i18nParameters); 088 result.put("organisation-chart-page-title", msg); 089 090 ed = (I18nizableText) parameters.get("remove-organisation-chart-page-description"); 091 msg = new I18nizableText(ed.getCatalogue(), ed.getKey(), i18nParameters); 092 result.put("remove-organisation-chart-page-title", msg); 093 094 result.put("organisation-chart-page-id", new I18nizableText(page.getId())); 095 } 096 else if (_pageHandler.getOrganisationChartRootPages(page.getSiteName(), page.getSitemapName()) != null) 097 { 098 I18nizableText ed = (I18nizableText) parameters.get("organisation-chart-root-already-exist"); 099 result.put("organisation-chart-root-already-exist", ed); 100 } 101 else 102 { 103 List<String> i18nParameters = new ArrayList<>(); 104 i18nParameters.add(page.getTitle()); 105 106 I18nizableText ed = (I18nizableText) parameters.get("add-organisation-chart-page-description"); 107 I18nizableText msg = new I18nizableText(ed.getCatalogue(), ed.getKey(), i18nParameters); 108 109 result.put("add-organisation-chart-page-id", new I18nizableText(page.getId())); 110 result.put("add-organisation-chart-page-title", msg); 111 } 112 } 113 else 114 { 115 List<String> noJcrI18nParameters = new ArrayList<>(); 116 noJcrI18nParameters.add(page.getTitle()); 117 118 I18nizableText ed = (I18nizableText) parameters.get("no-jcr-page-description"); 119 I18nizableText msg = new I18nizableText(ed.getCatalogue(), ed.getKey(), noJcrI18nParameters); 120 121 result.put("no-jcr-page-id", new I18nizableText(page.getId())); 122 result.put("no-jcr-page-title", msg); 123 } 124 125 return result; 126 } 127 128 /** 129 * Sets the given page as the root of a organisation chart 130 * @param pageId The id of the page 131 * @return A result map 132 * @throws RepositoryException if a repository error occured 133 */ 134 @Callable 135 public Map<String, Object> setOrganisationChartRoot(String pageId) throws RepositoryException 136 { 137 Map<String, Object> result = new HashMap<>(); 138 139 Page page = _resolver.resolveById(pageId); 140 141 if (_pageHandler.getOrganisationChartRootPages(page.getSiteName(), page.getSitemapName()) != null) 142 { 143 result.put("error", "already-exist"); 144 return result; 145 } 146 147 Map<String, Object> eventParams = new HashMap<>(); 148 eventParams.put(org.ametys.web.ObservationConstants.ARGS_PAGE, page); 149 150 _addOrganisationChartRootProperty(page); 151 152 // Live synchronization 153 _notifyPageUpdated(page); 154 155 // Indexation 156 _observationManager.notify(new Event(ObservationConstants.EVENT_ORGANISATION_CHART_ROOT_UPDATED, _currentUserProvider.getUser(), eventParams)); 157 return result; 158 } 159 160 /** 161 * Remove the organisation chart root status to the given page 162 * @param pageId The id of the page 163 * @return A result map 164 * @throws RepositoryException if a repository error occured 165 */ 166 @Callable 167 public Map<String, Object> removeOrganisationChartRoot(String pageId) throws RepositoryException 168 { 169 Map<String, Object> result = new HashMap<>(); 170 171 Page page = _resolver.resolveById(pageId); 172 173 if (page instanceof JCRAmetysObject) 174 { 175 if (!_pageHandler.isOrganisationChartRootPage((JCRAmetysObject) page)) 176 { 177 result.put("error", "no-root"); 178 return result; 179 } 180 181 Map<String, Object> eventParams = new HashMap<>(); 182 eventParams.put(org.ametys.web.ObservationConstants.ARGS_PAGE, page); 183 184 // Unindex pages for all workspaces before the properties were removed 185 _observationManager.notify(new Event(ObservationConstants.EVENT_ORGANISATION_CHART_ROOT_DELETING, _currentUserProvider.getUser(), eventParams)); 186 187 _removeUserDirectoryRootProperty(page); 188 189 _notifyPageUpdated(page); 190 191 // After live synchronization 192 _observationManager.notify(new Event(ObservationConstants.EVENT_ORGANISATION_CHART_ROOT_DELETED, _currentUserProvider.getUser(), eventParams)); 193 } 194 else 195 { 196 result.put("error", "no-root"); 197 } 198 return result; 199 } 200 201 private void _addOrganisationChartRootProperty(Page page) throws RepositoryException 202 { 203 if (page instanceof JCRAmetysObject) 204 { 205 JCRAmetysObject jcrPage = (JCRAmetysObject) page; 206 Node node = jcrPage.getNode(); 207 208 List<Value> values = new ArrayList<>(); 209 if (node.hasProperty(AmetysObjectResolver.VIRTUAL_PROPERTY)) 210 { 211 values.addAll(Arrays.asList(node.getProperty(AmetysObjectResolver.VIRTUAL_PROPERTY).getValues())); 212 } 213 214 StringValue virtualUserDirectoryPageFactoryClassName = new StringValue(VirtualOrganisationChartPageFactory.class.getName()); 215 if (!values.contains(virtualUserDirectoryPageFactoryClassName)) 216 { 217 values.add(virtualUserDirectoryPageFactoryClassName); 218 } 219 220 node.setProperty(AmetysObjectResolver.VIRTUAL_PROPERTY, values.toArray(new Value[values.size()])); 221 jcrPage.saveChanges(); 222 } 223 } 224 225 private void _removeUserDirectoryRootProperty(Page page) throws RepositoryException 226 { 227 if (page instanceof JCRAmetysObject) 228 { 229 JCRAmetysObject jcrPage = (JCRAmetysObject) page; 230 Node node = jcrPage.getNode(); 231 232 if (node.hasProperty(AmetysObjectResolver.VIRTUAL_PROPERTY)) 233 { 234 List<Value> values = new ArrayList<>(Arrays.asList(node.getProperty(AmetysObjectResolver.VIRTUAL_PROPERTY).getValues())); 235 int index = values.stream() 236 .map(LambdaUtils.wrap(Value::getString)) 237 .collect(Collectors.toList()) 238 .indexOf(VirtualOrganisationChartPageFactory.class.getName()); 239 240 if (index != -1) 241 { 242 values.remove(index); 243 node.setProperty(AmetysObjectResolver.VIRTUAL_PROPERTY, values.toArray(new Value[values.size()])); 244 } 245 246 jcrPage.saveChanges(); 247 } 248 } 249 } 250 251 private void _notifyPageUpdated(Page page) 252 { 253 Map<String, Object> eventParams = new HashMap<>(); 254 eventParams.put(org.ametys.web.ObservationConstants.ARGS_PAGE, page); 255 _observationManager.notify(new Event(org.ametys.web.ObservationConstants.EVENT_PAGE_UPDATED, _currentUserProvider.getUser(), eventParams)); 256 } 257}