001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (https://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library 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 GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software, please see the 018 * company website: https://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: https://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.ugc; 029 030import org.opencms.file.CmsObject; 031import org.opencms.file.CmsResource; 032import org.opencms.gwt.CmsGwtService; 033import org.opencms.gwt.CmsRpcException; 034import org.opencms.main.CmsException; 035import org.opencms.main.CmsLog; 036import org.opencms.main.OpenCms; 037import org.opencms.ugc.shared.CmsUgcConstants; 038import org.opencms.ugc.shared.CmsUgcContent; 039import org.opencms.ugc.shared.CmsUgcException; 040import org.opencms.ugc.shared.rpc.I_CmsUgcEditService; 041import org.opencms.util.CmsUUID; 042import org.opencms.xml.content.CmsXmlContentErrorHandler; 043 044import java.io.IOException; 045import java.util.Collections; 046import java.util.Map; 047import java.util.Set; 048 049import org.apache.commons.fileupload2.core.AbstractFileUpload; 050import org.apache.commons.fileupload2.jakarta.servlet5.JakartaServletRequestContext; 051import org.apache.commons.logging.Log; 052 053import com.google.common.collect.Maps; 054 055import jakarta.servlet.ServletException; 056import jakarta.servlet.http.HttpServletRequest; 057import jakarta.servlet.http.HttpServletResponse; 058 059/** 060 * The form editing service.<p> 061 */ 062public class CmsUgcEditService extends CmsGwtService implements I_CmsUgcEditService { 063 064 /** Log instance for this class. */ 065 private static final Log LOG = CmsLog.getLog(CmsUgcEditService.class); 066 067 /** The serial version id. */ 068 private static final long serialVersionUID = 5479252081304867604L; 069 070 /** 071 * @see org.opencms.gwt.CmsGwtService#checkPermissions(org.opencms.file.CmsObject) 072 */ 073 @Override 074 public void checkPermissions(CmsObject cms) { 075 076 // don't do permission checks, since this service should be available to "Guest" users from the frontend 077 } 078 079 /** 080 * @see org.opencms.ugc.shared.rpc.I_CmsUgcEditService#destroySession(org.opencms.util.CmsUUID) 081 */ 082 public void destroySession(CmsUUID sessionId) throws CmsUgcException { 083 084 try { 085 CmsUgcSession formSession = getFormSession(sessionId); 086 getRequest().getSession().removeAttribute("" + sessionId); 087 if (formSession != null) { 088 formSession.onSessionDestroyed(); 089 } 090 091 } catch (Exception e) { 092 error(e); 093 } 094 } 095 096 /** 097 * @see org.opencms.gwt.CmsGwtService#error(java.lang.Throwable) 098 */ 099 @Override 100 public void error(Throwable t) throws CmsUgcException { 101 102 logError(t); 103 CmsUgcException exception = t instanceof CmsUgcException ? (CmsUgcException)t : new CmsUgcException(t); 104 throw exception; 105 } 106 107 /** 108 * @see org.opencms.ugc.shared.rpc.I_CmsUgcEditService#getContent(org.opencms.util.CmsUUID) 109 */ 110 public CmsUgcContent getContent(CmsUUID sessionId) throws CmsUgcException { 111 112 CmsUgcContent formContent = null; 113 try { 114 CmsUgcSession session = CmsUgcSessionFactory.getInstance().getSession(getRequest(), sessionId); 115 formContent = readContent(session, session.getResource()); 116 } catch (Exception e) { 117 error(e); 118 } 119 120 return formContent; 121 } 122 123 /** 124 * @see org.opencms.ugc.shared.rpc.I_CmsUgcEditService#getLink(java.lang.String) 125 */ 126 public String getLink(String path) { 127 128 return OpenCms.getLinkManager().substituteLink(getCmsObject(), path); 129 } 130 131 /** 132 * @see org.opencms.ugc.shared.rpc.I_CmsUgcEditService#saveContent(org.opencms.util.CmsUUID, java.util.Map) 133 */ 134 public Map<String, String> saveContent(CmsUUID sessionId, Map<String, String> contentValues) 135 throws CmsUgcException { 136 137 Map<String, String> result = null; 138 try { 139 CmsUgcSession session = getFormSession(sessionId); 140 if ((session != null) && sessionId.equals(session.getId())) { 141 142 CmsXmlContentErrorHandler errorHandler = session.saveContent(contentValues); 143 if (errorHandler.hasErrors()) { 144 result = errorHandler.getErrors(session.getMessageLocale()); 145 } else { 146 session.finish(); 147 result = Collections.emptyMap(); 148 } 149 } else { 150 // invalid session 151 152 } 153 } catch (Exception e) { 154 error(e); 155 } 156 return result; 157 } 158 159 /** 160 * @see org.opencms.ugc.shared.rpc.I_CmsUgcEditService#uploadFiles(org.opencms.util.CmsUUID, java.util.Set, java.lang.String) 161 */ 162 public Map<String, String> uploadFiles( 163 final CmsUUID sessionId, 164 final Set<String> fieldNames, 165 final String formDataId) 166 throws CmsRpcException { 167 168 try { 169 final CmsUgcSession session = getFormSession(sessionId); 170 final Map<String, String> result = Maps.newHashMap(); 171 172 session.getFormUploadHelper().consumeFormData(formDataId, new I_CmsFormDataHandler() { 173 174 @SuppressWarnings("synthetic-access") 175 public void handleFormData(Map<String, I_CmsFormDataItem> items) throws Exception { 176 177 for (String fieldName : fieldNames) { 178 I_CmsFormDataItem item = items.get(fieldName); 179 if (item != null) { 180 CmsResource createdResource = session.createUploadResource( 181 item.getFieldName(), 182 item.getFileName(), 183 item.getData()); 184 String sitePath = session.getCmsObject().getSitePath(createdResource); 185 result.put(fieldName, sitePath); 186 } else { 187 LOG.debug(formDataId + ": requested upload for field " + fieldName + " which was empty."); 188 } 189 } 190 } 191 }); 192 return result; 193 } catch (Exception e) { 194 error(e); 195 return null; // will never be reached 196 197 } 198 } 199 200 /** 201 * @see org.opencms.ugc.shared.rpc.I_CmsUgcEditService#validateContent(org.opencms.util.CmsUUID, java.util.Map) 202 */ 203 public Map<String, String> validateContent(CmsUUID sessionId, Map<String, String> contentValues) 204 throws CmsUgcException { 205 206 Map<String, String> result = Maps.newHashMap(); 207 try { 208 CmsUgcSession session = getFormSession(sessionId); 209 if ((session != null) && sessionId.equals(session.getId())) { 210 CmsXmlContentErrorHandler errorHandler = session.validateContent(contentValues); 211 result = errorHandler.getErrors(session.getMessageLocale()); 212 } else { 213 // invalid session 214 215 } 216 } catch (Exception e) { 217 error(e); 218 } 219 return result; 220 } 221 222 /** 223 * Handles all multipart requests.<p> 224 * 225 * @param request the request 226 * @param response the response 227 */ 228 protected void handleUpload(HttpServletRequest request, HttpServletResponse response) { 229 230 String sessionIdStr = request.getParameter(CmsUgcConstants.PARAM_SESSION_ID); 231 CmsUUID sessionId = new CmsUUID(sessionIdStr); 232 CmsUgcSession session = CmsUgcSessionFactory.getInstance().getSession(request, sessionId); 233 session.getFormUploadHelper().processFormSubmitRequest(request); 234 } 235 236 /** 237 * @see jakarta.servlet.http.HttpServlet#service(jakarta.servlet.http.HttpServletRequest, jakarta.servlet.http.HttpServletResponse) 238 */ 239 @Override 240 protected void service(HttpServletRequest request, HttpServletResponse response) 241 throws ServletException, IOException { 242 243 boolean isMultiPart = AbstractFileUpload.isMultipartContent(new JakartaServletRequestContext(request)); 244 245 if (isMultiPart) { 246 try { 247 handleUpload(request, response); 248 } finally { 249 clearThreadStorage(); 250 } 251 } else { 252 super.service(request, response); 253 } 254 } 255 256 /** 257 * Gets the form session with the given id.<p> 258 * 259 * @param sessionId the session id 260 * 261 * @return the form session 262 */ 263 private CmsUgcSession getFormSession(CmsUUID sessionId) { 264 265 return CmsUgcSessionFactory.getInstance().getSession(getRequest(), sessionId); 266 } 267 268 /** 269 * Reads the form content information.<p> 270 * 271 * @param session the editing session 272 * @param resource the edited resource 273 * 274 * @return the form content 275 * 276 * @throws CmsException if reading the info fails 277 */ 278 private CmsUgcContent readContent(CmsUgcSession session, CmsResource resource) throws CmsException { 279 280 CmsUgcContent formContent = new CmsUgcContent(); 281 Map<String, String> contentValues = session.getValues(); 282 formContent.setContentValues(contentValues); 283 formContent.setSessionId(session.getId()); 284 formContent.setResourceType(OpenCms.getResourceManager().getResourceType(resource).getTypeName()); 285 formContent.setSitePath(getCmsObject().getSitePath(resource)); 286 formContent.setStrucureId(resource.getStructureId()); 287 return formContent; 288 } 289 290}