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.web.filter; 017 018import java.util.ArrayList; 019import java.util.Collection; 020import java.util.Collections; 021import java.util.HashSet; 022import java.util.List; 023import java.util.Set; 024 025import org.ametys.cms.data.type.ModelItemTypeConstants; 026import org.ametys.cms.repository.Content; 027import org.ametys.cms.search.query.AndQuery; 028import org.ametys.cms.search.query.OrQuery; 029import org.ametys.cms.search.query.Query; 030import org.ametys.plugins.repository.AmetysObjectIterable; 031import org.ametys.plugins.repository.AmetysRepositoryException; 032import org.ametys.plugins.repository.query.expression.AndExpression; 033import org.ametys.plugins.repository.query.expression.Expression; 034import org.ametys.plugins.repository.query.expression.Expression.Operator; 035import org.ametys.plugins.repository.query.expression.MetadataExpression; 036import org.ametys.plugins.repository.query.expression.NotExpression; 037import org.ametys.plugins.repository.query.expression.OrExpression; 038import org.ametys.plugins.repository.query.expression.StringExpression; 039import org.ametys.runtime.model.type.ModelItemType; 040import org.ametys.web.repository.SiteAwareAmetysObject; 041import org.ametys.web.repository.content.jcr.DefaultSharedContent; 042import org.ametys.web.repository.site.Site; 043import org.ametys.web.search.query.ContentPrivacyQuery; 044import org.ametys.web.search.query.SiteQuery; 045 046/** 047 * Helper for creating expression for shared contents 048 */ 049public final class SharedContentsHelper 050{ 051 private SharedContentsHelper() 052 { 053 // empty constructor 054 } 055 056 /** 057 * Copy the title of the source content to the target content 058 * @param srcContent The source content 059 * @param targetContent The shared target content 060 * @throws AmetysRepositoryException if an error occurs. 061 */ 062 public static void copyTitle(Content srcContent, DefaultSharedContent targetContent) throws AmetysRepositoryException 063 { 064 ModelItemType type = srcContent.getType(Content.ATTRIBUTE_TITLE); 065 if (ModelItemTypeConstants.MULTILINGUAL_STRING_ELEMENT_TYPE_ID.equals(type.getId())) 066 { 067 targetContent.getDataHolder().setValue(Content.ATTRIBUTE_TITLE, srcContent.getValue(Content.ATTRIBUTE_TITLE)); 068 } 069 else 070 { 071 targetContent.getDataHolder().setValue(Content.ATTRIBUTE_TITLE, srcContent.getTitle()); 072 } 073 } 074 075 /** 076 * Get the expression for shared contents 077 * @param currentSite the current site 078 * @param site the site of contents to find 079 * @return the expression to aware of privacy of contents or null if sites are equals 080 */ 081 public static Expression getSharedContentsExpression (Site currentSite, Site site) 082 { 083 String siteName = site.getName(); 084 List<String> siteNames = new ArrayList<>(); 085 siteNames.add(siteName); 086 087 if (!siteName.equals(currentSite.getName())) 088 { 089 String privacy = site.getValue("content-privacy", true, null); 090 boolean isClosed = currentSite.hasAncestor(siteName) || currentSite.hasDescendant(siteName); 091 092 if (isClosed) 093 { 094 if ("private".equals(privacy)) 095 { 096 return getSharedContentsExpressionForPrivateClosedSites(siteNames); 097 } 098 else 099 { 100 return getSharedContentsExpressionForPublicOrProtectedClosedSites(siteNames); 101 } 102 } 103 else 104 { 105 if ("public".equals(privacy)) 106 { 107 return getSharedContentsExpressionForPublicOutsideSites(siteNames); 108 } 109 else 110 { 111 return getSharedContentsExpressionForPrivateOrProtectedOutsideSites(siteNames); 112 } 113 } 114 } 115 116 return null; 117 } 118 119 /** 120 * Get the expression for shared contents 121 * @param currentSite the current site 122 * @param sites all sites 123 * @return the expression to aware of privacy of contents 124 */ 125 public static Expression getSharedContentsExpression (Site currentSite, AmetysObjectIterable<Site> sites) 126 { 127 List<String> privateClosedSites = new ArrayList<>(); 128 List<String> publicOrProtectedClosedSites = new ArrayList<>(); 129 List<String> publicOutsideSites = new ArrayList<>(); 130 List<String> privateOrProtectedOutsideSites = new ArrayList<>(); 131 132 for (Site site : sites) 133 { 134 String siteName = site.getName(); 135 if (!siteName.equals(currentSite.getName())) 136 { 137 String privacy = site.getValue("content-privacy", false, "public"); 138 boolean isClosed = currentSite.hasAncestor(siteName) || currentSite.hasDescendant(siteName); 139 140 if (isClosed) 141 { 142 if ("private".equals(privacy)) 143 { 144 privateClosedSites.add(siteName); 145 } 146 else 147 { 148 publicOrProtectedClosedSites.add(siteName); 149 } 150 } 151 else 152 { 153 if ("public".equals(privacy)) 154 { 155 publicOutsideSites.add(siteName); 156 } 157 else 158 { 159 privateOrProtectedOutsideSites.add(siteName); 160 } 161 } 162 } 163 } 164 165 List<Expression> exprs = new ArrayList<>(); 166 167 Expression expr0 = new StringExpression(SiteAwareAmetysObject.METADATA_SITE, Operator.EQ, currentSite.getName()); 168 exprs.add(expr0); 169 170 Expression expr1 = getSharedContentsExpressionForPrivateClosedSites(privateClosedSites); 171 if (expr1 != null) 172 { 173 exprs.add(expr1); 174 } 175 176 Expression expr2 = getSharedContentsExpressionForPublicOrProtectedClosedSites(publicOrProtectedClosedSites); 177 if (expr2 != null) 178 { 179 exprs.add(expr2); 180 } 181 182 Expression expr3 = getSharedContentsExpressionForPublicOutsideSites(publicOutsideSites); 183 if (expr3 != null) 184 { 185 exprs.add(expr3); 186 } 187 188 Expression expr4 = getSharedContentsExpressionForPrivateOrProtectedOutsideSites(privateOrProtectedOutsideSites); 189 if (expr4 != null) 190 { 191 exprs.add(expr4); 192 } 193 194 return new OrExpression(exprs.toArray(new Expression[exprs.size()])); 195 } 196 197 /** 198 * Get the expression corresponding to the shared contents of privates sites 199 * @param siteNames the site names of private and closed sites 200 * @return the expression corresponding to the shared contents of privates sites 201 */ 202 public static Expression getSharedContentsExpressionForPrivateClosedSites (List<String> siteNames) 203 { 204 if (siteNames.isEmpty()) 205 { 206 return null; 207 } 208 209 Expression expr = new OrExpression(new StringExpression("privacy", Operator.EQ, "public"), new StringExpression("privacy", Operator.EQ, "protected")); 210 Expression[] sitesExpr = new Expression[siteNames.size()]; 211 212 int i = 0; 213 for (String siteName : siteNames) 214 { 215 sitesExpr[i] = new StringExpression(SiteAwareAmetysObject.METADATA_SITE, Operator.EQ, siteName); 216 i++; 217 } 218 219 return new AndExpression(new OrExpression(sitesExpr), expr); 220 } 221 222 /** 223 * Get the expression corresponding to the shared contents of public or protected sites 224 * @param siteNames the list of public or protected sites 225 * @return the expression corresponding to the shared contents of public or protected sites 226 */ 227 public static Expression getSharedContentsExpressionForPublicOrProtectedClosedSites (List<String> siteNames) 228 { 229 if (siteNames.isEmpty()) 230 { 231 return null; 232 } 233 234 Expression expr = new OrExpression(new NotExpression(new MetadataExpression("privacy")), new StringExpression("privacy", Operator.NE, "private")); 235 Expression[] sitesExpr = new Expression[siteNames.size()]; 236 237 int i = 0; 238 for (String siteName : siteNames) 239 { 240 sitesExpr[i] = new StringExpression(SiteAwareAmetysObject.METADATA_SITE, Operator.EQ, siteName); 241 i++; 242 } 243 244 return new AndExpression(new OrExpression(sitesExpr), expr); 245 } 246 247 /** 248 * Get the expression corresponding to the shared contents of public sites 249 * @param siteNames the list of public sites 250 * @return the expression corresponding to the shared contents of public sites 251 */ 252 public static Expression getSharedContentsExpressionForPublicOutsideSites (List<String> siteNames) 253 { 254 if (siteNames.isEmpty()) 255 { 256 return null; 257 } 258 259 Expression expr = new OrExpression(new NotExpression(new MetadataExpression("privacy")), new StringExpression("privacy", Operator.EQ, "public")); 260 Expression[] sitesExpr = new Expression[siteNames.size()]; 261 262 int i = 0; 263 for (String siteName : siteNames) 264 { 265 sitesExpr[i] = new StringExpression(SiteAwareAmetysObject.METADATA_SITE, Operator.EQ, siteName); 266 i++; 267 } 268 269 return new AndExpression(new OrExpression(sitesExpr), expr); 270 } 271 272 /** 273 * Get the expression corresponding to the shared contents of private or protected sites 274 * @param siteNames the list of private or protected sites 275 * @return the expression corresponding to the shared contents of private or protected sites 276 */ 277 public static Expression getSharedContentsExpressionForPrivateOrProtectedOutsideSites (List<String> siteNames) 278 { 279 if (siteNames.isEmpty()) 280 { 281 return null; 282 } 283 284 Expression expr = new StringExpression("privacy", Operator.EQ, "public"); 285 Expression[] sitesExpr = new Expression[siteNames.size()]; 286 287 int i = 0; 288 for (String siteName : siteNames) 289 { 290 sitesExpr[i] = new StringExpression(SiteAwareAmetysObject.METADATA_SITE, Operator.EQ, siteName); 291 i++; 292 } 293 294 return new AndExpression(new OrExpression(sitesExpr), expr); 295 } 296 297 /** 298 * Get the expression for shared contents 299 * @param currentSite the current site 300 * @param site the site of contents to find 301 * @return the expression to aware of privacy of contents or null if sites are equals 302 */ 303 public static Query getContentAccessQuery(Site currentSite, Site site) 304 { 305 String siteName = site.getName(); 306 307 if (!siteName.equals(currentSite.getName())) 308 { 309 String privacy = site.getValue("content-privacy", false, "public"); 310 boolean isClosed = currentSite.hasAncestor(siteName) || currentSite.hasDescendant(siteName); 311 312 if (isClosed) 313 { 314 if ("private".equals(privacy)) 315 { 316 return getContentAccessQueryForPrivateClosedSites(Collections.singleton(siteName)); 317 } 318 else 319 { 320 return getContentAccessQueryForPublicOrProtectedClosedSites(Collections.singleton(siteName)); 321 } 322 } 323 else 324 { 325 if ("public".equals(privacy)) 326 { 327 return getContentAccessQueryForPublicOutsideSites(Collections.singleton(siteName)); 328 } 329 else 330 { 331 return getContentAccessQueryForPrivateOrProtectedOutsideSites(Collections.singleton(siteName)); 332 } 333 } 334 } 335 336 return null; 337 } 338 339 /** 340 * Get the expression for shared contents 341 * @param currentSite the current site 342 * @param sites all sites 343 * @return the expression to aware of privacy of contents 344 */ 345 public static Query getContentAccessQuery(Site currentSite, Iterable<Site> sites) 346 { 347 Set<String> privateClosedSites = new HashSet<>(); 348 Set<String> publicOrProtectedClosedSites = new HashSet<>(); 349 Set<String> publicOutsideSites = new HashSet<>(); 350 Set<String> privateOrProtectedOutsideSites = new HashSet<>(); 351 boolean containsCurrent = false; 352 353 for (Site site : sites) 354 { 355 String siteName = site.getName(); 356 if (!siteName.equals(currentSite.getName())) 357 { 358 String privacy = site.getValue("content-privacy", false, "public"); 359 boolean isClosed = currentSite.hasAncestor(siteName) || currentSite.hasDescendant(siteName); 360 361 if (isClosed) 362 { 363 if ("private".equals(privacy)) 364 { 365 privateClosedSites.add(siteName); 366 } 367 else 368 { 369 publicOrProtectedClosedSites.add(siteName); 370 } 371 } 372 else 373 { 374 if ("public".equals(privacy)) 375 { 376 publicOutsideSites.add(siteName); 377 } 378 else 379 { 380 privateOrProtectedOutsideSites.add(siteName); 381 } 382 } 383 } 384 else 385 { 386 containsCurrent = true; 387 } 388 } 389 390 List<Query> queries = new ArrayList<>(); 391 392 if (containsCurrent) 393 { 394 Query expr0 = new SiteQuery(currentSite.getName()); 395 queries.add(expr0); 396 } 397 398 Query expr1 = getContentAccessQueryForPrivateClosedSites(privateClosedSites); 399 if (expr1 != null) 400 { 401 queries.add(expr1); 402 } 403 404 Query expr2 = getContentAccessQueryForPublicOrProtectedClosedSites(publicOrProtectedClosedSites); 405 if (expr2 != null) 406 { 407 queries.add(expr2); 408 } 409 410 Query expr3 = getContentAccessQueryForPublicOutsideSites(publicOutsideSites); 411 if (expr3 != null) 412 { 413 queries.add(expr3); 414 } 415 416 Query expr4 = getContentAccessQueryForPrivateOrProtectedOutsideSites(privateOrProtectedOutsideSites); 417 if (expr4 != null) 418 { 419 queries.add(expr4); 420 } 421 422 return new OrQuery(queries); 423 } 424 425 /** 426 * Get the expression corresponding to the shared contents of privates sites 427 * @param siteNames the site names of private and closed sites 428 * @return the expression corresponding to the shared contents of privates sites 429 */ 430 public static Query getContentAccessQueryForPrivateClosedSites(Collection<String> siteNames) 431 { 432 if (siteNames.isEmpty()) 433 { 434 return null; 435 } 436 437 return new AndQuery(new SiteQuery(siteNames), new ContentPrivacyQuery("public", "protected")); 438 } 439 440 /** 441 * Get the expression corresponding to the shared contents of public or protected sites 442 * @param siteNames the list of public or protected sites 443 * @return the expression corresponding to the shared contents of public or protected sites 444 */ 445 public static Query getContentAccessQueryForPublicOrProtectedClosedSites(Collection<String> siteNames) 446 { 447 if (siteNames.isEmpty()) 448 { 449 return null; 450 } 451 452 Query privacyQuery = new ContentPrivacyQuery(org.ametys.cms.search.query.Query.Operator.NE, "private"); 453 454 return new AndQuery(new SiteQuery(siteNames), privacyQuery); 455 } 456 457 /** 458 * Get the expression corresponding to the shared contents of public sites 459 * @param siteNames the list of public sites 460 * @return the expression corresponding to the shared contents of public sites 461 */ 462 public static Query getContentAccessQueryForPublicOutsideSites(Collection<String> siteNames) 463 { 464 if (siteNames.isEmpty()) 465 { 466 return null; 467 } 468 469 return new AndQuery(new SiteQuery(siteNames), new ContentPrivacyQuery("public")); 470 } 471 472 /** 473 * Get the expression corresponding to the shared contents of private or protected sites 474 * @param siteNames the list of private or protected sites 475 * @return the expression corresponding to the shared contents of private or protected sites 476 */ 477 public static Query getContentAccessQueryForPrivateOrProtectedOutsideSites(Collection<String> siteNames) 478 { 479 if (siteNames.isEmpty()) 480 { 481 return null; 482 } 483 484 return new AndQuery(new SiteQuery(siteNames), new ContentPrivacyQuery("public")); 485 } 486 487}