001
014
015 package com.liferay.portlet.softwarecatalog.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.plugin.Version;
020 import com.liferay.portal.kernel.search.Indexable;
021 import com.liferay.portal.kernel.search.IndexableType;
022 import com.liferay.portal.kernel.util.OrderByComparator;
023 import com.liferay.portal.kernel.util.StringPool;
024 import com.liferay.portal.kernel.util.StringUtil;
025 import com.liferay.portal.kernel.util.Time;
026 import com.liferay.portal.kernel.util.Validator;
027 import com.liferay.portal.kernel.workflow.WorkflowConstants;
028 import com.liferay.portal.kernel.xml.Document;
029 import com.liferay.portal.kernel.xml.Element;
030 import com.liferay.portal.kernel.xml.SAXReaderUtil;
031 import com.liferay.portal.model.ResourceConstants;
032 import com.liferay.portal.model.User;
033 import com.liferay.portal.plugin.ModuleId;
034 import com.liferay.portal.service.ServiceContext;
035 import com.liferay.portal.util.PropsValues;
036 import com.liferay.portal.webserver.WebServerServletTokenUtil;
037 import com.liferay.portlet.softwarecatalog.DuplicateProductEntryModuleIdException;
038 import com.liferay.portlet.softwarecatalog.ProductEntryAuthorException;
039 import com.liferay.portlet.softwarecatalog.ProductEntryLicenseException;
040 import com.liferay.portlet.softwarecatalog.ProductEntryNameException;
041 import com.liferay.portlet.softwarecatalog.ProductEntryPageURLException;
042 import com.liferay.portlet.softwarecatalog.ProductEntryScreenshotsException;
043 import com.liferay.portlet.softwarecatalog.ProductEntryShortDescriptionException;
044 import com.liferay.portlet.softwarecatalog.ProductEntryTypeException;
045 import com.liferay.portlet.softwarecatalog.model.SCFrameworkVersion;
046 import com.liferay.portlet.softwarecatalog.model.SCLicense;
047 import com.liferay.portlet.softwarecatalog.model.SCProductEntry;
048 import com.liferay.portlet.softwarecatalog.model.SCProductScreenshot;
049 import com.liferay.portlet.softwarecatalog.model.SCProductVersion;
050 import com.liferay.portlet.softwarecatalog.service.base.SCProductEntryLocalServiceBaseImpl;
051 import com.liferay.util.xml.DocUtil;
052
053 import java.util.Date;
054 import java.util.List;
055 import java.util.Map;
056 import java.util.Properties;
057
058
063 public class SCProductEntryLocalServiceImpl
064 extends SCProductEntryLocalServiceBaseImpl {
065
066 @Indexable(type = IndexableType.REINDEX)
067 @Override
068 public SCProductEntry addProductEntry(
069 long userId, String name, String type, String tags,
070 String shortDescription, String longDescription, String pageURL,
071 String author, String repoGroupId, String repoArtifactId,
072 long[] licenseIds, List<byte[]> thumbnails, List<byte[]> fullImages,
073 ServiceContext serviceContext)
074 throws PortalException, SystemException {
075
076
077
078 User user = userPersistence.findByPrimaryKey(userId);
079 long groupId = serviceContext.getScopeGroupId();
080 tags = getTags(tags);
081 repoGroupId = StringUtil.toLowerCase(repoGroupId.trim());
082 repoArtifactId = StringUtil.toLowerCase(repoArtifactId.trim());
083 Date now = new Date();
084
085 validate(
086 0, name, type, shortDescription, pageURL, author, repoGroupId,
087 repoArtifactId, licenseIds, thumbnails, fullImages);
088
089 long productEntryId = counterLocalService.increment();
090
091 SCProductEntry productEntry = scProductEntryPersistence.create(
092 productEntryId);
093
094 productEntry.setGroupId(groupId);
095 productEntry.setCompanyId(user.getCompanyId());
096 productEntry.setUserId(user.getUserId());
097 productEntry.setUserName(user.getFullName());
098 productEntry.setCreateDate(now);
099 productEntry.setModifiedDate(now);
100 productEntry.setName(name);
101 productEntry.setType(type);
102 productEntry.setTags(tags);
103 productEntry.setShortDescription(shortDescription);
104 productEntry.setLongDescription(longDescription);
105 productEntry.setPageURL(pageURL);
106 productEntry.setAuthor(author);
107 productEntry.setRepoGroupId(repoGroupId);
108 productEntry.setRepoArtifactId(repoArtifactId);
109
110 scProductEntryPersistence.update(productEntry);
111
112
113
114 if (serviceContext.isAddGroupPermissions() ||
115 serviceContext.isAddGuestPermissions()) {
116
117 addProductEntryResources(
118 productEntry, serviceContext.isAddGroupPermissions(),
119 serviceContext.isAddGuestPermissions());
120 }
121 else {
122 addProductEntryResources(
123 productEntry, serviceContext.getGroupPermissions(),
124 serviceContext.getGuestPermissions());
125 }
126
127
128
129 scProductEntryPersistence.setSCLicenses(productEntryId, licenseIds);
130
131
132
133 saveProductScreenshots(productEntry, thumbnails, fullImages);
134
135
136
137 if (PropsValues.SC_PRODUCT_COMMENTS_ENABLED) {
138 mbMessageLocalService.addDiscussionMessage(
139 userId, productEntry.getUserName(), groupId,
140 SCProductEntry.class.getName(), productEntryId,
141 WorkflowConstants.ACTION_PUBLISH);
142 }
143
144 return productEntry;
145 }
146
147 @Override
148 public void addProductEntryResources(
149 long productEntryId, boolean addGroupPermissions,
150 boolean addGuestPermissions)
151 throws PortalException, SystemException {
152
153 SCProductEntry productEntry =
154 scProductEntryPersistence.findByPrimaryKey(productEntryId);
155
156 addProductEntryResources(
157 productEntry, addGroupPermissions, addGuestPermissions);
158 }
159
160 @Override
161 public void addProductEntryResources(
162 long productEntryId, String[] groupPermissions,
163 String[] guestPermissions)
164 throws PortalException, SystemException {
165
166 SCProductEntry productEntry =
167 scProductEntryPersistence.findByPrimaryKey(productEntryId);
168
169 addProductEntryResources(
170 productEntry, groupPermissions, guestPermissions);
171 }
172
173 @Override
174 public void addProductEntryResources(
175 SCProductEntry productEntry, boolean addGroupPermissions,
176 boolean addGuestPermissions)
177 throws PortalException, SystemException {
178
179 resourceLocalService.addResources(
180 productEntry.getCompanyId(), productEntry.getGroupId(),
181 productEntry.getUserId(), SCProductEntry.class.getName(),
182 productEntry.getProductEntryId(), false, addGroupPermissions,
183 addGuestPermissions);
184 }
185
186 @Override
187 public void addProductEntryResources(
188 SCProductEntry productEntry, String[] groupPermissions,
189 String[] guestPermissions)
190 throws PortalException, SystemException {
191
192 resourceLocalService.addModelResources(
193 productEntry.getCompanyId(), productEntry.getGroupId(),
194 productEntry.getUserId(), SCProductEntry.class.getName(),
195 productEntry.getProductEntryId(), groupPermissions,
196 guestPermissions);
197 }
198
199 @Override
200 public void deleteProductEntries(long groupId)
201 throws PortalException, SystemException {
202
203 List<SCProductEntry> productEntries =
204 scProductEntryPersistence.findByGroupId(groupId);
205
206 for (SCProductEntry productEntry : productEntries) {
207 scProductEntryLocalService.deleteProductEntry(productEntry);
208 }
209 }
210
211 @Indexable(type = IndexableType.DELETE)
212 @Override
213 public SCProductEntry deleteProductEntry(long productEntryId)
214 throws PortalException, SystemException {
215
216 SCProductEntry productEntry =
217 scProductEntryPersistence.findByPrimaryKey(productEntryId);
218
219 return deleteProductEntry(productEntry);
220 }
221
222 @Indexable(type = IndexableType.DELETE)
223 @Override
224 public SCProductEntry deleteProductEntry(SCProductEntry productEntry)
225 throws PortalException, SystemException {
226
227
228
229 scProductEntryPersistence.remove(productEntry);
230
231
232
233 resourceLocalService.deleteResource(
234 productEntry.getCompanyId(), SCProductEntry.class.getName(),
235 ResourceConstants.SCOPE_INDIVIDUAL,
236 productEntry.getProductEntryId());
237
238
239
240 subscriptionLocalService.deleteSubscriptions(
241 productEntry.getCompanyId(), SCProductEntry.class.getName(),
242 productEntry.getProductEntryId());
243
244
245
246 scProductScreenshotLocalService.deleteProductScreenshots(
247 productEntry.getProductEntryId());
248
249
250
251 scProductVersionLocalService.deleteProductVersions(
252 productEntry.getProductEntryId());
253
254
255
256 mbMessageLocalService.deleteDiscussionMessages(
257 SCProductEntry.class.getName(), productEntry.getProductEntryId());
258
259
260
261 ratingsStatsLocalService.deleteStats(
262 SCProductEntry.class.getName(), productEntry.getProductEntryId());
263
264 return productEntry;
265 }
266
267 @Override
268 public List<SCProductEntry> getCompanyProductEntries(
269 long companyId, int start, int end)
270 throws SystemException {
271
272 return scProductEntryPersistence.findByCompanyId(companyId, start, end);
273 }
274
275 @Override
276 public int getCompanyProductEntriesCount(long companyId)
277 throws SystemException {
278
279 return scProductEntryPersistence.countByCompanyId(companyId);
280 }
281
282 @Override
283 public List<SCProductEntry> getProductEntries(
284 long groupId, int start, int end)
285 throws SystemException {
286
287 return scProductEntryPersistence.findByGroupId(groupId, start, end);
288 }
289
290 @Override
291 public List<SCProductEntry> getProductEntries(
292 long groupId, int start, int end, OrderByComparator obc)
293 throws SystemException {
294
295 return scProductEntryPersistence.findByGroupId(
296 groupId, start, end, obc);
297 }
298
299 @Override
300 public List<SCProductEntry> getProductEntries(
301 long groupId, long userId, int start, int end)
302 throws SystemException {
303
304 return scProductEntryPersistence.findByG_U(groupId, userId, start, end);
305 }
306
307 @Override
308 public List<SCProductEntry> getProductEntries(
309 long groupId, long userId, int start, int end,
310 OrderByComparator obc)
311 throws SystemException {
312
313 return scProductEntryPersistence.findByG_U(
314 groupId, userId, start, end, obc);
315 }
316
317 @Override
318 public int getProductEntriesCount(long groupId) throws SystemException {
319 return scProductEntryPersistence.countByGroupId(groupId);
320 }
321
322 @Override
323 public int getProductEntriesCount(long groupId, long userId)
324 throws SystemException {
325
326 return scProductEntryPersistence.countByG_U(groupId, userId);
327 }
328
329 @Override
330 public SCProductEntry getProductEntry(long productEntryId)
331 throws PortalException, SystemException {
332
333 return scProductEntryPersistence.findByPrimaryKey(productEntryId);
334 }
335
336 @Override
337 public String getRepositoryXML(
338 long groupId, String baseImageURL, Date oldestDate,
339 int maxNumOfVersions, Properties repoSettings)
340 throws SystemException {
341
342 return getRepositoryXML(
343 groupId, null, baseImageURL, oldestDate, maxNumOfVersions,
344 repoSettings);
345 }
346
347 @Override
348 public String getRepositoryXML(
349 long groupId, String version, String baseImageURL, Date oldestDate,
350 int maxNumOfVersions, Properties repoSettings)
351 throws SystemException {
352
353 Document doc = SAXReaderUtil.createDocument();
354
355 doc.setXMLEncoding(StringPool.UTF8);
356
357 Element root = doc.addElement("plugin-repository");
358
359 Element settingsEl = root.addElement("settings");
360
361 populateSettingsElement(settingsEl, repoSettings);
362
363 List<SCProductEntry> productEntries =
364 scProductEntryPersistence.findByGroupId(groupId);
365
366 for (SCProductEntry productEntry : productEntries) {
367 if (Validator.isNull(productEntry.getRepoGroupId()) ||
368 Validator.isNull(productEntry.getRepoArtifactId())) {
369
370 continue;
371 }
372
373 List<SCProductVersion> productVersions =
374 scProductVersionPersistence.findByProductEntryId(
375 productEntry.getProductEntryId());
376
377 for (int i = 0; i < productVersions.size(); i++) {
378 SCProductVersion productVersion = productVersions.get(i);
379
380 if ((maxNumOfVersions > 0) && (maxNumOfVersions < (i + 1))) {
381 break;
382 }
383
384 if (!productVersion.isRepoStoreArtifact()) {
385 continue;
386 }
387
388 if ((oldestDate != null) &&
389 oldestDate.after(productVersion.getModifiedDate())) {
390
391 continue;
392 }
393
394 if (Validator.isNotNull(version) &&
395 !isVersionSupported(
396 version, productVersion.getFrameworkVersions())) {
397
398 continue;
399 }
400
401 Element el = root.addElement("plugin-package");
402
403 populatePluginPackageElement(
404 el, productEntry, productVersion, baseImageURL);
405 }
406 }
407
408 return doc.asXML();
409 }
410
411 @Indexable(type = IndexableType.REINDEX)
412 @Override
413 public SCProductEntry updateProductEntry(
414 long productEntryId, String name, String type, String tags,
415 String shortDescription, String longDescription, String pageURL,
416 String author, String repoGroupId, String repoArtifactId,
417 long[] licenseIds, List<byte[]> thumbnails, List<byte[]> fullImages)
418 throws PortalException, SystemException {
419
420
421
422 tags = getTags(tags);
423 repoGroupId = StringUtil.toLowerCase(repoGroupId.trim());
424 repoArtifactId = StringUtil.toLowerCase(repoArtifactId.trim());
425 Date now = new Date();
426
427 validate(
428 productEntryId, name, type, shortDescription, pageURL, author,
429 repoGroupId, repoArtifactId, licenseIds, thumbnails, fullImages);
430
431 SCProductEntry productEntry =
432 scProductEntryPersistence.findByPrimaryKey(productEntryId);
433
434 productEntry.setModifiedDate(now);
435 productEntry.setName(name);
436 productEntry.setType(type);
437 productEntry.setTags(tags);
438 productEntry.setShortDescription(shortDescription);
439 productEntry.setLongDescription(longDescription);
440 productEntry.setPageURL(pageURL);
441 productEntry.setAuthor(author);
442 productEntry.setRepoGroupId(repoGroupId);
443 productEntry.setRepoArtifactId(repoArtifactId);
444
445 scProductEntryPersistence.update(productEntry);
446
447
448
449 scProductEntryPersistence.setSCLicenses(productEntryId, licenseIds);
450
451
452
453 if (thumbnails.size() == 0) {
454 scProductScreenshotLocalService.deleteProductScreenshots(
455 productEntryId);
456 }
457 else {
458 saveProductScreenshots(productEntry, thumbnails, fullImages);
459 }
460
461 return productEntry;
462 }
463
464 protected String getTags(String tags) {
465 tags = StringUtil.toLowerCase(tags.trim());
466
467 return StringUtil.merge(StringUtil.split(tags), ", ");
468 }
469
470 protected boolean isVersionSupported(
471 String version, List<SCFrameworkVersion> frameworkVersions) {
472
473 Version currentVersion = Version.getInstance(version);
474
475 for (SCFrameworkVersion frameworkVersion : frameworkVersions) {
476 Version supportedVersion = Version.getInstance(
477 frameworkVersion.getName());
478
479 if (supportedVersion.includes(currentVersion)) {
480 return true;
481 }
482 }
483
484 return false;
485 }
486
487 protected void populatePluginPackageElement(
488 Element el, SCProductEntry productEntry,
489 SCProductVersion productVersion, String baseImageURL)
490 throws SystemException {
491
492 DocUtil.add(el, "name", productEntry.getName());
493
494 String moduleId = ModuleId.toString(
495 productEntry.getRepoGroupId(), productEntry.getRepoArtifactId(),
496 productVersion.getVersion(), "war");
497
498 DocUtil.add(el, "module-id", moduleId);
499
500 DocUtil.add(
501 el, "modified-date",
502 Time.getRFC822(productVersion.getModifiedDate()));
503
504 Element typesEl = el.addElement("types");
505
506 DocUtil.add(typesEl, "type", productEntry.getType());
507
508 Element tagsEl = el.addElement("tags");
509
510 String[] tags = StringUtil.split(productEntry.getTags());
511
512 for (int i = 0; i < tags.length; i++) {
513 DocUtil.add(tagsEl, "tag", tags[i]);
514 }
515
516 DocUtil.add(
517 el, "short-description", productEntry.getShortDescription());
518
519 if (Validator.isNotNull(productEntry.getLongDescription())) {
520 DocUtil.add(
521 el, "long-description", productEntry.getLongDescription());
522 }
523
524 if (Validator.isNotNull(productVersion.getChangeLog())) {
525 DocUtil.add(el, "change-log", productVersion.getChangeLog());
526 }
527
528 if (Validator.isNotNull(productVersion.getDirectDownloadURL())) {
529 DocUtil.add(
530 el, "download-url", productVersion.getDirectDownloadURL());
531 }
532
533 DocUtil.add(el, "author", productEntry.getAuthor());
534
535 Element screenshotsEl = el.addElement("screenshots");
536
537 for (SCProductScreenshot screenshot : productEntry.getScreenshots()) {
538 long thumbnailId = screenshot.getThumbnailId();
539 long fullImageId = screenshot.getFullImageId();
540
541 Element screenshotEl = screenshotsEl.addElement("screenshot");
542
543 DocUtil.add(
544 screenshotEl, "thumbnail-url",
545 baseImageURL + "?img_id=" + thumbnailId + "&t=" +
546 WebServerServletTokenUtil.getToken(thumbnailId));
547 DocUtil.add(
548 screenshotEl, "large-image-url",
549 baseImageURL + "?img_id=" + fullImageId + "&t=" +
550 WebServerServletTokenUtil.getToken(fullImageId));
551 }
552
553 Element licensesEl = el.addElement("licenses");
554
555 for (SCLicense license : productEntry.getLicenses()) {
556 Element licenseEl = licensesEl.addElement("license");
557
558 licenseEl.addText(license.getName());
559 licenseEl.addAttribute(
560 "osi-approved", String.valueOf(license.isOpenSource()));
561 }
562
563 Element liferayVersionsEl = el.addElement("liferay-versions");
564
565 for (SCFrameworkVersion frameworkVersion :
566 productVersion.getFrameworkVersions()) {
567
568 DocUtil.add(
569 liferayVersionsEl, "liferay-version",
570 frameworkVersion.getName());
571 }
572 }
573
574 protected void populateSettingsElement(
575 Element el, Properties repoSettings) {
576
577 if (repoSettings == null) {
578 return;
579 }
580
581 for (Map.Entry<Object, Object> entry : repoSettings.entrySet()) {
582 String name = (String)entry.getKey();
583 String value = (String)entry.getValue();
584
585 Element settingEl = el.addElement("setting");
586
587 settingEl.addAttribute("name", name);
588 settingEl.addAttribute("value", value);
589 }
590 }
591
592 protected void saveProductScreenshots(
593 SCProductEntry productEntry, List<byte[]> thumbnails,
594 List<byte[]> fullImages)
595 throws PortalException, SystemException {
596
597 long productEntryId = productEntry.getProductEntryId();
598
599 List<SCProductScreenshot> productScreenshots =
600 scProductScreenshotPersistence.findByProductEntryId(productEntryId);
601
602 if (thumbnails.size() < productScreenshots.size()) {
603 for (int i = thumbnails.size(); i < productScreenshots.size();
604 i++) {
605
606 SCProductScreenshot productScreenshot = productScreenshots.get(
607 i);
608
609 scProductScreenshotLocalService.deleteProductScreenshot(
610 productScreenshot);
611 }
612 }
613
614 for (int i = 0; i < thumbnails.size(); i++) {
615 int priority = i;
616
617 byte[] thumbnail = thumbnails.get(i);
618 byte[] fullImage = fullImages.get(i);
619
620 SCProductScreenshot productScreenshot =
621 scProductScreenshotPersistence.fetchByP_P(
622 productEntryId, priority);
623
624 if (productScreenshot == null) {
625 long productScreenshotId = counterLocalService.increment();
626
627 productScreenshot = scProductScreenshotPersistence.create(
628 productScreenshotId);
629
630 productScreenshot.setCompanyId(productEntry.getCompanyId());
631 productScreenshot.setGroupId(productEntry.getGroupId());
632 productScreenshot.setProductEntryId(productEntryId);
633 productScreenshot.setThumbnailId(
634 counterLocalService.increment());
635 productScreenshot.setFullImageId(
636 counterLocalService.increment());
637 productScreenshot.setPriority(priority);
638
639 scProductScreenshotPersistence.update(productScreenshot);
640 }
641
642 imageLocalService.updateImage(
643 productScreenshot.getThumbnailId(), thumbnail);
644 imageLocalService.updateImage(
645 productScreenshot.getFullImageId(), fullImage);
646 }
647 }
648
649 protected void validate(
650 long productEntryId, String name, String type,
651 String shortDescription, String pageURL, String author,
652 String repoGroupId, String repoArtifactId, long[] licenseIds,
653 List<byte[]> thumbnails, List<byte[]> fullImages)
654 throws PortalException, SystemException {
655
656 if (Validator.isNull(name)) {
657 throw new ProductEntryNameException();
658 }
659
660 if (Validator.isNull(type)) {
661 throw new ProductEntryTypeException();
662 }
663
664 if (Validator.isNull(shortDescription)) {
665 throw new ProductEntryShortDescriptionException();
666 }
667
668 if (Validator.isNull(pageURL)) {
669 throw new ProductEntryPageURLException();
670 }
671 else if (!Validator.isUrl(pageURL)) {
672 throw new ProductEntryPageURLException();
673 }
674
675 if (Validator.isNull(author)) {
676 throw new ProductEntryAuthorException();
677 }
678
679 SCProductEntry productEntry = scProductEntryPersistence.fetchByRG_RA(
680 repoGroupId, repoArtifactId);
681
682 if ((productEntry != null) &&
683 (productEntry.getProductEntryId() != productEntryId)) {
684
685 throw new DuplicateProductEntryModuleIdException(
686 "{productEntryId=" + productEntryId + "}");
687 }
688
689 if (licenseIds.length == 0) {
690 throw new ProductEntryLicenseException();
691 }
692
693 if (thumbnails.size() != fullImages.size()) {
694 throw new ProductEntryScreenshotsException();
695 }
696 else {
697 for (byte[] thumbnail : thumbnails) {
698 if (thumbnail == null) {
699 throw new ProductEntryScreenshotsException();
700 }
701 }
702
703 for (byte[] fullImage : fullImages) {
704 if (fullImage == null) {
705 throw new ProductEntryScreenshotsException();
706 }
707 }
708 }
709 }
710
711 }