View Javadoc
1   /**
2    * This file Copyright (c) 2009-2018 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.imaging;
35  
36  import info.magnolia.imaging.util.PathSplitter;
37  import info.magnolia.objectfactory.Components;
38  
39  import java.io.IOException;
40  import java.io.OutputStream;
41  
42  import javax.inject.Inject;
43  import javax.inject.Provider;
44  import javax.servlet.ServletException;
45  import javax.servlet.http.HttpServlet;
46  import javax.servlet.http.HttpServletRequest;
47  import javax.servlet.http.HttpServletResponse;
48  
49  import org.slf4j.Logger;
50  import org.slf4j.LoggerFactory;
51  
52  import com.google.common.net.MediaType;
53  
54  /**
55   * Servlet responsible for the actual generation of the images.
56   */
57  public class ImagingServlet extends HttpServlet {
58      private static final Logger log = LoggerFactory.getLogger(ImagingServlet.class);
59      private final Imaging imaging;
60      private final Provider<ImagingModule> imagingModuleProvider;
61  
62      @Inject
63      public ImagingServlet(Imaging imaging, Provider<ImagingModule> imagingModuleProvider) {
64          this.imaging = imaging;
65          this.imagingModuleProvider = imagingModuleProvider;
66      }
67  
68      /**
69       * @deprecated Since Imaging 3.3 (Magnolia 5.5), use {@link ImagingServlet(Imaging)}.
70       */
71      @Deprecated
72      public ImagingServlet(final ImagingModule imagingModule) {
73          this.imaging = Components.getComponent(Imaging.class);
74          this.imagingModuleProvider = new Provider<ImagingModule>() {
75              @Override
76              public ImagingModule get() {
77                  return Components.getComponent(ImagingModule.class);
78              }
79          };
80      }
81  
82      @Override
83      protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
84          final String generatorName = getImageGeneratorName(request);
85  
86          try {
87              imaging.generate(generatorName, request, new ServletImageResponse(response));
88              response.flushBuffer();
89          } catch (IllegalArgumentException | ImagingRuntimeException | ImagingException e) {
90              log.warn("Because of incorrect arguments the image couldn't be found", e);
91              response.sendError(HttpServletResponse.SC_NOT_FOUND);
92          } catch (IOException e) {
93              // only log at debug level
94              // tomcat usually throws a ClientAbortException anytime the user stop loading the page
95              log.debug("Unable to spool resource due to a {} exception", e.getClass().getName());
96              if (!response.isCommitted()) {
97                  response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
98              }
99          }
100     }
101 
102     /**
103      * Determines the ImageGenerator to use, using the first path element of the
104      * pathInfo.
105      */
106     protected String getImageGeneratorName(HttpServletRequest request) {
107         final String pathInfo = request.getPathInfo();
108         return new PathSplitter(pathInfo).skipTo(0);
109     }
110 
111     protected ImageGenerator getGenerator(String generatorName) {
112         final ImagingModule module = getImagingModule();
113         return module.getGenerators().get(generatorName);
114     }
115 
116     protected ImagingModule getImagingModule() {
117         return imagingModuleProvider.get();
118     }
119 
120     private static class ServletImageResponse implements ImageResponse {
121         private final HttpServletResponse response;
122 
123         public ServletImageResponse(HttpServletResponse response) {
124             this.response = response;
125         }
126 
127         @Override
128         public void setMediaType(MediaType mediaType) throws IOException {
129             response.setContentType(mediaType.toString());
130         }
131 
132         @Override
133         public OutputStream getOutputStream() throws IOException {
134             return response.getOutputStream();
135         }
136     }
137 }