001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.social.service.impl;
016    
017    import com.liferay.ibm.icu.util.Calendar;
018    import com.liferay.ibm.icu.util.GregorianCalendar;
019    import com.liferay.portal.NoSuchUserException;
020    import com.liferay.portal.kernel.exception.PortalException;
021    import com.liferay.portal.kernel.exception.SystemException;
022    import com.liferay.portal.kernel.increment.BufferedIncrement;
023    import com.liferay.portal.kernel.increment.SocialEquityIncrement;
024    import com.liferay.portal.kernel.messaging.async.Async;
025    import com.liferay.portal.kernel.util.StringUtil;
026    import com.liferay.portal.model.User;
027    import com.liferay.portal.util.PropsValues;
028    import com.liferay.portlet.asset.NoSuchEntryException;
029    import com.liferay.portlet.asset.model.AssetEntry;
030    import com.liferay.portlet.social.NoSuchEquityAssetEntryException;
031    import com.liferay.portlet.social.model.SocialEquityAssetEntry;
032    import com.liferay.portlet.social.model.SocialEquityLog;
033    import com.liferay.portlet.social.model.SocialEquitySetting;
034    import com.liferay.portlet.social.model.SocialEquitySettingConstants;
035    import com.liferay.portlet.social.model.SocialEquityValue;
036    import com.liferay.portlet.social.service.base.SocialEquityLogLocalServiceBaseImpl;
037    import com.liferay.util.dao.orm.CustomSQLUtil;
038    
039    import java.sql.PreparedStatement;
040    import java.sql.ResultSet;
041    import java.sql.SQLException;
042    
043    import java.util.ArrayList;
044    import java.util.Date;
045    import java.util.List;
046    
047    import javax.sql.DataSource;
048    
049    import org.springframework.dao.DataAccessException;
050    import org.springframework.jdbc.core.BatchPreparedStatementSetter;
051    import org.springframework.jdbc.core.JdbcTemplate;
052    import org.springframework.jdbc.core.RowCallbackHandler;
053    
054    /**
055     * @author Zsolt Berentey
056     * @author Brian Wing Shun Chan
057     */
058    public class SocialEquityLogLocalServiceImpl
059            extends SocialEquityLogLocalServiceBaseImpl {
060    
061            public void addEquityLogs(
062                            long userId, long assetEntryId, String actionId)
063                    throws PortalException, SystemException {
064    
065                    if (!PropsValues.SOCIAL_EQUITY_EQUITY_LOG_ENABLED) {
066                            return;
067                    }
068    
069                    User user = userPersistence.findByPrimaryKey(userId);
070    
071                    AssetEntry assetEntry = assetEntryPersistence.findByPrimaryKey(
072                            assetEntryId);
073    
074                    User assetEntryUser = null;
075    
076                    try {
077                            assetEntryUser = userPersistence.findByPrimaryKey(
078                                    assetEntry.getUserId());
079                    }
080                    catch (NoSuchUserException nsue) {
081                    }
082    
083                    List<SocialEquitySetting> equitySettings =
084                            socialEquitySettingLocalService.getEquitySettings(
085                                    assetEntry.getGroupId(), assetEntry.getClassNameId(), actionId);
086    
087                    for (SocialEquitySetting equitySetting : equitySettings) {
088                            addEquityLog(user, assetEntry, assetEntryUser, equitySetting);
089                    }
090            }
091    
092            public void addEquityLogs(
093                            long userId, String className, long classPK, String actionId)
094                    throws PortalException, SystemException {
095    
096                    if (!PropsValues.SOCIAL_EQUITY_EQUITY_LOG_ENABLED) {
097                            return;
098                    }
099    
100                    AssetEntry assetEntry = null;
101    
102                    try {
103                            assetEntry = assetEntryLocalService.getEntry(
104                                    className, classPK);
105                    }
106                    catch (NoSuchEntryException nsee) {
107                            return;
108                    }
109    
110                    addEquityLogs(userId, assetEntry.getEntryId(), actionId);
111            }
112    
113            public void checkEquityLogs() throws SystemException {
114                    int validity = getEquityDate();
115    
116                    if (!PropsValues.SOCIAL_EQUITY_EQUITY_LOG_ENABLED) {
117                            return;
118                    }
119    
120                    runCheckSQL(_CHECK_SOCIAL_EQUITY_ASSET_ENTRY_IQ, validity);
121    
122                    assetEntryPersistence.clearCache();
123    
124                    runCheckSQL(_CHECK_SOCIAL_EQUITY_USER, validity);
125                    runCheckSQL(_CHECK_SOCIAL_EQUITY_USER_CQ, validity);
126                    runCheckSQL(_CHECK_SOCIAL_EQUITY_USER_PQ, validity);
127    
128                    userPersistence.clearCache();
129    
130                    runCheckSQL(_CHECK_SOCIAL_EQUITY_LOGS, validity);
131    
132                    socialEquityLogPersistence.clearCache();
133    
134                    updateRanks();
135            }
136    
137            public void deactivateEquityLogs(long assetEntryId)
138                    throws PortalException, SystemException {
139    
140                    if (!PropsValues.SOCIAL_EQUITY_EQUITY_LOG_ENABLED) {
141                            return;
142                    }
143    
144                    SocialEquityAssetEntry equityAssetEntry = null;
145    
146                    try {
147                            equityAssetEntry =
148                                    socialEquityAssetEntryPersistence.findByAssetEntryId(
149                                            assetEntryId);
150    
151                            socialEquityAssetEntryPersistence.removeByAssetEntryId(
152                                    assetEntryId);
153                    }
154                    catch (NoSuchEquityAssetEntryException nseaee) {
155                            return;
156                    }
157    
158                    User user = null;
159    
160                    try {
161                            user = userPersistence.findByPrimaryKey(
162                                    equityAssetEntry.getUserId());
163    
164                            if (!user.isDefaultUser()) {
165                                    SocialEquityValue socialEquityValue = new SocialEquityValue(
166                                            -equityAssetEntry.getInformationK(),
167                                            -equityAssetEntry.getInformationB());
168    
169                                    incrementSocialEquityUser_CQ(
170                                            equityAssetEntry.getGroupId(), user.getUserId(),
171                                            socialEquityValue);
172                            }
173                    }
174                    catch (NoSuchUserException nsue) {
175                    }
176    
177                    List<SocialEquityLog> equityLogs =
178                            socialEquityLogPersistence.findByAEI_T_A(
179                                    assetEntryId, SocialEquitySettingConstants.TYPE_INFORMATION,
180                                    true);
181    
182                    for (SocialEquityLog equityLog : equityLogs) {
183                            equityLog.setActive(false);
184    
185                            socialEquityLogPersistence.update(equityLog, false);
186                    }
187            }
188    
189            public void deactivateEquityLogs(
190                            long userId, long assetEntryId, String actionId)
191                    throws PortalException, SystemException {
192    
193                    if (!PropsValues.SOCIAL_EQUITY_EQUITY_LOG_ENABLED) {
194                            return;
195                    }
196    
197                    User user = userPersistence.findByPrimaryKey(userId);
198    
199                    AssetEntry assetEntry = assetEntryPersistence.findByPrimaryKey(
200                            assetEntryId);
201    
202                    // Information Equity
203    
204                    List<SocialEquityLog> equityLogs =
205                            socialEquityLogPersistence.findByAEI_AID_A_T(
206                                    assetEntryId, actionId, true,
207                                    SocialEquitySettingConstants.TYPE_INFORMATION);
208    
209                    SocialEquityValue socialEquityValue = new SocialEquityValue(0,0);
210    
211                    for (SocialEquityLog equityLog : equityLogs) {
212                            double k = calculateK(equityLog.getValue(),equityLog.getLifespan());
213                            double b = calculateB(
214                                    equityLog.getActionDate(), equityLog.getValue(),
215                                    equityLog.getLifespan());
216    
217                            socialEquityValue.subtract(new SocialEquityValue(k,b));
218    
219                            equityLog.setActive(false);
220    
221                            socialEquityLogPersistence.remove(equityLog);
222                    }
223    
224                    socialEquityLogLocalService.incrementSocialEquityAssetEntry_IQ(
225                            assetEntryId, socialEquityValue);
226    
227                    socialEquityLogLocalService.incrementSocialEquityUser_CQ(
228                            assetEntry.getGroupId(), assetEntry.getUserId(), socialEquityValue);
229    
230                    // Participation Equity
231                    equityLogs = socialEquityLogPersistence.findByU_AID_A_T(
232                            userId, actionId, true,
233                            SocialEquitySettingConstants.TYPE_PARTICIPATION);
234    
235                    socialEquityValue = new SocialEquityValue(0,0);
236    
237                    for (SocialEquityLog equityLog : equityLogs) {
238                            double k = calculateK(equityLog.getValue(),equityLog.getLifespan());
239                            double b = calculateB(
240                                    equityLog.getActionDate(), equityLog.getValue(),
241                                    equityLog.getLifespan());
242    
243                            socialEquityValue.subtract(new SocialEquityValue(k,b));
244    
245                            equityLog.setActive(false);
246    
247                            socialEquityLogPersistence.remove(equityLog);
248                    }
249    
250                    socialEquityLogLocalService.incrementSocialEquityUser_PQ(
251                            user.getGroup().getGroupId(), userId, socialEquityValue);
252            }
253    
254            public void deactivateEquityLogs(
255                            long userId, String className, long classPK, String actionId)
256                    throws PortalException, SystemException {
257    
258                    if (!PropsValues.SOCIAL_EQUITY_EQUITY_LOG_ENABLED) {
259                            return;
260                    }
261    
262                    AssetEntry assetEntry = null;
263    
264                    try {
265                            assetEntry = assetEntryLocalService.getEntry(
266                                    className, classPK);
267                    }
268                    catch (NoSuchEntryException nsee) {
269                            return;
270                    }
271    
272                    deactivateEquityLogs(userId, assetEntry.getEntryId(), actionId);
273            }
274    
275            @BufferedIncrement(incrementClass = SocialEquityIncrement.class)
276            public void incrementSocialEquityAssetEntry_IQ(
277                            long assetEntryId, SocialEquityValue socialEquityValue)
278                    throws SystemException {
279    
280                    AssetEntry assetEntry = assetEntryPersistence.fetchByPrimaryKey(
281                            assetEntryId);
282    
283                    assetEntry.updateSocialInformationEquity(socialEquityValue.getValue());
284    
285                    int count = socialEquityAssetEntryPersistence.countByAssetEntryId(
286                            assetEntryId);
287    
288                    if (count == 0) {
289                            addSocialEquityAssetEntry(assetEntry);
290                    }
291    
292                    String sql = CustomSQLUtil.get(_UPDATE_SOCIAL_EQUITY_ASSET_ENTRY_IQ);
293    
294                    sql = StringUtil.replace(
295                            sql,
296                            new String[] {
297                                    "[$ASSET_ENTRY_ID$]",
298                                    "[$INFORMATION_B$]",
299                                    "[$INFORMATION_K$]"
300                            },
301                            new String[] {
302                                    String.valueOf(assetEntryId),
303                                    String.valueOf(socialEquityValue.getB()),
304                                    String.valueOf(socialEquityValue.getK())
305                            });
306    
307                    runSQL(sql);
308            }
309    
310            @BufferedIncrement(incrementClass = SocialEquityIncrement.class)
311            public void incrementSocialEquityUser_CQ(
312                            long groupId, long userId, SocialEquityValue socialEquityValue)
313                    throws PortalException, SystemException {
314    
315                    User user = userLocalService.getUser(userId);
316    
317                    int count = socialEquityUserPersistence.countByG_U(groupId, userId);
318    
319                    if (count == 0) {
320                            addSocialEquityUser(groupId, user);
321                    }
322    
323                    user.updateSocialContributionEquity(socialEquityValue.getValue());
324    
325                    String sql = CustomSQLUtil.get(_UPDATE_SOCIAL_EQUITY_USER_CQ);
326    
327                    sql = StringUtil.replace(
328                            sql,
329                            new String[] {
330                                    "[$CONTRIBUTION_B$]",
331                                    "[$CONTRIBUTION_K$]",
332                                    "[$GROUP_ID$]",
333                                    "[$USER_ID$]"
334                            },
335                            new String[] {
336                                    String.valueOf(socialEquityValue.getB()),
337                                    String.valueOf(socialEquityValue.getK()),
338                                    String.valueOf(groupId),
339                                    String.valueOf(userId)
340                            });
341    
342                    runSQL(sql);
343            }
344    
345            @BufferedIncrement(incrementClass = SocialEquityIncrement.class)
346            public void incrementSocialEquityUser_PQ(
347                            long groupId, long userId, SocialEquityValue socialEquityValue)
348                    throws PortalException, SystemException {
349    
350                    User user = userLocalService.getUser(userId);
351    
352                    int count = socialEquityUserPersistence.countByG_U(groupId, userId);
353    
354                    if (count == 0) {
355                            addSocialEquityUser(groupId, user);
356                    }
357    
358                    user.updateSocialParticipationEquity(socialEquityValue.getValue());
359    
360                    String sql = CustomSQLUtil.get(_UPDATE_SOCIAL_EQUITY_USER_PQ);
361    
362                    sql = StringUtil.replace(
363                            sql,
364                            new String[] {
365                                    "[$GROUP_ID$]",
366                                    "[$PARTICIPATION_B$]",
367                                    "[$PARTICIPATION_K$]",
368                                    "[$USER_ID$]"
369                            },
370                            new String[] {
371                                    String.valueOf(groupId),
372                                    String.valueOf(socialEquityValue.getB()),
373                                    String.valueOf(socialEquityValue.getK()),
374                                    String.valueOf(userId)
375                            });
376    
377                    runSQL(sql);
378            }
379    
380            @Async
381            public void updateRanks() {
382                    DataSource dataSource = socialEquityLogPersistence.getDataSource();
383    
384                    JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
385    
386                    UpdateRanksHandler updateRanksHandler = new UpdateRanksHandler(
387                            jdbcTemplate);
388    
389                    String sql = CustomSQLUtil.get(_FIND_SOCIAL_EQUITY_USER_BY_RANK);
390    
391                    sql = StringUtil.replace(
392                            sql, "[$ACTION_DATE$]", String.valueOf(getEquityDate()));
393    
394                    jdbcTemplate.query(sql, updateRanksHandler);
395    
396                    updateRanksHandler.flush();
397            }
398    
399            protected void addEquityLog(
400                            User user, AssetEntry assetEntry, User assetEntryUser,
401                            SocialEquitySetting equitySetting)
402                    throws PortalException, SystemException {
403    
404                    if (!checkActionRestrictions(
405                            user.getUserId(), assetEntry.getEntryId(), equitySetting)) {
406    
407                            return;
408                    }
409    
410                    int actionDate = getEquityDate();
411    
412                    double k = calculateK(
413                            equitySetting.getValue(), equitySetting.getLifespan());
414                    double b = calculateB(
415                            actionDate, equitySetting.getValue(), equitySetting.getLifespan());
416    
417                    SocialEquityValue socialEquity = new SocialEquityValue(k, b);
418    
419                    if (equitySetting.getType() ==
420                                    SocialEquitySettingConstants.TYPE_INFORMATION) {
421    
422                            socialEquityLogLocalService.incrementSocialEquityAssetEntry_IQ(
423                                    assetEntry.getEntryId(), socialEquity);
424    
425                            if ((assetEntryUser != null) && !assetEntryUser.isDefaultUser()) {
426                                    socialEquityLogLocalService.incrementSocialEquityUser_CQ(
427                                            assetEntry.getGroupId(), assetEntryUser.getUserId(),
428                                            socialEquity);
429                            }
430                    }
431                    else if (equitySetting.getType() ==
432                                            SocialEquitySettingConstants.TYPE_PARTICIPATION) {
433    
434                            if (!user.isDefaultUser()) {
435                                    socialEquityLogLocalService.incrementSocialEquityUser_PQ(
436                                            assetEntry.getGroupId(), user.getUserId(), socialEquity);
437                            }
438                    }
439    
440                    long equityLogId = counterLocalService.increment();
441    
442                    SocialEquityLog equityLog = socialEquityLogPersistence.create(
443                            equityLogId);
444    
445                    equityLog.setGroupId(assetEntry.getGroupId());
446                    equityLog.setCompanyId(user.getCompanyId());
447                    equityLog.setUserId(user.getUserId());
448                    equityLog.setAssetEntryId(assetEntry.getEntryId());
449                    equityLog.setActionId(equitySetting.getActionId());
450                    equityLog.setActionDate(actionDate);
451                    equityLog.setType(equitySetting.getType());
452                    equityLog.setValue(equitySetting.getValue());
453                    equityLog.setExpiration(actionDate + equitySetting.getLifespan());
454                    equityLog.setActive(true);
455    
456                    socialEquityLogPersistence.update(equityLog, false);
457            }
458    
459            protected void addSocialEquityAssetEntry(AssetEntry assetEntry)
460                    throws SystemException {
461    
462                    String sql = CustomSQLUtil.get(_ADD_SOCIAL_EQUITY_ASSET_ENTRY);
463    
464                    sql = StringUtil.replace(
465                            sql,
466                            new String[] {
467                                    "[$ASSET_ENTRY_ID$]",
468                                    "[$COMPANY_ID$]",
469                                    "[$EQUITY_ASSET_ENTRY_ID$]",
470                                    "[$GROUP_ID$]",
471                                    "[$USER_ID$]"
472                            },
473                            new String[] {
474                                    String.valueOf(assetEntry.getEntryId()),
475                                    String.valueOf(assetEntry.getCompanyId()),
476                                    String.valueOf(counterLocalService.increment()),
477                                    String.valueOf(assetEntry.getGroupId()),
478                                    String.valueOf(assetEntry.getUserId())
479                            });
480    
481                    runSQL(sql);
482            }
483    
484            protected void addSocialEquityUser(long groupId, User user)
485                    throws SystemException {
486    
487                    String sql = CustomSQLUtil.get(_ADD_SOCIAL_EQUITY_USER);
488    
489                    sql = StringUtil.replace(
490                            sql,
491                            new String[] {
492                                    "[$COMPANY_ID$]",
493                                    "[$EQUITY_USER_ID$]",
494                                    "[$GROUP_ID$]",
495                                    "[$USER_ID$]"
496                            },
497                            new String[] {
498                                    String.valueOf(user.getCompanyId()),
499                                    String.valueOf(counterLocalService.increment()),
500                                    String.valueOf(groupId),
501                                    String.valueOf(user.getUserId())
502                            });
503    
504                    runSQL(sql);
505            }
506    
507            protected double calculateB(int actionDate, int value, int lifespan) {
508                    return calculateK(value, lifespan) * (actionDate + lifespan) * -1;
509            }
510    
511            protected double calculateEquity(int actionDate, double k, double b) {
512                    return k * actionDate + b;
513            }
514    
515            protected double calculateK(int value, int lifespan) {
516                    if (lifespan == 0) {
517                            return 0;
518                    }
519    
520                    return ((double)value / lifespan) * -1;
521            }
522    
523            protected boolean checkActionRestrictions(
524                            long userId, long assetEntryId, SocialEquitySetting equitySetting)
525                    throws SystemException {
526    
527                    if (equitySetting.getDailyLimit() < 0) {
528                            return false;
529                    }
530    
531                    String actionId = equitySetting.getActionId();
532                    int actionDate = getEquityDate();
533                    int type = equitySetting.getType();
534    
535                    // Duplicate
536    
537                    if (socialEquityLogPersistence.countByU_AEI_AID_AD_A_T(
538                                    userId, assetEntryId, actionId, actionDate, true, type) > 0) {
539    
540                            return false;
541                    }
542    
543                    // Unique
544    
545                    if (equitySetting.isUniqueEntry()) {
546                            int count = 0;
547    
548                            if (type == SocialEquitySettingConstants.TYPE_INFORMATION) {
549                                    count = socialEquityLogPersistence.countByAEI_AID_A_T(
550                                            assetEntryId, actionId, true, type);
551                            }
552                            else {
553                                    count = socialEquityLogPersistence.countByU_AID_A_T(
554                                            userId, actionId, true, type);
555                            }
556    
557                            if (count > 0) {
558                                    return false;
559                            }
560                    }
561    
562                    // Daily limit
563    
564                    if (equitySetting.getDailyLimit() == 0) {
565                            return true;
566                    }
567    
568                    int count = 0;
569    
570                    if (type == SocialEquitySettingConstants.TYPE_INFORMATION) {
571                            count = socialEquityLogPersistence.countByAEI_AID_AD_A_T(
572                                    assetEntryId, actionId, actionDate, true, type);
573                    }
574                    else {
575                            count = socialEquityLogPersistence.countByU_AID_AD_A_T(
576                                    userId, actionId, actionDate, true, type);
577                    }
578    
579                    if (count < equitySetting.getDailyLimit()) {
580                            return true;
581                    }
582                    else {
583                            return false;
584                    }
585            }
586    
587            protected int getEquityDate() {
588                    return getEquityDate(new Date());
589            }
590    
591            protected int getEquityDate(Date date) {
592                    Calendar calendar = new GregorianCalendar(2010, Calendar.JANUARY, 1);
593    
594                    return calendar.fieldDifference(date, Calendar.DATE);
595            }
596    
597            protected void runCheckSQL(String sqlId, int validity)
598                    throws SystemException {
599    
600                    String sql = CustomSQLUtil.get(sqlId);
601    
602                    sql = StringUtil.replace(
603                            sql,
604                            new String[] {
605                                    "[$TYPE_INFORMATION$]",
606                                    "[$TYPE_PARTICIPATION$]",
607                                    "[$EXPIRATION$]"
608                            },
609                            new String[] {
610                                    String.valueOf(SocialEquitySettingConstants.TYPE_INFORMATION),
611                                    String.valueOf(SocialEquitySettingConstants.TYPE_PARTICIPATION),
612                                    String.valueOf(validity)
613                            });
614    
615                    runSQL(sql);
616            }
617    
618            private static final String _ADD_SOCIAL_EQUITY_ASSET_ENTRY =
619                    SocialEquityLogLocalServiceImpl.class.getName() +
620                            ".addSocialEquityAssetEntry";
621    
622            private static final String _ADD_SOCIAL_EQUITY_USER =
623                    SocialEquityLogLocalServiceImpl.class.getName() +
624                            ".addSocialEquityUser";
625    
626            private static final String _CHECK_SOCIAL_EQUITY_ASSET_ENTRY_IQ =
627                    SocialEquityLogLocalServiceImpl.class.getName() +
628                            ".checkSocialEquityAssetEntry_IQ";
629    
630            private static final String _CHECK_SOCIAL_EQUITY_LOGS =
631                    SocialEquityLogLocalServiceImpl.class.getName() +
632                            ".checkSocialEquityLogs";
633    
634            private static final String _CHECK_SOCIAL_EQUITY_USER =
635                    SocialEquityLogLocalServiceImpl.class.getName() +
636                            ".checkSocialEquityUser";
637    
638            private static final String _CHECK_SOCIAL_EQUITY_USER_CQ =
639                    SocialEquityLogLocalServiceImpl.class.getName() +
640                            ".checkSocialEquityUser_CQ";
641    
642            private static final String _CHECK_SOCIAL_EQUITY_USER_PQ =
643                    SocialEquityLogLocalServiceImpl.class.getName() +
644                            ".checkSocialEquityUser_PQ";
645    
646            private static final String _FIND_SOCIAL_EQUITY_USER_BY_RANK =
647                    SocialEquityLogLocalServiceImpl.class.getName() +
648                            ".findSocialEquityUserByRank";
649    
650            private static final String _UPDATE_SOCIAL_EQUITY_ASSET_ENTRY_IQ =
651                    SocialEquityLogLocalServiceImpl.class.getName() +
652                            ".updateSocialEquityAssetEntry_IQ";
653    
654            private static final String _UPDATE_SOCIAL_EQUITY_USER_CQ =
655                    SocialEquityLogLocalServiceImpl.class.getName() +
656                            ".updateSocialEquityUser_CQ";
657    
658            private static final String _UPDATE_SOCIAL_EQUITY_USER_PQ =
659                    SocialEquityLogLocalServiceImpl.class.getName() +
660                            ".updateSocialEquityUser_PQ";
661    
662            private static final String _UPDATE_SOCIAL_EQUITY_USER_RANK =
663                    SocialEquityLogLocalServiceImpl.class.getName() +
664                            ".updateSocialEquityUserRank";
665    
666            private class UpdateRanksHandler implements RowCallbackHandler {
667    
668                    public UpdateRanksHandler(JdbcTemplate jdbcTemplate) {
669                            _updateRanksSetter = new UpdateRanksSetter(jdbcTemplate);
670                    }
671    
672                    public void flush() {
673                            _updateRanksSetter.flush();
674                    }
675    
676                    public void processRow(ResultSet rs) throws SQLException {
677                            long equityUserId = rs.getLong("equityUserId");
678                            long groupId = rs.getLong("groupId");
679                            double equityValue = rs.getDouble("equityValue");
680    
681                            if (groupId == _groupId) {
682                                    if (equityValue == _equityValue) {
683                                            _ties++;
684                                    }
685                                    else {
686                                            _equityValue = equityValue;
687                                            _rank = _rank + _ties + 1;
688                                            _ties = 0;
689                                    }
690                            }
691                            else {
692                                    _groupId = groupId;
693                                    _rank = 1;
694                                    _ties = 0;
695                            }
696    
697                            _updateRanksSetter.add(equityUserId, _rank);
698                    }
699    
700                    private double _equityValue;
701                    private long _groupId;
702                    private long _rank;
703                    private long _ties;
704                    private UpdateRanksSetter _updateRanksSetter;
705    
706            }
707    
708            private class UpdateRanksSetter implements BatchPreparedStatementSetter {
709    
710                    public UpdateRanksSetter(JdbcTemplate jdbcTemplate) {
711                            _jdbcTemplate = jdbcTemplate;
712                    }
713    
714                    public void add(long equityUserId, long rank) {
715                            _sqlParams.add(new Long[] {equityUserId, rank});
716    
717                            if (_sqlParams.size() >= 100) {
718                                    flush();
719                            }
720                    }
721    
722                    public int getBatchSize() {
723                            return _sqlParams.size();
724                    }
725    
726                    public void flush() {
727                            try {
728                                    _jdbcTemplate.batchUpdate(_sql, this);
729                            }
730                            catch (DataAccessException dae) {
731                                    throw dae;
732                            }
733                            finally {
734                                    _sqlParams.clear();
735                            }
736                    }
737    
738                    public void setValues(PreparedStatement ps, int index)
739                            throws SQLException {
740    
741                            Long[] sqlParams = _sqlParams.get(index);
742    
743                            long equityUserId = sqlParams[0];
744                            long rank = sqlParams[1];
745    
746                            ps.setLong(1, rank);
747                            ps.setLong(2, equityUserId);
748                            ps.setLong(3, rank);
749                    }
750    
751                    private JdbcTemplate _jdbcTemplate;
752                    private String _sql = CustomSQLUtil.get(
753                            _UPDATE_SOCIAL_EQUITY_USER_RANK);
754                    private List<Long[]> _sqlParams = new ArrayList<Long[]>();
755    
756            }
757    
758    }