/***************************************************************************
* Copyright (C) 2003-2007 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.forum.webui.popup;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.exoplatform.container.ExoContainerContext;
import org.exoplatform.forum.ForumUtils;
import org.exoplatform.forum.TimeConvertUtils;
import org.exoplatform.forum.common.CommonUtils;
import org.exoplatform.forum.common.UserHelper;
import org.exoplatform.forum.common.webui.UIFormMultiValueInputSet;
import org.exoplatform.forum.common.webui.WebUIUtils;
import org.exoplatform.forum.service.Forum;
import org.exoplatform.forum.service.Topic;
import org.exoplatform.forum.service.Utils;
import org.exoplatform.forum.webui.BaseForumForm;
import org.exoplatform.forum.webui.UIForumContainer;
import org.exoplatform.forum.webui.UIForumDescription;
import org.exoplatform.forum.webui.UIForumPortlet;
import org.exoplatform.forum.webui.UITopicContainer;
import org.exoplatform.forum.webui.UITopicDetail;
import org.exoplatform.forum.webui.UITopicDetailContainer;
import org.exoplatform.forum.webui.UITopicPoll;
import org.exoplatform.poll.service.Poll;
import org.exoplatform.poll.service.PollService;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
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.UIPopupComponent;
import org.exoplatform.webui.core.lifecycle.UIFormLifecycle;
import org.exoplatform.webui.event.Event;
import org.exoplatform.webui.event.Event.Phase;
import org.exoplatform.webui.event.EventListener;
import org.exoplatform.webui.form.UIFormStringInput;
import org.exoplatform.webui.form.input.UICheckBoxInput;
import org.exoplatform.webui.form.validator.MandatoryValidator;
import org.exoplatform.webui.form.validator.PositiveNumberFormatValidator;
@ComponentConfig(
lifecycle = UIFormLifecycle.class,
template = "app:/templates/forum/webui/popup/UIPollForm.gtmpl",
events = {
@EventConfig(listeners = UIPollForm.SaveActionListener.class),
@EventConfig(listeners = UIPollForm.RefreshActionListener.class, phase = Phase.DECODE),
@EventConfig(listeners = UIPollForm.CancelActionListener.class,phase = Phase.DECODE)
}
)
public class UIPollForm extends BaseForumForm implements UIPopupComponent {
public static final String FIELD_QUESTION_INPUT = "Question";
final static public String FIELD_OPTIONS = "Option";
public static final String FIELD_TIMEOUT_INPUT = "TimeOut";
public static final String FIELD_AGAINVOTE_CHECKBOX = "VoteAgain";
public static final String FIELD_MULTIVOTE_CHECKBOX = "MultiVote";
public static final String COLON = ":";
public static final String DELETED = "deleted";
public static final String ZERO = "0.0";
private UIFormMultiValueInputSet uiFormMultiValue = new UIFormMultiValueInputSet(FIELD_OPTIONS, FIELD_OPTIONS);
private String topicPath;
private String forumPath;
private Poll poll = new Poll();
private boolean isUpdate = false;
private boolean isAddTopic = false;
private static final Log LOG = ExoLogger.getLogger(UIPollForm.class);
public UIPollForm() throws Exception {
UIFormStringInput question = new UIFormStringInput(FIELD_QUESTION_INPUT, FIELD_QUESTION_INPUT, null);
UIFormStringInput timeOut = new UIFormStringInput(FIELD_TIMEOUT_INPUT, FIELD_TIMEOUT_INPUT, null);
timeOut.addValidator(PositiveNumberFormatValidator.class);
UICheckBoxInput VoteAgain = new UICheckBoxInput(FIELD_AGAINVOTE_CHECKBOX, FIELD_AGAINVOTE_CHECKBOX, false);
UICheckBoxInput MultiVote = new UICheckBoxInput(FIELD_MULTIVOTE_CHECKBOX, FIELD_MULTIVOTE_CHECKBOX, false);
addUIFormInput(question.addValidator(MandatoryValidator.class));
addUIFormInput(timeOut);
addUIFormInput(VoteAgain);
addUIFormInput(MultiVote);
setDefaulFall();
}
private void initMultiValuesField(List<String> list) throws Exception {
if (uiFormMultiValue != null)
removeChildById(FIELD_OPTIONS);
uiFormMultiValue = createUIComponent(UIFormMultiValueInputSet.class, null, null);
uiFormMultiValue.addValidator(MandatoryValidator.class);
uiFormMultiValue.setId(FIELD_OPTIONS);
uiFormMultiValue.setName(FIELD_OPTIONS);
uiFormMultiValue.setType(UIFormStringInput.class);
uiFormMultiValue.setValue(list);
if (this.isUpdate) {
uiFormMultiValue.resetListIndexItemRemoved();
uiFormMultiValue.setMaxOld(list.size());
}
addUIFormInput(uiFormMultiValue);
}
public void setTopicPath(String topicPath) {
this.topicPath = topicPath;
this.isUpdate = false;
}
public void setAddTopic(String forumPath) {
this.isAddTopic = true;
this.isUpdate = false;
this.forumPath = forumPath;
}
protected String getDateAfter() throws Exception {
Date date = new Date();
if (poll != null && poll.getTimeOut() > 0) {
date = poll.getModifiedDate();
}
String format = "MM-dd-yyyy";
try {
format = this.getAncestorOfType(UIForumPortlet.class).getUserProfile().getShortDateFormat();
} catch (NullPointerException e) {
format = getForumService().getDefaultUserProfile(UserHelper.getCurrentUser(), null).getShortDateFormat();
}
return TimeConvertUtils.getFormatDate(format, date);
}
public void setUpdatePoll(Poll poll, boolean isUpdate) throws Exception {
if (isUpdate) {
this.poll = poll;
getUIStringInput(FIELD_QUESTION_INPUT).setValue(CommonUtils.decodeSpecialCharToHTMLnumber(poll.getQuestion()));
getUIStringInput(FIELD_TIMEOUT_INPUT).setValue(String.valueOf(poll.getTimeOut()));
getUICheckBoxInput(FIELD_AGAINVOTE_CHECKBOX).setChecked(poll.getIsAgainVote());
UICheckBoxInput multiVoteCheckInput = getUICheckBoxInput(FIELD_MULTIVOTE_CHECKBOX);
multiVoteCheckInput.setChecked(poll.getIsMultiCheck());
multiVoteCheckInput.setDisabled(true);
this.isUpdate = isUpdate;
setDefaulFall();
}
}
private void setDefaulFall() throws Exception {
List<String> list = new ArrayList<String>();
if (isUpdate) {
for (String string : this.poll.getOption()) {
list.add(CommonUtils.decodeSpecialCharToHTMLnumber(string));
}
} else {
list.add(ForumUtils.EMPTY_STR);
list.add(ForumUtils.EMPTY_STR);
}
this.initMultiValuesField(list);
}
public void activate() {
}
public void deActivate() {
}
static public class SaveActionListener extends EventListener<UIPollForm> {
@SuppressWarnings("unchecked")
public void execute(Event<UIPollForm> event) throws Exception {
UIPollForm uiForm = event.getSource();
UIFormStringInput questionInput = uiForm.getUIStringInput(FIELD_QUESTION_INPUT);
String question = questionInput.getValue();
question = CommonUtils.encodeSpecialCharInTitle(question);
String timeOutStr = uiForm.getUIStringInput(FIELD_TIMEOUT_INPUT).getValue();
timeOutStr = ForumUtils.removeZeroFirstNumber(timeOutStr);
long timeOut = 0;
if (!ForumUtils.isEmpty(timeOutStr)) {
if (timeOutStr.length() > 4) {
uiForm.warning("UIPollForm.msg.longTimeOut", new String[] { uiForm.getLabel(FIELD_TIMEOUT_INPUT) }, false);
}
timeOut = Long.parseLong(timeOutStr);
}
boolean isAgainVote = uiForm.getUICheckBoxInput(FIELD_AGAINVOTE_CHECKBOX).isChecked();
boolean isMultiVote = uiForm.getUICheckBoxInput(FIELD_MULTIVOTE_CHECKBOX).isChecked();
String sms = ForumUtils.EMPTY_STR;
List<String> values = (List<String>) uiForm.uiFormMultiValue.getValue();
List<String> values_ = new ArrayList<String>();
int i = 1;
for (String value : values) {
if (!ForumUtils.isEmpty(value)) {
if (value.length() > org.exoplatform.poll.service.Utils.MAX_TITLE) {
String[] args = new String[] { uiForm.getLabel(FIELD_OPTIONS) + "(" + i + ")", String.valueOf(org.exoplatform.poll.service.Utils.MAX_TITLE) };
uiForm.warning("NameValidator.msg.warning-long-text", args);
return;
}
values_.add(CommonUtils.encodeSpecialCharInTitle(value));
}
++i;
}
String[] options = values_.toArray(new String[] {});
int sizeOption = values_.size();
if (sizeOption < 2)
sms = "Minimum";
if (sizeOption > 10)
sms = "Maximum";
if (ForumUtils.isEmpty(question)) {
sms = "NotQuestion";
sizeOption = 0;
} else {
if (question.length() > org.exoplatform.poll.service.Utils.MAX_TITLE) {
String[] args = { uiForm.getLabel(FIELD_QUESTION_INPUT), String.valueOf(org.exoplatform.poll.service.Utils.MAX_TITLE) };
uiForm.warning("NameValidator.msg.warning-long-text", args);
return;
}
}
/*
* sizeOption: size option newUser: list user after edit poll oldUserVote: list user before edit poll vote: % vote after edit poll oldVote: % old vote before edit poll voteRemoved: % vote removed rmPecent: % removed
*/
if (sizeOption >= 2 && sizeOption <= 10) {
String[] newUser = null;
String[] vote = new String[sizeOption];
for (int j = 0; j < sizeOption; j++) {
vote[j] = ZERO;
}
if (uiForm.isUpdate) {
List<Integer> listIndexItemRemoved = uiForm.uiFormMultiValue.getListIndexItemRemoved();
String[] oldVote = uiForm.poll.getVote();
String[] oldUserVote = uiForm.poll.getUserVote();
String[] voteTp = new String[oldVote.length];
double rmPecent = 0;
List<String> voteRemoved = new ArrayList<String>();
for (Integer integer : listIndexItemRemoved) {
if (integer < oldVote.length) {
rmPecent = rmPecent + Double.parseDouble(oldVote[integer]);
voteRemoved.add(String.valueOf(integer));
}
}
double leftPecent = 100 - rmPecent;
i = 0;
for (int k = 0; k < oldVote.length; ++k) {
if (listIndexItemRemoved.contains(k)) {
voteTp[k] = DELETED;
continue;
}
if (leftPecent > 1) {
double newVote = Double.parseDouble(oldVote[k]);
String vl = String.valueOf((newVote * 100) / leftPecent);
voteTp[k] = vl;
vote[i] = vl;
} else {
voteTp[k] = ZERO;
vote[i] = ZERO;
}
++i;
}
if (!uiForm.poll.getIsMultiCheck()) {
if (leftPecent > 1) {
List<String> userL = new ArrayList<String>();
for (String string : oldUserVote) {
boolean isAdd = true;
for (String j : voteRemoved) {
if (string.indexOf(COLON + j) > 0) {
isAdd = false;
}
}
if (isAdd)
userL.add(string);
}
newUser = new String[] {};
i = 0;
Map<String, String> mab = new HashMap<String, String>();
for (int j = 0; j < voteTp.length; j++) {
if (voteTp[j].equals(DELETED)) {
continue;
}
// vote[i] = voteTp[j];
for (String str : userL) {
if (str.indexOf(COLON + j) > 0) {
mab.put(str, str.replace(COLON + j, COLON + i));
} else {
if (!mab.keySet().contains(str)) {
mab.put(str, str);
}
}
}
++i;
}
newUser = mab.values().toArray(new String[userL.size()]);
} else if (voteRemoved.size() > 0 && rmPecent > 0.0) {
newUser = new String[] {};
}
// multi vote
} else {
List<String> newUserVote = new ArrayList<String>();
for (String uv : oldUserVote) {
StringBuffer sbUserInfo = new StringBuffer();
for (String string : uv.split(COLON)) {
if (!voteRemoved.contains(string)) {
if (sbUserInfo.length() > 0)
sbUserInfo.append(COLON);
sbUserInfo.append(string);
}
}
String userInfo = sbUserInfo.toString();
if (userInfo.split(COLON).length >= 2)
newUserVote.add(userInfo);
}
i = 0;
Map<String, String> mab = new HashMap<String, String>();
for (int j = 0; j < voteTp.length; j++) {
if (voteTp[j].equals(DELETED)) {
continue;
}
// vote[i] = voteTp[j];
for (String str : newUserVote) {
if (str.indexOf(COLON + j) > 0) {
if (mab.containsKey(str))
mab.put(str, mab.get(str).replace(COLON + j, COLON + i));
else
mab.put(str, str.replace(COLON + j, COLON + i));
} else {
if (!mab.keySet().contains(str)) {
mab.put(str, str);
}
}
}
++i;
}
newUser = mab.values().toArray(new String[newUserVote.size()]);
}
}
String userName = UserHelper.getCurrentUser();
uiForm.poll.setOwner(userName);
uiForm.poll.setQuestion(question);
uiForm.poll.setModifiedBy(userName);
uiForm.poll.setIsAgainVote(isAgainVote);
uiForm.poll.setIsMultiCheck(isMultiVote);
uiForm.poll.setOption(options);
uiForm.poll.setVote(vote);
uiForm.poll.setTimeOut(timeOut);
uiForm.poll.setIsClosed(uiForm.poll.getIsClosed());
Topic topic = new Topic();
if(uiForm.isAddTopic) {
String link = ForumUtils.createdForumLink(ForumUtils.TOPIC, topic.getId(), false);
uiForm.topicPath = uiForm.forumPath + "/" + topic.getId();
StringBuilder message = new StringBuilder(question);
message.append("<br/> ________________________________<br/>");
for(int j = 0; j < options.length; ++j) {
message.append("<br/>").append(String.valueOf(j+1)).append(". ").append(options[j]);
}
//
topic.setOwner(userName);
topic.setTopicName(question);
topic.setCreatedDate(new Date());
topic.setModifiedBy(userName);
topic.setModifiedDate(new Date());
topic.setLastPostBy(userName);
topic.setLastPostDate(new Date());
topic.setIcon("IconsView");
topic.setCanView(new String[] {});
topic.setCanPost(new String[] {});
topic.setRemoteAddr(WebUIUtils.getRemoteIP());
topic.setPath(uiForm.topicPath);
topic.setDescription(message.toString());
topic.setLink(link);
uiForm.getForumService().saveTopic(topic.getCategoryId(), topic.getForumId(), topic, true, false, ForumUtils.getDefaultMail());
}
String[] id = uiForm.topicPath.trim().split(ForumUtils.SLASH);
try {
PollService pollSv = (PollService) ExoContainerContext.getCurrentContainer().getComponentInstanceOfType(PollService.class);
if (uiForm.isUpdate) {
if (newUser != null) {
uiForm.poll.setUserVote(newUser);
}
pollSv.savePoll(uiForm.poll, false, false);
} else {
uiForm.poll.setUserVote(new String[] {});
uiForm.poll.setId(id[id.length - 1].replace(Utils.TOPIC, Utils.POLL));
uiForm.poll.setParentPath(uiForm.topicPath.trim());
pollSv.savePoll(uiForm.poll, true, false);
}
} catch (Exception e) {
uiForm.log.debug("Failed to save poll.", e);
}
uiForm.isUpdate = false;
UIForumPortlet forumPortlet = uiForm.getAncestorOfType(UIForumPortlet.class);
UIForumContainer forumContainer = forumPortlet.findFirstComponentOfType(UIForumContainer.class);
UITopicDetailContainer detailContainer = forumContainer.getChild(UITopicDetailContainer.class);
detailContainer.setRederPoll(true);
detailContainer.getChild(UITopicPoll.class).updateFormPoll(id[id.length - 3], id[id.length - 2], id[id.length - 1]);
forumPortlet.cancelAction();
if(uiForm.isAddTopic) {
Forum forum = uiForm.getForumService().getForum(topic.getCategoryId(), topic.getForumId());
forumContainer.setIsRenderChild(false);
forumContainer.getChild(UIForumDescription.class).setForum(forum);
UITopicContainer topicContainer = forumContainer.getChild(UITopicContainer.class);
event.getRequestContext().addUIComponentToUpdateByAjax(topicContainer);
topicContainer.setUpdateForum(topic.getCategoryId(), forum, 0);
Event<UIComponent> openTopicEvent = topicContainer.createEvent("OpenTopic", Event.Phase.PROCESS, event.getRequestContext());
if (openTopicEvent != null) {
topicContainer.openTopicId = topic.getId();
openTopicEvent.broadcast();
}
} else {
UITopicDetail topicDetail = detailContainer.getChild(UITopicDetail.class);
topicDetail.hasPoll(true);
event.getRequestContext().addUIComponentToUpdateByAjax(detailContainer);
}
}
if (!ForumUtils.isEmpty(sms)) {
uiForm.warning("UIPollForm.msg." + sms);
}
}
}
static public class RefreshActionListener extends EventListener<UIPollForm> {
public void execute(Event<UIPollForm> event) throws Exception {
UIPollForm uiForm = event.getSource();
if(uiForm.isUpdate) {
uiForm.setUpdatePoll(uiForm.poll, uiForm.isUpdate);
} else {
List<String> list = new ArrayList<String>();
list.add(ForumUtils.EMPTY_STR);
list.add(ForumUtils.EMPTY_STR);
uiForm.initMultiValuesField(list);
uiForm.getUIStringInput(FIELD_QUESTION_INPUT).setValue(ForumUtils.EMPTY_STR);
uiForm.getUIStringInput(FIELD_TIMEOUT_INPUT).setValue("0");
uiForm.getUICheckBoxInput(FIELD_AGAINVOTE_CHECKBOX).setChecked(false);
uiForm.getUICheckBoxInput(FIELD_MULTIVOTE_CHECKBOX).setChecked(false);
}
event.getRequestContext().addUIComponentToUpdateByAjax(uiForm);
}
}
static public class CancelActionListener extends EventListener<UIPollForm> {
public void execute(Event<UIPollForm> event) throws Exception {
UIPollForm uiForm = event.getSource();
UIForumPortlet forumPortlet = uiForm.getAncestorOfType(UIForumPortlet.class);
forumPortlet.cancelAction();
uiForm.isUpdate = false;
}
}
}