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