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