001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://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: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://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 javax.servlet.ServletException;
050import javax.servlet.http.HttpServletRequest;
051import javax.servlet.http.HttpServletResponse;
052
053import org.apache.commons.fileupload.FileUploadBase;
054import org.apache.commons.fileupload.servlet.ServletRequestContext;
055import org.apache.commons.logging.Log;
056
057import com.google.common.collect.Maps;
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) throws CmsRpcException {
166
167        try {
168            final CmsUgcSession session = getFormSession(sessionId);
169            final Map<String, String> result = Maps.newHashMap();
170
171            session.getFormUploadHelper().consumeFormData(formDataId, new I_CmsFormDataHandler() {
172
173                @SuppressWarnings("synthetic-access")
174                public void handleFormData(Map<String, I_CmsFormDataItem> items) throws Exception {
175
176                    for (String fieldName : fieldNames) {
177                        I_CmsFormDataItem item = items.get(fieldName);
178                        if (item != null) {
179                            CmsResource createdResource = session.createUploadResource(
180                                item.getFieldName(),
181                                item.getFileName(),
182                                item.getData());
183                            String sitePath = session.getCmsObject().getSitePath(createdResource);
184                            result.put(fieldName, sitePath);
185                        } else {
186                            LOG.debug(formDataId + ": requested upload for field " + fieldName + " which was empty.");
187                        }
188                    }
189                }
190            });
191            return result;
192        } catch (Exception e) {
193            error(e);
194            return null; // will never be reached
195
196        }
197    }
198
199    /**
200     * @see org.opencms.ugc.shared.rpc.I_CmsUgcEditService#validateContent(org.opencms.util.CmsUUID, java.util.Map)
201     */
202    public Map<String, String> validateContent(CmsUUID sessionId, Map<String, String> contentValues)
203    throws CmsUgcException {
204
205        Map<String, String> result = Maps.newHashMap();
206        try {
207            CmsUgcSession session = getFormSession(sessionId);
208            if ((session != null) && sessionId.equals(session.getId())) {
209                CmsXmlContentErrorHandler errorHandler = session.validateContent(contentValues);
210                result = errorHandler.getErrors(session.getMessageLocale());
211            } else {
212                // invalid session
213
214            }
215        } catch (Exception e) {
216            error(e);
217        }
218        return result;
219    }
220
221    /**
222     * Handles all multipart requests.<p>
223     *
224     * @param request the request
225     * @param response the response
226     */
227    protected void handleUpload(HttpServletRequest request, HttpServletResponse response) {
228
229        String sessionIdStr = request.getParameter(CmsUgcConstants.PARAM_SESSION_ID);
230        CmsUUID sessionId = new CmsUUID(sessionIdStr);
231        CmsUgcSession session = CmsUgcSessionFactory.getInstance().getSession(request, sessionId);
232        session.getFormUploadHelper().processFormSubmitRequest(request);
233    }
234
235    /**
236     * @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
237     */
238    @Override
239    protected void service(HttpServletRequest request, HttpServletResponse response)
240    throws ServletException, IOException {
241
242        boolean isMultiPart = FileUploadBase.isMultipartContent(new ServletRequestContext(request));
243
244        if (isMultiPart) {
245            try {
246                handleUpload(request, response);
247            } finally {
248                clearThreadStorage();
249            }
250        } else {
251            super.service(request, response);
252        }
253    }
254
255    /**
256     * Gets the form session  with the given id.<p>
257     *
258     * @param sessionId the session id
259     *
260     * @return the form session
261     */
262    private CmsUgcSession getFormSession(CmsUUID sessionId) {
263
264        return CmsUgcSessionFactory.getInstance().getSession(getRequest(), sessionId);
265    }
266
267    /**
268     * Reads the form content information.<p>
269     *
270     * @param session the editing session
271     * @param resource the edited resource
272     *
273     * @return the form content
274     *
275     * @throws CmsException if reading the info fails
276     */
277    private CmsUgcContent readContent(CmsUgcSession session, CmsResource resource) throws CmsException {
278
279        CmsUgcContent formContent = new CmsUgcContent();
280        Map<String, String> contentValues = session.getValues();
281        formContent.setContentValues(contentValues);
282        formContent.setSessionId(session.getId());
283        formContent.setResourceType(OpenCms.getResourceManager().getResourceType(resource).getTypeName());
284        formContent.setSitePath(getCmsObject().getSitePath(resource));
285        formContent.setStrucureId(resource.getStructureId());
286        return formContent;
287    }
288
289}