1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    *
5    *
6    *
7    * The contents of this file are subject to the terms of the Liferay Enterprise
8    * Subscription License ("License"). You may not use this file except in
9    * compliance with the License. You can obtain a copy of the License by
10   * contacting Liferay, Inc. See the License for the specific language governing
11   * permissions and limitations under the License, including but not limited to
12   * distribution rights of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.servlet;
24  
25  import com.liferay.portal.NoSuchImageException;
26  import com.liferay.portal.PortalException;
27  import com.liferay.portal.SystemException;
28  import com.liferay.portal.kernel.log.Log;
29  import com.liferay.portal.kernel.log.LogFactoryUtil;
30  import com.liferay.portal.kernel.servlet.HttpHeaders;
31  import com.liferay.portal.kernel.util.GetterUtil;
32  import com.liferay.portal.kernel.util.MimeTypesUtil;
33  import com.liferay.portal.kernel.util.ParamUtil;
34  import com.liferay.portal.kernel.util.PropsKeys;
35  import com.liferay.portal.kernel.util.Validator;
36  import com.liferay.portal.model.Image;
37  import com.liferay.portal.model.User;
38  import com.liferay.portal.model.impl.ImageImpl;
39  import com.liferay.portal.service.ImageLocalServiceUtil;
40  import com.liferay.portal.service.UserLocalServiceUtil;
41  import com.liferay.portal.util.PortalUtil;
42  import com.liferay.portal.util.PrefsPropsUtil;
43  import com.liferay.portal.util.PropsValues;
44  import com.liferay.portlet.imagegallery.model.IGImage;
45  import com.liferay.portlet.imagegallery.service.IGImageLocalServiceUtil;
46  import com.liferay.util.servlet.ServletResponseUtil;
47  
48  import java.io.IOException;
49  
50  import java.util.Date;
51  
52  import javax.portlet.PortletPreferences;
53  
54  import javax.servlet.ServletConfig;
55  import javax.servlet.ServletException;
56  import javax.servlet.http.HttpServlet;
57  import javax.servlet.http.HttpServletRequest;
58  import javax.servlet.http.HttpServletResponse;
59  
60  /**
61   * <a href="ImageServlet.java.html"><b><i>View Source</i></b></a>
62   *
63   * @author Brian Wing Shun Chan
64   * @author Brett Randall
65   */
66  public class ImageServlet extends HttpServlet {
67  
68      public void init(ServletConfig servletConfig) throws ServletException {
69          super.init(servletConfig);
70  
71          _lastModified = GetterUtil.getBoolean(
72              servletConfig.getInitParameter("last_modified"), true);
73      }
74  
75      public void service(
76              HttpServletRequest request, HttpServletResponse response)
77          throws IOException, ServletException {
78  
79          if (_lastModified) {
80              long lastModified = getLastModified(request);
81  
82              if (lastModified > 0) {
83                  long ifModifiedSince = request.getDateHeader(
84                      HttpHeaders.IF_MODIFIED_SINCE);
85  
86                  if ((ifModifiedSince > 0) &&
87                      (ifModifiedSince == lastModified)) {
88  
89                      response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
90  
91                      return;
92                  }
93              }
94  
95              if (lastModified > 0) {
96                  response.setDateHeader(HttpHeaders.LAST_MODIFIED, lastModified);
97              }
98          }
99  
100         try {
101             writeImage(request, response);
102         }
103         catch (Exception e) {
104             PortalUtil.sendError(
105                 HttpServletResponse.SC_NOT_FOUND, e, request, response);
106         }
107     }
108 
109     protected boolean checkIGImageThumbnailMaxDimensions(
110             Image image, long igImageId)
111         throws PortalException, SystemException {
112 
113         PortletPreferences preferences = PrefsPropsUtil.getPreferences();
114 
115         long igThumbnailMaxDimension = GetterUtil.getLong(
116             preferences.getValue(
117                 PropsKeys.IG_IMAGE_THUMBNAIL_MAX_DIMENSION, null));
118 
119         if ((image.getHeight() > igThumbnailMaxDimension) ||
120             (image.getWidth() > igThumbnailMaxDimension)) {
121 
122             IGImage igImage = IGImageLocalServiceUtil.getImage(
123                 igImageId);
124 
125             IGImageLocalServiceUtil.updateSmallImage(
126                 igImage.getSmallImageId(), igImage.getLargeImageId());
127 
128             return true;
129         }
130 
131         return false;
132     }
133 
134     protected boolean checkUserImageMaxDimensions(Image image, long imageId)
135         throws PortalException, SystemException {
136 
137         if ((image.getHeight() > PropsValues.USERS_IMAGE_MAX_HEIGHT) ||
138             (image.getWidth() > PropsValues.USERS_IMAGE_MAX_WIDTH)) {
139 
140             User user = UserLocalServiceUtil.getUserByPortraitId(imageId);
141 
142             UserLocalServiceUtil.updatePortrait(
143                 user.getUserId(), image.getTextObj());
144 
145             return true;
146         }
147 
148         return false;
149     }
150 
151     protected Image getDefaultImage(HttpServletRequest request, long imageId)
152         throws NoSuchImageException {
153 
154         String path = GetterUtil.getString(request.getPathInfo());
155 
156         if (path.startsWith("/company_logo")) {
157             return ImageLocalServiceUtil.getDefaultCompanyLogo();
158         }
159         else if (path.startsWith("/organization_logo")) {
160             return ImageLocalServiceUtil.getDefaultOrganizationLogo();
161         }
162         else if (path.startsWith("/user_female_portrait")) {
163             return ImageLocalServiceUtil.getDefaultUserFemalePortrait();
164         }
165         else if (path.startsWith("/user_male_portrait")) {
166             return ImageLocalServiceUtil.getDefaultUserMalePortrait();
167         }
168         else if (path.startsWith("/user_portrait")) {
169             return ImageLocalServiceUtil.getDefaultUserMalePortrait();
170         }
171         else {
172             throw new NoSuchImageException(
173                 "No default image exists for " + imageId);
174         }
175     }
176 
177     protected Image getImage(HttpServletRequest request, boolean getDefault)
178         throws PortalException, SystemException {
179 
180         long imageId = getImageId(request);
181 
182         Image image = null;
183 
184         if (imageId > 0) {
185             image = ImageLocalServiceUtil.getImage(imageId);
186 
187             String path = GetterUtil.getString(request.getPathInfo());
188 
189             if (path.startsWith("/user_female_portrait") ||
190                 path.startsWith("/user_male_portrait") ||
191                 path.startsWith("/user_portrait")) {
192 
193                 if (checkUserImageMaxDimensions(image, imageId)) {
194                     image = ImageLocalServiceUtil.getImage(imageId);
195                 }
196             }
197             else {
198                 long igImageId = ParamUtil.getLong(request, "igImageId");
199                 boolean igSmallImage = ParamUtil.getBoolean(
200                     request, "igSmallImage");
201 
202                 if ((igImageId > 0) && igSmallImage) {
203                     if (checkIGImageThumbnailMaxDimensions(image, igImageId)) {
204                         image = ImageLocalServiceUtil.getImage(imageId);
205                     }
206                 }
207             }
208         }
209         else {
210             String uuid = ParamUtil.getString(request, "uuid");
211             long groupId = ParamUtil.getLong(request, "groupId");
212 
213             try {
214                 if (Validator.isNotNull(uuid) && (groupId > 0)) {
215                     IGImage igImage =
216                         IGImageLocalServiceUtil.getImageByUuidAndGroupId(
217                             uuid, groupId);
218 
219                     image = ImageLocalServiceUtil.getImage(
220                         igImage.getLargeImageId());
221                 }
222             }
223             catch (Exception e) {
224             }
225         }
226 
227         if (getDefault) {
228             if (image == null) {
229                 if (_log.isWarnEnabled()) {
230                     _log.warn("Get a default image for " + imageId);
231                 }
232 
233                 image = getDefaultImage(request, imageId);
234             }
235         }
236 
237         return image;
238     }
239 
240     protected long getImageId(HttpServletRequest request) {
241 
242         // The image id may be passed in as image_id, img_id, or i_id
243 
244         long imageId = ParamUtil.getLong(request, "image_id");
245 
246         if (imageId <= 0) {
247             imageId = ParamUtil.getLong(request, "img_id");
248         }
249 
250         if (imageId <= 0) {
251             imageId = ParamUtil.getLong(request, "i_id");
252         }
253 
254         if (imageId <= 0) {
255             long companyId = ParamUtil.getLong(request, "companyId");
256             String screenName = ParamUtil.getString(request, "screenName");
257 
258             try {
259                 if ((companyId > 0) && Validator.isNotNull(screenName)) {
260                     User user = UserLocalServiceUtil.getUserByScreenName(
261                         companyId, screenName);
262 
263                     imageId = user.getPortraitId();
264                 }
265             }
266             catch (Exception e) {
267             }
268         }
269 
270         return imageId;
271     }
272 
273     protected long getLastModified(HttpServletRequest request) {
274         try {
275             Image image = getImage(request, false);
276 
277             if (image == null) {
278                 return -1;
279             }
280 
281             Date modifiedDate = image.getModifiedDate();
282 
283             if (modifiedDate == null) {
284                 modifiedDate = PortalUtil.getUptime();
285             }
286 
287             // Round down and remove milliseconds
288 
289             return (modifiedDate.getTime() / 1000) * 1000;
290         }
291         catch (Exception e) {
292             _log.error(e, e);
293 
294             return -1;
295         }
296     }
297 
298     protected void writeImage(
299             HttpServletRequest request, HttpServletResponse response)
300         throws PortalException, SystemException {
301 
302         Image image = getImage(request, true);
303 
304         if (image == null) {
305             throw new NoSuchImageException("Image is null");
306         }
307         else {
308             if (!image.getType().equals(ImageImpl.TYPE_NOT_AVAILABLE)) {
309                 String contentType = MimeTypesUtil.getContentType(
310                     image.getType());
311 
312                 response.setContentType(contentType);
313             }
314 
315             try {
316                 ServletResponseUtil.write(response, image.getTextObj());
317             }
318             catch (Exception e) {
319                 if (_log.isWarnEnabled()) {
320                     _log.warn(e, e);
321                 }
322             }
323         }
324     }
325 
326     private static Log _log = LogFactoryUtil.getLog(ImageServlet.class);
327 
328     private boolean _lastModified = true;
329 
330 }