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.Properties;
057
058
063 public class SCProductEntryLocalServiceImpl
064 extends SCProductEntryLocalServiceBaseImpl {
065
066 public SCProductEntry addProductEntry(
067 long userId, String name, String type, String tags,
068 String shortDescription, String longDescription, String pageURL,
069 String author, String repoGroupId, String repoArtifactId,
070 long[] licenseIds, List<byte[]> thumbnails, List<byte[]> fullImages,
071 ServiceContext serviceContext)
072 throws PortalException, SystemException {
073
074
075
076 User user = userPersistence.findByPrimaryKey(userId);
077 long groupId = serviceContext.getScopeGroupId();
078 tags = getTags(tags);
079 repoGroupId = repoGroupId.trim().toLowerCase();
080 repoArtifactId = repoArtifactId.trim().toLowerCase();
081 Date now = new Date();
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.setCreateDate(now);
097 productEntry.setModifiedDate(now);
098 productEntry.setName(name);
099 productEntry.setType(type);
100 productEntry.setTags(tags);
101 productEntry.setShortDescription(shortDescription);
102 productEntry.setLongDescription(longDescription);
103 productEntry.setPageURL(pageURL);
104 productEntry.setAuthor(author);
105 productEntry.setRepoGroupId(repoGroupId);
106 productEntry.setRepoArtifactId(repoArtifactId);
107
108 scProductEntryPersistence.update(productEntry, false);
109
110
111
112 if (serviceContext.getAddCommunityPermissions() ||
113 serviceContext.getAddGuestPermissions()) {
114
115 addProductEntryResources(
116 productEntry, serviceContext.getAddCommunityPermissions(),
117 serviceContext.getAddGuestPermissions());
118 }
119 else {
120 addProductEntryResources(
121 productEntry, serviceContext.getCommunityPermissions(),
122 serviceContext.getGuestPermissions());
123 }
124
125
126
127 scProductEntryPersistence.setSCLicenses(productEntryId, licenseIds);
128
129
130
131 saveProductScreenshots(productEntry, thumbnails, fullImages);
132
133
134
135 if (PropsValues.SC_PRODUCT_COMMENTS_ENABLED) {
136 mbMessageLocalService.addDiscussionMessage(
137 userId, productEntry.getUserName(), groupId,
138 SCProductEntry.class.getName(), productEntryId,
139 WorkflowConstants.ACTION_PUBLISH);
140 }
141
142
143
144 Indexer indexer = IndexerRegistryUtil.getIndexer(SCProductEntry.class);
145
146 indexer.reindex(productEntry);
147
148 return productEntry;
149 }
150
151 public void addProductEntryResources(
152 long productEntryId, boolean addCommunityPermissions,
153 boolean addGuestPermissions)
154 throws PortalException, SystemException {
155
156 SCProductEntry productEntry =
157 scProductEntryPersistence.findByPrimaryKey(productEntryId);
158
159 addProductEntryResources(
160 productEntry, addCommunityPermissions, addGuestPermissions);
161 }
162
163 public void addProductEntryResources(
164 long productEntryId, String[] communityPermissions,
165 String[] guestPermissions)
166 throws PortalException, SystemException {
167
168 SCProductEntry productEntry =
169 scProductEntryPersistence.findByPrimaryKey(productEntryId);
170
171 addProductEntryResources(
172 productEntry, communityPermissions, guestPermissions);
173 }
174
175 public void addProductEntryResources(
176 SCProductEntry productEntry, boolean addCommunityPermissions,
177 boolean addGuestPermissions)
178 throws PortalException, SystemException {
179
180 resourceLocalService.addResources(
181 productEntry.getCompanyId(), productEntry.getGroupId(),
182 productEntry.getUserId(), SCProductEntry.class.getName(),
183 productEntry.getProductEntryId(), false, addCommunityPermissions,
184 addGuestPermissions);
185 }
186
187 public void addProductEntryResources(
188 SCProductEntry productEntry, String[] communityPermissions,
189 String[] guestPermissions)
190 throws PortalException, SystemException {
191
192 resourceLocalService.addModelResources(
193 productEntry.getCompanyId(), productEntry.getGroupId(),
194 productEntry.getUserId(), SCProductEntry.class.getName(),
195 productEntry.getProductEntryId(), communityPermissions,
196 guestPermissions);
197 }
198
199 public void deleteProductEntries(long groupId)
200 throws PortalException, SystemException {
201
202 List<SCProductEntry> productEntries =
203 scProductEntryPersistence.findByGroupId(groupId);
204
205 for (SCProductEntry productEntry : productEntries) {
206 deleteProductEntry(productEntry);
207 }
208 }
209
210 public void deleteProductEntry(long productEntryId)
211 throws PortalException, SystemException {
212
213 SCProductEntry productEntry =
214 scProductEntryPersistence.findByPrimaryKey(productEntryId);
215
216 deleteProductEntry(productEntry);
217 }
218
219 public void deleteProductEntry(SCProductEntry productEntry)
220 throws PortalException, SystemException {
221
222
223
224 scProductEntryPersistence.remove(productEntry);
225
226
227
228 resourceLocalService.deleteResource(
229 productEntry.getCompanyId(), SCProductEntry.class.getName(),
230 ResourceConstants.SCOPE_INDIVIDUAL,
231 productEntry.getProductEntryId());
232
233
234
235 scProductScreenshotLocalService.deleteProductScreenshots(
236 productEntry.getProductEntryId());
237
238
239
240 scProductVersionLocalService.deleteProductVersions(
241 productEntry.getProductEntryId());
242
243
244
245 mbMessageLocalService.deleteDiscussionMessages(
246 SCProductEntry.class.getName(), productEntry.getProductEntryId());
247
248
249
250 ratingsStatsLocalService.deleteStats(
251 SCProductEntry.class.getName(), productEntry.getProductEntryId());
252
253
254
255 Indexer indexer = IndexerRegistryUtil.getIndexer(SCProductEntry.class);
256
257 indexer.delete(productEntry);
258 }
259
260 public List<SCProductEntry> getCompanyProductEntries(
261 long companyId, int start, int end)
262 throws SystemException {
263
264 return scProductEntryPersistence.findByCompanyId(companyId, start, end);
265 }
266
267 public int getCompanyProductEntriesCount(long companyId)
268 throws SystemException {
269
270 return scProductEntryPersistence.countByCompanyId(companyId);
271 }
272
273 public List<SCProductEntry> getProductEntries(
274 long groupId, int start, int end)
275 throws SystemException {
276
277 return scProductEntryPersistence.findByGroupId(groupId, start, end);
278 }
279
280 public List<SCProductEntry> getProductEntries(
281 long groupId, int start, int end, OrderByComparator obc)
282 throws SystemException {
283
284 return scProductEntryPersistence.findByGroupId(
285 groupId, start, end, obc);
286 }
287
288 public List<SCProductEntry> getProductEntries(
289 long groupId, long userId, int start, int end)
290 throws SystemException {
291
292 return scProductEntryPersistence.findByG_U(groupId, userId, start, end);
293 }
294
295 public List<SCProductEntry> getProductEntries(
296 long groupId, long userId, int start, int end,
297 OrderByComparator obc)
298 throws SystemException {
299
300 return scProductEntryPersistence.findByG_U(
301 groupId, userId, start, end, obc);
302 }
303
304 public int getProductEntriesCount(long groupId)
305 throws SystemException {
306
307 return scProductEntryPersistence.countByGroupId(groupId);
308 }
309
310 public int getProductEntriesCount(long groupId, long userId)
311 throws SystemException {
312
313 return scProductEntryPersistence.countByG_U(groupId, userId);
314 }
315
316 public SCProductEntry getProductEntry(long productEntryId)
317 throws PortalException, SystemException {
318
319 return scProductEntryPersistence.findByPrimaryKey(productEntryId);
320 }
321
322 public String getRepositoryXML(
323 long groupId, String baseImageURL, Date oldestDate,
324 int maxNumOfVersions, Properties repoSettings)
325 throws SystemException {
326
327 return getRepositoryXML(
328 groupId, null, baseImageURL, oldestDate, maxNumOfVersions,
329 repoSettings);
330 }
331
332 public String getRepositoryXML(
333 long groupId, String version, String baseImageURL, Date oldestDate,
334 int maxNumOfVersions, Properties repoSettings)
335 throws SystemException {
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 public SCProductEntry updateProductEntry(
396 long productEntryId, String name, String type, String tags,
397 String shortDescription, String longDescription, String pageURL,
398 String author, String repoGroupId, String repoArtifactId,
399 long[] licenseIds, List<byte[]> thumbnails, List<byte[]> fullImages)
400 throws PortalException, SystemException {
401
402
403
404 tags = getTags(tags);
405 repoGroupId = repoGroupId.trim().toLowerCase();
406 repoArtifactId = repoArtifactId.trim().toLowerCase();
407 Date now = new Date();
408
409 validate(
410 productEntryId, name, type, shortDescription, pageURL, author,
411 repoGroupId, repoArtifactId, licenseIds, thumbnails, fullImages);
412
413 SCProductEntry productEntry =
414 scProductEntryPersistence.findByPrimaryKey(productEntryId);
415
416 productEntry.setModifiedDate(now);
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, false);
428
429
430
431 scProductEntryPersistence.setSCLicenses(productEntryId, licenseIds);
432
433
434
435 if (thumbnails.size() == 0) {
436 scProductScreenshotLocalService.deleteProductScreenshots(
437 productEntryId);
438 }
439 else {
440 saveProductScreenshots(productEntry, thumbnails, fullImages);
441 }
442
443
444
445 Indexer indexer = IndexerRegistryUtil.getIndexer(SCProductEntry.class);
446
447 indexer.reindex(productEntry);
448
449 return productEntry;
450 }
451
452 protected String getTags(String tags) {
453 tags = tags.trim().toLowerCase();
454
455 return StringUtil.merge(StringUtil.split(tags), ", ");
456 }
457
458 protected boolean isVersionSupported(
459 String version, List<SCFrameworkVersion> frameworkVersions) {
460
461 Version currentVersion = Version.getInstance(version);
462
463 for (SCFrameworkVersion frameworkVersion : frameworkVersions) {
464 Version supportedVersion = Version.getInstance(
465 frameworkVersion.getName());
466
467 if (supportedVersion.includes(currentVersion)) {
468 return true;
469 }
470 }
471
472 return false;
473 }
474
475 protected void populatePluginPackageElement(
476 Element el, SCProductEntry productEntry,
477 SCProductVersion productVersion, String baseImageURL)
478 throws SystemException {
479
480 DocUtil.add(el, "name", productEntry.getName());
481
482 String moduleId = ModuleId.toString(
483 productEntry.getRepoGroupId(), productEntry.getRepoArtifactId(),
484 productVersion.getVersion(), "war");
485
486 DocUtil.add(el, "module-id", moduleId);
487
488 DocUtil.add(
489 el, "modified-date",
490 Time.getRFC822(productVersion.getModifiedDate()));
491
492 Element typesEl = el.addElement("types");
493
494 DocUtil.add(typesEl, "type", productEntry.getType());
495
496 Element tagsEl = el.addElement("tags");
497
498 String[] tags = StringUtil.split(productEntry.getTags());
499
500 for (int i = 0; i < tags.length; i++) {
501 DocUtil.add(tagsEl, "tag", tags[i]);
502 }
503
504 DocUtil.add(
505 el, "short-description", productEntry.getShortDescription());
506
507 if (Validator.isNotNull(productEntry.getLongDescription())) {
508 DocUtil.add(
509 el, "long-description", productEntry.getLongDescription());
510 }
511
512 if (Validator.isNotNull(productVersion.getChangeLog())) {
513 DocUtil.add(el, "change-log", productVersion.getChangeLog());
514 }
515
516 if (Validator.isNotNull(productVersion.getDirectDownloadURL())) {
517 DocUtil.add(
518 el, "download-url", productVersion.getDirectDownloadURL());
519 }
520
521 DocUtil.add(el, "author", productEntry.getAuthor());
522
523 Element screenshotsEl = el.addElement("screenshots");
524
525 for (SCProductScreenshot screenshot : productEntry.getScreenshots()) {
526 long thumbnailId = screenshot.getThumbnailId();
527 long fullImageId = screenshot.getFullImageId();
528
529 Element screenshotEl = screenshotsEl.addElement("screenshot");
530
531 DocUtil.add(
532 screenshotEl, "thumbnail-url",
533 baseImageURL + "?img_id=" + thumbnailId + "&t=" +
534 ImageServletTokenUtil.getToken(thumbnailId));
535 DocUtil.add(
536 screenshotEl, "large-image-url",
537 baseImageURL + "?img_id=" + fullImageId + "&t=" +
538 ImageServletTokenUtil.getToken(fullImageId));
539 }
540
541 Element licensesEl = el.addElement("licenses");
542
543 for (SCLicense license : productEntry.getLicenses()) {
544 Element licenseEl = licensesEl.addElement("license");
545
546 licenseEl.addText(license.getName());
547 licenseEl.addAttribute(
548 "osi-approved", String.valueOf(license.isOpenSource()));
549 }
550
551 Element liferayVersionsEl = el.addElement("liferay-versions");
552
553 for (SCFrameworkVersion frameworkVersion :
554 productVersion.getFrameworkVersions()) {
555
556 DocUtil.add(
557 liferayVersionsEl, "liferay-version",
558 frameworkVersion.getName());
559 }
560 }
561
562 protected void populateSettingsElement(
563 Element el, Properties repoSettings) {
564
565 if (repoSettings == null) {
566 return;
567 }
568
569 Iterator<Object> itr = repoSettings.keySet().iterator();
570
571 while (itr.hasNext()) {
572 String key = (String)itr.next();
573
574 Element settingEl = el.addElement("setting");
575
576 settingEl.addAttribute("name", key);
577 settingEl.addAttribute("value", repoSettings.getProperty(key));
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 }