/*************************************************************************** * Copyright (C) 2003-2010 eXo Platform SAS. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see<http://www.gnu.org/licenses/>. ***************************************************************************/ package org.exoplatform.poll.webui; import java.util.ArrayList; import java.util.Date; import java.util.List; import javax.portlet.PortletPreferences; import org.exoplatform.container.PortalContainer; import org.exoplatform.ks.common.webui.BaseEventListener; import org.exoplatform.ks.common.webui.UIPopupAction; import org.exoplatform.poll.Utils; import org.exoplatform.poll.service.Poll; import org.exoplatform.poll.service.PollNodeTypes; import org.exoplatform.poll.webui.popup.UIPollForm; import org.exoplatform.services.organization.Group; import org.exoplatform.services.organization.OrganizationService; import org.exoplatform.webui.application.WebuiRequestContext; import org.exoplatform.webui.application.portlet.PortletRequestContext; import org.exoplatform.webui.config.annotation.ComponentConfig; import org.exoplatform.webui.config.annotation.EventConfig; import org.exoplatform.webui.core.UIComponent; import org.exoplatform.webui.core.lifecycle.UIFormLifecycle; import org.exoplatform.webui.core.model.SelectItemOption; import org.exoplatform.webui.event.Event; import org.exoplatform.webui.event.EventListener; import org.exoplatform.webui.form.UIFormRadioBoxInput; /** * Created by The eXo Platform SARL * Author : Vu Duy Tu * tu.duy@exoplatform.com * June 26, 2010 9:48:18 AM */ @ComponentConfig( lifecycle = UIFormLifecycle.class, template = "app:/templates/poll/webui/UIPoll.gtmpl", events = { @EventConfig(listeners = UIPoll.VoteActionListener.class), @EventConfig(listeners = UIPoll.EditPollActionListener.class), @EventConfig(listeners = UIPoll.RemovePollActionListener.class, confirm = "UIPoll.msg.confirm-RemovePoll"), @EventConfig(listeners = UIPoll.ClosedPollActionListener.class), @EventConfig(listeners = UIPoll.VoteAgainPollActionListener.class) } ) @SuppressWarnings("unused") public class UIPoll extends BasePollForm { private Poll poll_; private String pollId, userId; private boolean isAgainVote = false; private boolean isEditPoll = false; private boolean hasPermission = true; private boolean isAdmin = false; private String[] dateUnit = new String[] { "Never", "Closed", "day(s)", "hour(s)", "minutes" }; public UIPoll() throws Exception { try { dateUnit = new String[] { getLabel("Never"), getLabel("Closed"), getLabel("day"), getLabel("hour"), getLabel("minutes") }; } catch (Exception e) { } } public void setPollId() throws Exception { UIPollPortlet pollPortlet = getAncestorOfType(UIPollPortlet.class); isAdmin = pollPortlet.isAdmin(); userId = pollPortlet.getUserId(); PortletRequestContext pcontext = (PortletRequestContext) WebuiRequestContext.getCurrentInstance(); PortletPreferences portletPref = pcontext.getRequest().getPreferences(); pollId = portletPref.getValue(Utils.POLL_ID_SHOW, ""); if (Utils.isEmpty(pollId)) { List<String> list = getPollService().getPollSummary(null).getPollId(); if (!list.isEmpty()) { pollId = list.iterator().next(); } } this.isEditPoll = true; } public boolean hasUserInGroup(String groupId, String userId) throws Exception { try { OrganizationService organizationService = (OrganizationService) PortalContainer.getComponent(OrganizationService.class); for (Object object : organizationService.getGroupHandler().findGroupsOfUser(userId)) { if (((Group) object).getId().equals(groupId)) { return true; } } } catch (Exception e) { log.debug("Failed to check user permission by OrganizationService !", e); } return false; } private boolean checkPermission() throws Exception { String path = poll_.getParentPath(); if (path.indexOf(PollNodeTypes.APPLICATION_DATA) > 0) { String group = path.substring(path.indexOf("/", 3), path.indexOf(PollNodeTypes.APPLICATION_DATA) - 1); hasPermission = hasUserInGroup(group, userId); } else { hasPermission = true; } return hasPermission; } public void updateFormPoll(Poll poll) throws Exception { if (poll.getIsClosed()) poll.setExpire(Utils.getExpire(-1, poll.getModifiedDate(), dateUnit)); else poll.setExpire(Utils.getExpire(poll.getTimeOut(), poll.getModifiedDate(), dateUnit)); poll_ = poll; this.isEditPoll = false; checkPermission(); } public void updatePollById(String pollId) throws Exception { this.pollId = pollId; this.isEditPoll = true; } @SuppressWarnings("unchecked") private void init() throws Exception { if (this.hasChildren()) { this.removeChild(UIFormRadioBoxInput.class); int i = 0; while (i < 10) { if (this.hasChildren()) this.removeChild(UIForumCheckBoxInput.class); else break; ++i; } } if (poll_ != null) { if (!poll_.getIsMultiCheck()) { List<SelectItemOption<String>> options = new ArrayList<SelectItemOption<String>>(); for (String s : poll_.getOption()) { options.add(new SelectItemOption<String>(s, s)); } UIFormRadioBoxInput input = new UIFormRadioBoxInput("vote", "vote", options); input.setAlign(1); addUIFormInput(input); } else { for (String s : poll_.getOption()) { addUIFormInput(new UIForumCheckBoxInput(s, s, false)); } } } } private Poll getPoll() throws Exception { if (isEditPoll || poll_ == null) { poll_ = getPollService().getPoll(pollId); if (poll_ != null) { checkPermission(); if (poll_.getIsClosed()) poll_.setExpire(Utils.getExpire(-1, poll_.getModifiedDate(), dateUnit)); else poll_.setExpire(Utils.getExpire(poll_.getTimeOut(), poll_.getModifiedDate(), dateUnit)); } else hasPermission = false; } this.init(); return poll_; } private boolean getIsEditPoll() { return isEditPoll; } public void setEditPoll(boolean isEditPoll) { this.isEditPoll = isEditPoll; } private boolean getCanViewEditMenu() { return isAdmin; } private boolean isGuestPermission() throws Exception { if (poll_.getIsClosed()) return true; if (Utils.isEmpty(userId)) return true; if (poll_.getTimeOut() > 0) { Date today = new Date(); if ((today.getTime() - this.poll_.getCreatedDate().getTime()) >= poll_.getTimeOut() * 86400000) return true; } if (this.isAgainVote) { return false; } String[] userVotes = poll_.getUserVote(); for (String string : userVotes) { string = string.substring(0, string.indexOf(":")); if (string.equalsIgnoreCase(userId)) return true; } return false; } private String[] getInfoVote() throws Exception { Poll poll = poll_; String[] voteNumber = poll.getVote(); String[] userVotes = poll.getUserVote(); long size = 0, temp = 1; if (!poll.getIsMultiCheck()) { size = userVotes.length; } else { for (int i = 0; i < userVotes.length; i++) { size += userVotes[i].split(":").length - 1; } } temp = size; if (size == 0) size = 1; int l = voteNumber.length; String[] infoVote = new String[(l + 1)]; for (int j = 0; j < l; j++) { String string = voteNumber[j]; double tmp = Double.parseDouble(string); double k = (tmp * size) / 100; int t = (int) Math.round(k); string = "" + (double) t * 100 / size; infoVote[j] = string + ":" + t; } infoVote[l] = "" + temp; if (poll.getIsMultiCheck()) { infoVote[l] = String.valueOf(userVotes.length); } return infoVote; } static public class VoteActionListener extends EventListener<UIPoll> { @SuppressWarnings("unchecked") public void execute(Event<UIPoll> event) throws Exception { UIPoll topicPoll = event.getSource(); Poll poll = topicPoll.poll_; String[] votes; String[] setUserVote; String userVote = topicPoll.userId; List<UIComponent> children = topicPoll.getChildren(); // User vote and vote number String[] temporary = topicPoll.poll_.getUserVote(); int size = 0; if (temporary != null && temporary.length > 0) { size = temporary.length; } if (!poll.getIsMultiCheck()) { UIFormRadioBoxInput radioInput = null; for (UIComponent child : children) { if (child instanceof UIFormRadioBoxInput) { radioInput = (UIFormRadioBoxInput) child; } } if (radioInput.getValue().equalsIgnoreCase("vote")) { topicPoll.warning("UIPoll.msg.notCheck"); } else { // order number List<SelectItemOption<String>> options = new ArrayList<SelectItemOption<String>>(); options = radioInput.getOptions(); int i = 0, j = 0; for (SelectItemOption<String> option : options) { if (option.getValue().equalsIgnoreCase(radioInput.getValue())) { j = i; break; } i = i + 1; } int index = 0; if (topicPoll.isAgainVote) { setUserVote = new String[size]; for (int t = 0; t < size; t++) { String string = temporary[t].substring(0, temporary[t].length() - 2); if (string.equalsIgnoreCase(userVote)) { setUserVote[t] = userVote + ":" + j; index = t; } else { setUserVote[t] = temporary[t]; } } } else { setUserVote = new String[(size + 1)]; System.arraycopy(temporary, 0, setUserVote, 0, size); setUserVote[size] = userVote + ":" + j; size = size + 1; } votes = topicPoll.poll_.getVote(); double onePercent = (double) 100 / size; if (topicPoll.isAgainVote) { char tmp = temporary[index].charAt((temporary[index].length() - 1)); int k = Integer.valueOf(tmp) - 48; if (k < votes.length) votes[k] = String.valueOf((Double.parseDouble(votes[k]) - onePercent)); votes[j] = String.valueOf((Double.parseDouble(votes[j]) + onePercent)); } else { i = 0; for (String vote : votes) { double a = Double.parseDouble(vote); if (i == j) votes[i] = "" + ((a - a / size) + onePercent); else votes[i] = "" + (a - a / size); i = i + 1; } } // save Poll poll.setVote(votes); poll.setUserVote(setUserVote); } // multichoice when vote } else { UIForumCheckBoxInput forumCheckBox = null; List<String> listValue = new ArrayList<String>(); for (UIComponent child : children) { if (child instanceof UIForumCheckBoxInput) { forumCheckBox = ((UIForumCheckBoxInput) child); if (forumCheckBox.isChecked()) { listValue.add(forumCheckBox.getName()); } } } if (!listValue.isEmpty()) { votes = topicPoll.poll_.getVote(); double totalVote = 0; double doubleVote[] = new double[votes.length]; String[] listUserVoted = topicPoll.poll_.getUserVote(); if (listUserVoted.length > 0) { for (String us : listUserVoted) { totalVote += us.split(":").length - 1; } } int i = 0; int pos = 0; if (votes != null && votes.length > 0) { for (String v : votes) { doubleVote[i++] = Double.parseDouble(v); } } if (totalVote > 0) { for (i = 0; i < doubleVote.length; i++) { doubleVote[i] = (doubleVote[i] * totalVote) / 100; } } if (!topicPoll.isAgainVote) { i = 0; pos = size; setUserVote = new String[size + 1]; for (String userHaveVoted : poll.getUserVote()) setUserVote[i++] = userHaveVoted; setUserVote[i] = userVote; } else { setUserVote = poll.getUserVote(); for (i = 0; i < setUserVote.length; i++) { if (setUserVote[i].split(":")[0].equals(userVote)) { pos = i; break; } } String[] posHaveVoted = (setUserVote[pos].substring(setUserVote[pos].indexOf(":"))).split(":"); setUserVote[pos] = setUserVote[pos].substring(0, setUserVote[pos].indexOf(":")); for (String posVoted : posHaveVoted) { if (!Utils.isEmpty(posVoted)) { doubleVote[Integer.parseInt(posVoted)] -= 1; totalVote -= 1; } } } i = 0; for (String option : topicPoll.poll_.getOption()) { if (listValue.contains(option)) { doubleVote[i] += 1; totalVote += 1; setUserVote[pos] += ":" + i; } i++; } i = 0; for (double dv : doubleVote) { if (totalVote > 0 && dv > 0) votes[i] = ((dv / totalVote) * 100) + ""; else votes[i] = "0.0"; i++; } // save votes: poll.setUserVote(setUserVote); poll.setVote(votes); } else { topicPoll.warning("UIPoll.msg.notCheck"); } } topicPoll.getPollService().savePoll(poll, false, true); topicPoll.isAgainVote = false; event.getRequestContext().addUIComponentToUpdateByAjax(topicPoll.getParent()); } } static public class EditPollActionListener extends BaseEventListener<UIPoll> { public void onEvent(Event<UIPoll> event, UIPoll topicPoll, final String objectId) throws Exception { UIPopupAction popupAction; try { UIPollPortlet forumPortlet = topicPoll.getAncestorOfType(UIPollPortlet.class); popupAction = forumPortlet.getChild(UIPopupAction.class); } catch (Exception e) { UIPollPortlet forumPollPortlet = topicPoll.getAncestorOfType(UIPollPortlet.class); popupAction = forumPollPortlet.getChild(UIPopupAction.class); } UIPollForm pollForm = popupAction.createUIComponent(UIPollForm.class, null, null); topicPoll.poll_ = topicPoll.getPoll(); pollForm.setUpdatePoll(topicPoll.poll_, true); popupAction.activate(pollForm, 662, 466); topicPoll.isEditPoll = true; } } static public class RemovePollActionListener extends EventListener<UIPoll> { public void execute(Event<UIPoll> event) throws Exception { UIPoll topicPoll = event.getSource(); try { topicPoll.getPollService().removePoll(topicPoll.pollId); } catch (Exception e) { } if (topicPoll.poll_.getIsMultiCheck()) { List<UIComponent> children = topicPoll.getChildren(); for (int i = 0; i < children.size(); i++) { topicPoll.removeChild(UIForumCheckBoxInput.class); } } else { topicPoll.removeChild(UIFormRadioBoxInput.class); } UIPollPortlet pollPortlet = topicPoll.getAncestorOfType(UIPollPortlet.class); topicPoll.setRendered(false); event.getRequestContext().addUIComponentToUpdateByAjax(pollPortlet); } } static public class VoteAgainPollActionListener extends EventListener<UIPoll> { public void execute(Event<UIPoll> event) throws Exception { UIPoll topicPoll = event.getSource(); topicPoll.isAgainVote = true; topicPoll.poll_ = topicPoll.getPoll(); topicPoll.init(); event.getRequestContext().addUIComponentToUpdateByAjax(topicPoll); } } static public class ClosedPollActionListener extends BaseEventListener<UIPoll> { public void onEvent(Event<UIPoll> event, UIPoll topicPoll, final String id) throws Exception { if (id.equals("true")) { topicPoll.poll_.setIsClosed(false); topicPoll.poll_.setTimeOut(0); } else { topicPoll.poll_.setIsClosed(!topicPoll.poll_.getIsClosed()); } try { topicPoll.getPollService().setClosedPoll(topicPoll.poll_); } catch (Exception e) { } topicPoll.isAgainVote = false; event.getRequestContext().addUIComponentToUpdateByAjax(topicPoll); } } }