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.web.repository.page; 017 018import java.util.ArrayList; 019import java.util.Collection; 020import java.util.HashMap; 021import java.util.List; 022import java.util.Map; 023import java.util.Set; 024 025import org.apache.avalon.framework.component.Component; 026import org.apache.avalon.framework.service.ServiceException; 027import org.apache.avalon.framework.service.ServiceManager; 028import org.apache.commons.lang3.StringUtils; 029 030import org.ametys.core.right.RightManager; 031import org.ametys.core.right.RightManager.RightResult; 032import org.ametys.core.ui.Callable; 033import org.ametys.core.user.CurrentUserProvider; 034import org.ametys.core.user.UserIdentity; 035import org.ametys.plugins.repository.AmetysObject; 036import org.ametys.plugins.repository.AmetysObjectIterable; 037import org.ametys.plugins.repository.AmetysObjectResolver; 038import org.ametys.plugins.repository.UnknownAmetysObjectException; 039import org.ametys.web.repository.content.WebContentDAO; 040import org.ametys.web.repository.site.Site; 041import org.ametys.web.repository.site.SiteManager; 042import org.ametys.web.repository.sitemap.Sitemap; 043import org.ametys.web.sitemap.SitemapIndicatorsHandler; 044import org.ametys.web.sitemap.SitemapTreeIndicator; 045 046/** 047 * DAO for manipulating pages 048 */ 049public class SitemapDAO extends AbstractSitemapElementsDAO implements Component 050{ 051 /** The component's role */ 052 public static final String ROLE = SitemapDAO.class.getName(); 053 054 private AmetysObjectResolver _resolver; 055 private RightManager _rightManager; 056 private CurrentUserProvider _currentUserProvider; 057 private SiteManager _siteManager; 058 private SitemapIndicatorsHandler _sitemapHandler; 059 private WebContentDAO _webContentDAO; 060 061 @Override 062 public void deferredService(ServiceManager smanager) throws ServiceException 063 { 064 super.deferredService(smanager); 065 066 _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE); 067 _rightManager = (RightManager) smanager.lookup(RightManager.ROLE); 068 _currentUserProvider = (CurrentUserProvider) smanager.lookup(CurrentUserProvider.ROLE); 069 _siteManager = (SiteManager) smanager.lookup(SiteManager.ROLE); 070 _sitemapHandler = (SitemapIndicatorsHandler) smanager.lookup(SitemapIndicatorsHandler.ROLE); 071 _webContentDAO = (WebContentDAO) smanager.lookup(WebContentDAO.ROLE); 072 } 073 074 /** 075 * Get sitemap properties 076 * @param sitemapId the sitemap ID 077 * @return the sitemap's properties or null if not found 078 */ 079 public Map<String, Object> getSitemap(String sitemapId) 080 { 081 return getSitemap(sitemapId, null, null); 082 } 083 084 /** 085 * Get sitemap properties 086 * @param sitemapId the sitemap ID 087 * @param zoneName The optional zone name to limit informations of zones to that zone. Can be null or empty to avoid limitation. 088 * @param zoneItemId The optional zone item identifier to limit informations of zones to that zone item. Can be null or empty to avoid limitation. 089 * @return the sitemap's properties or null if not found 090 */ 091 @Callable(rights = Callable.NO_CHECK_REQUIRED) // Required by the SitemapMessageTargetFactory 092 public Map<String, Object> getSitemap(String sitemapId, String zoneName, String zoneItemId) 093 { 094 try 095 { 096 Sitemap sitemap = _resolver.resolveById(sitemapId); 097 098 Map<String, Object> infos = new HashMap<>(); 099 100 infos.put("id", sitemap.getId()); 101 infos.put("name", sitemap.getName()); 102 infos.put("siteName", sitemap.getSiteName()); 103 infos.put("isModifiable", true); 104 infos.put("rights", getUserRights(sitemap)); 105 106 String type = sitemap.getTemplate() != null ? "container" : "node"; 107 infos.put("type", type); 108 109 // limitation information 110 if (StringUtils.isNotBlank(zoneName)) 111 { 112 infos.put("zoneName", zoneName); 113 } 114 if (StringUtils.isNotBlank(zoneItemId)) 115 { 116 infos.put("zoneItemId", zoneItemId); 117 } 118 119 switch (type) 120 { 121 case "container": 122 infos.putAll(_sitemapElement2json(sitemap, zoneName, zoneItemId)); 123 break; 124 default: 125 } 126 127 return infos; 128 } 129 catch (UnknownAmetysObjectException e) 130 { 131 return null; 132 } 133 } 134 135 /** 136 * Get properties of a site, sitemap or on sites root node 137 * @param siteName the site name. Set to null to get properties of sites root node 138 * @param lang the sitemap language. Set to null to get properties of site node 139 * @return the properties 140 */ 141 public Map<String, Object> getProperties(String siteName, String lang) 142 { 143 Map<String, Object> result = new HashMap<>(); 144 145 if (StringUtils.isEmpty(siteName)) 146 { 147 // Get information on root sites node 148 AmetysObject root = _siteManager.getRoot(); 149 result.put("id", root.getId()); 150 result.put("name", root.getId()); 151 } 152 else if (StringUtils.isEmpty(lang)) 153 { 154 // Get properties on site node 155 Site site = _siteManager.getSite(siteName); 156 result.put("id", site.getId()); 157 result.put("name", site.getName()); 158 result.put("title", site.getTitle()); 159 } 160 else 161 { 162 // Get properties on sitemap node 163 result = getSitemapProperties(siteName, lang, null); 164 } 165 166 return result; 167 } 168 169 /** 170 * Get the sitemap properties as JSON object 171 * @param siteName the site name. Set to null to get properties of sites root node 172 * @param lang the sitemap language. Set to null to get properties of site node 173 * @param rights If not null, the sitemap properties will contain a 'isAllowed' property based on user rights. Can be null. 174 * @return the sitemap properties 175 */ 176 @Callable(rights = Callable.NO_CHECK_REQUIRED) // required by the select-page widget 177 public Map<String, Object> getSitemapProperties(String siteName, String lang, List<String> rights) 178 { 179 Site site = _siteManager.getSite(siteName); 180 Sitemap sitemap = site.getSitemap(lang); 181 182 return getSitemapProperties(sitemap, rights); 183 } 184 185 /** 186 * Get the sitemap properties into a JSON object 187 * @param sitemap The sitemap 188 * @param rightsToCheck If not null, the sitemap properties will contain a 'isAllowed' property based on user rights. Can be null. 189 * @return the sitemap properties 190 */ 191 public Map<String, Object> getSitemapProperties(Sitemap sitemap, List<String> rightsToCheck) 192 { 193 Map<String, Object> jsonObject = new HashMap<>(); 194 195 jsonObject.put("id", sitemap.getId()); 196 jsonObject.put("name", sitemap.getName()); 197 jsonObject.put("lang", sitemap.getName()); 198 jsonObject.put("siteName", sitemap.getSiteName()); 199 200 if (rightsToCheck != null) 201 { 202 jsonObject.put("isAllowed", isCurrentUserAllowed(sitemap, rightsToCheck)); 203 } 204 205 return jsonObject; 206 } 207 208 /** 209 * Returns the properties of referencing pages of the given content 210 * @param contentId The content's id 211 * @return The list of referencing pages' properties 212 */ 213 @Callable(rights = "Web_Rights_Tool_Sitemap") 214 public List<Map<String, Object>> getReferencingPages (String contentId) 215 { 216 List<Map<String, Object>> referencingPages = new ArrayList<>(); 217 218 Collection<Page> pages = _webContentDAO.getReferencingPages(contentId); 219 for (Page page : pages) 220 { 221 referencingPages.add(getPageProperties(page)); 222 } 223 224 return referencingPages; 225 } 226 227 /** 228 * Get the properties of a page in order to display it into a sitemap tree 229 * @param pageId The page's id 230 * @return The page's properties 231 */ 232 @Callable(rights = "Web_Rights_Tool_Sitemap") 233 public Map<String, Object> getPageProperties(String pageId) 234 { 235 return getPageProperties((Page) _resolver.resolveById(pageId)); 236 } 237 238 /** 239 * Get the properties of a page in order to display it into a sitemap tree 240 * @param page The page 241 * @return The page's properties 242 */ 243 public Map<String, Object> getPageProperties(Page page) 244 { 245 return getPageProperties(page, null); 246 } 247 248 /** 249 * Get the properties of a page in order to display it into a sitemap tree 250 * @param page The page 251 * @param rightsToCheck If not null, the page properties will contain a 'isAllowed' property based on user rights 252 * @return The page's properties 253 */ 254 public Map<String, Object> getPageProperties(Page page, List<String> rightsToCheck) 255 { 256 boolean hasChild = page.getChildrenPages().iterator().hasNext(); 257 boolean isLocked = page instanceof LockablePage lockablePage && lockablePage.isLocked(); 258 Map<String, Object> jsonObject = new HashMap<>(); 259 260 jsonObject.put("id", page.getId()); 261 jsonObject.put("name", page.getName()); 262 jsonObject.put("siteName", page.getSiteName()); 263 jsonObject.put("lang", page.getSitemapName()); 264 jsonObject.put("title", page.getTitle()); 265 jsonObject.put("longTitle", page.getLongTitle()); 266 jsonObject.put("type", page.getType()); 267 jsonObject.put("template", page.getTemplate()); 268 jsonObject.put("path", page.getPathInSitemap()); 269 jsonObject.put("moveable", page instanceof MoveablePage && !isLocked); 270 jsonObject.put("modifiable", page instanceof ModifiablePage); 271 jsonObject.put("hasChild", hasChild); 272 jsonObject.put("locked", isLocked); 273 274 SitemapTreeIndicator icon = _sitemapHandler.getIcon(page); 275 276 jsonObject.put("iconGlyph", icon.getIconGlyph()); 277 jsonObject.put("iconDecorator", icon.getIconDecorator()); 278 jsonObject.put("iconSmall", icon.getIcon()); 279 280 List<String> decorators = new ArrayList<>(); 281 for (SitemapTreeIndicator decorator : _sitemapHandler.getDecorators(page)) 282 { 283 decorators.add(decorator.getId()); 284 } 285 jsonObject.put("decorators", StringUtils.join(decorators, ",")); 286 287 if (!hasChild) 288 { 289 jsonObject.put("pages", new ArrayList<>()); 290 } 291 292 if (rightsToCheck != null) 293 { 294 jsonObject.put("isAllowed", isCurrentUserAllowed(page, rightsToCheck)); 295 } 296 return jsonObject; 297 } 298 299 /** 300 * Determines if the current user has the requested right on this sitemap element 301 * @param sitemapElement The sitemap element 302 * @param rights The rights to check 303 * @return true if the current user is allowed 304 */ 305 public boolean isCurrentUserAllowed(SitemapElement sitemapElement, List<String> rights) 306 { 307 if (rights == null || rights.isEmpty()) 308 { 309 return true; 310 } 311 312 for (String rightId : rights) 313 { 314 if (_rightManager.currentUserHasRight(rightId, sitemapElement) != RightResult.RIGHT_ALLOW) 315 { 316 return false; 317 } 318 } 319 320 return true; 321 } 322 323 /** 324 * Get the path of pages which match filter regexp 325 * @param id The id of page or sitemap to start search 326 * @param value the value to match 327 * @return the matching paths 328 */ 329 @Callable(rights = Callable.NO_CHECK_REQUIRED) // required by the select-page widget 330 public List<String> filterPagesByRegExp(String id, String value) 331 { 332 List<String> matchingPaths = new ArrayList<>(); 333 334 SitemapElement container = _resolver.resolveById(id); 335 336 String toMatch = StringUtils.stripAccents(value.toLowerCase()).trim(); 337 338 AmetysObjectIterable< ? extends Page> childrenPages = container.getChildrenPages(); 339 for (Page childPage : childrenPages) 340 { 341 _getMatchingPages(childPage, toMatch, matchingPaths); 342 } 343 344 return matchingPaths; 345 } 346 347 private void _getMatchingPages(Page page, String value, List<String> matchingPaths) 348 { 349 String title = StringUtils.stripAccents(page.getTitle().toLowerCase()); 350 if (title.contains(value)) 351 { 352 matchingPaths.add(page.getPathInSitemap()); 353 } 354 355 AmetysObjectIterable< ? extends Page> childrenPages = page.getChildrenPages(); 356 for (Page childPage : childrenPages) 357 { 358 _getMatchingPages (childPage, value, matchingPaths); 359 } 360 } 361 362 /** 363 * Get the sitemap's decorators 364 * @param siteName the site name 365 * @return the list of decorators 366 */ 367 public List<Map<String, Object>> getDecorators (String siteName) 368 { 369 Site site = _siteManager.getSite(siteName); 370 371 List<Map<String, Object>> decorators = new ArrayList<>(); 372 373 for (SitemapTreeIndicator decorator : _sitemapHandler.getDecorators(site)) 374 { 375 Map<String, Object> object = new HashMap<>(); 376 object.put("id", decorator.getId()); 377 object.put("label", decorator.getLabel()); 378 379 if (StringUtils.isNotBlank(decorator.getIcon())) 380 { 381 object.put("icon", decorator.getIcon()); 382 } 383 if (StringUtils.isNotBlank(decorator.getIconGlyph())) 384 { 385 object.put("iconGlyph", decorator.getIconGlyph()); 386 } 387 388 decorators.add(object); 389 } 390 391 return decorators; 392 } 393 394 /** 395 * Get the id of a page from its site name, language and sitemap's path 396 * @param siteName The site name 397 * @param lang The language 398 * @param path the page's path. Can be null to get sitemap's id 399 * @return the page id or null if not found 400 */ 401 @Callable(rights = Callable.NO_CHECK_REQUIRED) 402 public String convertPathToId (String siteName, String lang, String path) 403 { 404 assert lang != null; 405 assert siteName != null; 406 407 Site site = _siteManager.getSite(siteName); 408 assert site != null; 409 410 Sitemap sitemap = site.getSitemap(lang); 411 assert sitemap != null; 412 413 try 414 { 415 if (path != null) 416 { 417 return sitemap.getChild(path).getId(); 418 } 419 else 420 { 421 return sitemap.getId(); 422 } 423 } 424 catch (UnknownAmetysObjectException e) 425 { 426 return null; 427 } 428 } 429 430 431 /** 432 * Get the user rights on a sitemap 433 * @param sitemap the sitemap 434 * @return The user's rights 435 */ 436 protected Set<String> getUserRights (Sitemap sitemap) 437 { 438 UserIdentity user = _currentUserProvider.getUser(); 439 return _rightManager.getUserRights(user, sitemap); 440 } 441}