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