001: /**********************************************************************************
002: * $URL: https://source.sakaiproject.org/svn/sam/tags/sakai_2-4-1/samigo-app/src/java/org/sakaiproject/tool/assessment/ui/servlet/delivery/UploadAudioMediaServlet.java $
003: * $Id: UploadAudioMediaServlet.java 17072 2006-10-12 00:15:06Z ktsao@stanford.edu $
004: ***********************************************************************************
005: *
006: * Copyright (c) 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 java.io.BufferedInputStream;
023: import java.io.BufferedOutputStream;
024: import java.io.File;
025: import java.io.FileNotFoundException;
026: import java.io.FileInputStream;
027: import java.io.FileOutputStream;
028: import java.io.IOException;
029: import javax.servlet.ServletContext;
030: import javax.servlet.ServletException;
031: import javax.servlet.ServletInputStream;
032: import javax.servlet.http.HttpServlet;
033: import javax.servlet.http.HttpServletRequest;
034: import javax.servlet.http.HttpServletResponse;
035:
036: import org.apache.commons.logging.Log;
037: import org.apache.commons.logging.LogFactory;
038:
039: import org.sakaiproject.tool.assessment.data.dao.grading.AssessmentGradingData;
040: import org.sakaiproject.tool.assessment.data.dao.grading.ItemGradingData;
041: import org.sakaiproject.tool.assessment.data.dao.grading.MediaData;
042: import org.sakaiproject.tool.assessment.data.dao.assessment.PublishedItemData;
043: import org.sakaiproject.tool.assessment.data.dao.assessment.PublishedItemText;
044: import org.sakaiproject.tool.assessment.services.assessment.PublishedAssessmentService;
045: import org.sakaiproject.tool.assessment.services.GradingService;
046:
047: import java.util.Date;
048: import java.util.ArrayList;
049:
050: /**
051: * <p>Title: Samigo</p>
052: * <p>Description: Sakai Assessment Manager.
053: * Upload audio media to delivery bean.
054: * This gets a posted input stream (from AudioRecorder.java in the client JVM)
055: * and writes out to a file.</p>
056: * <p>Copyright: Copyright (c) 2004 Sakai Project</p>
057: * <p>Organization: Sakai Project</p>
058: * @author Ed Smiley
059: * @version $Id: UploadAudioMediaServlet.java 17072 2006-10-12 00:15:06Z ktsao@stanford.edu $
060: */
061:
062: public class UploadAudioMediaServlet extends HttpServlet {
063: /**
064: *
065: */
066: private static final long serialVersionUID = 8389831837152012411L;
067: private static Log log = LogFactory
068: .getLog(UploadAudioMediaServlet.class);
069:
070: public UploadAudioMediaServlet() {
071: }
072:
073: public void doGet(HttpServletRequest req, HttpServletResponse res)
074: throws ServletException, IOException {
075: doPost(req, res);
076: }
077:
078: public void doPost(HttpServletRequest req, HttpServletResponse res)
079: throws ServletException, IOException {
080: boolean mediaIsValid = true;
081: ServletContext context = super .getServletContext();
082: String repositoryPath = (String) context
083: .getAttribute("FILEUPLOAD_REPOSITORY_PATH");
084: String saveToDb = (String) context
085: .getAttribute("FILEUPLOAD_SAVE_MEDIA_TO_DB");
086:
087: log.debug("req content length =" + req.getContentLength());
088: log.debug("req content type =" + req.getContentType());
089:
090: // we get media location in assessmentXXX/questionXXX/agentId/audio_assessmentGradingIdXXX.au form
091: String suffix = req.getParameter("suffix");
092: if (suffix == null || ("").equals(suffix))
093: suffix = "au";
094: String mediaLocation = req.getParameter("media") + "." + suffix;
095: log.debug("****media location=" + mediaLocation);
096: String zip_mediaLocation = null;
097:
098: // test for nonemptiness first
099: if (mediaLocation != null && !(mediaLocation.trim()).equals("")) {
100: mediaLocation = repositoryPath + "/" + mediaLocation;
101: File mediaFile = new File(mediaLocation);
102: File mediaDir = mediaFile.getParentFile();
103: if (!mediaDir.exists())
104: mediaDir.mkdirs();
105: //log.debug("*** directory exist="+mediaDir.exists());
106: mediaIsValid = writeToFile(req, mediaLocation);
107:
108: //this is progess for SAK-5792, comment is out for now
109: //zip_mediaLocation = createZipFile(mediaDir.getPath(), mediaLocation);
110: }
111:
112: res.flushBuffer();
113:
114: //#2 - record media as question submission
115: if (mediaIsValid) {
116: // note that this delivery bean is empty. this is not the same one created for the
117: // user during take assessment.
118: try {
119: if (zip_mediaLocation != null)
120: submitMediaAsAnswer(req, zip_mediaLocation,
121: saveToDb);
122: else
123: submitMediaAsAnswer(req, mediaLocation, saveToDb);
124: log
125: .info("Audio has been saved and submitted as answer to the question. Any old recordings have been removed from the system.");
126: } catch (Exception ex) {
127: log.info(ex.getMessage());
128: }
129: }
130: }
131:
132: private boolean writeToFile(HttpServletRequest req,
133: String mediaLocation) {
134: // default status message, if things go wrong
135: boolean mediaIsValid = false;
136: String status = "Upload failure: empty media location.";
137: ServletInputStream inputStream = null;
138: FileOutputStream fileOutputStream = null;
139: BufferedInputStream bufInputStream = null;
140: BufferedOutputStream bufOutputStream = null;
141: int count = 0;
142:
143: try {
144: inputStream = req.getInputStream();
145: fileOutputStream = getFileOutputStream(mediaLocation);
146:
147: // buffered input for servlet
148: bufInputStream = new BufferedInputStream(inputStream);
149: // buffered output to file
150: bufOutputStream = new BufferedOutputStream(fileOutputStream);
151:
152: // write the binary data
153: int i = 0;
154: count = 0;
155: if (bufInputStream != null) {
156: while ((i = bufInputStream.read()) != -1) {
157: bufOutputStream.write(i);
158: count++;
159: }
160: }
161: bufOutputStream.flush();
162:
163: /* Move following clean up code to finally block
164: // clean up
165: bufOutputStream.close();
166: bufInputStream.close();
167: if (inputStream != null){
168: inputStream.close();
169: }
170: fileOutputStream.close();
171: */
172: status = "Acknowleged: " + mediaLocation + "-> " + count
173: + " bytes.";
174: if (count > 0)
175: mediaIsValid = true;
176: } catch (Exception ex) {
177: log.info(ex.getMessage());
178: status = "Upload failure: " + mediaLocation;
179: } finally {
180: if (bufOutputStream != null) {
181: try {
182: bufOutputStream.close();
183: } catch (IOException e) {
184: log.error(e.getMessage());
185: }
186: }
187: if (bufInputStream != null) {
188: try {
189: bufInputStream.close();
190: } catch (IOException e) {
191: log.error(e.getMessage());
192: }
193: }
194: if (inputStream != null) {
195: try {
196: inputStream.close();
197: } catch (IOException e) {
198: log.error(e.getMessage());
199: }
200: }
201: if (fileOutputStream != null) {
202: try {
203: fileOutputStream.close();
204: } catch (IOException e) {
205: log.error(e.getMessage());
206: }
207: }
208: }
209: log.info(status);
210: return mediaIsValid;
211: }
212:
213: /*
214: private String createZipFile(String mediaDirString, String mediaLocation){
215: // Create a buffer for reading the files
216: File file = new File(mediaLocation);
217: String fileName=file.getName();
218: byte[] buf = new byte[1024];
219: String zip_mediaLocation = mediaDirString+"/"+fileName+".zip";
220: ZipOutputStream zip = null;
221: FileInputStream in = null;
222: FileOutputStream out = null;
223: try {
224: // Create the ZIP file
225: log.debug("*** zip file="+zip_mediaLocation);
226: out = new FileOutputStream(zip_mediaLocation);
227: zip = new ZipOutputStream(out);
228:
229: // Add ZIP entry to output stream.
230: zip.putNextEntry(new ZipEntry(fileName));
231:
232: // Transfer bytes from the file to the ZIP file
233: in = new FileInputStream(mediaLocation);
234: int len;
235: while ((len = in.read(buf)) > 0) {
236: zip.write(buf, 0, len);
237: }
238: }
239: catch (IOException e) {
240: zip_mediaLocation=null;
241: log.error("problem zipping file at "+mediaLocation);
242: }
243: finally {
244: if (zip != null) {
245: try {
246: zip.closeEntry();
247: zip.close();
248: }
249: catch (IOException e) {
250: log.error(e.getMessage());
251: }
252: }
253: if (in != null) {
254: try {
255: in.close();
256: }
257: catch (IOException e) {
258: log.error(e.getMessage());
259: }
260: }
261: if (out != null) {
262: try {
263: out.close();
264: }
265: catch (IOException e) {
266: log.error(e.getMessage());
267: }
268: }
269: }
270: return zip_mediaLocation;
271: }
272: */
273:
274: private FileOutputStream getFileOutputStream(String mediaLocation) {
275: FileOutputStream outputStream = null;
276: try {
277: File media = new File(mediaLocation);
278: outputStream = new FileOutputStream(media);
279: } catch (FileNotFoundException ex) {
280: log.warn("file not found=" + ex.getMessage());
281: }
282: return outputStream;
283: }
284:
285: private void submitMediaAsAnswer(HttpServletRequest req,
286: String mediaLocation, String saveToDb) throws Exception {
287: // read parameters passed in
288: String mimeType = req.getContentType();
289: String duration = req.getParameter("lastDuration");
290: String agentId = req.getParameter("agent");
291:
292: int attemptsRemaining = 0;
293: GradingService gradingService = new GradingService();
294: PublishedAssessmentService pubService = new PublishedAssessmentService();
295: int assessmentIndex = mediaLocation.indexOf("assessment");
296: int questionIndex = mediaLocation.indexOf("question");
297: int agentIndex = mediaLocation.indexOf("/", questionIndex + 8);
298: //int myfileIndex = mediaLocation.lastIndexOf("/");
299: String pubAssessmentId = mediaLocation.substring(
300: assessmentIndex + 10, questionIndex - 1);
301: String questionId = mediaLocation.substring(questionIndex + 8,
302: agentIndex);
303: //String agentEid = mediaLocation.substring(agentIndex+1, myfileIndex);
304: //log.debug("****pubAss="+pubAssessmentId);
305: //log.debug("****questionId="+questionId);
306: //log.debug("****agent="+agentId);
307:
308: PublishedItemData item = pubService
309: .loadPublishedItem(questionId);
310: PublishedItemText itemText = (PublishedItemText) (item
311: .getItemTextSet()).iterator().next();
312:
313: log.debug("****agentId=" + agentId);
314: log.debug("****pubAssId=" + pubAssessmentId);
315: // 1. get assessmentGrading form DB
316: AssessmentGradingData adata = gradingService
317: .getLastSavedAssessmentGradingByAgentId(
318: pubAssessmentId, agentId);
319:
320: if (adata == null) {
321: // adata should already be created by BeginAssessment
322: // lets throws exception
323: throw new Exception(
324: "This page must have been reached by mistake.");
325: }
326:
327: // 2. get itemGrading from DB, remove any attached media
328: // also work out no. of attempts remaining
329: ItemGradingData itemGrading = gradingService
330: .getItemGradingData(adata.getAssessmentGradingId()
331: .toString(), questionId);
332: ArrayList mediaList = new ArrayList();
333: if (itemGrading != null) {
334: // just need update itemGrading, and media.media
335: GradingService service = new GradingService();
336: if (itemGrading.getItemGradingId() != null)
337: mediaList = service.getMediaArray(itemGrading
338: .getItemGradingId().toString());
339:
340: if (mediaList.size() > 0) {
341: log.debug("*** delete old audio");
342: gradingService.deleteAll(mediaList);
343: }
344: if (itemGrading.getAttemptsRemaining() == null) {
345: // this is not possible unless the question is submitted without the
346: // attempt set correctly
347: if ((item.getTriesAllowed()).intValue() >= 9999)
348: attemptsRemaining = 9999;
349: else
350: attemptsRemaining = (item.getTriesAllowed())
351: .intValue() - 1;
352: } else {
353: if ((item.getTriesAllowed()).intValue() >= 9999)
354: attemptsRemaining = 9999;
355: else if (itemGrading.getAttemptsRemaining().intValue() > 0)
356: attemptsRemaining = itemGrading
357: .getAttemptsRemaining().intValue() - 1;
358: else
359: throw new Exception(
360: "This page must have been reached by mistake. Our record shows that no more attempt for this question is allowed.");
361: }
362: } else {
363: // create an itemGrading
364: if ((item.getTriesAllowed()).intValue() >= 9999)
365: attemptsRemaining = 9999;
366: else
367: attemptsRemaining = (item.getTriesAllowed()).intValue() - 1;
368: itemGrading = new ItemGradingData();
369: itemGrading.setAssessmentGradingId(adata
370: .getAssessmentGradingId());
371: itemGrading.setPublishedItemId(item.getItemId());
372: itemGrading.setPublishedItemTextId(itemText.getId());
373: itemGrading.setAgentId(agentId);
374: itemGrading.setOverrideScore(new Float(0));
375: itemGrading.setSubmittedDate(new Date());
376: itemGrading.setAttemptsRemaining(new Integer(
377: attemptsRemaining));
378: itemGrading.setLastDuration(duration);
379: gradingService.saveItemGrading(itemGrading);
380: }
381: log.debug("****1. assessmentGradingId="
382: + adata.getAssessmentGradingId());
383: log.debug("****2. attemptsRemaining=" + attemptsRemaining);
384: log.debug("****3. itemGradingDataId="
385: + itemGrading.getItemGradingId());
386: // 3. save Media and fix up itemGrading
387: saveMedia(attemptsRemaining, mimeType, agentId, mediaLocation,
388: itemGrading, saveToDb, duration);
389: }
390:
391: private void saveMedia(int attemptsRemaining, String mimeType,
392: String agent, String mediaLocation,
393: ItemGradingData itemGrading, String saveToDb,
394: String duration) {
395: boolean SAVETODB = false;
396: if (saveToDb.equals("true"))
397: SAVETODB = true;
398:
399: log.debug("****4. saveMedia, saveToDB" + SAVETODB);
400: log.debug("****5. saveMedia, mediaLocation" + mediaLocation);
401:
402: GradingService gradingService = new GradingService();
403: // 1. create a media record
404: File media = new File(mediaLocation);
405: byte[] mediaByte = getMediaStream(mediaLocation);
406: log.debug("**** SAVETODB=" + SAVETODB);
407: MediaData mediaData = null;
408:
409: if (SAVETODB) { // put the byte[] in
410: mediaData = new MediaData(itemGrading, mediaByte, new Long(
411: mediaByte.length + ""), mimeType, "description",
412: null, media.getName(), false, false,
413: new Integer(1), agent, new Date(), agent,
414: new Date(), duration);
415: } else { // put the location in
416: mediaData = new MediaData(itemGrading, null, new Long(
417: mediaByte.length + ""), mimeType, "description",
418: mediaLocation, media.getName(), false, false,
419: new Integer(1), agent, new Date(), agent,
420: new Date(), duration);
421:
422: }
423: Long mediaId = gradingService.saveMedia(mediaData);
424: log.debug("mediaId=" + mediaId);
425:
426: // 2. store mediaId in itemGradingRecord.answerText
427: itemGrading
428: .setAttemptsRemaining(new Integer(attemptsRemaining));
429: itemGrading.setSubmittedDate(new Date());
430: itemGrading.setAnswerText(mediaId + "");
431: gradingService.saveItemGrading(itemGrading);
432:
433: // 3. if saveToDB, remove file from file system
434: try {
435: if (SAVETODB)
436: media.delete();
437: } catch (Exception e) {
438: log.warn(e.getMessage());
439: }
440: }
441:
442: private byte[] getMediaStream(String mediaLocation) {
443: FileInputStream mediaStream = null;
444: FileInputStream mediaStream2 = null;
445: byte[] mediaByte = new byte[0];
446: try {
447: //int i = 0;
448: int size = 0;
449: mediaStream = new FileInputStream(mediaLocation);
450: if (mediaStream != null) {
451: //while ( (i = mediaStream.read()) != -1)
452: while (mediaStream.read() != -1) {
453: size++;
454: }
455: }
456: mediaStream2 = new FileInputStream(mediaLocation);
457: mediaByte = new byte[size];
458: if (mediaStream2 != null) {
459: mediaStream2.read(mediaByte, 0, size);
460: }
461: } catch (FileNotFoundException ex) {
462: log.debug("file not found=" + ex.getMessage());
463: } catch (IOException ex) {
464: log.debug("io exception=" + ex.getMessage());
465: } finally {
466: if (mediaStream != null) {
467: try {
468: mediaStream.close();
469: } catch (IOException ex1) {
470: log.warn(ex1.getMessage());
471: }
472: }
473: if (mediaStream2 != null) {
474: try {
475: mediaStream2.close();
476: } catch (IOException ex1) {
477: log.warn(ex1.getMessage());
478: }
479: }
480: }
481: return mediaByte;
482: }
483:
484: }
|