1
14
15 package com.liferay.portlet.softwarecatalog.service.impl;
16
17 import com.liferay.portal.kernel.exception.PortalException;
18 import com.liferay.portal.kernel.exception.SystemException;
19 import com.liferay.portal.kernel.plugin.Version;
20 import com.liferay.portal.kernel.search.Indexer;
21 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
22 import com.liferay.portal.kernel.servlet.ImageServletTokenUtil;
23 import com.liferay.portal.kernel.util.OrderByComparator;
24 import com.liferay.portal.kernel.util.StringPool;
25 import com.liferay.portal.kernel.util.StringUtil;
26 import com.liferay.portal.kernel.util.Time;
27 import com.liferay.portal.kernel.util.Validator;
28 import com.liferay.portal.kernel.workflow.StatusConstants;
29 import com.liferay.portal.kernel.xml.Document;
30 import com.liferay.portal.kernel.xml.Element;
31 import com.liferay.portal.kernel.xml.SAXReaderUtil;
32 import com.liferay.portal.model.ResourceConstants;
33 import com.liferay.portal.model.User;
34 import com.liferay.portal.plugin.ModuleId;
35 import com.liferay.portal.service.ServiceContext;
36 import com.liferay.portal.util.PropsValues;
37 import com.liferay.portlet.softwarecatalog.DuplicateProductEntryModuleIdException;
38 import com.liferay.portlet.softwarecatalog.ProductEntryAuthorException;
39 import com.liferay.portlet.softwarecatalog.ProductEntryLicenseException;
40 import com.liferay.portlet.softwarecatalog.ProductEntryNameException;
41 import com.liferay.portlet.softwarecatalog.ProductEntryPageURLException;
42 import com.liferay.portlet.softwarecatalog.ProductEntryScreenshotsException;
43 import com.liferay.portlet.softwarecatalog.ProductEntryShortDescriptionException;
44 import com.liferay.portlet.softwarecatalog.ProductEntryTypeException;
45 import com.liferay.portlet.softwarecatalog.model.SCFrameworkVersion;
46 import com.liferay.portlet.softwarecatalog.model.SCLicense;
47 import com.liferay.portlet.softwarecatalog.model.SCProductEntry;
48 import com.liferay.portlet.softwarecatalog.model.SCProductScreenshot;
49 import com.liferay.portlet.softwarecatalog.model.SCProductVersion;
50 import com.liferay.portlet.softwarecatalog.service.base.SCProductEntryLocalServiceBaseImpl;
51 import com.liferay.util.xml.DocUtil;
52
53 import java.net.MalformedURLException;
54 import java.net.URL;
55
56 import java.util.Date;
57 import java.util.Iterator;
58 import java.util.List;
59 import java.util.Properties;
60
61
69 public class SCProductEntryLocalServiceImpl
70 extends SCProductEntryLocalServiceBaseImpl {
71
72 public SCProductEntry addProductEntry(
73 long userId, String name, String type, String tags,
74 String shortDescription, String longDescription, String pageURL,
75 String author, String repoGroupId, String repoArtifactId,
76 long[] licenseIds, List<byte[]> thumbnails, List<byte[]> fullImages,
77 ServiceContext serviceContext)
78 throws PortalException, SystemException {
79
80
82 User user = userPersistence.findByPrimaryKey(userId);
83 long groupId = serviceContext.getScopeGroupId();
84 tags = getTags(tags);
85 repoGroupId = repoGroupId.trim().toLowerCase();
86 repoArtifactId = repoArtifactId.trim().toLowerCase();
87 Date now = new Date();
88
89 validate(
90 0, name, type, shortDescription, pageURL, author, repoGroupId,
91 repoArtifactId, licenseIds, thumbnails, fullImages);
92
93 long productEntryId = counterLocalService.increment();
94
95 SCProductEntry productEntry = scProductEntryPersistence.create(
96 productEntryId);
97
98 productEntry.setGroupId(groupId);
99 productEntry.setCompanyId(user.getCompanyId());
100 productEntry.setUserId(user.getUserId());
101 productEntry.setUserName(user.getFullName());
102 productEntry.setCreateDate(now);
103 productEntry.setModifiedDate(now);
104 productEntry.setName(name);
105 productEntry.setType(type);
106 productEntry.setTags(tags);
107 productEntry.setShortDescription(shortDescription);
108 productEntry.setLongDescription(longDescription);
109 productEntry.setPageURL(pageURL);
110 productEntry.setAuthor(author);
111 productEntry.setRepoGroupId(repoGroupId);
112 productEntry.setRepoArtifactId(repoArtifactId);
113
114 scProductEntryPersistence.update(productEntry, false);
115
116
118 if (serviceContext.getAddCommunityPermissions() ||
119 serviceContext.getAddGuestPermissions()) {
120
121 addProductEntryResources(
122 productEntry, serviceContext.getAddCommunityPermissions(),
123 serviceContext.getAddGuestPermissions());
124 }
125 else {
126 addProductEntryResources(
127 productEntry, serviceContext.getCommunityPermissions(),
128 serviceContext.getGuestPermissions());
129 }
130
131
133 scProductEntryPersistence.setSCLicenses(productEntryId, licenseIds);
134
135
137 saveProductScreenshots(productEntry, thumbnails, fullImages);
138
139
141 if (PropsValues.SC_PRODUCT_COMMENTS_ENABLED) {
142 mbMessageLocalService.addDiscussionMessage(
143 userId, productEntry.getUserName(),
144 SCProductEntry.class.getName(), productEntryId,
145 StatusConstants.APPROVED);
146 }
147
148
150 Indexer indexer = IndexerRegistryUtil.getIndexer(SCProductEntry.class);
151
152 indexer.reindex(productEntry);
153
154 return productEntry;
155 }
156
157 public void addProductEntryResources(
158 long productEntryId, boolean addCommunityPermissions,
159 boolean addGuestPermissions)
160 throws PortalException, SystemException {
161
162 SCProductEntry productEntry =
163 scProductEntryPersistence.findByPrimaryKey(productEntryId);
164
165 addProductEntryResources(
166 productEntry, addCommunityPermissions, addGuestPermissions);
167 }
168
169 public void addProductEntryResources(
170 long productEntryId, String[] communityPermissions,
171 String[] guestPermissions)
172 throws PortalException, SystemException {
173
174 SCProductEntry productEntry =
175 scProductEntryPersistence.findByPrimaryKey(productEntryId);
176
177 addProductEntryResources(
178 productEntry, communityPermissions, guestPermissions);
179 }
180
181 public void addProductEntryResources(
182 SCProductEntry productEntry, boolean addCommunityPermissions,
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, addCommunityPermissions,
190 addGuestPermissions);
191 }
192
193 public void addProductEntryResources(
194 SCProductEntry productEntry, String[] communityPermissions,
195 String[] guestPermissions)
196 throws PortalException, SystemException {
197
198 resourceLocalService.addModelResources(
199 productEntry.getCompanyId(), productEntry.getGroupId(),
200 productEntry.getUserId(), SCProductEntry.class.getName(),
201 productEntry.getProductEntryId(), communityPermissions,
202 guestPermissions);
203 }
204
205 public void deleteProductEntries(long groupId)
206 throws PortalException, SystemException {
207
208 List<SCProductEntry> productEntries =
209 scProductEntryPersistence.findByGroupId(groupId);
210
211 for (SCProductEntry productEntry : productEntries) {
212 deleteProductEntry(productEntry);
213 }
214 }
215
216 public void deleteProductEntry(long productEntryId)
217 throws PortalException, SystemException {
218
219 SCProductEntry productEntry =
220 scProductEntryPersistence.findByPrimaryKey(productEntryId);
221
222 deleteProductEntry(productEntry);
223 }
224
225 public void deleteProductEntry(SCProductEntry productEntry)
226 throws PortalException, SystemException {
227
228
230 scProductEntryPersistence.remove(productEntry);
231
232
234 resourceLocalService.deleteResource(
235 productEntry.getCompanyId(), SCProductEntry.class.getName(),
236 ResourceConstants.SCOPE_INDIVIDUAL,
237 productEntry.getProductEntryId());
238
239
241 scProductScreenshotLocalService.deleteProductScreenshots(
242 productEntry.getProductEntryId());
243
244
246 scProductVersionLocalService.deleteProductVersions(
247 productEntry.getProductEntryId());
248
249
251 mbMessageLocalService.deleteDiscussionMessages(
252 SCProductEntry.class.getName(), productEntry.getProductEntryId());
253
254
256 ratingsStatsLocalService.deleteStats(
257 SCProductEntry.class.getName(), productEntry.getProductEntryId());
258
259
261 Indexer indexer = IndexerRegistryUtil.getIndexer(SCProductEntry.class);
262
263 indexer.delete(productEntry);
264 }
265
266 public List<SCProductEntry> getCompanyProductEntries(
267 long companyId, int start, int end)
268 throws SystemException {
269
270 return scProductEntryPersistence.findByCompanyId(companyId, start, end);
271 }
272
273 public int getCompanyProductEntriesCount(long companyId)
274 throws SystemException {
275
276 return scProductEntryPersistence.countByCompanyId(companyId);
277 }
278
279 public List<SCProductEntry> getProductEntries(
280 long groupId, int start, int end)
281 throws SystemException {
282
283 return scProductEntryPersistence.findByGroupId(groupId, start, end);
284 }
285
286 public List<SCProductEntry> getProductEntries(
287 long groupId, int start, int end, OrderByComparator obc)
288 throws SystemException {
289
290 return scProductEntryPersistence.findByGroupId(
291 groupId, start, end, obc);
292 }
293
294 public List<SCProductEntry> getProductEntries(
295 long groupId, long userId, int start, int end)
296 throws SystemException {
297
298 return scProductEntryPersistence.findByG_U(groupId, userId, start, end);
299 }
300
301 public List<SCProductEntry> getProductEntries(
302 long groupId, long userId, int start, int end,
303 OrderByComparator obc)
304 throws SystemException {
305
306 return scProductEntryPersistence.findByG_U(
307 groupId, userId, start, end, obc);
308 }
309
310 public int getProductEntriesCount(long groupId)
311 throws SystemException {
312
313 return scProductEntryPersistence.countByGroupId(groupId);
314 }
315
316 public int getProductEntriesCount(long groupId, long userId)
317 throws SystemException {
318
319 return scProductEntryPersistence.countByG_U(groupId, userId);
320 }
321
322 public SCProductEntry getProductEntry(long productEntryId)
323 throws PortalException, SystemException {
324
325 return scProductEntryPersistence.findByPrimaryKey(productEntryId);
326 }
327
328 public String getRepositoryXML(
329 long groupId, String baseImageURL, Date oldestDate,
330 int maxNumOfVersions, Properties repoSettings)
331 throws SystemException {
332
333 return getRepositoryXML(
334 groupId, null, baseImageURL, oldestDate, maxNumOfVersions,
335 repoSettings);
336 }
337
338 public String getRepositoryXML(
339 long groupId, String version, String baseImageURL, Date oldestDate,
340 int maxNumOfVersions, Properties repoSettings)
341 throws SystemException {
342
343 Document doc = SAXReaderUtil.createDocument();
344
345 doc.setXMLEncoding(StringPool.UTF8);
346
347 Element root = doc.addElement("plugin-repository");
348
349 Element settingsEl = root.addElement("settings");
350
351 populateSettingsElement(settingsEl, repoSettings);
352
353 List<SCProductEntry> productEntries =
354 scProductEntryPersistence.findByGroupId(groupId);
355
356 for (SCProductEntry productEntry : productEntries) {
357 if (Validator.isNull(productEntry.getRepoGroupId()) ||
358 Validator.isNull(productEntry.getRepoArtifactId())) {
359
360 continue;
361 }
362
363 List<SCProductVersion> productVersions =
364 scProductVersionPersistence.findByProductEntryId(
365 productEntry.getProductEntryId());
366
367 for (int i = 0; i < productVersions.size(); i++) {
368 SCProductVersion productVersion = productVersions.get(i);
369
370 if ((maxNumOfVersions > 0) && (maxNumOfVersions < (i + 1))) {
371 break;
372 }
373
374 if (!productVersion.isRepoStoreArtifact()) {
375 continue;
376 }
377
378 if ((oldestDate != null) &&
379 (oldestDate.after(productVersion.getModifiedDate()))) {
380
381 continue;
382 }
383
384 if (Validator.isNotNull(version) &&
385 !isVersionSupported(
386 version, productVersion.getFrameworkVersions())) {
387
388 continue;
389 }
390
391 Element el = root.addElement("plugin-package");
392
393 populatePluginPackageElement(
394 el, productEntry, productVersion, baseImageURL);
395 }
396 }
397
398 return doc.asXML();
399 }
400
401 public SCProductEntry updateProductEntry(
402 long productEntryId, String name, String type, String tags,
403 String shortDescription, String longDescription, String pageURL,
404 String author, String repoGroupId, String repoArtifactId,
405 long[] licenseIds, List<byte[]> thumbnails, List<byte[]> fullImages)
406 throws PortalException, SystemException {
407
408
410 tags = getTags(tags);
411 repoGroupId = repoGroupId.trim().toLowerCase();
412 repoArtifactId = repoArtifactId.trim().toLowerCase();
413 Date now = new Date();
414
415 validate(
416 productEntryId, name, type, shortDescription, pageURL, author,
417 repoGroupId, repoArtifactId, licenseIds, thumbnails, fullImages);
418
419 SCProductEntry productEntry =
420 scProductEntryPersistence.findByPrimaryKey(productEntryId);
421
422 productEntry.setModifiedDate(now);
423 productEntry.setName(name);
424 productEntry.setType(type);
425 productEntry.setTags(tags);
426 productEntry.setShortDescription(shortDescription);
427 productEntry.setLongDescription(longDescription);
428 productEntry.setPageURL(pageURL);
429 productEntry.setAuthor(author);
430 productEntry.setRepoGroupId(repoGroupId);
431 productEntry.setRepoArtifactId(repoArtifactId);
432
433 scProductEntryPersistence.update(productEntry, false);
434
435
437 scProductEntryPersistence.setSCLicenses(productEntryId, licenseIds);
438
439
441 if (thumbnails.size() == 0) {
442 scProductScreenshotLocalService.deleteProductScreenshots(
443 productEntryId);
444 }
445 else {
446 saveProductScreenshots(productEntry, thumbnails, fullImages);
447 }
448
449
451 Indexer indexer = IndexerRegistryUtil.getIndexer(SCProductEntry.class);
452
453 indexer.reindex(productEntry);
454
455 return productEntry;
456 }
457
458 protected String getTags(String tags) {
459 tags = tags.trim().toLowerCase();
460
461 return StringUtil.merge(StringUtil.split(tags), ", ");
462 }
463
464 protected boolean isVersionSupported(
465 String version, List<SCFrameworkVersion> frameworkVersions) {
466
467 Version currentVersion = Version.getInstance(version);
468
469 for (SCFrameworkVersion frameworkVersion : frameworkVersions) {
470 Version supportedVersion = Version.getInstance(
471 frameworkVersion.getName());
472
473 if (supportedVersion.includes(currentVersion)) {
474 return true;
475 }
476 }
477
478 return false;
479 }
480
481 protected void populatePluginPackageElement(
482 Element el, SCProductEntry productEntry,
483 SCProductVersion productVersion, String baseImageURL)
484 throws SystemException {
485
486 DocUtil.add(el, "name", productEntry.getName());
487
488 String moduleId = ModuleId.toString(
489 productEntry.getRepoGroupId(), productEntry.getRepoArtifactId(),
490 productVersion.getVersion(), "war");
491
492 DocUtil.add(el, "module-id", moduleId);
493
494 DocUtil.add(
495 el, "modified-date",
496 Time.getRFC822(productVersion.getModifiedDate()));
497
498 Element typesEl = el.addElement("types");
499
500 DocUtil.add(typesEl, "type", productEntry.getType());
501
502 Element tagsEl = el.addElement("tags");
503
504 String[] tags = StringUtil.split(productEntry.getTags());
505
506 for (int i = 0; i < tags.length; i++) {
507 DocUtil.add(tagsEl, "tag", tags[i]);
508 }
509
510 DocUtil.add(
511 el, "short-description", productEntry.getShortDescription());
512
513 if (Validator.isNotNull(productEntry.getLongDescription())) {
514 DocUtil.add(
515 el, "long-description", productEntry.getLongDescription());
516 }
517
518 if (Validator.isNotNull(productVersion.getChangeLog())) {
519 DocUtil.add(el, "change-log", productVersion.getChangeLog());
520 }
521
522 if (Validator.isNotNull(productVersion.getDirectDownloadURL())) {
523 DocUtil.add(
524 el, "download-url", productVersion.getDirectDownloadURL());
525 }
526
527 DocUtil.add(el, "author", productEntry.getAuthor());
528
529 Element screenshotsEl = el.addElement("screenshots");
530
531 for (SCProductScreenshot screenshot : productEntry.getScreenshots()) {
532 long thumbnailId = screenshot.getThumbnailId();
533 long fullImageId = screenshot.getFullImageId();
534
535 Element screenshotEl = screenshotsEl.addElement("screenshot");
536
537 DocUtil.add(
538 screenshotEl, "thumbnail-url",
539 baseImageURL + "?img_id=" + thumbnailId + "&t=" +
540 ImageServletTokenUtil.getToken(thumbnailId));
541 DocUtil.add(
542 screenshotEl, "large-image-url",
543 baseImageURL + "?img_id=" + fullImageId + "&t=" +
544 ImageServletTokenUtil.getToken(fullImageId));
545 }
546
547 Element licensesEl = el.addElement("licenses");
548
549 for (SCLicense license : productEntry.getLicenses()) {
550 Element licenseEl = licensesEl.addElement("license");
551
552 licenseEl.addText(license.getName());
553 licenseEl.addAttribute(
554 "osi-approved", String.valueOf(license.isOpenSource()));
555 }
556
557 Element liferayVersionsEl = el.addElement("liferay-versions");
558
559 for (SCFrameworkVersion frameworkVersion :
560 productVersion.getFrameworkVersions()) {
561
562 DocUtil.add(
563 liferayVersionsEl, "liferay-version",
564 frameworkVersion.getName());
565 }
566 }
567
568 protected void populateSettingsElement(
569 Element el, Properties repoSettings) {
570
571 if (repoSettings == null) {
572 return;
573 }
574
575 Iterator<Object> itr = repoSettings.keySet().iterator();
576
577 while (itr.hasNext()) {
578 String key = (String)itr.next();
579
580 Element settingEl = el.addElement("setting");
581
582 settingEl.addAttribute("name", key);
583 settingEl.addAttribute("value", repoSettings.getProperty(key));
584 }
585 }
586
587 protected void saveProductScreenshots(
588 SCProductEntry productEntry, List<byte[]> thumbnails,
589 List<byte[]> fullImages)
590 throws PortalException, SystemException {
591
592 long productEntryId = productEntry.getProductEntryId();
593
594 List<SCProductScreenshot> productScreenshots =
595 scProductScreenshotPersistence.findByProductEntryId(productEntryId);
596
597 if (thumbnails.size() < productScreenshots.size()) {
598 for (int i = thumbnails.size(); i < productScreenshots.size();
599 i++) {
600
601 SCProductScreenshot productScreenshot =
602 productScreenshots.get(i);
603
604 scProductScreenshotLocalService.deleteProductScreenshot(
605 productScreenshot);
606 }
607 }
608
609 for (int i = 0; i < thumbnails.size(); i++) {
610 int priority = i;
611
612 byte[] thumbnail = thumbnails.get(i);
613 byte[] fullImage = fullImages.get(i);
614
615 SCProductScreenshot productScreenshot =
616 scProductScreenshotPersistence.fetchByP_P(
617 productEntryId, priority);
618
619 if (productScreenshot == null) {
620 long productScreenshotId = counterLocalService.increment();
621
622 productScreenshot = scProductScreenshotPersistence.create(
623 productScreenshotId);
624
625 productScreenshot.setCompanyId(productEntry.getCompanyId());
626 productScreenshot.setGroupId(productEntry.getGroupId());
627 productScreenshot.setProductEntryId(productEntryId);
628 productScreenshot.setThumbnailId(
629 counterLocalService.increment());
630 productScreenshot.setFullImageId(
631 counterLocalService.increment());
632 productScreenshot.setPriority(priority);
633
634 scProductScreenshotPersistence.update(productScreenshot, false);
635 }
636
637 imageLocalService.updateImage(
638 productScreenshot.getThumbnailId(), thumbnail);
639 imageLocalService.updateImage(
640 productScreenshot.getFullImageId(), fullImage);
641 }
642 }
643
644 protected void validate(
645 long productEntryId, String name, String type,
646 String shortDescription, String pageURL, String author,
647 String repoGroupId, String repoArtifactId, long[] licenseIds,
648 List<byte[]> thumbnails, List<byte[]> fullImages)
649 throws PortalException, SystemException {
650
651 if (Validator.isNull(name)) {
652 throw new ProductEntryNameException();
653 }
654
655 if (Validator.isNull(type)) {
656 throw new ProductEntryTypeException();
657 }
658
659 if (Validator.isNull(shortDescription)) {
660 throw new ProductEntryShortDescriptionException();
661 }
662
663 if (Validator.isNull(pageURL)) {
664 throw new ProductEntryPageURLException();
665 }
666 else {
667 try {
668 new URL(pageURL);
669 }
670 catch (MalformedURLException murle) {
671 throw new ProductEntryPageURLException();
672 }
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 }
687
688 if (licenseIds.length == 0) {
689 throw new ProductEntryLicenseException();
690 }
691
692 if (thumbnails.size() != fullImages.size()) {
693 throw new ProductEntryScreenshotsException();
694 }
695 else {
696 Iterator<byte[]> itr = thumbnails.iterator();
697
698 while (itr.hasNext()) {
699 if (itr.next() == null) {
700 throw new ProductEntryScreenshotsException();
701 }
702 }
703
704 itr = fullImages.iterator();
705
706 while (itr.hasNext()) {
707 if (itr.next() == null) {
708 throw new ProductEntryScreenshotsException();
709 }
710 }
711 }
712 }
713
714 }