Package org.internna.iwebmvc.spring.mvc.controllers

Source Code of org.internna.iwebmvc.spring.mvc.controllers.ResourceController

/*
* Copyright 2009-2010 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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.internna.iwebmvc.spring.mvc.controllers;

import static org.springframework.util.FileCopyUtils.copy;
import static org.springframework.util.StringUtils.hasText;

import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringReader;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.internna.iwebmvc.crypto.Decipherer;
import org.internna.iwebmvc.dao.DAO;
import org.internna.iwebmvc.model.Document;
import org.internna.iwebmvc.model.UUID;
import org.internna.iwebmvc.utils.Assert;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

/**
* Serves files from META-INF directory.
*
* @author Jose Noheda
* @since 2.0
*/
@Controller
@RequestMapping({"/resource.iwebmvc"})
public final class ResourceController implements InitializingBean {

    protected Log logger = LogFactory.getLog(getClass());

    private Calendar calendar;
    private DateFormat httpDateFormat;
    private int seconds = 3 * 24 * 60 * 60;
    private long lastModified = new Date().getTime();

    private DAO dao;
    private Decipherer decipherer;
    private Map<String, String> mimes;

    public void setDao(DAO dao) {
        this.dao = dao;
    }

    public void setDecipherer(Decipherer decipherer) {
        this.decipherer = decipherer;
    }

    @Override public void afterPropertiesSet() throws Exception {
        mimes = new HashMap<String, String>();
        mimes.put("swf", "application/x-shockwave-flash");
        mimes.put("gif", "image/gif");
        mimes.put("png", "image/png");
        mimes.put("jpg", "image/jpeg");
        mimes.put("jpeg", "image/jpeg");
        calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, seconds / 60 / 60 / 24);
        httpDateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
        httpDateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
    }

    protected BufferedImage getScaledInstance(BufferedImage original, int width, int height) {
        int w = original.getWidth();
        int h = original.getHeight();
        BufferedImage ret = original;
        int type = original.getTransparency() == Transparency.OPAQUE ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
        while ((w > width) & (h > height)) {
            if (w > width) {
                w /= 2;
                if (w < width) w = width;
            }
            if (h > height) {
                h /= 2;
                if (h < height) h = height;
            }
            BufferedImage tmp = new BufferedImage(w, h, type);
            Graphics2D g2 = tmp.createGraphics();
            g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
            g2.drawImage(ret, 0, 0, w, h, null);
            g2.dispose();
            ret.flush();
            ret = tmp;
        }
        return ret;
    }

    @RequestMapping(method = RequestMethod.GET)
    public void serve(@RequestParam("file") String file, @RequestParam(required = false, value = "width") String width, @RequestParam(required = false, value = "height") String height, @RequestParam(required = false, value = "escape") String escape, HttpServletRequest request, HttpServletResponse response) throws IOException {
        if (hasText(file)) {
            if (decipherer.isEncrypted(file)) {
                Document doc = dao.find(Document.class, new UUID(decipherer.decrypt(file)));
                response.setContentType(doc.getMimeType());
                if (logger.isDebugEnabled()) logger.debug("Setting MIME type [" + doc.getMimeType() + "] to document [" + doc.getId() + "]");
                if (doc.isText()) sendText(doc, escape, response);
                else send(new ByteArrayInputStream(doc.getContents()), doc.getMimeType(), response.getOutputStream(), width, height);
            } else {
                if (file.contains("..")) throw new IllegalArgumentException("Security alert: Will not serve file [" + file + "]");
                InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("META-INF" + (file.startsWith("/") ? file : "/" + file));
                String ext = StringUtils.getFilenameExtension(file);
                String mimeType = null;
                if (mimes.containsKey(ext)) {
                    mimeType = mimes.get(ext);
                    response.setContentType(mimeType);
                    if (logger.isDebugEnabled()) logger.debug("Setting MIME type [" + mimeType + "] to [" + file + "]");
                }
                response.setHeader("Pragma", "public");
                response.setDateHeader("Last-Modified", lastModified);
                response.setHeader("Cache-Control", "PUBLIC, max-age=" + seconds + ", must-revalidate");
                response.setHeader("Expires", httpDateFormat.format(calendar.getTime()));
                if (request.getDateHeader("If-Modified-Since") > -1) response.sendError(HttpServletResponse.SC_NOT_MODIFIED);
                else if ((in != null) && (in.available() > 0)) send(in, mimeType, response.getOutputStream(), width, height);
            }
            response.getOutputStream().close();
        }
    }

    protected void sendText(Document doc, String escape, HttpServletResponse response) throws IOException {
        byte[] contents = doc.getContents();
        if (hasText(escape) && "true".equals(escape.toLowerCase(Locale.ENGLISH))) {
            String data = new String(doc.getContents());
            if (hasText(data)) data = data.replaceAll("<", "&lt;");
            contents = data.getBytes();
        }
        send(new ByteArrayInputStream(contents), doc.getMimeType(), response.getOutputStream(), null, null);
    }

    private void send(InputStream content, String mimetype, OutputStream out, String width, String height) throws IOException {
        if (hasText(width)) {
            Assert.notNull(height);
            BufferedImage im = getScaledInstance(ImageIO.read(content), Integer.parseInt(width), Integer.parseInt(height));
            ImageIO.write(im, getImageFormat(mimetype), out);
        } else copy(content, out);
    }

    protected String getImageFormat(String mimeType) {
        return "PNG";
    }

}
TOP

Related Classes of org.internna.iwebmvc.spring.mvc.controllers.ResourceController

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.