org.sakaiproject.tool.assessment.ui.servlet.delivery.ShowMediaServlet.java Source code

Java tutorial

Introduction

Here is the source code for org.sakaiproject.tool.assessment.ui.servlet.delivery.ShowMediaServlet.java

Source

/**********************************************************************************
 * $URL$
 * $Id$
 ***********************************************************************************
 *
 * Copyright (c) 2005, 2006, 2008, 2009 The Sakai Foundation
 *
 * Licensed under the Educational Community License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.opensource.org/licenses/ECL-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 **********************************************************************************/

package org.sakaiproject.tool.assessment.ui.servlet.delivery;

import org.sakaiproject.authz.cover.SecurityService;
import org.sakaiproject.tool.assessment.services.assessment.PublishedAssessmentService;
import org.sakaiproject.tool.assessment.services.GradingService;
import org.sakaiproject.tool.assessment.data.dao.grading.MediaData;
import org.sakaiproject.tool.assessment.data.ifc.assessment.PublishedAssessmentIfc;
import org.sakaiproject.tool.assessment.data.ifc.shared.TypeIfc;
import org.sakaiproject.tool.assessment.facade.AgentFacade;
import org.sakaiproject.tool.assessment.ui.bean.shared.PersonBean;
import org.sakaiproject.tool.assessment.ui.listener.util.ContextUtil;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.RequestDispatcher;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * <p>Title: Samigo</p>
 * <p>Description: Sakai Assessment Manager</p>
 * @author Ed Smiley
 * @version $Id$
 */

public class ShowMediaServlet extends HttpServlet {
    /**
      * 
      */
    private static final long serialVersionUID = 2203681863823855810L;
    private static Log log = LogFactory.getLog(ShowMediaServlet.class);
    private static final Pattern HTTP_RANGE_PATTERN = Pattern.compile("bytes=(?<start>\\d*)-(?<end>\\d*)");

    public ShowMediaServlet() {
    }

