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