1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portlet.softwarecatalog.service.impl;
16  
17  import com.liferay.portal.PortalException;
18  import com.liferay.portal.SystemException;
19  import com.liferay.portal.kernel.log.Log;
20  import com.liferay.portal.kernel.log.LogFactoryUtil;
21  import com.liferay.portal.kernel.plugin.Version;
22  import com.liferay.portal.kernel.search.BooleanClauseOccur;
23  import com.liferay.portal.kernel.search.BooleanQuery;
24  import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
25  import com.liferay.portal.kernel.search.Field;
26  import com.liferay.portal.kernel.search.Hits;
27  import com.liferay.portal.kernel.search.SearchEngineUtil;
28  import com.liferay.portal.kernel.search.SearchException;
29  import com.liferay.portal.kernel.servlet.ImageServletTokenUtil;
30  import com.liferay.portal.kernel.util.GetterUtil;
31  import com.liferay.portal.kernel.util.OrderByComparator;
32  import com.liferay.portal.kernel.util.StringPool;
33  import com.liferay.portal.kernel.util.StringUtil;
34  import com.liferay.portal.kernel.util.Time;
35  import com.liferay.portal.kernel.util.Validator;
36  import com.liferay.portal.kernel.xml.Document;
37  import com.liferay.portal.kernel.xml.Element;
38  import com.liferay.portal.kernel.xml.SAXReaderUtil;
39  import com.liferay.portal.model.Group;
40  import com.liferay.portal.model.ResourceConstants;
41  import com.liferay.portal.model.User;
42  import com.liferay.portal.plugin.ModuleId;
43  import com.liferay.portal.service.ServiceContext;
44  import com.liferay.portal.util.PropsValues;
45  import com.liferay.portlet.expando.model.ExpandoBridge;
46  import com.liferay.portlet.softwarecatalog.DuplicateProductEntryModuleIdException;
47  import com.liferay.portlet.softwarecatalog.ProductEntryAuthorException;
48  import com.liferay.portlet.softwarecatalog.ProductEntryLicenseException;
49  import com.liferay.portlet.softwarecatalog.ProductEntryNameException;
50  import com.liferay.portlet.softwarecatalog.ProductEntryPageURLException;
51  import com.liferay.portlet.softwarecatalog.ProductEntryScreenshotsException;
52  import com.liferay.portlet.softwarecatalog.ProductEntryShortDescriptionException;
53  import com.liferay.portlet.softwarecatalog.ProductEntryTypeException;
54  import com.liferay.portlet.softwarecatalog.model.SCFrameworkVersion;
55  import com.liferay.portlet.softwarecatalog.model.SCLicense;
56  import com.liferay.portlet.softwarecatalog.model.SCProductEntry;
57  import com.liferay.portlet.softwarecatalog.model.SCProductScreenshot;
58  import com.liferay.portlet.softwarecatalog.model.SCProductVersion;
59  import com.liferay.portlet.softwarecatalog.service.base.SCProductEntryLocalServiceBaseImpl;
60  import com.liferay.portlet.softwarecatalog.util.Indexer;
61  import com.liferay.util.xml.DocUtil;
62  
63  import java.net.MalformedURLException;
64  import java.net.URL;
65  
66  import java.util.Date;
67  import java.util.Iterator;
68  import java.util.List;
69  import java.util.Properties;
70  
71  /**
72   * <a href="SCProductEntryLocalServiceImpl.java.html"><b><i>View Source</i></b>
73   * </a>
74   *
75   * @author Jorge Ferrer
76   * @author Brian Wing Shun Chan
77   * @author Raymond Augé
78   */
79  public class SCProductEntryLocalServiceImpl
80      extends SCProductEntryLocalServiceBaseImpl {
81  
82      public SCProductEntry addProductEntry(
83              long userId, String name, String type, String tags,
84              String shortDescription, String longDescription, String pageURL,
85              String author, String repoGroupId, String repoArtifactId,
86              long[] licenseIds, List<byte[]> thumbnails, List<byte[]> fullImages,
87              ServiceContext serviceContext)
88          throws PortalException, SystemException {
89  
90          // Product entry
91  
92          User user = userPersistence.findByPrimaryKey(userId);
93          long groupId = serviceContext.getScopeGroupId();
94          tags = getTags(tags);
95          repoGroupId = repoGroupId.trim().toLowerCase();
96          repoArtifactId = repoArtifactId.trim().toLowerCase();
97          Date now = new Date();
98  
99          validate(
100             0, name, type, shortDescription, pageURL, author, repoGroupId,
101             repoArtifactId, licenseIds, thumbnails, fullImages);
102 
103         long productEntryId = counterLocalService.increment();
104 
105         SCProductEntry productEntry = scProductEntryPersistence.create(
106             productEntryId);
107 
108         productEntry.setGroupId(groupId);
109         productEntry.setCompanyId(user.getCompanyId());
110         productEntry.setUserId(user.getUserId());
111         productEntry.setUserName(user.getFullName());
112         productEntry.setCreateDate(now);
113         productEntry.setModifiedDate(now);
114         productEntry.setName(name);
115         productEntry.setType(type);
116         productEntry.setTags(tags);
117         productEntry.setShortDescription(shortDescription);
118         productEntry.setLongDescription(longDescription);
119         productEntry.setPageURL(pageURL);
120         productEntry.setAuthor(author);
121         productEntry.setRepoGroupId(repoGroupId);
122         productEntry.setRepoArtifactId(repoArtifactId);
123 
124         scProductEntryPersistence.update(productEntry, false);
125 
126         // Resources
127 
128         if (serviceContext.getAddCommunityPermissions() ||
129             serviceContext.getAddGuestPermissions()) {
130 
131             addProductEntryResources(
132                 productEntry, serviceContext.getAddCommunityPermissions(),
133                 serviceContext.getAddGuestPermissions());
134         }
135         else {
136             addProductEntryResources(
137                 productEntry, serviceContext.getCommunityPermissions(),
138                 serviceContext.getGuestPermissions());
139         }
140 
141         // Licenses
142 
143         scProductEntryPersistence.setSCLicenses(productEntryId, licenseIds);
144 
145         // Product screenshots
146 
147         saveProductScreenshots(productEntry, thumbnails, fullImages);
148 
149         // Message boards
150 
151         if (PropsValues.SC_PRODUCT_COMMENTS_ENABLED) {
152             mbMessageLocalService.addDiscussionMessage(
153                 userId, productEntry.getUserName(),
154                 SCProductEntry.class.getName(), productEntryId);
155         }
156 
157         // Indexer
158 
159         reIndex(productEntry);
160 
161         return productEntry;
162     }
163 
164     public void addProductEntryResources(
165             long productEntryId, boolean addCommunityPermissions,
166             boolean addGuestPermissions)
167         throws PortalException, SystemException {
168 
169         SCProductEntry productEntry =
170             scProductEntryPersistence.findByPrimaryKey(productEntryId);
171 
172         addProductEntryResources(
173             productEntry, addCommunityPermissions, addGuestPermissions);
174     }
175 
176     public void addProductEntryResources(
177             long productEntryId, String[] communityPermissions,
178             String[] guestPermissions)
179         throws PortalException, SystemException {
180 
181         SCProductEntry productEntry =
182             scProductEntryPersistence.findByPrimaryKey(productEntryId);
183 
184         addProductEntryResources(
185             productEntry, communityPermissions, guestPermissions);
186     }
187 
188     public void addProductEntryResources(
189             SCProductEntry productEntry, boolean addCommunityPermissions,
190             boolean addGuestPermissions)
191         throws PortalException, SystemException {
192 
193         resourceLocalService.addResources(
194             productEntry.getCompanyId(), productEntry.getGroupId(),
195             productEntry.getUserId(), SCProductEntry.class.getName(),
196             productEntry.getProductEntryId(), false, addCommunityPermissions,
197             addGuestPermissions);
198     }
199 
200     public void addProductEntryResources(
201             SCProductEntry productEntry, String[] communityPermissions,
202             String[] guestPermissions)
203         throws PortalException, SystemException {
204 
205         resourceLocalService.addModelResources(
206             productEntry.getCompanyId(), productEntry.getGroupId(),
207             productEntry.getUserId(), SCProductEntry.class.getName(),
208             productEntry.getProductEntryId(), communityPermissions,
209             guestPermissions);
210     }
211 
212     public void deleteProductEntries(long groupId)
213         throws PortalException, SystemException {
214 
215         List<SCProductEntry> productEntries =
216             scProductEntryPersistence.findByGroupId(groupId);
217 
218         for (SCProductEntry productEntry : productEntries) {
219             deleteProductEntry(productEntry);
220         }
221     }
222 
223     public void deleteProductEntry(long productEntryId)
224         throws PortalException, SystemException {
225 
226         SCProductEntry productEntry =
227             scProductEntryPersistence.findByPrimaryKey(productEntryId);
228 
229         deleteProductEntry(productEntry);
230     }
231 
232     public void deleteProductEntry(SCProductEntry productEntry)
233         throws PortalException, SystemException {
234 
235         // Product entry
236 
237         scProductEntryPersistence.remove(productEntry);
238 
239         // Resources
240 
241         resourceLocalService.deleteResource(
242             productEntry.getCompanyId(), SCProductEntry.class.getName(),
243             ResourceConstants.SCOPE_INDIVIDUAL,
244             productEntry.getProductEntryId());
245 
246         // Product screenshots
247 
248         scProductScreenshotLocalService.deleteProductScreenshots(
249             productEntry.getProductEntryId());
250 
251         // Product versions
252 
253         scProductVersionLocalService.deleteProductVersions(
254             productEntry.getProductEntryId());
255 
256         // Message boards
257 
258         mbMessageLocalService.deleteDiscussionMessages(
259             SCProductEntry.class.getName(), productEntry.getProductEntryId());
260 
261         // Ratings
262 
263         ratingsStatsLocalService.deleteStats(
264             SCProductEntry.class.getName(), productEntry.getProductEntryId());
265 
266         // Indexer
267 
268         try {
269             Indexer.deleteProductEntry(
270                 productEntry.getCompanyId(), productEntry.getProductEntryId());
271         }
272         catch (SearchException se) {
273             _log.error(
274                 "Deleting index " + productEntry.getProductEntryId(), se);
275         }
276     }
277 
278     public List<SCProductEntry> getProductEntries(
279             long groupId, int start, int end)
280         throws SystemException {
281 
282         return scProductEntryPersistence.findByGroupId(groupId, start, end);
283     }
284 
285     public List<SCProductEntry> getProductEntries(
286             long groupId, int start, int end, OrderByComparator obc)
287         throws SystemException {
288 
289         return scProductEntryPersistence.findByGroupId(
290             groupId, start, end, obc);
291     }
292 
293     public List<SCProductEntry> getProductEntries(
294             long groupId, long userId, int start, int end)
295         throws SystemException {
296 
297         return scProductEntryPersistence.findByG_U(groupId, userId, start, end);
298     }
299 
300     public List<SCProductEntry> getProductEntries(
301             long groupId, long userId, int start, int end,
302             OrderByComparator obc)
303         throws SystemException {
304 
305         return scProductEntryPersistence.findByG_U(
306             groupId, userId, start, end, obc);
307     }
308 
309     public int getProductEntriesCount(long groupId)
310         throws SystemException {
311 
312         return scProductEntryPersistence.countByGroupId(groupId);
313     }
314 
315     public int getProductEntriesCount(long groupId, long userId)
316         throws SystemException {
317 
318         return scProductEntryPersistence.countByG_U(groupId, userId);
319     }
320 
321     public SCProductEntry getProductEntry(long productEntryId)
322         throws PortalException, SystemException {
323 
324         return scProductEntryPersistence.findByPrimaryKey(productEntryId);
325     }
326 
327     public String getRepositoryXML(
328             long groupId, String baseImageURL, Date oldestDate,
329             int maxNumOfVersions, Properties repoSettings)
330         throws SystemException {
331 
332         return getRepositoryXML(
333             groupId, null, baseImageURL, oldestDate, maxNumOfVersions,
334             repoSettings);
335     }
336 
337     public String getRepositoryXML(
338             long groupId, String version, String baseImageURL, Date oldestDate,
339             int maxNumOfVersions, Properties repoSettings)
340         throws SystemException {
341 
342         Document doc = SAXReaderUtil.createDocument();
343 
344         doc.setXMLEncoding(StringPool.UTF8);
345 
346         Element root = doc.addElement("plugin-repository");
347 
348         Element settingsEl = root.addElement("settings");
349 
350         populateSettingsElement(settingsEl, repoSettings);
351 
352         List<SCProductEntry> productEntries =
353             scProductEntryPersistence.findByGroupId(groupId);
354 
355         for (SCProductEntry productEntry : productEntries) {
356             if (Validator.isNull(productEntry.getRepoGroupId()) ||
357                 Validator.isNull(productEntry.getRepoArtifactId())) {
358 
359                 continue;
360             }
361 
362             List<SCProductVersion> productVersions =
363                 scProductVersionPersistence.findByProductEntryId(
364                     productEntry.getProductEntryId());
365 
366             for (int i = 0; i < productVersions.size(); i++) {
367                 SCProductVersion productVersion = productVersions.get(i);
368 
369                 if ((maxNumOfVersions > 0) && (maxNumOfVersions < (i + 1))) {
370                     break;
371                 }
372 
373                 if (!productVersion.isRepoStoreArtifact()) {
374                     continue;
375                 }
376 
377                 if ((oldestDate != null) &&
378                     (oldestDate.after(productVersion.getModifiedDate()))) {
379 
380                     continue;
381                 }
382 
383                 if (Validator.isNotNull(version) &&
384                     !isVersionSupported(
385                         version, productVersion.getFrameworkVersions())) {
386 
387                     continue;
388                 }
389 
390                 Element el = root.addElement("plugin-package");
391 
392                 populatePluginPackageElement(
393                     el, productEntry, productVersion, baseImageURL);
394             }
395         }
396 
397         return doc.asXML();
398     }
399 
400     public void reIndex(long productEntryId) throws SystemException {
401         if (SearchEngineUtil.isIndexReadOnly()) {
402             return;
403         }
404 
405         SCProductEntry productEntry =
406             scProductEntryPersistence.fetchByPrimaryKey(productEntryId);
407 
408         if (productEntry == null) {
409             return;
410         }
411 
412         reIndex(productEntry);
413     }
414 
415     public void reIndex(SCProductEntry productEntry) throws SystemException {
416         long companyId = productEntry.getCompanyId();
417         long groupId = productEntry.getGroupId();
418         long userId = productEntry.getUserId();
419         String userName = productEntry.getUserName();
420         long productEntryId = productEntry.getProductEntryId();
421         String name = productEntry.getName();
422         Date modifiedDate = productEntry.getModifiedDate();
423 
424         String version = StringPool.BLANK;
425 
426         SCProductVersion latestProductVersion = productEntry.getLatestVersion();
427 
428         if (latestProductVersion != null) {
429             version = latestProductVersion.getVersion();
430         }
431 
432         String type = productEntry.getType();
433         String shortDescription = productEntry.getShortDescription();
434         String longDescription = productEntry.getLongDescription();
435         String pageURL = productEntry.getPageURL();
436         String repoGroupId = productEntry.getRepoGroupId();
437         String repoArtifactId = productEntry.getRepoArtifactId();
438 
439         ExpandoBridge expandoBridge = productEntry.getExpandoBridge();
440 
441         try {
442             Indexer.updateProductEntry(
443                 companyId, groupId, userId, userName, productEntryId, name,
444                 modifiedDate, version, type, shortDescription, longDescription,
445                 pageURL, repoGroupId, repoArtifactId, expandoBridge);
446         }
447         catch (SearchException se) {
448             _log.error("Reindexing " + productEntry.getProductEntryId(), se);
449         }
450     }
451 
452     public void reIndex(String[] ids) throws SystemException {
453         if (SearchEngineUtil.isIndexReadOnly()) {
454             return;
455         }
456 
457         long companyId = GetterUtil.getLong(ids[0]);
458 
459         try {
460             reIndexProductEntries(companyId);
461         }
462         catch (SystemException se) {
463             throw se;
464         }
465         catch (Exception e) {
466             throw new SystemException(e);
467         }
468     }
469 
470     public Hits search(
471             long companyId, long groupId, String keywords, String type,
472             int start, int end)
473         throws SystemException {
474 
475         try {
476             BooleanQuery contextQuery = BooleanQueryFactoryUtil.create();
477 
478             contextQuery.addRequiredTerm(Field.PORTLET_ID, Indexer.PORTLET_ID);
479 
480             if (groupId > 0) {
481                 Group group = groupLocalService.getGroup(groupId);
482 
483                 if (group.isLayout()) {
484                     contextQuery.addRequiredTerm(Field.SCOPE_GROUP_ID, groupId);
485 
486                     groupId = group.getParentGroupId();
487                 }
488 
489                 contextQuery.addRequiredTerm(Field.GROUP_ID, groupId);
490             }
491 
492             BooleanQuery fullQuery = BooleanQueryFactoryUtil.create();
493 
494             fullQuery.add(contextQuery, BooleanClauseOccur.MUST);
495 
496             if (Validator.isNotNull(keywords)) {
497                 BooleanQuery searchQuery = BooleanQueryFactoryUtil.create();
498 
499                 searchQuery.addTerm(Field.USER_NAME, keywords);
500                 searchQuery.addTerm(Field.TITLE, keywords);
501                 searchQuery.addTerm(Field.CONTENT, keywords);
502 
503                 fullQuery.add(searchQuery, BooleanClauseOccur.MUST);
504             }
505 
506             if (Validator.isNotNull(type)) {
507                 BooleanQuery searchQuery = BooleanQueryFactoryUtil.create();
508 
509                 searchQuery.addRequiredTerm("type", type);
510 
511                 fullQuery.add(searchQuery, BooleanClauseOccur.MUST);
512             }
513 
514             return SearchEngineUtil.search(companyId, fullQuery, start, end);
515         }
516         catch (Exception e) {
517             throw new SystemException(e);
518         }
519     }
520 
521     public SCProductEntry updateProductEntry(
522             long productEntryId, String name, String type, String tags,
523             String shortDescription, String longDescription, String pageURL,
524             String author, String repoGroupId, String repoArtifactId,
525             long[] licenseIds, List<byte[]> thumbnails, List<byte[]> fullImages)
526         throws PortalException, SystemException {
527 
528         // Product entry
529 
530         tags = getTags(tags);
531         repoGroupId = repoGroupId.trim().toLowerCase();
532         repoArtifactId = repoArtifactId.trim().toLowerCase();
533         Date now = new Date();
534 
535         validate(
536             productEntryId, name, type, shortDescription, pageURL, author,
537             repoGroupId, repoArtifactId, licenseIds, thumbnails, fullImages);
538 
539         SCProductEntry productEntry =
540             scProductEntryPersistence.findByPrimaryKey(productEntryId);
541 
542         productEntry.setModifiedDate(now);
543         productEntry.setName(name);
544         productEntry.setType(type);
545         productEntry.setTags(tags);
546         productEntry.setShortDescription(shortDescription);
547         productEntry.setLongDescription(longDescription);
548         productEntry.setPageURL(pageURL);
549         productEntry.setAuthor(author);
550         productEntry.setRepoGroupId(repoGroupId);
551         productEntry.setRepoArtifactId(repoArtifactId);
552 
553         scProductEntryPersistence.update(productEntry, false);
554 
555         // Licenses
556 
557         scProductEntryPersistence.setSCLicenses(productEntryId, licenseIds);
558 
559         // Product screenshots
560 
561         if (thumbnails.size() == 0) {
562             scProductScreenshotLocalService.deleteProductScreenshots(
563                 productEntryId);
564         }
565         else {
566             saveProductScreenshots(productEntry, thumbnails, fullImages);
567         }
568 
569         // Indexer
570 
571         reIndex(productEntry);
572 
573         return productEntry;
574     }
575 
576     protected String getTags(String tags) {
577         tags = tags.trim().toLowerCase();
578 
579         return StringUtil.merge(StringUtil.split(tags), ", ");
580     }
581 
582     protected boolean isVersionSupported(
583         String version, List<SCFrameworkVersion> frameworkVersions) {
584 
585         Version currentVersion = Version.getInstance(version);
586 
587         for (SCFrameworkVersion frameworkVersion : frameworkVersions) {
588             Version supportedVersion = Version.getInstance(
589                 frameworkVersion.getName());
590 
591             if (supportedVersion.includes(currentVersion)) {
592                 return true;
593             }
594         }
595 
596         return false;
597     }
598 
599     protected void populatePluginPackageElement(
600             Element el, SCProductEntry productEntry,
601             SCProductVersion productVersion, String baseImageURL)
602         throws SystemException {
603 
604         DocUtil.add(el, "name", productEntry.getName());
605 
606         String moduleId = ModuleId.toString(
607             productEntry.getRepoGroupId(), productEntry.getRepoArtifactId(),
608             productVersion.getVersion(), "war");
609 
610         DocUtil.add(el, "module-id", moduleId);
611 
612         DocUtil.add(
613             el, "modified-date",
614             Time.getRFC822(productVersion.getModifiedDate()));
615 
616         Element typesEl = el.addElement("types");
617 
618         DocUtil.add(typesEl, "type", productEntry.getType());
619 
620         Element tagsEl = el.addElement("tags");
621 
622         String[] tags = StringUtil.split(productEntry.getTags());
623 
624         for (int i = 0; i < tags.length; i++) {
625             DocUtil.add(tagsEl, "tag", tags[i]);
626         }
627 
628         DocUtil.add(
629             el, "short-description", productEntry.getShortDescription());
630 
631         if (Validator.isNotNull(productEntry.getLongDescription())) {
632             DocUtil.add(
633                 el, "long-description", productEntry.getLongDescription());
634         }
635 
636         if (Validator.isNotNull(productVersion.getChangeLog())) {
637             DocUtil.add(el, "change-log", productVersion.getChangeLog());
638         }
639 
640         if (Validator.isNotNull(productVersion.getDirectDownloadURL())) {
641             DocUtil.add(
642                 el, "download-url", productVersion.getDirectDownloadURL());
643         }
644 
645         DocUtil.add(el, "author", productEntry.getAuthor());
646 
647         Element screenshotsEl = el.addElement("screenshots");
648 
649         for (SCProductScreenshot screenshot : productEntry.getScreenshots()) {
650             long thumbnailId = screenshot.getThumbnailId();
651             long fullImageId = screenshot.getFullImageId();
652 
653             Element screenshotEl = screenshotsEl.addElement("screenshot");
654 
655             DocUtil.add(
656                 screenshotEl, "thumbnail-url",
657                 baseImageURL + "?img_id=" + thumbnailId + "&t=" +
658                     ImageServletTokenUtil.getToken(thumbnailId));
659             DocUtil.add(
660                 screenshotEl, "large-image-url",
661                 baseImageURL + "?img_id=" + fullImageId + "&t=" +
662                     ImageServletTokenUtil.getToken(fullImageId));
663         }
664 
665         Element licensesEl = el.addElement("licenses");
666 
667         for (SCLicense license : productEntry.getLicenses()) {
668             Element licenseEl = licensesEl.addElement("license");
669 
670             licenseEl.addText(license.getName());
671             licenseEl.addAttribute(
672                 "osi-approved", String.valueOf(license.isOpenSource()));
673         }
674 
675         Element liferayVersionsEl = el.addElement("liferay-versions");
676 
677         for (SCFrameworkVersion frameworkVersion :
678                 productVersion.getFrameworkVersions()) {
679 
680             DocUtil.add(
681                 liferayVersionsEl, "liferay-version",
682                 frameworkVersion.getName());
683         }
684     }
685 
686     protected void populateSettingsElement(
687         Element el, Properties repoSettings) {
688 
689         if (repoSettings == null) {
690             return;
691         }
692 
693         Iterator<Object> itr = repoSettings.keySet().iterator();
694 
695         while (itr.hasNext()) {
696             String key = (String)itr.next();
697 
698             Element settingEl = el.addElement("setting");
699 
700             settingEl.addAttribute("name", key);
701             settingEl.addAttribute("value", repoSettings.getProperty(key));
702         }
703     }
704 
705     protected void reIndexProductEntries(long companyId)
706         throws SystemException {
707 
708         int count = scProductEntryPersistence.countByCompanyId(companyId);
709 
710         int pages = count / Indexer.DEFAULT_INTERVAL;
711 
712         for (int i = 0; i <= pages; i++) {
713             int start = (i * Indexer.DEFAULT_INTERVAL);
714             int end = start + Indexer.DEFAULT_INTERVAL;
715 
716             reIndexProductEntries(companyId, start, end);
717         }
718     }
719 
720     protected void reIndexProductEntries(long companyId, int start, int end)
721         throws SystemException {
722 
723         List<SCProductEntry> productEntries =
724             scProductEntryPersistence.findByCompanyId(companyId, start, end);
725 
726         for (SCProductEntry productEntry : productEntries) {
727             reIndex(productEntry);
728         }
729     }
730 
731     protected void saveProductScreenshots(
732             SCProductEntry productEntry, List<byte[]> thumbnails,
733             List<byte[]> fullImages)
734         throws PortalException, SystemException {
735 
736         long productEntryId = productEntry.getProductEntryId();
737 
738         List<SCProductScreenshot> productScreenshots =
739             scProductScreenshotPersistence.findByProductEntryId(productEntryId);
740 
741         if (thumbnails.size() < productScreenshots.size()) {
742             for (int i = thumbnails.size(); i < productScreenshots.size();
743                     i++) {
744 
745                 SCProductScreenshot productScreenshot =
746                     productScreenshots.get(i);
747 
748                 scProductScreenshotLocalService.deleteProductScreenshot(
749                     productScreenshot);
750             }
751         }
752 
753         for (int i = 0; i < thumbnails.size(); i++) {
754             int priority = i;
755 
756             byte[] thumbnail = thumbnails.get(i);
757             byte[] fullImage = fullImages.get(i);
758 
759             SCProductScreenshot productScreenshot =
760                 scProductScreenshotPersistence.fetchByP_P(
761                     productEntryId, priority);
762 
763             if (productScreenshot == null) {
764                 long productScreenshotId = counterLocalService.increment();
765 
766                 productScreenshot = scProductScreenshotPersistence.create(
767                     productScreenshotId);
768 
769                 productScreenshot.setCompanyId(productEntry.getCompanyId());
770                 productScreenshot.setGroupId(productEntry.getGroupId());
771                 productScreenshot.setProductEntryId(productEntryId);
772                 productScreenshot.setThumbnailId(
773                     counterLocalService.increment());
774                 productScreenshot.setFullImageId(
775                     counterLocalService.increment());
776                 productScreenshot.setPriority(priority);
777 
778                 scProductScreenshotPersistence.update(productScreenshot, false);
779             }
780 
781             imageLocalService.updateImage(
782                 productScreenshot.getThumbnailId(), thumbnail);
783             imageLocalService.updateImage(
784                 productScreenshot.getFullImageId(), fullImage);
785         }
786     }
787 
788     protected void validate(
789             long productEntryId, String name, String type,
790             String shortDescription, String pageURL, String author,
791             String repoGroupId, String repoArtifactId, long[] licenseIds,
792             List<byte[]> thumbnails, List<byte[]> fullImages)
793         throws PortalException, SystemException {
794 
795         if (Validator.isNull(name)) {
796             throw new ProductEntryNameException();
797         }
798 
799         if (Validator.isNull(type)) {
800             throw new ProductEntryTypeException();
801         }
802 
803         if (Validator.isNull(shortDescription)) {
804             throw new ProductEntryShortDescriptionException();
805         }
806 
807         if (Validator.isNull(pageURL)) {
808             throw new ProductEntryPageURLException();
809         }
810         else {
811             try {
812                 new URL(pageURL);
813             }
814             catch (MalformedURLException murle) {
815                 throw new ProductEntryPageURLException();
816             }
817         }
818 
819         if (Validator.isNull(author)) {
820             throw new ProductEntryAuthorException();
821         }
822 
823         SCProductEntry productEntry = scProductEntryPersistence.fetchByRG_RA(
824             repoGroupId, repoArtifactId);
825 
826         if ((productEntry != null) &&
827             (productEntry.getProductEntryId() != productEntryId)) {
828 
829             throw new DuplicateProductEntryModuleIdException();
830         }
831 
832         if (licenseIds.length == 0) {
833             throw new ProductEntryLicenseException();
834         }
835 
836         if (thumbnails.size() != fullImages.size()) {
837             throw new ProductEntryScreenshotsException();
838         }
839         else {
840             Iterator<byte[]> itr = thumbnails.iterator();
841 
842             while (itr.hasNext()) {
843                 if (itr.next() == null) {
844                     throw new ProductEntryScreenshotsException();
845                 }
846             }
847 
848             itr = fullImages.iterator();
849 
850             while (itr.hasNext()) {
851                 if (itr.next() == null) {
852                     throw new ProductEntryScreenshotsException();
853                 }
854             }
855         }
856     }
857 
858     private static Log _log = LogFactoryUtil.getLog(
859         SCProductEntryLocalServiceImpl.class);
860 
861 }