    public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        doPost(req, res);
    }

    public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        String agentIdString = getAgentString(req, res);
        if (agentIdString == null) {
            String path = "/jsf/delivery/mediaAccessDenied.faces";
            RequestDispatcher dispatcher = req.getRequestDispatcher(path);
            dispatcher.forward(req, res);
            return;
        }
        String mediaId = req.getParameter("mediaId");
        if (mediaId == null || mediaId.trim().equals("")) {
            return;
        }

        // get media
        GradingService gradingService = new GradingService();
        MediaData mediaData = gradingService.getMedia(mediaId);
        String mediaLocation = mediaData.getLocation();
        int fileSize = mediaData.getFileSize().intValue();
        log.info("****1. media file size=" + fileSize);

        //if setMimeType="false" in query string, implies, we want to do a forced download
        //in this case, we set contentType='application/octet-stream'
        String setMimeType = req.getParameter("setMimeType");
        log.info("****2. setMimeType=" + setMimeType);

        // get assessment's ownerId
        // String assessmentCreatedBy = req.getParameter("createdBy");

        // who can access the media? You can,
        // a. if you are the creator.
        // b. if you have a assessment.grade.any or assessment.grade.own permission
        boolean accessDenied = true;
        String currentSiteId = "";
        boolean isAudio = false;
        Long assessmentGradingId = mediaData.getItemGradingData().getAssessmentGradingId();
        PublishedAssessmentIfc pub = gradingService
                .getPublishedAssessmentByAssessmentGradingId(assessmentGradingId.toString());
        if (pub != null) {
            PublishedAssessmentService service = new PublishedAssessmentService();
            currentSiteId = service.getPublishedAssessmentOwner(pub.getPublishedAssessmentId());
        }

        // some log checking
        //log.debug("agentIdString ="+agentIdString);
        //log.debug("****current site Id ="+currentSiteId);

        boolean hasPrivilege = agentIdString != null && (agentIdString.equals(mediaData.getCreatedBy()) // user is creator
                || canGrade(req, res, agentIdString, currentSiteId));
        if (hasPrivilege) {
            accessDenied = false;
        }
        if (accessDenied) {
            String path = "/jsf/delivery/mediaAccessDenied.faces";
            RequestDispatcher dispatcher = req.getRequestDispatcher(path);
            dispatcher.forward(req, res);
        } else {
            String displayType = "inline";
            if (mediaData.getMimeType() != null && !mediaData.getMimeType().equals("application/octet-stream")
                    && !(setMimeType != null && ("false").equals(setMimeType))) {
                res.setContentType(mediaData.getMimeType());
            } else {
                displayType = "attachment";
                res.setContentType("application/octet-stream");
            }
            log.debug("****" + displayType + ";filename=\"" + mediaData.getFilename() + "\";");

            res.setHeader("Content-Disposition", displayType + ";filename=\"" + mediaData.getFilename() + "\";");

            int start = 0;
            int end = fileSize - 1;
            int rangeContentLength = end - start + 1;

            String range = req.getHeader("Range");

            if (StringUtils.isNotBlank(range)) {
                Matcher matcher = HTTP_RANGE_PATTERN.matcher(range);

                if (matcher.matches()) {
                    String startMatch = matcher.group(1);
                    start = startMatch.isEmpty() ? start : Integer.valueOf(startMatch);
                    start = start < 0 ? 0 : start;

                    String endMatch = matcher.group(2);
                    end = endMatch.isEmpty() ? end : Integer.valueOf(endMatch);
                    end = end > fileSize - 1 ? fileSize - 1 : end;

                    rangeContentLength = end - start + 1;
                }

                res.setHeader("Content-Range", String.format("bytes %s-%s/%s", start, end, fileSize));
                res.setHeader("Content-Length", String.format("%s", rangeContentLength));
                res.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
            } else {
                res.setContentLength(fileSize);
            }

            //** note that res.setContentType() must be called before res.getOutputStream(). see javadoc on this
            FileInputStream inputStream = null;
            BufferedInputStream buf_inputStream = null;
            ServletOutputStream outputStream = res.getOutputStream();
            BufferedOutputStream buf_outputStream = null;
            ByteArrayInputStream byteArrayInputStream = null;
            if (mediaLocation == null || (mediaLocation.trim()).equals("")) {
                try {
                    byteArrayInputStream = new ByteArrayInputStream(mediaData.getMedia());
                    buf_inputStream = new BufferedInputStream(byteArrayInputStream);
                } catch (Exception e) {
                    log.error("****empty media save to DB=" + e.getMessage());
                }
            } else {
                try {
                    inputStream = getFileStream(mediaLocation);
                    buf_inputStream = new BufferedInputStream(inputStream);
                } catch (Exception e) {
                    log.error("****empty media save to file =" + e.getMessage());
                }

            }

            try {

                buf_outputStream = new BufferedOutputStream(outputStream);
                int i = 0;
                if (buf_inputStream != null) {
                    // skip to the start of the possible range request
                    buf_inputStream.skip(start);

                    int bytesLeft = rangeContentLength;
                    byte[] buffer = new byte[1024];

                    while ((i = buf_inputStream.read(buffer)) != -1 && bytesLeft > 0) {
                        buf_outputStream.write(buffer);
                        bytesLeft -= i;
                    }
                }
                log.debug("**** mediaLocation=" + mediaLocation);

                res.flushBuffer();
            } catch (Exception e) {
                log.warn(e.getMessage());
            } finally {
                if (buf_outputStream != null) {
                    try {
                        buf_outputStream.close();
                    } catch (IOException e) {
                        log.error(e.getMessage());
                    }
                }
                if (buf_inputStream != null) {
                    try {
                        buf_inputStream.close();
                    } catch (IOException e) {
                        log.error(e.getMessage());
                    }
                }
                if (inputStream != null) {
                    try {
                        inputStream.close();
                    } catch (IOException e) {
                        log.error(e.getMessage());
                    }
                }
                if (outputStream != null) {
                    try {
                        outputStream.close();
                    } catch (IOException e) {
                        log.error(e.getMessage());
                    }
                }
                if (byteArrayInputStream != null) {
                    try {
                        byteArrayInputStream.close();
                    } catch (IOException e) {
                        log.error(e.getMessage());
                    }
                }
            }
        }
    }

    private FileInputStream getFileStream(String mediaLocation) {
        FileInputStream inputStream = null;
        try {
            File media = new File(mediaLocation);
            inputStream = new FileInputStream(media);
        } catch (FileNotFoundException ex) {
            log.warn("file not found=" + ex.getMessage());
        }
        return inputStream;
    }

    public String getAgentString(HttpServletRequest req, HttpServletResponse res) {
        //String agentIdString = req.getRemoteUser();
        String agentIdString = AgentFacade.getAgentString();
        if (agentIdString == null || agentIdString.equals("")) { // try this
            PersonBean person = (PersonBean) ContextUtil.lookupBeanFromExternalServlet("person", req, res);
            agentIdString = person.getAnonymousId();
        }
        return agentIdString;
    }

    public boolean canGrade(HttpServletRequest req, HttpServletResponse res, String agentId, String currentSiteId) {
        boolean hasPrivilege_any = hasPrivilege(req, "assessment.gradeAssessment.any", currentSiteId);
        boolean hasPrivilege_own = hasPrivilege(req, "assessment.gradeAssessment.own", currentSiteId);
        log.debug("hasPrivilege_any=" + hasPrivilege_any);
        log.debug("hasPrivilege_own=" + hasPrivilege_own);
        boolean hasPrivilege = (hasPrivilege_any || hasPrivilege_own);
        return hasPrivilege;

    }

    public boolean isOwner(String agentId, String ownerId) {
        boolean isOwner = false;
        isOwner = agentId.equals(ownerId);
        return isOwner;
    }

    public boolean hasPrivilege(HttpServletRequest req, String functionName, String context) {
        boolean privilege = SecurityService.unlock(functionName, "/site/" + context);
        return privilege;
    }
}