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