001: /**********************************************************************************
002: * $URL: https://source.sakaiproject.org/svn/sam/trunk/samigo-app/src/java/org/sakaiproject/tool/assessment/ui/servlet/delivery/DownloadAllMediaServlet.java $
003: * $Id: DownloadAllMediaServlet.java 11494 2006-07-05 21:15:29Z daisyf@stanford.edu $
004: ***********************************************************************************
005: *
006: * Copyright (c) 2005, 2006 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.tool.assessment.ui.servlet.delivery;
021:
022: import org.sakaiproject.tool.assessment.services.assessment.PublishedAssessmentService;
023: import org.sakaiproject.tool.assessment.services.GradingService;
024: import org.sakaiproject.tool.assessment.shared.impl.assessment.PublishedAssessmentServiceImpl;
025: import org.sakaiproject.tool.assessment.data.dao.grading.ItemGradingData;
026: import org.sakaiproject.tool.assessment.data.ifc.assessment.ItemDataIfc;
027: import org.sakaiproject.tool.assessment.data.ifc.assessment.PublishedAssessmentIfc;
028: import org.sakaiproject.tool.assessment.data.ifc.grading.MediaIfc;
029: import org.sakaiproject.tool.assessment.facade.AgentFacade;
030: import org.sakaiproject.tool.assessment.integration.helper.integrated.AgentHelperImpl;
031: import org.sakaiproject.tool.assessment.ui.bean.authz.AuthorizationBean;
032: import org.sakaiproject.tool.assessment.ui.bean.shared.PersonBean;
033: import org.sakaiproject.tool.assessment.ui.listener.util.ContextUtil;
034:
035: import java.io.*;
036: import java.util.ArrayList;
037: import java.util.Collections;
038: import java.util.HashMap;
039: import java.util.Iterator;
040: import java.util.List;
041: import java.util.zip.ZipEntry;
042: import java.util.zip.ZipOutputStream;
043:
044: import javax.servlet.ServletException;
045: import javax.servlet.ServletOutputStream;
046: import javax.servlet.http.HttpServlet;
047: import javax.servlet.http.HttpServletRequest;
048: import javax.servlet.http.HttpServletResponse;
049: import javax.servlet.RequestDispatcher;
050: import org.apache.commons.logging.Log;
051: import org.apache.commons.logging.LogFactory;
052:
053: /**
054: * <p>Title: Samigo</p>
055: * <p>Description: Sakai Assessment Manager</p>
056: * <p>Copyright: Copyright (c) 2004 Sakai Project</p>
057: * <p>Organization: Sakai Project</p>
058: * @author Ed Smiley
059: * @version $Id: DownloadAllMediaServlet 11494 2006-07-05 21:15:29Z daisyf@stanford.edu $
060: */
061:
062: public class DownloadAllMediaServlet extends HttpServlet {
063: /**
064: *
065: */
066: private static final long serialVersionUID = 1465451058167004991L;
067: private static Log log = LogFactory
068: .getLog(DownloadAllMediaServlet.class);
069: private GradingService gradingService = new GradingService();
070:
071: public DownloadAllMediaServlet() {
072: }
073:
074: public void doGet(HttpServletRequest req, HttpServletResponse res)
075: throws ServletException, IOException {
076: doPost(req, res);
077: }
078:
079: public void doPost(HttpServletRequest req, HttpServletResponse res)
080: throws ServletException, IOException {
081: String publishedItemId = req.getParameter("publishedItemId");
082: log.debug("publishedItemId = " + publishedItemId);
083:
084: // who can access the zip file? You can,
085: // if you have a assessment.grade.any or assessment.grade.own permission
086: boolean accessDenied = true;
087: String agentIdString = getAgentString(req, res);
088: String currentSiteId = "";
089:
090: PublishedAssessmentIfc pub = gradingService
091: .getPublishedAssessmentByPublishedItemId(publishedItemId
092: .toString());
093: if (pub != null) {
094: PublishedAssessmentService service = new PublishedAssessmentService();
095: log.debug("pub.getPublishedAssessmentId() = "
096: + pub.getPublishedAssessmentId());
097: currentSiteId = service.getPublishedAssessmentOwner(pub
098: .getPublishedAssessmentId());
099: }
100: // get assessment's ownerId
101: String assessmentCreatedBy = req.getParameter("createdBy");
102: if (canGrade(req, res, agentIdString, currentSiteId,
103: assessmentCreatedBy)) {
104: accessDenied = false;
105: }
106:
107: if (accessDenied) {
108: String path = "/jsf/delivery/mediaAccessDenied.faces";
109: RequestDispatcher dispatcher = req
110: .getRequestDispatcher(path);
111: dispatcher.forward(req, res);
112: } else {
113: res.setContentType("application/x-zip-compressed");
114: String assessmentName = req.getParameter("assessmentName");
115: StringBuffer zipFilename = new StringBuffer();
116: zipFilename.append(assessmentName);
117: String partAndQues = getPartNumAndQuestionNum(publishedItemId);
118: log.debug("partAndQues = " + partAndQues);
119: zipFilename.append(partAndQues);
120: zipFilename.append((".zip"));
121: log.debug("zipFilename = " + zipFilename);
122: res.setHeader("Content-Disposition",
123: "attachment;filename=\"" + zipFilename + "\";");
124:
125: String anonymous = req.getParameter("anonymous");
126: if ("true".equals(anonymous)) {
127: processAnonymous(req, res);
128: } else {
129: processNonAnonymous(req, res);
130: }
131: }
132: }
133:
134: private void processAnonymous(HttpServletRequest req,
135: HttpServletResponse res) {
136: String publishedId = req.getParameter("publishedId");
137: String publishedItemId = req.getParameter("publishedItemId");
138: String scoringType = req.getParameter("scoringType");
139: log.debug("publishedId = " + publishedId);
140: log.debug("publishedItemId = " + publishedItemId);
141: log.debug("scoringType = " + scoringType);
142:
143: GradingService gradingService = new GradingService();
144: List mediaList = gradingService.getMediaArray(publishedId,
145: publishedItemId, scoringType);
146:
147: MediaIfc mediaData;
148: log.debug("mediaList.size() = " + mediaList.size());
149:
150: ZipOutputStream zos = null;
151: try {
152: ServletOutputStream outputStream = res.getOutputStream();
153: zos = new ZipOutputStream(outputStream);
154: for (int i = 0; i < mediaList.size(); i++) {
155: mediaData = (MediaIfc) mediaList.get(i);
156: processOneMediaData(zos, mediaData, true, -1);
157: }
158: } catch (IOException e) {
159: log.error(e.getMessage());
160: e.printStackTrace();
161: } finally {
162: if (zos != null) {
163: try {
164: zos.close();
165: } catch (IOException e) {
166: log.error(e.getMessage());
167: }
168: }
169: }
170: }
171:
172: private void processNonAnonymous(HttpServletRequest req,
173: HttpServletResponse res) {
174: String publishedId = req.getParameter("publishedId");
175: String publishedItemId = req.getParameter("publishedItemId");
176: String scoringType = req.getParameter("scoringType");
177: log.debug("publishedId = " + publishedId);
178: log.debug("publishedItemId = " + publishedItemId);
179: log.debug("scoringType = " + scoringType);
180:
181: HashMap hashByAgentId = new HashMap();
182: HashMap subHashByAssessmentGradingId;
183: MediaIfc mediaData;
184: ArrayList list;
185: ItemGradingData itemGradingData;
186:
187: List mediaList;
188: mediaList = gradingService.getMediaArray(publishedId,
189: publishedItemId, scoringType);
190: log.debug("mediaList.size() = " + mediaList.size());
191:
192: String agentId;
193: Long assessmentGradingId;
194: for (int i = 0; i < mediaList.size(); i++) {
195: mediaData = (MediaIfc) mediaList.get(i);
196: itemGradingData = (ItemGradingData) mediaData
197: .getItemGradingData();
198: agentId = itemGradingData.getAgentId();
199: assessmentGradingId = itemGradingData
200: .getAssessmentGradingId();
201: log.debug("agentId = " + agentId);
202: log.debug("assessmentGradingId = " + assessmentGradingId);
203: if (hashByAgentId.containsKey(agentId)) {
204: log.error("same agentId");
205: subHashByAssessmentGradingId = (HashMap) hashByAgentId
206: .get(agentId);
207: if (subHashByAssessmentGradingId
208: .containsKey(assessmentGradingId)) {
209: log.debug("same assessmentGradingId");
210: list = (ArrayList) subHashByAssessmentGradingId
211: .get(assessmentGradingId);
212: list.add(mediaData);
213: } else {
214: log.debug("different assessmentGradingId");
215: list = new ArrayList();
216: list.add(mediaData);
217: subHashByAssessmentGradingId.put(
218: assessmentGradingId, list);
219: }
220: } else {
221: log.debug("different agentId");
222: list = new ArrayList();
223: list.add(mediaData);
224: subHashByAssessmentGradingId = new HashMap();
225: subHashByAssessmentGradingId.put(assessmentGradingId,
226: list);
227: hashByAgentId
228: .put(agentId, subHashByAssessmentGradingId);
229: }
230: }
231: log.debug("HashMap built successfully");
232: ZipOutputStream zos = null;
233: try {
234: ServletOutputStream outputStream = res.getOutputStream();
235: zos = new ZipOutputStream(outputStream);
236:
237: HashMap hashMap;
238: Iterator iter = hashByAgentId.values().iterator();
239: int numberSubmission;
240: while (iter.hasNext()) {
241: hashMap = (HashMap) iter.next();
242: numberSubmission = hashMap.size();
243: log.debug("numberSubmission = " + numberSubmission);
244: Iterator subIter = hashMap.keySet().iterator();
245: // this student has submitted more than once
246: if (numberSubmission > 1) {
247: // Because Hashmap makes no guarantees as to the order of the map;
248: // and it does not guarantee that the order will remain constant over time,
249: // following implementation is to make sure we get the correct order
250: // that is, if there are two submissions from John Doe:
251: // submission id 24 submitted on Jun 28, 2006 (file A.txt)
252: // submission id 33 submitted on Jul 03, 2006 (file B.txt)
253: // We want to make sure the filename of these two are:
254: // Doe_John_sub1_A.txt and Doe_John_sub2_B.txt
255: // If we don't sort it, the outcome might be:
256: // Doe_John_sub2_A.txt and Doe_John_sub1_B.txt which are not what we want
257: ArrayList keyList = new ArrayList();
258: Long key;
259: while (subIter.hasNext()) {
260: key = (Long) subIter.next();
261: log.debug("key = " + key);
262: keyList.add(key);
263: Collections.sort(keyList);
264: }
265:
266: ArrayList valueList;
267: Long sortedKey;
268: for (int i = 0; i < keyList.size(); i++) {
269: sortedKey = (Long) keyList.get(i);
270: valueList = (ArrayList) hashMap.get(sortedKey);
271: for (int j = 0; j < valueList.size(); j++) {
272: log.debug("j = " + j);
273: mediaData = (MediaIfc) valueList.get(j);
274: processOneMediaData(zos, mediaData, false,
275: i + 1);
276: }
277: }
278: }
279: // this student has only one submission
280: else if (numberSubmission == 1) {
281: ArrayList valueList;
282: while (subIter.hasNext()) {
283: valueList = (ArrayList) hashMap.get(subIter
284: .next());
285: log.debug("valueList.size() = "
286: + valueList.size());
287: for (int i = 0; i < valueList.size(); i++) {
288: log.debug("i = " + i);
289: mediaData = (MediaIfc) valueList.get(i);
290: // we use "-1" to indicate one submission
291: // "sub" will not be instered into filename
292: processOneMediaData(zos, mediaData, false,
293: -1);
294: }
295: }
296: }
297: }
298: } catch (IOException e) {
299: log.error(e.getMessage());
300: e.printStackTrace();
301: } finally {
302: if (zos != null) {
303: try {
304: zos.close();
305: } catch (IOException e) {
306: log.error(e.getMessage());
307: }
308: }
309: }
310: }
311:
312: private void processOneMediaData(ZipOutputStream zos,
313: MediaIfc mediaData, boolean anonymous, int numberSubmission)
314: throws IOException {
315: int BUFFER_SIZE = 2048;
316: byte data[] = new byte[BUFFER_SIZE];
317: int count = 0;
318: BufferedInputStream bufInputStream = null;
319: ZipEntry ze = null;
320: String mediaLocation = mediaData.getLocation();
321: log.debug("mediaLocation = " + mediaLocation);
322: String filename = getFilename(mediaData, anonymous,
323: numberSubmission);
324: if (mediaLocation == null || (mediaLocation.trim()).equals("")) {
325: byte[] media = mediaData.getMedia();
326: log.debug("media.length = " + media.length);
327: bufInputStream = new BufferedInputStream(
328: new ByteArrayInputStream(media));
329: } else {
330: bufInputStream = new BufferedInputStream(
331: getFileStream(mediaLocation));
332: }
333: ze = new ZipEntry(filename);
334: try {
335: zos.putNextEntry(ze);
336: while ((count = bufInputStream.read(data, 0, BUFFER_SIZE)) != -1) {
337: zos.write(data, 0, count);
338: }
339: } catch (IOException e) {
340: log.error(e.getMessage());
341: throw e;
342: } finally {
343: if (bufInputStream != null) {
344: try {
345: bufInputStream.close();
346: } catch (IOException e) {
347: log.error(e.getMessage());
348: }
349: }
350: if (zos != null) {
351: try {
352: zos.closeEntry();
353: } catch (IOException e) {
354: log.error(e.getMessage());
355: }
356: }
357: }
358: }
359:
360: private FileInputStream getFileStream(String mediaLocation) {
361: FileInputStream inputStream = null;
362: try {
363: File media = new File(mediaLocation);
364: inputStream = new FileInputStream(media);
365: } catch (FileNotFoundException ex) {
366: log.warn("file not found=" + ex.getMessage());
367: }
368: return inputStream;
369: }
370:
371: public String getAgentString(HttpServletRequest req,
372: HttpServletResponse res) {
373: String agentIdString = AgentFacade.getAgentString();
374: if (agentIdString == null || agentIdString.equals("")) { // try this
375: PersonBean person = (PersonBean) ContextUtil
376: .lookupBeanFromExternalServlet("person", req, res);
377: agentIdString = person.getAnonymousId();
378: }
379: return agentIdString;
380: }
381:
382: public boolean canGrade(HttpServletRequest req,
383: HttpServletResponse res, String agentId,
384: String currentSiteId, String assessmentCreatedBy) {
385: AuthorizationBean authzBean = (AuthorizationBean) ContextUtil
386: .lookupBeanFromExternalServlet("authorization", req,
387: res);
388: log.debug("agentId=" + agentId);
389: log.debug("currentSiteId=" + currentSiteId);
390: log.debug("assessmentCreatedBy=" + assessmentCreatedBy);
391: boolean hasPrivilege_any = authzBean.getGradeAnyAssessment(req,
392: currentSiteId);
393: boolean hasPrivilege_own0 = authzBean.getGradeOwnAssessment(
394: req, currentSiteId);
395: boolean hasPrivilege_own = (hasPrivilege_own0 && isOwner(
396: agentId, assessmentCreatedBy));
397: boolean hasPrivilege = (hasPrivilege_any || hasPrivilege_own);
398: return hasPrivilege;
399: }
400:
401: public boolean isOwner(String agentId, String ownerId) {
402: boolean isOwner = false;
403: isOwner = agentId.equals(ownerId);
404: return isOwner;
405: }
406:
407: private String getPartNumAndQuestionNum(String itemId) {
408: log.debug("itemId = " + itemId);
409: PublishedAssessmentServiceImpl pubAssessmentServiceImpl = new PublishedAssessmentServiceImpl();
410: ItemDataIfc item = pubAssessmentServiceImpl
411: .loadPublishedItem(itemId);
412: Integer partNum = item.getSection().getSequence();
413: log.debug("partNum = " + partNum);
414: Integer questionNum = item.getSequence();
415: log.debug("questionNum=" + questionNum);
416: StringBuffer partAndQues = new StringBuffer("_Part");
417: partAndQues.append(partNum);
418: partAndQues.append("_Ques");
419: partAndQues.append(questionNum);
420: log.debug("partAndQues = " + partAndQues);
421: return partAndQues.toString();
422: }
423:
424: private String getFilename(MediaIfc mediaData, boolean anonymous,
425: int numberSubmission) {
426: log.debug("numberSubmission = " + numberSubmission);
427: StringBuffer filename = new StringBuffer();
428: ItemGradingData itemGradingData = (ItemGradingData) mediaData
429: .getItemGradingData();
430: if (anonymous) {
431: Long assessmentGradingId = itemGradingData
432: .getAssessmentGradingId();
433: log.debug("submissionId(assessmentGradingId) = "
434: + assessmentGradingId);
435: filename.append(assessmentGradingId);
436: filename.append("_");
437: filename.append(mediaData.getFilename());
438: log.debug("filename = " + filename);
439: } else {
440: AgentHelperImpl helper = new AgentHelperImpl();
441: String agentId = itemGradingData.getAgentId();
442: String lastName = helper.getLastName(agentId);
443: String firstName = helper.getFirstName(agentId);
444: String eid = helper.getEidById(agentId);
445: filename.append(lastName);
446: filename.append("_");
447: filename.append(firstName);
448: filename.append("_");
449: filename.append(eid);
450: filename.append("_");
451: log.debug("filename = " + filename);
452: if (numberSubmission == -1) {
453: filename.append(mediaData.getFilename());
454: log.debug("filename = " + filename);
455: } else {
456: filename.append("sub");
457: filename.append(numberSubmission);
458: filename.append("_");
459: filename.append(mediaData.getFilename());
460: log.debug("filename = " + filename);
461: }
462: }
463:
464: return filename.toString();
465: }
466: }
|