001: /**********************************************************************************
002: * $URL: $
003: * $Id: $
004: ***********************************************************************************
005: *
006: * Copyright (c) 2006,2007 The Sakai Foundation.
007: *
008: * Licensed under the Educational Community License, Version 1.0 (the "License");
009: * you may not use this file except in compliance with the License.
010: * You may obtain a copy of the License at
011: *
012: * http://www.opensource.org/licenses/ecl1.php
013: *
014: * Unless required by applicable law or agreed to in writing, software
015: * distributed under the License is distributed on an "AS IS" BASIS,
016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: * See the License for the specific language governing permissions and
018: * limitations under the License.
019: *
020: **********************************************************************************/package org.sakaiproject.poll.tool.producers;
021:
022: import java.text.DateFormat;
023: import java.util.Locale;
024: import java.util.ArrayList;
025: import java.util.List;
026: import java.util.Date;
027:
028: import org.sakaiproject.authz.cover.SecurityService;
029: import org.sakaiproject.tool.api.ToolManager;
030: import org.sakaiproject.poll.logic.PollListManager;
031: import org.sakaiproject.poll.logic.PollVoteManager;
032: import org.sakaiproject.poll.model.Poll;
033: import org.sakaiproject.poll.tool.params.VoteBean;
034: import org.sakaiproject.user.api.User;
035: import org.sakaiproject.user.api.UserDirectoryService;
036: import org.sakaiproject.authz.cover.FunctionManager; //import org.sakaiproject.time.impl.BasicTimeService;
037:
038: import org.sakaiproject.site.api.SiteService;
039:
040: import uk.org.ponder.messageutil.MessageLocator;
041: import uk.org.ponder.rsf.components.UIBranchContainer;
042: import uk.org.ponder.rsf.components.UICommand;
043: import uk.org.ponder.rsf.components.UIContainer;
044: import uk.org.ponder.rsf.components.UIELBinding;
045: import uk.org.ponder.rsf.components.UIForm;
046:
047: import uk.org.ponder.rsf.components.UIOutput;
048: import uk.org.ponder.rsf.components.UISelect;
049: import uk.org.ponder.rsf.components.UISelectChoice;
050: import uk.org.ponder.rsf.flow.jsfnav.NavigationCase;
051: import uk.org.ponder.rsf.flow.jsfnav.NavigationCaseReporter;
052: import uk.org.ponder.rsf.view.ComponentChecker;
053: import uk.org.ponder.rsf.view.DefaultView;
054: import uk.org.ponder.rsf.view.ViewComponentProducer;
055: import uk.org.ponder.rsf.viewstate.SimpleViewParameters;
056: import uk.org.ponder.rsf.viewstate.ViewParameters;
057: import uk.org.ponder.localeutil.LocaleGetter;
058: import uk.org.ponder.stringutil.StringList;
059: import uk.org.ponder.rsf.components.UIInternalLink;
060: import uk.org.ponder.rsf.components.UILink;
061: import uk.org.ponder.rsf.viewstate.EntityCentredViewParameters;
062: import uk.org.ponder.beanutil.entity.EntityID;
063:
064: import org.apache.commons.logging.LogFactory;
065: import org.apache.commons.logging.Log;
066:
067: public class PollToolProducer implements ViewComponentProducer,
068: DefaultView, NavigationCaseReporter {
069: public static final String VIEW_ID = "votePolls";
070: private UserDirectoryService userDirectoryService;
071: private PollListManager pollListManager;
072: private ToolManager toolManager;
073: private MessageLocator messageLocator;
074: private LocaleGetter localegetter;
075: private PollVoteManager pollVoteManager;
076:
077: private static final String NAVIGATE_ADD = "actions-add";
078: private static final String NAVIGATE_PERMISSIONS = "actions-permissions";
079: private static final String NAVIGATE_VOTE = "poll-vote";
080:
081: private static Log m_log = LogFactory
082: .getLog(PollToolProducer.class);
083:
084: public String getViewID() {
085: return VIEW_ID;
086: }
087:
088: public void setMessageLocator(MessageLocator messageLocator) {
089:
090: this .messageLocator = messageLocator;
091: }
092:
093: public void setUserDirectoryService(
094: UserDirectoryService userDirectoryService) {
095: this .userDirectoryService = userDirectoryService;
096: }
097:
098: public void setPollListManager(PollListManager pollListManager) {
099: this .pollListManager = pollListManager;
100: }
101:
102: public void setToolManager(ToolManager toolManager) {
103: this .toolManager = toolManager;
104: }
105:
106: public void setLocaleGetter(LocaleGetter localegetter) {
107: this .localegetter = localegetter;
108: }
109:
110: public void setPollVoteManager(PollVoteManager pvm) {
111: this .pollVoteManager = pvm;
112: }
113:
114: private SiteService siteService;
115:
116: public void setSiteService(SiteService s) {
117: this .siteService = s;
118:
119: }
120:
121: private VoteBean voteBean;
122:
123: public void setVoteBean(VoteBean vb) {
124: this .voteBean = vb;
125: }
126:
127: public void fillComponents(UIContainer tofill,
128: ViewParameters viewparams, ComponentChecker checker) {
129:
130: voteBean.setPoll(null);
131: voteBean.voteCollection = null;
132:
133: UIOutput.make(tofill, "poll-list-title", messageLocator
134: .getMessage("poll_list_title"));
135:
136: boolean renderDelete = false;
137: //populte the action links
138: if (this .isAllowedPollAdd() || this .isSiteOwner()) {
139: UIBranchContainer actions = UIBranchContainer.make(tofill,
140: "actions:", Integer.toString(0));
141: m_log.debug("this user has some admin functions");
142: if (this .isAllowedPollAdd()) {
143: m_log.debug("User can add polls");
144: //UIOutput.make(tofill, "poll-add", messageLocator
145: // .getMessage("action_add_poll"));
146: UIInternalLink.make(actions, NAVIGATE_ADD,
147: messageLocator.getMessage("action_add_poll"),
148: new EntityCentredViewParameters(
149: AddPollProducer.VIEW_ID, new EntityID(
150: "Poll", "0"),
151: EntityCentredViewParameters.MODE_NEW));
152: }
153: if (this .isSiteOwner()) {
154: UIInternalLink.make(actions, NAVIGATE_PERMISSIONS,
155: messageLocator
156: .getMessage("action_set_permissions"),
157: new SimpleViewParameters(
158: PermissionsProducer.VIEW_ID));
159: }
160: }
161:
162: User currentuser = userDirectoryService.getCurrentUser();
163: String currentuserid = currentuser.getEid();
164:
165: List polls = null;
166:
167: String siteId = toolManager.getCurrentPlacement().getContext();
168: if (siteId != null) {
169: polls = pollListManager.findAllPolls(siteId);
170: } else {
171: m_log.warn("Unable to get siteid!");
172:
173: }
174:
175: // fix for broken en_ZA locale in JRE http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6488119
176: Locale M_locale = null;
177: String langLoc[] = localegetter.get().toString().split("_");
178: if (langLoc.length >= 2) {
179: if (langLoc[0].equals("en") && langLoc[1].equals("ZA"))
180: M_locale = new Locale("en", "GB");
181: else
182: M_locale = new Locale(langLoc[0], langLoc[1]);
183: } else {
184: M_locale = new Locale(langLoc[0]);
185: }
186:
187: DateFormat df = DateFormat.getDateTimeInstance(
188: DateFormat.MEDIUM, DateFormat.SHORT, M_locale);
189:
190: UIForm deleteForm = UIForm.make(tofill, "delete-poll-form");
191: // Create a multiple selection control for the tasks to be deleted.
192: // We will fill in the options at the loop end once we have collected them.
193: UISelect deleteselect = UISelect.makeMultiple(deleteForm,
194: "delete-poll", null, "#{pollToolBean.deleteids}",
195: new String[] {});
196:
197: //get the headers for the table
198: UIOutput.make(deleteForm, "poll-question-title", messageLocator
199: .getMessage("poll_question_title"));
200: UIOutput.make(deleteForm, "poll-open-title", messageLocator
201: .getMessage("poll_open_title"));
202: UIOutput.make(deleteForm, "poll-close-title", messageLocator
203: .getMessage("poll_close_title"));
204: UIOutput.make(deleteForm, "poll-result-title", messageLocator
205: .getMessage("poll_result_title"));
206: UIOutput.make(deleteForm, "poll-remove-title", messageLocator
207: .getMessage("poll_remove_title"));
208:
209: StringList deletable = new StringList();
210: m_log.debug("got a list of " + polls.size() + " polls");
211: for (int i = 0; i < polls.size(); i++) {
212: Poll poll = (Poll) polls.get(i);
213: boolean canVote = pollIsVotable(poll);
214:
215: UIBranchContainer pollrow = UIBranchContainer.make(
216: deleteForm, canVote ? "poll-row:votable"
217: : "poll-row:nonvotable", poll.getPollId()
218: .toString());
219: m_log.debug("adding poll row for " + poll.getText());
220:
221: if (canVote) {
222: UIInternalLink.make(pollrow, NAVIGATE_VOTE, poll
223: .getText(), new EntityCentredViewParameters(
224: PollVoteProducer.VIEW_ID, new EntityID("Poll",
225: poll.getPollId().toString()),
226: EntityCentredViewParameters.MODE_EDIT));
227: } else {
228: UIOutput.make(pollrow, "poll-text", poll.getText());
229: }
230:
231: if (isAllowedViewResults(poll))
232: UIInternalLink.make(pollrow, "poll-results",
233: messageLocator
234: .getMessage("action_view_results"),
235: new EntityCentredViewParameters(
236: ResultsProducer.VIEW_ID, new EntityID(
237: "Poll", poll.getPollId()
238: .toString()),
239: EntityCentredViewParameters.MODE_EDIT));
240:
241: UIOutput.make(pollrow, "poll-open-date", df.format(poll
242: .getVoteOpen()));
243: UIOutput.make(pollrow, "poll-close-date", df.format(poll
244: .getVoteClose()));
245: if (pollCanEdit(poll)) {
246: UIInternalLink
247: .make(
248: pollrow,
249: "poll-revise",
250: messageLocator
251: .getMessage("action_revise_poll"),
252: new EntityCentredViewParameters(
253: AddPollProducer.VIEW_ID,
254: new EntityID("Poll", poll
255: .getPollId().toString()),
256: EntityCentredViewParameters.MODE_EDIT));
257:
258: }
259: if (pollCanDelete(poll)) {
260: deletable.add(poll.getPollId().toString());
261: UISelectChoice.make(pollrow, "poll-select",
262: deleteselect.getFullID(),
263: (deletable.size() - 1));
264: m_log.debug("this poll can be deleted");
265: renderDelete = true;
266:
267: }
268: }
269:
270: deleteselect.optionlist.setValue(deletable.toStringArray());
271: deleteForm.parameters.add(new UIELBinding(
272: "#{pollToolBean.siteID}", siteId));
273:
274: if (renderDelete)
275: UICommand.make(deleteForm, "delete-polls", messageLocator
276: .getMessage("poll_list_update"),
277: "#{pollToolBean.processActionDelete}");
278: }
279:
280: private boolean isAllowedPollAdd() {
281: if (SecurityService.isSuperUser())
282: return true;
283:
284: if (SecurityService.unlock("poll.add", "/site/"
285: + toolManager.getCurrentPlacement().getContext()))
286: return true;
287:
288: return false;
289: }
290:
291: private boolean isSiteOwner() {
292: if (SecurityService.isSuperUser())
293: return true;
294: else if (SecurityService.unlock("site.upd", "/site/"
295: + toolManager.getCurrentPlacement().getContext()))
296: return true;
297: else
298: return false;
299: }
300:
301: public List reportNavigationCases() {
302: List togo = new ArrayList(); // Always navigate back to this view.
303: togo.add(new NavigationCase(null, new SimpleViewParameters(
304: VIEW_ID)));
305: return togo;
306: }
307:
308: private boolean pollIsVotable(Poll poll) {
309: if (poll.getVoteClose().after(new Date())
310: && new Date().after(poll.getVoteOpen())) {
311: if (poll.getLimitVoting()
312: && pollVoteManager.userHasVoted(poll.getPollId())) {
313: return false;
314: }
315: //the user hasn't voted do they have permission to vote?'
316: m_log.debug("about to check if this user can vote in "
317: + toolManager.getCurrentPlacement().getContext());
318: if (SecurityService.unlock("poll.vote", "/site/"
319: + toolManager.getCurrentPlacement().getContext())) {
320: m_log.debug("this poll is votable " + poll.getText());
321: return true;
322: }
323: }
324:
325: return false;
326: }
327:
328: private boolean isAllowedViewResults(Poll poll) {
329: if (SecurityService.isSuperUser())
330: return true;
331:
332: if (poll.getDisplayResult().equals("open"))
333: return true;
334:
335: if (poll.getOwner().equals(
336: userDirectoryService.getCurrentUser().getId()))
337: return true;
338:
339: if (poll.getDisplayResult().equals("afterVoting")
340: && pollVoteManager.userHasVoted(poll.getPollId()))
341: return true;
342:
343: if (poll.getDisplayResult().equals("afterClosing")
344: && poll.getVoteClose().before(new Date()))
345: return true;
346:
347: //the owner can view the results
348: if (poll.getOwner().equals(
349: userDirectoryService.getCurrentUser().getId()))
350: return true;
351:
352: return false;
353: }
354:
355: private boolean pollCanEdit(Poll poll) {
356: if (SecurityService.isSuperUser())
357: return true;
358:
359: if (SecurityService.unlock(pollListManager.PERMISSION_EDIT_ANY,
360: "/site/"
361: + toolManager.getCurrentPlacement()
362: .getContext()))
363: return true;
364:
365: if (SecurityService.unlock(pollListManager.PERMISSION_EDIT_OWN,
366: "/site/"
367: + toolManager.getCurrentPlacement()
368: .getContext())
369: && poll.getOwner().equals(
370: userDirectoryService.getCurrentUser().getId()))
371: return true;
372:
373: return false;
374: }
375:
376: private boolean pollCanDelete(Poll poll) {
377: if (SecurityService.isSuperUser())
378: return true;
379: if (SecurityService.unlock(
380: pollListManager.PERMISSION_DELETE_ANY, "/site/"
381: + toolManager.getCurrentPlacement()
382: .getContext()))
383: return true;
384:
385: if (SecurityService.unlock(
386: pollListManager.PERMISSION_DELETE_OWN, "/site/"
387: + toolManager.getCurrentPlacement()
388: .getContext())
389: && poll.getOwner().equals(
390: userDirectoryService.getCurrentUser().getId()))
391: return true;
392:
393: return false;
394: }
395: }
|