1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.exoplatform.services.cms.voting.impl;
18
19 import java.text.DecimalFormat;
20
21 import javax.jcr.Node;
22 import javax.jcr.NodeIterator;
23 import javax.jcr.Session;
24 import javax.jcr.Value;
25 import javax.jcr.nodetype.NoSuchNodeTypeException;
26
27 import org.exoplatform.services.cms.i18n.MultiLanguageService;
28 import org.exoplatform.services.cms.voting.VotingService;
29 import org.exoplatform.services.jcr.core.ManageableRepository;
30 import org.exoplatform.services.wcm.utils.WCMCoreUtils;
31
32
33
34
35
36
37
38 public class VotingServiceImpl implements VotingService {
39
40 final static String VOTABLE = "mix:votable";
41 final static String VOTER_PROP = "exo:voter";
42 final static String VOTER_VOTEVALUE_PROP = "exo:voterVoteValues";
43 final static String VOTING_RATE_PROP = "exo:votingRate";
44 final static String VOTE_TOTAL_PROP = "exo:voteTotal";
45 final static String VOTE_TOTAL_LANG_PROP = "exo:voteTotalOfLang";
46 private static final String LANGUAGES = "languages";
47 private static final String SPACE = " ";
48
49 private MultiLanguageService multiLangService_ ;
50
51 public VotingServiceImpl(MultiLanguageService multiLangService) {
52 multiLangService_ = multiLangService ;
53 }
54
55
56
57
58 public long getVoteTotal(Node node) throws Exception {
59 long voteTotal = 0;
60 if(!node.hasNode(LANGUAGES) && node.hasProperty(VOTE_TOTAL_PROP)) {
61 return node.getProperty(VOTE_TOTAL_LANG_PROP).getLong() ;
62 }
63 Node multiLanguages = node.getNode(LANGUAGES) ;
64 voteTotal = node.getProperty(VOTE_TOTAL_LANG_PROP).getLong() ;
65 NodeIterator nodeIter = multiLanguages.getNodes() ;
66 while(nodeIter.hasNext()) {
67 Node languageNode = nodeIter.nextNode() ;
68 if(node.isNodeType("nt:file")) {
69 languageNode = getFileLangNode(languageNode) ;
70 }
71 if(languageNode.hasProperty(VOTE_TOTAL_LANG_PROP)) {
72 voteTotal = voteTotal + languageNode.getProperty(VOTE_TOTAL_LANG_PROP).getLong() ;
73 }
74 }
75 return voteTotal ;
76 }
77
78
79
80
81
82
83 public Node getFileLangNode(Node currentNode) throws Exception {
84 if(currentNode.getNodes().getSize() > 0) {
85 NodeIterator nodeIter = currentNode.getNodes() ;
86 while(nodeIter.hasNext()) {
87 Node ntFile = nodeIter.nextNode() ;
88 if(ntFile.isNodeType("nt:file")) {
89 return ntFile ;
90 }
91 }
92 return currentNode ;
93 }
94 return currentNode ;
95 }
96
97
98
99
100 public void vote(Node node, double rate, String userName, String language) throws Exception {
101 Session session = node.getSession();
102 node = handleUser(session, node, userName);
103
104 if(!node.isNodeType(VOTABLE)) {
105 if(node.canAddMixin(VOTABLE)) node.addMixin(VOTABLE) ;
106 else throw new NoSuchNodeTypeException() ;
107 }
108
109 Node languageNode = handleLanguage(node, language);
110 if(!languageNode.isNodeType(VOTABLE)) {
111 if(languageNode.canAddMixin(VOTABLE)) languageNode.addMixin(VOTABLE) ;
112 else throw new NoSuchNodeTypeException() ;
113 }
114
115 long voteTotalOfLang = languageNode.getProperty(VOTE_TOTAL_LANG_PROP).getLong() ;
116 double votingRate = languageNode.getProperty(VOTING_RATE_PROP).getDouble() ;
117 Value voterVoteValue = getVoterVoteValue(languageNode, userName);
118
119
120 double newRating = 0;
121 if (voterVoteValue != null) {
122 String oldUserRateValueStr = voterVoteValue.getString().substring(voterVoteValue.getString().lastIndexOf(SPACE) + 1);
123 double oldUserRate = Double.parseDouble(oldUserRateValueStr);
124 newRating = ((voteTotalOfLang*votingRate)+rate - oldUserRate)/(voteTotalOfLang) ;
125 } else {
126 newRating = ((voteTotalOfLang*votingRate)+rate)/(voteTotalOfLang+1) ;
127 }
128 DecimalFormat format = new DecimalFormat("###.##") ;
129 double formatedRating= format.parse(format.format(newRating)).doubleValue() ;
130
131
132 Value[] voterVoteValues = {} ;
133 Value[] newVoterVoteValues = null;
134 if(languageNode.hasProperty(VOTER_VOTEVALUE_PROP)) {
135 voterVoteValues = languageNode.getProperty(VOTER_VOTEVALUE_PROP).getValues() ;
136 }
137 if (voterVoteValue != null) {
138 newVoterVoteValues = replaceOldValue(voterVoteValues, userName, rate, languageNode.getSession());
139 } else {
140 Value newVoterVoteValue = languageNode.getSession().getValueFactory().createValue(userName + SPACE + rate);
141 newVoterVoteValues = new Value[voterVoteValues.length + (userName == null ? 0 : 1)];
142 System.arraycopy(voterVoteValues, 0, newVoterVoteValues, 0, voterVoteValues.length);
143 if (userName != null)
144 newVoterVoteValues[voterVoteValues.length] = newVoterVoteValue;
145 }
146 languageNode.setProperty(VOTER_VOTEVALUE_PROP, newVoterVoteValues);
147
148
149 node.setProperty(VOTE_TOTAL_PROP,getVoteTotal(node)+(voterVoteValue == null ? 1 : 0)) ;
150 languageNode.setProperty(VOTE_TOTAL_LANG_PROP,voteTotalOfLang+(voterVoteValue == null ? 1 : 0)) ;
151 languageNode.setProperty(VOTING_RATE_PROP,formatedRating) ;
152
153 node.getSession().save() ;
154 languageNode.getSession().save();
155 }
156
157
158 private Value getVoterVoteValue(Node languageNode, String userName) throws Exception {
159 if (!languageNode.hasProperty(VOTER_VOTEVALUE_PROP)) {
160 return null;
161 }
162 Value ret = null;
163 for (Value voterVoteValue : languageNode.getProperty(VOTER_VOTEVALUE_PROP).getValues()) {
164 if (voterVoteValue.getString().startsWith(userName + SPACE)) {
165 return voterVoteValue;
166 }
167 }
168 return ret;
169 }
170
171
172 private Value[] replaceOldValue(Value[] voterVoteValues, String userName, double rate, Session session)
173 throws Exception {
174 for (int i = 0; i < voterVoteValues.length; i++) {
175 if (voterVoteValues[i].getString().startsWith(userName + SPACE)) {
176 voterVoteValues[i] = session.getValueFactory().createValue(userName + SPACE + rate);
177 break;
178 }
179 }
180 return voterVoteValues;
181 }
182 public boolean isVoted(Node node, String userName, String language) throws Exception {
183 return getVoteValueOfUser(node, userName, language) > 0;
184 }
185
186 private Node handleLanguage(Node node, String language) throws Exception {
187 String defaultLang = multiLangService_.getDefault(node) ;
188 Node multiLanguages =null, languageNode= null ;
189 if((defaultLang == null && language == null) || language.equals(defaultLang)) {
190 languageNode = node ;
191 } else {
192 if(node.hasNode(LANGUAGES)) {
193 multiLanguages = node.getNode(LANGUAGES) ;
194 if(multiLanguages.hasNode(language)) {
195 languageNode = multiLanguages.getNode(language) ;
196 if(node.isNodeType("nt:file")) {
197 languageNode = getFileLangNode(languageNode) ;
198 }
199 }
200 } else {
201 languageNode = node;
202 }
203 }
204 return languageNode;
205 }
206
207 private Node handleUser(Session session, Node node, String userName) throws Exception {
208 if (userName == null || "__anonim".equals(userName)) {
209 String strWorkspaceName = node.getSession().getWorkspace().getName();
210 ManageableRepository manageRepository = WCMCoreUtils.getRepository();
211 session = WCMCoreUtils.getSystemSessionProvider().getSession(strWorkspaceName,
212 manageRepository);
213 String uid = node.getUUID();
214 node = session.getNodeByUUID(uid);
215 }
216 return node;
217 }
218
219 @Override
220 public double getVoteValueOfUser(Node node, String userName, String language) throws Exception {
221 Session session = node.getSession();
222 node = handleUser(session, node, userName);
223
224 if(!node.isNodeType(VOTABLE)) {
225 if(node.canAddMixin(VOTABLE)) node.addMixin(VOTABLE) ;
226 else throw new NoSuchNodeTypeException() ;
227 }
228
229 Node languageNode = handleLanguage(node, language);
230 Value voterVoteValue = getVoterVoteValue(languageNode, userName);
231 if (voterVoteValue != null) {
232 String stValue = voterVoteValue.getString();
233 return Double.parseDouble(stValue.substring(stValue.indexOf(SPACE) + 1));
234 }
235 return 0;
236 }
237 }