001 /** 002 * Copyright (c) 2000-2013 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.exception.SystemException; 019 import com.liferay.portal.kernel.log.Log; 020 import com.liferay.portal.kernel.log.LogFactoryUtil; 021 import com.liferay.portal.kernel.util.FileUtil; 022 import com.liferay.portal.kernel.util.LocaleUtil; 023 import com.liferay.portal.kernel.util.OrderByComparator; 024 import com.liferay.portal.kernel.util.PropsKeys; 025 import com.liferay.portal.kernel.util.StringPool; 026 import com.liferay.portal.kernel.util.StringUtil; 027 import com.liferay.portal.kernel.util.Validator; 028 import com.liferay.portal.model.Group; 029 import com.liferay.portal.model.Image; 030 import com.liferay.portal.model.ResourceConstants; 031 import com.liferay.portal.model.User; 032 import com.liferay.portal.service.ServiceContext; 033 import com.liferay.portal.service.persistence.ImageUtil; 034 import com.liferay.portal.util.PortalUtil; 035 import com.liferay.portal.util.PrefsPropsUtil; 036 import com.liferay.portlet.dynamicdatamapping.NoSuchTemplateException; 037 import com.liferay.portlet.dynamicdatamapping.RequiredTemplateException; 038 import com.liferay.portlet.dynamicdatamapping.TemplateDuplicateTemplateKeyException; 039 import com.liferay.portlet.dynamicdatamapping.TemplateNameException; 040 import com.liferay.portlet.dynamicdatamapping.TemplateScriptException; 041 import com.liferay.portlet.dynamicdatamapping.TemplateSmallImageNameException; 042 import com.liferay.portlet.dynamicdatamapping.TemplateSmallImageSizeException; 043 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure; 044 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate; 045 import com.liferay.portlet.dynamicdatamapping.service.base.DDMTemplateLocalServiceBaseImpl; 046 import com.liferay.portlet.journal.model.JournalArticle; 047 import com.liferay.portlet.journal.service.persistence.JournalArticleUtil; 048 049 import java.io.File; 050 import java.io.IOException; 051 052 import java.util.ArrayList; 053 import java.util.Date; 054 import java.util.List; 055 import java.util.Locale; 056 import java.util.Map; 057 058 /** 059 * Provides the local service for accessing, adding, copying, deleting, and 060 * updating dynamic data mapping (DDM) templates. 061 * 062 * <p> 063 * DDM templates (templates) are used in Liferay to render templated content 064 * like applications, forms, dynamic data lists, or web contents. 065 * </p> 066 * 067 * <p> 068 * Templates support a variety of templating languages, like Velocity or 069 * FreeMarker. They also support multi-language names and descriptions. 070 * </p> 071 * 072 * <p> 073 * Templates can be related to many models in Liferay, such as those for 074 * structures, dynamic data lists, and applications. This relationship can be 075 * established via the class name ID and class PK. 076 * </p> 077 * 078 * @author Brian Wing Shun Chan 079 * @author Eduardo Lundgren 080 * @author Marcellus Tavares 081 */ 082 public class DDMTemplateLocalServiceImpl 083 extends DDMTemplateLocalServiceBaseImpl { 084 085 /** 086 * Adds a template. 087 * 088 * @param userId the primary key of the template's creator/owner 089 * @param groupId the primary key of the group 090 * @param classNameId the primary key of the class name for the template's 091 * related model 092 * @param classPK the primary key of the template's related entity 093 * @param nameMap the template's locales and localized names 094 * @param descriptionMap the template's locales and localized descriptions 095 * @param type the template's type. For more information, see {@link 096 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 097 * @param mode the template's mode. For more information, see {@link 098 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 099 * @param language the template's script language. For more information, 100 * see {@link 101 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 102 * @param script the template's script 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 template. 106 * @return the template 107 * @throws PortalException if a portal exception occurred 108 * @throws SystemException if a system exception occurred 109 */ 110 public DDMTemplate addTemplate( 111 long userId, long groupId, long classNameId, long classPK, 112 Map<Locale, String> nameMap, Map<Locale, String> descriptionMap, 113 String type, String mode, String language, String script, 114 ServiceContext serviceContext) 115 throws PortalException, SystemException { 116 117 return addTemplate( 118 userId, groupId, classNameId, classPK, null, nameMap, 119 descriptionMap, type, mode, language, script, false, false, null, 120 null, serviceContext); 121 } 122 123 /** 124 * Adds a template with additional parameters. 125 * 126 * @param userId the primary key of the template's creator/owner 127 * @param groupId the primary key of the group 128 * @param classNameId the primary key of the class name for the template's 129 * related model 130 * @param classPK the primary key of the template's related entity 131 * @param templateKey the unique string identifying the template 132 * (optionally <code>null</code>) 133 * @param nameMap the template's locales and localized names 134 * @param descriptionMap the template's locales and localized descriptions 135 * @param type the template's type. For more information, see {@link 136 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 137 * @param mode the template's mode. For more information, see {@link 138 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 139 * @param language the template's script language. For more information, 140 * see {@link 141 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 142 * @param script the template's script 143 * @param cacheable whether the template is cacheable 144 * @param smallImage whether the template has a small image 145 * @param smallImageURL the template's small image URL (optionally 146 * <code>null</code>) 147 * @param smallImageFile the template's small image file (optionally 148 * <code>null</code>) 149 * @param serviceContext the service context to be applied. Can set the 150 * UUID, creation date, modification date, guest permissions, and 151 * group permissions for the template. 152 * @return the template 153 * @throws PortalException if a portal exception occurred 154 * @throws SystemException if a system exception occurred 155 */ 156 public DDMTemplate addTemplate( 157 long userId, long groupId, long classNameId, long classPK, 158 String templateKey, Map<Locale, String> nameMap, 159 Map<Locale, String> descriptionMap, String type, String mode, 160 String language, String script, boolean cacheable, 161 boolean smallImage, String smallImageURL, File smallImageFile, 162 ServiceContext serviceContext) 163 throws PortalException, SystemException { 164 165 // Template 166 167 User user = userPersistence.findByPrimaryKey(userId); 168 Date now = new Date(); 169 170 if (Validator.isNull(templateKey)) { 171 templateKey = String.valueOf(counterLocalService.increment()); 172 } 173 else { 174 templateKey = templateKey.trim().toUpperCase(); 175 } 176 177 byte[] smallImageBytes = null; 178 179 if (smallImage) { 180 try { 181 smallImageBytes = FileUtil.getBytes(smallImageFile); 182 } 183 catch (IOException ioe) { 184 } 185 186 if ((smallImageBytes == null) || Validator.isUrl(smallImageURL)) { 187 smallImage = false; 188 } 189 } 190 191 validate( 192 groupId, classNameId, templateKey, nameMap, script, smallImage, 193 smallImageURL, smallImageFile, smallImageBytes); 194 195 long templateId = counterLocalService.increment(); 196 197 DDMTemplate template = ddmTemplatePersistence.create(templateId); 198 199 template.setUuid(serviceContext.getUuid()); 200 template.setGroupId(groupId); 201 template.setCompanyId(user.getCompanyId()); 202 template.setUserId(user.getUserId()); 203 template.setUserName(user.getFullName()); 204 template.setCreateDate(serviceContext.getCreateDate(now)); 205 template.setModifiedDate(serviceContext.getModifiedDate(now)); 206 template.setClassNameId(classNameId); 207 template.setClassPK(classPK); 208 template.setTemplateKey(templateKey); 209 template.setNameMap(nameMap); 210 template.setDescriptionMap(descriptionMap); 211 template.setType(type); 212 template.setMode(mode); 213 template.setLanguage(language); 214 template.setScript(script); 215 template.setCacheable(cacheable); 216 template.setSmallImage(smallImage); 217 template.setSmallImageId(counterLocalService.increment()); 218 template.setSmallImageURL(smallImageURL); 219 220 ddmTemplatePersistence.update(template); 221 222 // Resources 223 224 if (serviceContext.isAddGroupPermissions() || 225 serviceContext.isAddGuestPermissions()) { 226 227 addTemplateResources( 228 template, serviceContext.isAddGroupPermissions(), 229 serviceContext.isAddGuestPermissions()); 230 } 231 else { 232 addTemplateResources( 233 template, serviceContext.getGroupPermissions(), 234 serviceContext.getGuestPermissions()); 235 } 236 237 // Small image 238 239 saveImages( 240 smallImage, template.getSmallImageId(), smallImageFile, 241 smallImageBytes); 242 243 return template; 244 } 245 246 /** 247 * Adds the resources to the template. 248 * 249 * @param template the template to add resources to 250 * @param addGroupPermissions whether to add group permissions 251 * @param addGuestPermissions whether to add guest permissions 252 * @throws PortalException if a portal exception occurred 253 * @throws SystemException if a system exception occurred 254 */ 255 public void addTemplateResources( 256 DDMTemplate template, boolean addGroupPermissions, 257 boolean addGuestPermissions) 258 throws PortalException, SystemException { 259 260 resourceLocalService.addResources( 261 template.getCompanyId(), template.getGroupId(), 262 template.getUserId(), DDMTemplate.class.getName(), 263 template.getTemplateId(), false, addGroupPermissions, 264 addGuestPermissions); 265 } 266 267 /** 268 * Adds the model resources with the permissions to the template. 269 * 270 * @param template the template to add resources to 271 * @param groupPermissions the group permissions to be added 272 * @param guestPermissions the guest permissions to be added 273 * @throws PortalException if a portal exception occurred 274 * @throws SystemException if a system exception occurred 275 */ 276 public void addTemplateResources( 277 DDMTemplate template, String[] groupPermissions, 278 String[] guestPermissions) 279 throws PortalException, SystemException { 280 281 resourceLocalService.addModelResources( 282 template.getCompanyId(), template.getGroupId(), 283 template.getUserId(), DDMTemplate.class.getName(), 284 template.getTemplateId(), groupPermissions, guestPermissions); 285 } 286 287 /** 288 * Copies the template, creating a new template with all the values 289 * extracted from the original one. This method supports defining a new name 290 * and description. 291 * 292 * @param userId the primary key of the template's creator/owner 293 * @param templateId the primary key of the template to be copied 294 * @param nameMap the new template's locales and localized names 295 * @param descriptionMap the new template's locales and localized 296 * descriptions 297 * @param serviceContext the service context to be applied. Can set the 298 * UUID, creation date, modification date, guest permissions, and 299 * group permissions for the template. 300 * @return the new template 301 * @throws PortalException if a portal exception occurred 302 * @throws SystemException if a system exception occurred 303 */ 304 public DDMTemplate copyTemplate( 305 long userId, long templateId, Map<Locale, String> nameMap, 306 Map<Locale, String> descriptionMap, ServiceContext serviceContext) 307 throws PortalException, SystemException { 308 309 DDMTemplate template = ddmTemplatePersistence.findByPrimaryKey( 310 templateId); 311 312 File smallImageFile = copySmallImage(template); 313 314 return addTemplate( 315 userId, template.getGroupId(), template.getClassNameId(), 316 template.getClassPK(), null, nameMap, descriptionMap, 317 template.getType(), template.getMode(), template.getLanguage(), 318 template.getScript(), template.isCacheable(), 319 template.isSmallImage(), template.getSmallImageURL(), 320 smallImageFile, serviceContext); 321 } 322 323 public DDMTemplate copyTemplate( 324 long userId, long templateId, ServiceContext serviceContext) 325 throws PortalException, SystemException { 326 327 DDMTemplate template = ddmTemplatePersistence.findByPrimaryKey( 328 templateId); 329 330 File smallImageFile = copySmallImage(template); 331 332 return addTemplate( 333 userId, template.getGroupId(), template.getClassNameId(), 334 template.getClassPK(), null, template.getNameMap(), 335 template.getDescriptionMap(), template.getType(), 336 template.getMode(), template.getLanguage(), template.getScript(), 337 template.isCacheable(), template.isSmallImage(), 338 template.getSmallImageURL(), smallImageFile, serviceContext); 339 } 340 341 /** 342 * Copies all the templates matching the class name ID, class PK, and type. 343 * This method creates new templates, extracting all the values from the old 344 * ones and updating their class PKs. 345 * 346 * @param userId the primary key of the template's creator/owner 347 * @param classNameId the primary key of the class name for the template's 348 * related model 349 * @param oldClassPK the primary key of the old template's related entity 350 * @param newClassPK the primary key of the new template's related entity 351 * @param type the template's type. For more information, see {@link 352 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 353 * @param serviceContext the service context to be applied. Can set the 354 * creation date, modification date, guest permissions, and group 355 * permissions for the new templates. 356 * @return the new templates 357 * @throws PortalException if a portal exception occurred 358 * @throws SystemException if a system exception occurred 359 */ 360 public List<DDMTemplate> copyTemplates( 361 long userId, long classNameId, long oldClassPK, long newClassPK, 362 String type, ServiceContext serviceContext) 363 throws PortalException, SystemException { 364 365 List<DDMTemplate> newTemplates = new ArrayList<DDMTemplate>(); 366 367 List<DDMTemplate> oldTemplates = ddmTemplatePersistence.findByC_C_T( 368 classNameId, oldClassPK, type); 369 370 for (DDMTemplate oldTemplate : oldTemplates) { 371 DDMTemplate newTemplate = copyTemplate( 372 userId, oldTemplate.getTemplateId(), serviceContext); 373 374 newTemplates.add(newTemplate); 375 } 376 377 return newTemplates; 378 } 379 380 /** 381 * Deletes the template and its resources. 382 * 383 * @param template the template to be deleted 384 * @throws PortalException if a portal exception occurred 385 * @throws SystemException if a system exception occurred 386 */ 387 public void deleteTemplate(DDMTemplate template) 388 throws PortalException, SystemException { 389 390 // Template 391 392 if (template.getClassNameId() == 393 PortalUtil.getClassNameId(DDMStructure.class.getName())) { 394 395 DDMStructure structure = ddmStructureLocalService.fetchDDMStructure( 396 template.getClassPK()); 397 398 if ((structure != null) && 399 (structure.getClassNameId() == 400 PortalUtil.getClassNameId( 401 JournalArticle.class.getName()))) { 402 403 Group companyGroup = groupLocalService.getCompanyGroup( 404 template.getCompanyId()); 405 406 if (template.getGroupId() == companyGroup.getGroupId()) { 407 if (JournalArticleUtil.countByTemplateId( 408 template.getTemplateKey()) > 0) { 409 410 throw new RequiredTemplateException(); 411 } 412 } 413 else { 414 if (JournalArticleUtil.countByG_T( 415 template.getGroupId(), 416 template.getTemplateKey()) > 0) { 417 418 throw new RequiredTemplateException(); 419 } 420 } 421 } 422 } 423 424 ddmTemplatePersistence.remove(template); 425 426 // Resources 427 428 resourceLocalService.deleteResource( 429 template.getCompanyId(), DDMTemplate.class.getName(), 430 ResourceConstants.SCOPE_INDIVIDUAL, template.getTemplateId()); 431 } 432 433 /** 434 * Deletes the template and its resources. 435 * 436 * @param templateId the primary key of the template to be deleted 437 * @throws PortalException if a portal exception occurred 438 * @throws SystemException if a system exception occurred 439 */ 440 public void deleteTemplate(long templateId) 441 throws PortalException, SystemException { 442 443 DDMTemplate template = ddmTemplatePersistence.findByPrimaryKey( 444 templateId); 445 446 deleteTemplate(template); 447 } 448 449 /** 450 * Deletes all the templates of the group. 451 * 452 * @param groupId the primary key of the group 453 * @throws PortalException if a portal exception occurred 454 * @throws SystemException if a system exception occurred 455 */ 456 public void deleteTemplates(long groupId) 457 throws PortalException, SystemException { 458 459 List<DDMTemplate> templates = ddmTemplatePersistence.findByGroupId( 460 groupId); 461 462 for (DDMTemplate template : templates) { 463 deleteTemplate(template); 464 } 465 } 466 467 /** 468 * Returns the template matching the group and template key. 469 * 470 * @param groupId the primary key of the group 471 * @param classNameId the primary key of the class name for the template's 472 * related model 473 * @param templateKey the unique string identifying the template 474 * @return the matching template, or <code>null</code> if a matching 475 * template could not be found 476 * @throws SystemException if a system exception occurred 477 */ 478 public DDMTemplate fetchTemplate( 479 long groupId, long classNameId, String templateKey) 480 throws SystemException { 481 482 templateKey = templateKey.trim().toUpperCase(); 483 484 return ddmTemplatePersistence.fetchByG_C_T( 485 groupId, classNameId, templateKey); 486 } 487 488 /** 489 * Returns the template matching the group and template key, optionally in 490 * the global scope. 491 * 492 * <p> 493 * This method first searches in the given group. If the template is still 494 * not found and <code>includeGlobalTemplates</code> is set to 495 * <code>true</code>, this method searches the global group. 496 * </p> 497 * 498 * @param groupId the primary key of the group 499 * @param classNameId the primary key of the class name for the template's 500 * related model 501 * @param templateKey the unique string identifying the template 502 * @param includeGlobalTemplates whether to include the global scope in the 503 * search 504 * @return the matching template, or <code>null</code> if a matching 505 * template could not be found 506 * @throws PortalException if a portal exception occurred 507 * @throws SystemException if a system exception occurred 508 */ 509 public DDMTemplate fetchTemplate( 510 long groupId, long classNameId, String templateKey, 511 boolean includeGlobalTemplates) 512 throws PortalException, SystemException { 513 514 templateKey = templateKey.trim().toUpperCase(); 515 516 DDMTemplate template = ddmTemplatePersistence.fetchByG_C_T( 517 groupId, classNameId, templateKey); 518 519 if ((template != null) || !includeGlobalTemplates) { 520 return template; 521 } 522 523 Group group = groupPersistence.findByPrimaryKey(groupId); 524 525 Group companyGroup = groupLocalService.getCompanyGroup( 526 group.getCompanyId()); 527 528 return ddmTemplatePersistence.fetchByG_C_T( 529 companyGroup.getGroupId(), classNameId, templateKey); 530 } 531 532 /** 533 * Returns the template matching the UUID and group. 534 * 535 * @param uuid the unique string identifying the template 536 * @param groupId the primary key of the group 537 * @return the matching template, or <code>null</code> if a matching 538 * template could not be found 539 * @throws SystemException if a system exception occurred 540 */ 541 public DDMTemplate fetchTemplate(String uuid, long groupId) 542 throws SystemException { 543 544 return ddmTemplatePersistence.fetchByUUID_G(uuid, groupId); 545 } 546 547 /** 548 * Returns the template with the ID. 549 * 550 * @param templateId the primary key of the template 551 * @return the template with the ID 552 * @throws PortalException if a matching template could not be found 553 * @throws SystemException if a system exception occurred 554 */ 555 public DDMTemplate getTemplate(long templateId) 556 throws PortalException, SystemException { 557 558 return ddmTemplatePersistence.findByPrimaryKey(templateId); 559 } 560 561 /** 562 * Returns the template matching the group and template key. 563 * 564 * @param groupId the primary key of the group 565 * @param classNameId the primary key of the class name for the template's 566 * related model 567 * @param templateKey the unique string identifying the template 568 * @return the matching template 569 * @throws PortalException if a matching template could not be found 570 * @throws SystemException if a system exception occurred 571 */ 572 public DDMTemplate getTemplate( 573 long groupId, long classNameId, String templateKey) 574 throws PortalException, SystemException { 575 576 templateKey = templateKey.trim().toUpperCase(); 577 578 return ddmTemplatePersistence.findByG_C_T( 579 groupId, classNameId, templateKey); 580 } 581 582 /** 583 * Returns the template matching the group and template key, optionally in 584 * the global scope. 585 * 586 * <p> 587 * This method first searches in the group. If the template is still not 588 * found and <code>includeGlobalTemplates</code> is set to 589 * <code>true</code>, this method searches the global group. 590 * </p> 591 * 592 * @param groupId the primary key of the group 593 * @param classNameId the primary key of the class name for the template's 594 * related model 595 * @param templateKey the unique string identifying the template 596 * @param includeGlobalTemplates whether to include the global scope in the 597 * search 598 * @return the matching template 599 * @throws PortalException if a matching template could not be found 600 * @throws SystemException if a system exception occurred 601 */ 602 public DDMTemplate getTemplate( 603 long groupId, long classNameId, String templateKey, 604 boolean includeGlobalTemplates) 605 throws PortalException, SystemException { 606 607 templateKey = templateKey.trim().toUpperCase(); 608 609 DDMTemplate template = ddmTemplatePersistence.fetchByG_C_T( 610 groupId, classNameId, templateKey); 611 612 if (template != null) { 613 return template; 614 } 615 616 if (!includeGlobalTemplates) { 617 throw new NoSuchTemplateException( 618 "No DDMTemplate exists with the template key " + templateKey); 619 } 620 621 Group group = groupPersistence.findByPrimaryKey(groupId); 622 623 Group companyGroup = groupLocalService.getCompanyGroup( 624 group.getCompanyId()); 625 626 return ddmTemplatePersistence.findByG_C_T( 627 companyGroup.getGroupId(), classNameId, templateKey); 628 } 629 630 /** 631 * Returns all the templates with the class PK. 632 * 633 * @param classPK the primary key of the template's related entity 634 * @return the templates with the class PK 635 * @throws SystemException if a system exception occurred 636 */ 637 public List<DDMTemplate> getTemplates(long classPK) throws SystemException { 638 return ddmTemplatePersistence.findByClassPK(classPK); 639 } 640 641 /** 642 * Returns all the templates matching the group and class name ID. 643 * 644 * @param groupId the primary key of the group 645 * @param classNameId the primary key of the class name for the template's 646 * related model 647 * @return the matching templates 648 * @throws SystemException if a system exception occurred 649 */ 650 public List<DDMTemplate> getTemplates(long groupId, long classNameId) 651 throws SystemException { 652 653 return ddmTemplatePersistence.findByG_C(groupId, classNameId); 654 } 655 656 /** 657 * Returns all the templates matching the group, class name ID, and class 658 * PK. 659 * 660 * @param groupId the primary key of the group 661 * @param classNameId the primary key of the class name for the template's 662 * related model 663 * @param classPK the primary key of the template's related entity 664 * @return the matching templates 665 * @throws SystemException if a system exception occurred 666 */ 667 public List<DDMTemplate> getTemplates( 668 long groupId, long classNameId, long classPK) 669 throws SystemException { 670 671 return ddmTemplatePersistence.findByG_C_C( 672 groupId, classNameId, classPK); 673 } 674 675 /** 676 * Returns all the templates matching the group, class name ID, class PK, 677 * and type. 678 * 679 * @param groupId the primary key of the group 680 * @param classNameId the primary key of the class name for the template's 681 * related model 682 * @param classPK the primary key of the template's related entity 683 * @param type the template's type. For more information, see {@link 684 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 685 * @return the matching templates 686 * @throws SystemException if a system exception occurred 687 */ 688 public List<DDMTemplate> getTemplates( 689 long groupId, long classNameId, long classPK, String type) 690 throws SystemException { 691 692 return ddmTemplatePersistence.findByG_C_C_T( 693 groupId, classNameId, classPK, type); 694 } 695 696 /** 697 * Returns all the templates matching the group, class name ID, class PK, 698 * type, and mode. 699 * 700 * @param groupId the primary key of the group 701 * @param classNameId the primary key of the class name for the template's 702 * related model 703 * @param classPK the primary key of the template's related entity 704 * @param type the template's type. For more information, see {@link 705 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 706 * @param mode the template's mode. For more information, see {@link 707 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 708 * @return the matching templates 709 * @throws SystemException if a system exception occurred 710 */ 711 public List<DDMTemplate> getTemplates( 712 long groupId, long classNameId, long classPK, String type, 713 String mode) 714 throws SystemException { 715 716 return ddmTemplatePersistence.findByG_C_C_T_M( 717 groupId, classNameId, classPK, type, mode); 718 } 719 720 /** 721 * Returns all the templates matching the group and class PK. 722 * 723 * @param groupId the primary key of the group 724 * @param classPK the primary key of the template's related entity 725 * @return the matching templates 726 * @throws SystemException if a system exception occurred 727 */ 728 public List<DDMTemplate> getTemplatesByClassPK(long groupId, long classPK) 729 throws SystemException { 730 731 return ddmTemplatePersistence.findByG_CPK(groupId, classPK); 732 } 733 734 /** 735 * Returns an ordered range of all the templates matching the group and 736 * structure class name ID. 737 * 738 * <p> 739 * Useful when paginating results. Returns a maximum of <code>end - 740 * start</code> instances. <code>start</code> and <code>end</code> are not 741 * primary keys, they are indexes in the result set. Thus, <code>0</code> 742 * refers to the first result in the set. Setting both <code>start</code> 743 * and <code>end</code> to {@link 744 * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full 745 * result set. 746 * </p> 747 * 748 * @param groupId the primary key of the group 749 * @param structureClassNameId the primary key of the class name for the 750 * template's related structure 751 * @param start the lower bound of the range of templates to return 752 * @param end the upper bound of the range of templates to return (not 753 * inclusive) 754 * @param orderByComparator the comparator to order the templates 755 * (optionally <code>null</code>) 756 * @return the range of matching templates ordered by the comparator 757 * @throws SystemException if a system exception occurred 758 */ 759 public List<DDMTemplate> getTemplatesByStructureClassNameId( 760 long groupId, long structureClassNameId, int start, int end, 761 OrderByComparator orderByComparator) 762 throws SystemException { 763 764 return ddmTemplateFinder.findByG_SC( 765 groupId, structureClassNameId, start, end, orderByComparator); 766 } 767 768 /** 769 * Returns the number of templates belonging to the group. 770 * 771 * @param groupId the primary key of the group 772 * @return the number of templates belonging to the group 773 * @throws SystemException if a system exception occurred 774 */ 775 public int getTemplatesCount(long groupId) throws SystemException { 776 return ddmTemplatePersistence.countByGroupId(groupId); 777 } 778 779 /** 780 * Returns the number of templates matching the group and class name ID. 781 * 782 * @param groupId the primary key of the group 783 * @param classNameId the primary key of the class name for the template's 784 * related model 785 * @return the number of matching templates 786 * @throws SystemException if a system exception occurred 787 */ 788 public int getTemplatesCount(long groupId, long classNameId) 789 throws SystemException { 790 791 return ddmTemplatePersistence.countByG_C(groupId, classNameId); 792 } 793 794 /** 795 * Returns an ordered range of all the templates matching the group, class 796 * name ID, class PK, type, and mode, and matching the keywords in the 797 * template names and descriptions. 798 * 799 * <p> 800 * Useful when paginating results. Returns a maximum of <code>end - 801 * start</code> instances. <code>start</code> and <code>end</code> are not 802 * primary keys, they are indexes in the result set. Thus, <code>0</code> 803 * refers to the first result in the set. Setting both <code>start</code> 804 * and <code>end</code> to {@link 805 * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full 806 * result set. 807 * </p> 808 * 809 * @param companyId the primary key of the template's company 810 * @param groupId the primary key of the group 811 * @param classNameId the primary key of the class name for the template's 812 * related model 813 * @param classPK the primary key of the template's related entity 814 * @param keywords the keywords (space separated), which may occur in the 815 * template's name or description (optionally <code>null</code>) 816 * @param type the template's type (optionally <code>null</code>). For more 817 * information, see {@link 818 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 819 * @param mode the template's mode (optionally <code>null</code>). For more 820 * information, see {@link 821 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 822 * @param start the lower bound of the range of templates to return 823 * @param end the upper bound of the range of templates to return (not 824 * inclusive) 825 * @param orderByComparator the comparator to order the templates 826 * (optionally <code>null</code>) 827 * @return the range of matching templates ordered by the comparator 828 * @throws SystemException if a system exception occurred 829 */ 830 public List<DDMTemplate> search( 831 long companyId, long groupId, long classNameId, long classPK, 832 String keywords, String type, String mode, int start, int end, 833 OrderByComparator orderByComparator) 834 throws SystemException { 835 836 return ddmTemplateFinder.findByKeywords( 837 companyId, groupId, classNameId, classPK, keywords, type, mode, 838 start, end, orderByComparator); 839 } 840 841 /** 842 * Returns an ordered range of all the templates matching the group, class 843 * name ID, class PK, name keyword, description keyword, type, mode, and 844 * language. 845 * 846 * <p> 847 * Useful when paginating results. Returns a maximum of <code>end - 848 * start</code> instances. <code>start</code> and <code>end</code> are not 849 * primary keys, they are indexes in the result set. Thus, <code>0</code> 850 * refers to the first result in the set. Setting both <code>start</code> 851 * and <code>end</code> to {@link 852 * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full 853 * result set. 854 * </p> 855 * 856 * @param companyId the primary key of the template's company 857 * @param groupId the primary key of the group 858 * @param classNameId the primary key of the class name for the template's 859 * related model 860 * @param classPK the primary key of the template's related entity 861 * @param name the name keywords (optionally <code>null</code>) 862 * @param description the description keywords (optionally 863 * <code>null</code>) 864 * @param type the template's type (optionally <code>null</code>). For more 865 * information, see {@link 866 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 867 * @param mode the template's mode (optionally <code>null</code>). For more 868 * information, see {@link 869 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 870 * @param language the template's script language (optionally 871 * <code>null</code>). For more information, see {@link 872 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 873 * @param andOperator whether every field must match its keywords, or just 874 * one field 875 * @param start the lower bound of the range of templates to return 876 * @param end the upper bound of the range of templates to return (not 877 * inclusive) 878 * @param orderByComparator the comparator to order the templates 879 * (optionally <code>null</code>) 880 * @return the range of matching templates ordered by the comparator 881 * @throws SystemException if a system exception occurred 882 */ 883 public List<DDMTemplate> search( 884 long companyId, long groupId, long classNameId, long classPK, 885 String name, String description, String type, String mode, 886 String language, boolean andOperator, int start, int end, 887 OrderByComparator orderByComparator) 888 throws SystemException { 889 890 return ddmTemplateFinder.findByC_G_C_C_N_D_T_M_L( 891 companyId, groupId, classNameId, classPK, name, description, type, 892 mode, language, andOperator, start, end, orderByComparator); 893 } 894 895 /** 896 * Returns an ordered range of all the templates matching the group IDs, 897 * class Name IDs, class PK, type, and mode, and include the keywords on its 898 * names and descriptions. 899 * 900 * <p> 901 * Useful when paginating results. Returns a maximum of <code>end - 902 * start</code> instances. <code>start</code> and <code>end</code> are not 903 * primary keys, they are indexes in the result set. Thus, <code>0</code> 904 * refers to the first result in the set. Setting both <code>start</code> 905 * and <code>end</code> to {@link 906 * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full 907 * result set. 908 * </p> 909 * 910 * @param companyId the primary key of the template's company 911 * @param groupIds the primary keys of the groups 912 * @param classNameIds the primary keys of the entity's instances the 913 * templates are related to 914 * @param classPK the primary key of the template's related entity 915 * @param keywords the keywords (space separated), which may occur in the 916 * template's name or description (optionally <code>null</code>) 917 * @param type the template's type (optionally <code>null</code>). For more 918 * information, see {@link 919 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 920 * @param mode the template's mode (optionally <code>null</code>). For more 921 * information, see {@link 922 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 923 * @param start the lower bound of the range of templates to return 924 * @param end the upper bound of the range of templates to return (not 925 * inclusive) 926 * @param orderByComparator the comparator to order the templates 927 * (optionally <code>null</code>) 928 * @return the range of matching templates ordered by the comparator 929 * @throws SystemException if a system exception occurred 930 */ 931 public List<DDMTemplate> search( 932 long companyId, long[] groupIds, long[] classNameIds, long classPK, 933 String keywords, String type, String mode, int start, int end, 934 OrderByComparator orderByComparator) 935 throws SystemException { 936 937 return ddmTemplateFinder.findByKeywords( 938 companyId, groupIds, classNameIds, classPK, keywords, type, mode, 939 start, end, orderByComparator); 940 } 941 942 /** 943 * Returns an ordered range of all the templates matching the group IDs, 944 * class name IDs, class PK, name keyword, description keyword, type, mode, 945 * and language. 946 * 947 * <p> 948 * Useful when paginating results. Returns a maximum of <code>end - 949 * start</code> instances. <code>start</code> and <code>end</code> are not 950 * primary keys, they are indexes in the result set. Thus, <code>0</code> 951 * refers to the first result in the set. Setting both <code>start</code> 952 * and <code>end</code> to {@link 953 * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full 954 * result set. 955 * </p> 956 * 957 * @param companyId the primary key of the template's company 958 * @param groupIds the primary keys of the groups 959 * @param classNameIds the primary keys of the entity's instances the 960 * templates are related to 961 * @param classPK the primary key of the template's related entity 962 * @param name the name keywords (optionally <code>null</code>) 963 * @param description the description keywords (optionally 964 * <code>null</code>) 965 * @param type the template's type (optionally <code>null</code>). For more 966 * information, see {@link 967 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 968 * @param mode the template's mode (optionally <code>null</code>). For more 969 * information, see {@link 970 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 971 * @param language the template's script language (optionally 972 * <code>null</code>). For more information, see {@link 973 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 974 * @param andOperator whether every field must match its keywords, or just 975 * one field. 976 * @param start the lower bound of the range of templates to return 977 * @param end the upper bound of the range of templates to return (not 978 * inclusive) 979 * @param orderByComparator the comparator to order the templates 980 * (optionally <code>null</code>) 981 * @return the range of matching templates ordered by the comparator 982 * @throws SystemException if a system exception occurred 983 */ 984 public List<DDMTemplate> search( 985 long companyId, long[] groupIds, long[] classNameIds, long classPK, 986 String name, String description, String type, String mode, 987 String language, boolean andOperator, int start, int end, 988 OrderByComparator orderByComparator) 989 throws SystemException { 990 991 return ddmTemplateFinder.findByC_G_C_C_N_D_T_M_L( 992 companyId, groupIds, classNameIds, classPK, name, description, type, 993 mode, language, andOperator, start, end, orderByComparator); 994 } 995 996 /** 997 * Returns the number of templates matching the group, class name ID, class 998 * PK, type, and matching the keywords in the template names and 999 * descriptions. 1000 * 1001 * @param companyId the primary key of the template's company 1002 * @param groupId the primary key of the group 1003 * @param classNameId the primary key of the class name for the template's 1004 * related model 1005 * @param classPK the primary key of the template's related entity 1006 * @param keywords the keywords (space separated), which may occur in the 1007 * template's name or description (optionally <code>null</code>) 1008 * @param type the template's type (optionally <code>null</code>). For more 1009 * information, see {@link 1010 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 1011 * @param mode the template's mode (optionally <code>null</code>). For more 1012 * information, see {@link 1013 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 1014 * @return the number of matching templates 1015 * @throws SystemException if a system exception occurred 1016 */ 1017 public int searchCount( 1018 long companyId, long groupId, long classNameId, long classPK, 1019 String keywords, String type, String mode) 1020 throws SystemException { 1021 1022 return ddmTemplateFinder.countByKeywords( 1023 companyId, groupId, classNameId, classPK, keywords, type, mode); 1024 } 1025 1026 /** 1027 * Returns the number of templates matching the group, class name ID, class 1028 * PK, name keyword, description keyword, type, mode, and language. 1029 * 1030 * @param companyId the primary key of the template's company 1031 * @param groupId the primary key of the group 1032 * @param classNameId the primary key of the class name for the template's 1033 * related model 1034 * @param classPK the primary key of the template's related entity 1035 * @param name the name keywords (optionally <code>null</code>) 1036 * @param description the description keywords (optionally 1037 * <code>null</code>) 1038 * @param type the template's type (optionally <code>null</code>). For more 1039 * information, see {@link 1040 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 1041 * @param mode the template's mode (optionally <code>null</code>). For more 1042 * information, see {@link 1043 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 1044 * @param language the template's script language (optionally 1045 * <code>null</code>). For more information, see {@link 1046 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 1047 * @param andOperator whether every field must match its keywords, or just 1048 * one field. 1049 * @return the number of matching templates 1050 * @throws SystemException if a system exception occurred 1051 */ 1052 public int searchCount( 1053 long companyId, long groupId, long classNameId, long classPK, 1054 String name, String description, String type, String mode, 1055 String language, boolean andOperator) 1056 throws SystemException { 1057 1058 return ddmTemplateFinder.countByC_G_C_C_N_D_T_M_L( 1059 companyId, groupId, classNameId, classPK, name, description, type, 1060 mode, language, andOperator); 1061 } 1062 1063 /** 1064 * Returns the number of templates matching the group IDs, class name IDs, 1065 * class PK, type, and mode, and matching the keywords in the template names 1066 * and descriptions. 1067 * 1068 * @param companyId the primary key of the template's company 1069 * @param groupIds the primary keys of the groups 1070 * @param classNameIds the primary keys of the entity's instance the 1071 * templates are related to 1072 * @param classPK the primary key of the template's related entity 1073 * @param keywords the keywords (space separated), which may occur in the 1074 * template's name or description (optionally <code>null</code>) 1075 * @param type the template's type (optionally <code>null</code>). For more 1076 * information, see {@link 1077 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 1078 * @param mode the template's mode (optionally <code>null</code>). For more 1079 * information, see {@link 1080 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 1081 * @return the number of matching templates 1082 * @throws SystemException if a system exception occurred 1083 */ 1084 public int searchCount( 1085 long companyId, long[] groupIds, long[] classNameIds, long classPK, 1086 String keywords, String type, String mode) 1087 throws SystemException { 1088 1089 return ddmTemplateFinder.countByKeywords( 1090 companyId, groupIds, classNameIds, classPK, keywords, type, mode); 1091 } 1092 1093 /** 1094 * Returns the number of templates matching the group IDs, class name IDs, 1095 * class PKs, name keyword, description keyword, type, mode, and language. 1096 * 1097 * @param companyId the primary key of the templates company 1098 * @param groupIds the primary keys of the groups 1099 * @param classNameIds the primary keys of the entity's instance the 1100 * templates are related to 1101 * @param classPK the primary key of the template's related entity 1102 * @param name the name keywords (optionally <code>null</code>) 1103 * @param description the description keywords (optionally 1104 * <code>null</code>) 1105 * @param type the template's type (optionally <code>null</code>). For more 1106 * information, see {@link 1107 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 1108 * @param mode the template's mode (optionally <code>null</code>). For more 1109 * information, see {@link 1110 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 1111 * @param language the template's script language (optionally 1112 * <code>null</code>). For more information, see {@link 1113 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 1114 * @param andOperator whether every field must match its keywords, or just 1115 * one field. 1116 * @return the number of matching templates 1117 * @throws SystemException if a system exception occurred 1118 */ 1119 public int searchCount( 1120 long companyId, long[] groupIds, long[] classNameIds, long classPK, 1121 String name, String description, String type, String mode, 1122 String language, boolean andOperator) 1123 throws SystemException { 1124 1125 return ddmTemplateFinder.countByC_G_C_C_N_D_T_M_L( 1126 companyId, groupIds, classNameIds, classPK, name, description, type, 1127 mode, language, andOperator); 1128 } 1129 1130 /** 1131 * Updates the template matching the ID. 1132 * 1133 * @param templateId the primary key of the template 1134 * @param nameMap the template's new locales and localized names 1135 * @param descriptionMap the template's new locales and localized 1136 * description 1137 * @param type the template's type. For more information, see {@link 1138 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 1139 * @param mode the template's mode. For more information, see {@link 1140 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 1141 * @param language the template's script language. For more information, 1142 * see {@link 1143 * com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}. 1144 * @param script the template's script 1145 * @param cacheable whether the template is cacheable 1146 * @param smallImage whether the template has a small image 1147 * @param smallImageURL the template's small image URL (optionally 1148 * <code>null</code>) 1149 * @param smallImageFile the template's small image file (optionally 1150 * <code>null</code>) 1151 * @param serviceContext the service context to be applied. Can set the 1152 * modification date. 1153 * @return the updated template 1154 * @throws PortalException if a portal exception occurred 1155 * @throws SystemException if a system exception occurred 1156 */ 1157 public DDMTemplate updateTemplate( 1158 long templateId, Map<Locale, String> nameMap, 1159 Map<Locale, String> descriptionMap, String type, String mode, 1160 String language, String script, boolean cacheable, 1161 boolean smallImage, String smallImageURL, File smallImageFile, 1162 ServiceContext serviceContext) 1163 throws PortalException, SystemException { 1164 1165 byte[] smallImageBytes = null; 1166 1167 try { 1168 smallImageBytes = FileUtil.getBytes(smallImageFile); 1169 } 1170 catch (IOException ioe) { 1171 } 1172 1173 validate( 1174 nameMap, script, smallImage, smallImageURL, smallImageFile, 1175 smallImageBytes); 1176 1177 DDMTemplate template = ddmTemplateLocalService.getDDMTemplate( 1178 templateId); 1179 1180 template.setModifiedDate(serviceContext.getModifiedDate(null)); 1181 template.setNameMap(nameMap); 1182 template.setDescriptionMap(descriptionMap); 1183 template.setType(type); 1184 template.setMode(mode); 1185 template.setLanguage(language); 1186 template.setScript(script); 1187 template.setCacheable(cacheable); 1188 template.setSmallImage(smallImage); 1189 template.setSmallImageURL(smallImageURL); 1190 1191 ddmTemplatePersistence.update(template); 1192 1193 // Small image 1194 1195 saveImages( 1196 smallImage, template.getSmallImageId(), smallImageFile, 1197 smallImageBytes); 1198 1199 return template; 1200 } 1201 1202 protected File copySmallImage(DDMTemplate template) throws SystemException { 1203 File smallImageFile = null; 1204 1205 if (template.isSmallImage() && 1206 Validator.isNull(template.getSmallImageURL())) { 1207 1208 Image smallImage = ImageUtil.fetchByPrimaryKey( 1209 template.getSmallImageId()); 1210 1211 if (smallImage != null) { 1212 smallImageFile = FileUtil.createTempFile(smallImage.getType()); 1213 1214 try { 1215 FileUtil.write(smallImageFile, smallImage.getTextObj()); 1216 } 1217 catch (IOException ioe) { 1218 _log.error(ioe, ioe); 1219 } 1220 } 1221 } 1222 1223 return smallImageFile; 1224 } 1225 1226 protected void saveImages( 1227 boolean smallImage, long smallImageId, File smallImageFile, 1228 byte[] smallImageBytes) 1229 throws PortalException, SystemException { 1230 1231 if (smallImage) { 1232 if ((smallImageFile != null) && (smallImageBytes != null)) { 1233 imageLocalService.updateImage(smallImageId, smallImageBytes); 1234 } 1235 } 1236 else { 1237 imageLocalService.deleteImage(smallImageId); 1238 } 1239 } 1240 1241 protected void validate( 1242 long groupId, long classNameId, String templateKey, 1243 Map<Locale, String> nameMap, String script, boolean smallImage, 1244 String smallImageURL, File smallImageFile, byte[] smallImageBytes) 1245 throws PortalException, SystemException { 1246 1247 templateKey = templateKey.trim().toUpperCase(); 1248 1249 DDMTemplate template = ddmTemplatePersistence.fetchByG_C_T( 1250 groupId, classNameId, templateKey); 1251 1252 if (template != null) { 1253 throw new TemplateDuplicateTemplateKeyException(); 1254 } 1255 1256 validate( 1257 nameMap, script, smallImage, smallImageURL, smallImageFile, 1258 smallImageBytes); 1259 } 1260 1261 protected void validate( 1262 Map<Locale, String> nameMap, String script, boolean smallImage, 1263 String smallImageURL, File smallImageFile, byte[] smallImageBytes) 1264 throws PortalException, SystemException { 1265 1266 validateName(nameMap); 1267 1268 if (Validator.isNull(script)) { 1269 throw new TemplateScriptException(); 1270 } 1271 1272 String[] imageExtensions = PrefsPropsUtil.getStringArray( 1273 PropsKeys.DYNAMIC_DATA_MAPPING_IMAGE_EXTENSIONS, StringPool.COMMA); 1274 1275 if (smallImage && Validator.isNull(smallImageURL) && 1276 (smallImageFile != null) && (smallImageBytes != null)) { 1277 1278 String smallImageName = smallImageFile.getName(); 1279 1280 if (smallImageName != null) { 1281 boolean validSmallImageExtension = false; 1282 1283 for (int i = 0; i < imageExtensions.length; i++) { 1284 if (StringPool.STAR.equals(imageExtensions[i]) || 1285 StringUtil.endsWith( 1286 smallImageName, imageExtensions[i])) { 1287 1288 validSmallImageExtension = true; 1289 1290 break; 1291 } 1292 } 1293 1294 if (!validSmallImageExtension) { 1295 throw new TemplateSmallImageNameException(smallImageName); 1296 } 1297 } 1298 1299 long smallImageMaxSize = PrefsPropsUtil.getLong( 1300 PropsKeys.DYNAMIC_DATA_MAPPING_IMAGE_SMALL_MAX_SIZE); 1301 1302 if ((smallImageMaxSize > 0) && 1303 ((smallImageBytes == null) || 1304 (smallImageBytes.length > smallImageMaxSize))) { 1305 1306 throw new TemplateSmallImageSizeException(); 1307 } 1308 } 1309 } 1310 1311 protected void validateName(Map<Locale, String> nameMap) 1312 throws PortalException { 1313 1314 String name = nameMap.get(LocaleUtil.getDefault()); 1315 1316 if (Validator.isNull(name)) { 1317 throw new TemplateNameException(); 1318 } 1319 } 1320 1321 private static Log _log = LogFactoryUtil.getLog( 1322 DDMTemplateLocalServiceImpl.class); 1323 1324 }