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