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