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