001/* 002 * cilla - Blog Management System 003 * 004 * Copyright (C) 2012 Richard "Shred" Körber 005 * http://cilla.shredzone.org 006 * 007 * This program is free software: you can redistribute it and/or modify 008 * it under the terms of the GNU Affero General Public License as published 009 * by the Free Software Foundation, either version 3 of the License, or 010 * (at your option) any later version. 011 * 012 * This program is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 015 * GNU General Public License for more details. 016 * 017 * You should have received a copy of the GNU Affero General Public License 018 * along with this program. If not, see <http://www.gnu.org/licenses/>. 019 */ 020package org.shredzone.cilla.view; 021 022import java.util.List; 023 024import javax.annotation.Resource; 025import javax.servlet.http.HttpServletRequest; 026import javax.servlet.http.HttpServletResponse; 027 028import org.shredzone.cilla.core.datasource.ResourceDataSource; 029import org.shredzone.cilla.core.model.GallerySection; 030import org.shredzone.cilla.core.model.Picture; 031import org.shredzone.cilla.service.PageService; 032import org.shredzone.cilla.service.PictureService; 033import org.shredzone.cilla.view.annotation.Framed; 034import org.shredzone.cilla.view.model.PictureInfoModel; 035import org.shredzone.cilla.web.comment.CommentFormHandler; 036import org.shredzone.cilla.web.page.ResourceLockManager; 037import org.shredzone.cilla.web.plugin.manager.ImageProcessingManager; 038import org.shredzone.cilla.ws.ImageProcessing; 039import org.shredzone.cilla.ws.exception.CillaServiceException; 040import org.shredzone.commons.view.annotation.Optional; 041import org.shredzone.commons.view.annotation.PathPart; 042import org.shredzone.commons.view.annotation.Qualifier; 043import org.shredzone.commons.view.annotation.View; 044import org.shredzone.commons.view.annotation.ViewHandler; 045import org.shredzone.commons.view.exception.ErrorResponseException; 046import org.shredzone.commons.view.exception.PageNotFoundException; 047import org.shredzone.commons.view.exception.ViewException; 048import org.springframework.stereotype.Component; 049 050/** 051 * Views for showing the standalone parts of the gallery section. 052 * 053 * @author Richard "Shred" Körber 054 */ 055@ViewHandler 056@Component 057public class GalleryView extends AbstractView { 058 059 private @Resource PageService pageService; 060 private @Resource PictureService pictureService; 061 private @Resource ResourceLockManager unlockService; 062 private @Resource ImageProcessingManager imageProcessingManager; 063 private @Resource CommentFormHandler commentFormHandler; 064 065 /** 066 * Shows a single picture of a gallery. 067 */ 068 @Framed 069 @View(pattern = "/show/gallery/${section.id}/picture/${picture.id}.html", signature = {"section", "picture"}) 070 @View(pattern = "/ajax/gallery/${section.id}/picture/${picture.id}.html", signature = {"section", "picture"}, qualifier = "ajax") 071 public String galleryPictureView( 072 @PathPart("section.id") GallerySection section, 073 @PathPart("picture.id") Picture picture, 074 @Qualifier String qualifier, 075 HttpServletRequest req, HttpServletResponse resp) 076 throws ViewException { 077 if (!pageService.isVisible(section.getPage())) { 078 throw new ErrorResponseException(HttpServletResponse.SC_FORBIDDEN); 079 } 080 081 commentFormHandler.handleComment(picture, req, section.isCommentable()); 082 083 List<Picture> pictureList = section.getPictures(); 084 int size = pictureList.size(); 085 int current = pictureList.indexOf(picture); 086 087 if (current < 0 || size == 0) { 088 // There is such a picture, but not in this gallery! 089 throw new PageNotFoundException("No such picture in this gallery."); 090 } 091 092 if (redirectRestricted(section.getPage(), req, resp)) { 093 return null; 094 } 095 096 req.setAttribute("page", section.getPage()); 097 req.setAttribute("section", section); 098 req.setAttribute("picture", picture); 099 req.setAttribute("info", new PictureInfoModel(pictureList, current)); 100 101 if ("ajax".equals(qualifier)) { 102 return "section/gallery/picture-ajax.jsp"; 103 } else { 104 return "section/gallery/picture.jsp"; 105 } 106 } 107 108 /** 109 * Shows a map of the location the picture was taken. 110 */ 111 @Framed 112 @View(pattern = "/show/gallery/${section.id}/map/${picture.id}.html", name="gallery.map") 113 public String galleryMapView( 114 @PathPart("section.id") GallerySection section, 115 @PathPart("picture.id") Picture picture, 116 HttpServletRequest req, HttpServletResponse resp) 117 throws ViewException { 118 if (!pageService.isVisible(section.getPage())) { 119 throw new ErrorResponseException(HttpServletResponse.SC_FORBIDDEN); 120 } 121 122 if (!section.getPictures().contains(picture)) { 123 // There is such a picture, but not in this gallery! 124 throw new PageNotFoundException("No such picture in this gallery."); 125 } 126 127 if (redirectRestricted(section.getPage(), req, resp)) { 128 return null; 129 } 130 131 req.setAttribute("page", section.getPage()); 132 req.setAttribute("section", section); 133 req.setAttribute("picture", picture); 134 135 return "section/gallery/map.jsp"; 136 } 137 138 /** 139 * Streams the picture of a gallery. 140 */ 141 @View(pattern = "/picture/${picture.id}-${#type}.${#suffix(picture.image.contentType)}", signature = {"picture", "#type"}) 142 @View(pattern = "/picture/${picture.id}.${#suffix(picture.image.contentType)}", signature = {"picture"}) 143 public void pictureView( 144 @PathPart("picture.id") Picture picture, 145 @Optional @PathPart("#type") String type, 146 HttpServletRequest req, HttpServletResponse resp) 147 throws ViewException, CillaServiceException { 148 // Take measures against deep linking of the pictures. No need to check page 149 // permissions, as the picture is not unlocked if the visitor had no access 150 // to the page. 151 if (!unlockService.isUnlocked(req.getSession(), picture)) { 152 throw new ErrorResponseException(HttpServletResponse.SC_FORBIDDEN); 153 } 154 155 ImageProcessing ip = null; 156 if (type != null) { 157 ip = imageProcessingManager.createImageProcessing(type); 158 if (ip == null) { 159 throw new ErrorResponseException(HttpServletResponse.SC_NOT_FOUND); 160 } 161 } 162 163 ResourceDataSource ds = pictureService.getImage(picture, ip); 164 streamDataSource(ds, req, resp); 165 } 166 167}