001 /** 002 * Copyright (c) 2000-present Liferay, Inc. All rights reserved. 003 * 004 * This library is free software; you can redistribute it and/or modify it under 005 * the terms of the GNU Lesser General Public License as published by the Free 006 * Software Foundation; either version 2.1 of the License, or (at your option) 007 * any later version. 008 * 009 * This library is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 011 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 012 * details. 013 */ 014 015 package com.liferay.portlet.dynamicdatamapping.service.impl; 016 017 import com.liferay.portal.kernel.exception.PortalException; 018 import com.liferay.portal.kernel.util.ListUtil; 019 import com.liferay.portal.kernel.util.OrderByComparator; 020 import com.liferay.portal.security.permission.ActionKeys; 021 import com.liferay.portal.security.permission.PermissionChecker; 022 import com.liferay.portal.service.ServiceContext; 023 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure; 024 import com.liferay.portlet.dynamicdatamapping.service.base.DDMStructureServiceBaseImpl; 025 import com.liferay.portlet.dynamicdatamapping.service.permission.DDMPermission; 026 import com.liferay.portlet.dynamicdatamapping.service.permission.DDMStructurePermission; 027 import com.liferay.portlet.dynamicdatamapping.util.DDMDisplay; 028 import com.liferay.portlet.dynamicdatamapping.util.DDMUtil; 029 030 import java.util.Iterator; 031 import java.util.List; 032 import java.util.Locale; 033 import java.util.Map; 034 035 /** 036 * Provides the remote service for accessing, adding, deleting, and updating 037 * dynamic data mapping (DDM) structures. Its methods include permission checks. 038 * 039 * @author Brian Wing Shun Chan 040 * @author Bruno Basto 041 * @author Marcellus Tavares 042 * @see com.liferay.portlet.dynamicdatamapping.service.impl.DDMStructureLocalServiceImpl 043 */ 044 public class DDMStructureServiceImpl extends DDMStructureServiceBaseImpl { 045 046 /** 047 * Adds a structure referencing a default parent structure, using the portal 048 * property <code>dynamic.data.lists.storage.type</code> storage type and 049 * default structure type. 050 * 051 * @param userId the primary key of the structure's creator/owner 052 * @param groupId the primary key of the group 053 * @param classNameId the primary key of the class name for the structure's 054 * related model 055 * @param nameMap the structure's locales and localized names 056 * @param descriptionMap the structure's locales and localized descriptions 057 * @param xsd the structure's XML schema definition 058 * @param serviceContext the service context to be applied. Can set the 059 * UUID, creation date, modification date, guest permissions, and 060 * group permissions for the structure. 061 * @return the structure 062 * @throws PortalException if a user with the primary key could not be 063 * found, if the user did not have permission to add the structure, 064 * if the XSD was not well-formed, or if a portal exception occurred 065 */ 066 @Override 067 public DDMStructure addStructure( 068 long userId, long groupId, long classNameId, 069 Map<Locale, String> nameMap, Map<Locale, String> descriptionMap, 070 String xsd, ServiceContext serviceContext) 071 throws PortalException { 072 073 DDMDisplay ddmDisplay = DDMUtil.getDDMDisplay(serviceContext); 074 075 DDMPermission.check( 076 getPermissionChecker(), serviceContext.getScopeGroupId(), 077 ddmDisplay.getResourceName(), ddmDisplay.getAddStructureActionId()); 078 079 return ddmStructureLocalService.addStructure( 080 getUserId(), groupId, classNameId, nameMap, descriptionMap, xsd, 081 serviceContext); 082 } 083 084 /** 085 * Adds a structure referencing its parent structure. 086 * 087 * @param groupId the primary key of the group 088 * @param parentStructureId the primary key of the parent structure 089 * (optionally {@link 090 * com.liferay.portlet.dynamicdatamapping.model.DDMStructureConstants#DEFAULT_PARENT_STRUCTURE_ID}) 091 * @param classNameId the primary key of the class name for the structure's 092 * related model 093 * @param structureKey the unique string identifying the structure 094 * (optionally <code>null</code>) 095 * @param nameMap the structure's locales and localized names 096 * @param descriptionMap the structure's locales and localized descriptions 097 * @param xsd the structure's XML schema definition 098 * @param storageType the structure's storage type. It can be "xml" or 099 * "expando". For more information, see {@link 100 * com.liferay.portlet.dynamicdatamapping.storage.StorageType}. 101 * @param type the structure's type. For more information, see {@link 102 * com.liferay.portlet.dynamicdatamapping.model.DDMStructureConstants}. 103 * @param serviceContext the service context to be applied. Can set the 104 * UUID, creation date, modification date, guest permissions, and 105 * group permissions for the structure. 106 * @return the structure 107 * @throws PortalException if the user did not have permission to add the 108 * structure, if the XSD is not well formed, or if a portal 109 * exception occurred 110 */ 111 @Override 112 public DDMStructure addStructure( 113 long groupId, long parentStructureId, long classNameId, 114 String structureKey, Map<Locale, String> nameMap, 115 Map<Locale, String> descriptionMap, String xsd, String storageType, 116 int type, ServiceContext serviceContext) 117 throws PortalException { 118 119 DDMDisplay ddmDisplay = DDMUtil.getDDMDisplay(serviceContext); 120 121 DDMPermission.check( 122 getPermissionChecker(), serviceContext.getScopeGroupId(), 123 ddmDisplay.getResourceName(), ddmDisplay.getAddStructureActionId()); 124 125 return ddmStructureLocalService.addStructure( 126 getUserId(), groupId, parentStructureId, classNameId, structureKey, 127 nameMap, descriptionMap, xsd, storageType, type, serviceContext); 128 } 129 130 /** 131 * Adds a structure referencing the parent structure by its structure key. 132 * In case the parent structure is not found, it uses the default parent 133 * structure ID. 134 * 135 * @param userId the primary key of the structure's creator/owner 136 * @param groupId the primary key of the group 137 * @param parentStructureKey the unique string identifying the structure 138 * @param classNameId the primary key of the class name for the structure's 139 * related model 140 * @param structureKey unique string identifying the structure (optionally 141 * <code>null</code>) 142 * @param nameMap the structure's locales and localized names 143 * @param descriptionMap the structure's locales and localized descriptions 144 * @param xsd the XML schema definition of the structure 145 * @param storageType the storage type of the structure. It can be XML or 146 * expando. For more information, see {@link 147 * com.liferay.portlet.dynamicdatamapping.storage.StorageType}. 148 * @param type the structure's type. For more information, see {@link 149 * com.liferay.portlet.dynamicdatamapping.model.DDMStructureConstants}. 150 * @param serviceContext the service context to be applied. Must have the 151 * <code>ddmResource</code> attribute to check permissions. Can set 152 * the UUID, creation date, modification date, guest permissions, 153 * and group permissions for the structure. 154 * @return the structure 155 * @throws PortalException if a user with the primary key could not be 156 * found, if the user did not have permission to add the structure, 157 * if the XSD was not well-formed, or if a portal exception occurred 158 */ 159 @Override 160 public DDMStructure addStructure( 161 long userId, long groupId, String parentStructureKey, 162 long classNameId, String structureKey, Map<Locale, String> nameMap, 163 Map<Locale, String> descriptionMap, String xsd, String storageType, 164 int type, ServiceContext serviceContext) 165 throws PortalException { 166 167 DDMDisplay ddmDisplay = DDMUtil.getDDMDisplay(serviceContext); 168 169 DDMPermission.check( 170 getPermissionChecker(), serviceContext.getScopeGroupId(), 171 ddmDisplay.getResourceName(), ddmDisplay.getAddStructureActionId()); 172 173 return ddmStructureLocalService.addStructure( 174 userId, groupId, parentStructureKey, classNameId, structureKey, 175 nameMap, descriptionMap, xsd, storageType, type, serviceContext); 176 } 177 178 /** 179 * Copies a structure, creating a new structure with all the values 180 * extracted from the original one. The new structure supports a new name 181 * and description. 182 * 183 * @param structureId the primary key of the structure to be copied 184 * @param nameMap the new structure's locales and localized names 185 * @param descriptionMap the new structure's locales and localized 186 * descriptions 187 * @param serviceContext the service context to be applied. Can set the 188 * UUID, creation date, modification date, guest permissions, and 189 * group permissions for the structure. 190 * @return the new structure 191 * @throws PortalException if the user did not have permission to add the 192 * structure or if a portal exception occurred 193 */ 194 @Override 195 public DDMStructure copyStructure( 196 long structureId, Map<Locale, String> nameMap, 197 Map<Locale, String> descriptionMap, ServiceContext serviceContext) 198 throws PortalException { 199 200 DDMDisplay ddmDisplay = DDMUtil.getDDMDisplay(serviceContext); 201 202 DDMPermission.check( 203 getPermissionChecker(), serviceContext.getScopeGroupId(), 204 ddmDisplay.getResourceName(), ddmDisplay.getAddStructureActionId()); 205 206 return ddmStructureLocalService.copyStructure( 207 getUserId(), structureId, nameMap, descriptionMap, serviceContext); 208 } 209 210 @Override 211 public DDMStructure copyStructure( 212 long structureId, ServiceContext serviceContext) 213 throws PortalException { 214 215 DDMDisplay ddmDisplay = DDMUtil.getDDMDisplay(serviceContext); 216 217 DDMPermission.check( 218 getPermissionChecker(), serviceContext.getScopeGroupId(), 219 ddmDisplay.getResourceName(), ddmDisplay.getAddStructureActionId()); 220 221 return ddmStructureLocalService.copyStructure( 222 getUserId(), structureId, serviceContext); 223 } 224 225 /** 226 * Deletes the structure and its resources. 227 * 228 * <p> 229 * Before deleting the structure, the system verifies whether the structure 230 * is required by another entity. If it is needed, an exception is thrown. 231 * </p> 232 * 233 * @param structureId the primary key of the structure to be deleted 234 * @throws PortalException if the user did not have permission to delete the 235 * structure or if a portal exception occurred 236 */ 237 @Override 238 public void deleteStructure(long structureId) throws PortalException { 239 DDMStructurePermission.check( 240 getPermissionChecker(), structureId, ActionKeys.DELETE); 241 242 ddmStructureLocalService.deleteStructure(structureId); 243 } 244 245 /** 246 * Returns the structure matching the class name ID, structure key, and 247 * group. 248 * 249 * @param groupId the primary key of the group 250 * @param classNameId the primary key of the class name for the structure's 251 * related model 252 * @param structureKey the unique string identifying the structure 253 * @return the matching structure, or <code>null</code> if a matching 254 * structure could not be found 255 * @throws PortalException if the user did not have permission to view the 256 * structure or if a portal exception occurred 257 */ 258 @Override 259 public DDMStructure fetchStructure( 260 long groupId, long classNameId, String structureKey) 261 throws PortalException { 262 263 DDMStructure ddmStructure = ddmStructurePersistence.fetchByG_C_S( 264 groupId, classNameId, structureKey); 265 266 if (ddmStructure != null) { 267 DDMStructurePermission.check( 268 getPermissionChecker(), ddmStructure, ActionKeys.VIEW); 269 } 270 271 return ddmStructure; 272 } 273 274 @Override 275 public List<DDMStructure> getJournalFolderStructures( 276 long[] groupIds, long journalFolderId, int restrictionType) 277 throws PortalException { 278 279 return filterStructures( 280 ddmStructureLocalService.getJournalFolderStructures( 281 groupIds, journalFolderId, restrictionType)); 282 } 283 284 /** 285 * Returns the structure with the ID. 286 * 287 * @param structureId the primary key of the structure 288 * @return the structure with the ID 289 * @throws PortalException if the user did not have permission to view the 290 * structure or if a structure with the ID could not be found 291 */ 292 @Override 293 public DDMStructure getStructure(long structureId) throws PortalException { 294 DDMStructurePermission.check( 295 getPermissionChecker(), structureId, ActionKeys.VIEW); 296 297 return ddmStructurePersistence.findByPrimaryKey(structureId); 298 } 299 300 /** 301 * Returns the structure matching the class name ID, structure key, and 302 * group. 303 * 304 * @param groupId the primary key of the structure's group 305 * @param classNameId the primary key of the class name for the structure's 306 * related model 307 * @param structureKey the unique string identifying the structure 308 * @return the matching structure 309 * @throws PortalException if the user did not have permission to view the 310 * structure or if a matching structure could not be found 311 */ 312 @Override 313 public DDMStructure getStructure( 314 long groupId, long classNameId, String structureKey) 315 throws PortalException { 316 317 DDMStructurePermission.check( 318 getPermissionChecker(), groupId, classNameId, structureKey, 319 ActionKeys.VIEW); 320 321 return ddmStructureLocalService.getStructure( 322 groupId, classNameId, structureKey); 323 } 324 325 /** 326 * Returns the structure matching the class name ID, structure key, and 327 * group, optionally searching ancestor sites (that have sharing enabled) 328 * and global scoped sites. 329 * 330 * <p> 331 * This method first searches in the group. If the structure is still not 332 * found and <code>includeAncestorStructures</code> is set to 333 * <code>true</code>, this method searches the group's ancestor sites (that 334 * have sharing enabled) and lastly searches global scoped sites. 335 * </p> 336 * 337 * @param groupId the primary key of the structure's group 338 * @param classNameId the primary key of the class name for the structure's 339 * related model 340 * @param structureKey the unique string identifying the structure 341 * @param includeAncestorStructures whether to include ancestor sites (that 342 * have sharing enabled) and include global scoped sites in the 343 * search 344 * @return the matching structure 345 * @throws PortalException if the user did not have permission to view the 346 * structure or if a matching structure could not be found 347 */ 348 @Override 349 public DDMStructure getStructure( 350 long groupId, long classNameId, String structureKey, 351 boolean includeAncestorStructures) 352 throws PortalException { 353 354 DDMStructurePermission.check( 355 getPermissionChecker(), groupId, classNameId, structureKey, 356 ActionKeys.VIEW); 357 358 return ddmStructureLocalService.getStructure( 359 groupId, classNameId, structureKey, includeAncestorStructures); 360 } 361 362 /** 363 * Returns all the structures in the group that the user has permission to 364 * view. 365 * 366 * @param groupId the primary key of the group 367 * @return the structures in the group that the user has permission to view 368 */ 369 @Override 370 public List<DDMStructure> getStructures(long groupId) { 371 return ddmStructurePersistence.filterFindByGroupId(groupId); 372 } 373 374 /** 375 * Returns all the structures in the groups that the user has permission to 376 * view. 377 * 378 * @param groupIds the primary key of the groups 379 * @return the structures in the groups that the user has permission to view 380 */ 381 @Override 382 public List<DDMStructure> getStructures(long[] groupIds) { 383 return ddmStructurePersistence.filterFindByGroupId(groupIds); 384 } 385 386 /** 387 * Returns all the structures matching the groups and class name ID that the 388 * user has permission to view. 389 * 390 * @param groupIds the primary keys of the groups 391 * @param classNameId the primary key of the class name for the structure's 392 * related model 393 * @return the structures matching the groups and class name ID that the 394 * user has permission to view 395 */ 396 @Override 397 public List<DDMStructure> getStructures(long[] groupIds, long classNameId) { 398 return ddmStructurePersistence.filterFindByG_C(groupIds, classNameId); 399 } 400 401 @Override 402 public List<DDMStructure> getStructures( 403 long[] groupIds, long classNameId, int start, int end) { 404 405 return ddmStructurePersistence.filterFindByG_C( 406 groupIds, classNameId, start, end); 407 } 408 409 /** 410 * Returns an ordered range of all the structures matching the groups and 411 * class name IDs, and matching the keywords in the structure names and 412 * descriptions. 413 * 414 * <p> 415 * Useful when paginating results. Returns a maximum of <code>end - 416 * start</code> instances. <code>start</code> and <code>end</code> are not 417 * primary keys, they are indexes in the result set. Thus, <code>0</code> 418 * refers to the first result in the set. Setting both <code>start</code> 419 * and <code>end</code> to {@link 420 * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full 421 * result set. 422 * </p> 423 * 424 * @param companyId the primary key of the structure's company 425 * @param groupIds the primary keys of the groups 426 * @param classNameIds the primary keys of the class names of the models 427 * the structures are related to 428 * @param keywords the keywords (space separated), which may occur in the 429 * structure's name or description (optionally <code>null</code>) 430 * @param start the lower bound of the range of structures to return 431 * @param end the upper bound of the range of structures to return (not 432 * inclusive) 433 * @param orderByComparator the comparator to order the structures 434 * (optionally <code>null</code>) 435 * @return the range of matching structures ordered by the comparator 436 */ 437 @Override 438 public List<DDMStructure> search( 439 long companyId, long[] groupIds, long[] classNameIds, String keywords, 440 int start, int end, OrderByComparator<DDMStructure> orderByComparator) { 441 442 return ddmStructureFinder.filterFindByKeywords( 443 companyId, groupIds, classNameIds, keywords, start, end, 444 orderByComparator); 445 } 446 447 /** 448 * Returns an ordered range of all the structures matching the groups, class 449 * name IDs, name keyword, description keyword, storage type, and type. 450 * 451 * <p> 452 * Useful when paginating results. Returns a maximum of <code>end - 453 * start</code> instances. <code>start</code> and <code>end</code> are not 454 * primary keys, they are indexes in the result set. Thus, <code>0</code> 455 * refers to the first result in the set. Setting both <code>start</code> 456 * and <code>end</code> to {@link 457 * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full 458 * result set. 459 * </p> 460 * 461 * @param companyId the primary key of the structure's company 462 * @param groupIds the primary keys of the groups 463 * @param classNameIds the primary keys of the class names of the models 464 * the structures are related to 465 * @param name the name keywords 466 * @param description the description keywords 467 * @param storageType the structure's storage type. It can be "xml" or 468 * "expando". For more information, see {@link 469 * com.liferay.portlet.dynamicdatamapping.storage.StorageType}. 470 * @param type the structure's type. For more information, see {@link 471 * com.liferay.portlet.dynamicdatamapping.model.DDMStructureConstants}. 472 * @param andOperator whether every field must match its keywords, or just 473 * one field 474 * @param start the lower bound of the range of structures to return 475 * @param end the upper bound of the range of structures to return (not 476 * inclusive) 477 * @param orderByComparator the comparator to order the structures 478 * (optionally <code>null</code>) 479 * @return the range of matching structures ordered by the comparator 480 */ 481 @Override 482 public List<DDMStructure> search( 483 long companyId, long[] groupIds, long[] classNameIds, String name, 484 String description, String storageType, int type, boolean andOperator, 485 int start, int end, OrderByComparator<DDMStructure> orderByComparator) { 486 487 return ddmStructureFinder.filterFindByC_G_C_N_D_S_T( 488 companyId, groupIds, classNameIds, name, description, storageType, 489 type, andOperator, start, end, orderByComparator); 490 } 491 492 /** 493 * Returns the number of structures matching the groups and class name IDs, 494 * and matching the keywords in the structure names and descriptions. 495 * 496 * @param companyId the primary key of the structure's company 497 * @param groupIds the primary keys of the groups 498 * @param classNameIds the primary keys of the class names of the models 499 * the structures are related to 500 * @param keywords the keywords (space separated), which may occur in the 501 * structure's name or description (optionally <code>null</code>) 502 * @return the number of matching structures 503 */ 504 @Override 505 public int searchCount( 506 long companyId, long[] groupIds, long[] classNameIds, String keywords) { 507 508 return ddmStructureFinder.filterCountByKeywords( 509 companyId, groupIds, classNameIds, keywords); 510 } 511 512 /** 513 * Returns the number of structures matching the groups, class name IDs, 514 * name keyword, description keyword, storage type, and type 515 * 516 * @param companyId the primary key of the structure's company 517 * @param groupIds the primary keys of the groups 518 * @param classNameIds the primary keys of the class names of the models 519 * the structure's are related to 520 * @param name the name keywords 521 * @param description the description keywords 522 * @param storageType the structure's storage type. It can be "xml" or 523 * "expando". For more information, see {@link 524 * com.liferay.portlet.dynamicdatamapping.storage.StorageType}. 525 * @param type the structure's type. For more information, see {@link 526 * com.liferay.portlet.dynamicdatamapping.model.DDMStructureConstants}. 527 * @param andOperator whether every field must match its keywords, or just 528 * one field 529 * @return the number of matching structures 530 */ 531 @Override 532 public int searchCount( 533 long companyId, long[] groupIds, long[] classNameIds, String name, 534 String description, String storageType, int type, boolean andOperator) { 535 536 return ddmStructureFinder.filterCountByC_G_C_N_D_S_T( 537 companyId, groupIds, classNameIds, name, description, storageType, 538 type, andOperator); 539 } 540 541 /** 542 * Updates the structure matching the class name ID, structure key, and 543 * group, replacing its old parent structure, name map, description map, and 544 * XSD with new ones. 545 * 546 * @param groupId the primary key of the group 547 * @param parentStructureId the primary key of the new parent structure 548 * @param classNameId the primary key of the class name for the structure's 549 * related model 550 * @param structureKey the unique string identifying the structure 551 * @param nameMap the structure's new locales and localized names 552 * @param descriptionMap the structure's new locales and localized 553 * description 554 * @param xsd the structure's new XML schema definition 555 * @param serviceContext the service context to be applied. Can set the 556 * modification date. 557 * @return the updated structure 558 * @throws PortalException if the user did not have permission to update the 559 * structure or if a portal exception occurred 560 */ 561 @Override 562 public DDMStructure updateStructure( 563 long groupId, long parentStructureId, long classNameId, 564 String structureKey, Map<Locale, String> nameMap, 565 Map<Locale, String> descriptionMap, String xsd, 566 ServiceContext serviceContext) 567 throws PortalException { 568 569 DDMStructurePermission.check( 570 getPermissionChecker(), groupId, classNameId, structureKey, 571 ActionKeys.UPDATE); 572 573 return ddmStructureLocalService.updateStructure( 574 groupId, parentStructureId, classNameId, structureKey, nameMap, 575 descriptionMap, xsd, serviceContext); 576 } 577 578 /** 579 * Updates the structure matching the structure ID, replacing the old parent 580 * structure ID, name map, description map, and XSD with the new values. 581 * 582 * @param structureId the primary key of the structure 583 * @param parentStructureId the new parent structure primary key 584 * @param nameMap the structure's new locales and localized names 585 * @param descriptionMap the structure's new locales and localized 586 * description 587 * @param xsd the new XML schema definition of the structure 588 * @param serviceContext the service context to be applied. Can set the 589 * modification date. 590 * @return the updated structure 591 * @throws PortalException if the user did not have permission to update the 592 * structure or if a portal exception occurred 593 */ 594 @Override 595 public DDMStructure updateStructure( 596 long structureId, long parentStructureId, 597 Map<Locale, String> nameMap, Map<Locale, String> descriptionMap, 598 String xsd, ServiceContext serviceContext) 599 throws PortalException { 600 601 DDMStructurePermission.check( 602 getPermissionChecker(), structureId, ActionKeys.UPDATE); 603 604 return ddmStructureLocalService.updateStructure( 605 structureId, parentStructureId, nameMap, descriptionMap, xsd, 606 serviceContext); 607 } 608 609 protected List<DDMStructure> filterStructures(List<DDMStructure> structures) 610 throws PortalException { 611 612 PermissionChecker permissionChecker = getPermissionChecker(); 613 614 structures = ListUtil.copy(structures); 615 616 Iterator<DDMStructure> itr = structures.iterator(); 617 618 while (itr.hasNext()) { 619 DDMStructure structure = itr.next(); 620 621 if (!DDMStructurePermission.contains( 622 permissionChecker, structure, ActionKeys.VIEW)) { 623 624 itr.remove(); 625 } 626 } 627 628 return structures; 629 } 630 631 }