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