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