package com.celements.webform; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xwiki.component.annotation.Component; import org.xwiki.component.annotation.Requirement; import org.xwiki.context.Execution; import org.xwiki.model.reference.DocumentReference; import org.xwiki.script.service.ScriptService; import com.celements.web.plugin.cmd.DocFormCommand; import com.celements.web.service.IWebUtilsService; import com.xpn.xwiki.XWikiContext; import com.xpn.xwiki.XWikiException; import com.xpn.xwiki.api.Document; import com.xpn.xwiki.doc.XWikiDocument; @Component("docform") public class DocFormScriptService implements ScriptService { private static Logger LOGGER = LoggerFactory.getLogger(DocFormScriptService.class); private static final String _DOC_FORM_COMMAND_OBJECT = "com.celements.DocFormCommand"; @Requirement private Execution execution; @Requirement IWebUtilsService webUtilsService; private XWikiContext getContext() { return (XWikiContext) execution.getContext().getProperty("xwikicontext"); } /* * TODO: Please get rid of throwing an exception to the view (client), use try/catch and * write the exception in a log-file ATTENTION: use only for preview and NOT for save! * Removed objects will not be saved correctly using this method. To save use * updateAndSaveDocFromRequest() instead. */ public Set<Document> updateDocFromMap(DocumentReference docRef, Map<String, ?> map) throws XWikiException { Collection<XWikiDocument> xdocs = getDocFormCommand().updateDocFromMap(docRef, getDocFormCommand().prepareMapForDocUpdate(map), getContext()); Set<Document> docs = new HashSet<Document>(); for (XWikiDocument xdoc : xdocs) { docs.add(xdoc.newDocument(getContext())); } return docs; } public Map<String, Set<DocumentReference>> updateAndSaveDocFromMap(DocumentReference docRef, Map<String, ?> map) { Collection<XWikiDocument> xdocs = Collections.<XWikiDocument>emptyList(); try { xdocs = getDocFormCommand().updateDocFromMap(docRef, getDocFormCommand().prepareMapForDocUpdate(map), getContext()); return checkRightsAndSaveXWikiDocCollection(xdocs); } catch (XWikiException xwe) { LOGGER.error("Exception in getDocFormCommand().updateDocFromMap()", xwe); } return Collections.emptyMap(); } /* * TODO: Please get rid of throwing an exception to the view (client), use try/catch and * write the exception in a log-file */ public Set<Document> updateDocFromRequest() throws XWikiException { return updateDocFromRequest(null); } /* * TODO: Please get rid of throwing an exception to the view (client), use try/catch and * write the exception in a log-file ATTENTION: use only for preview and NOT for save! * Removed objects will not be saved correctly using this method. To save use * updateAndSaveDocFromRequest() instead. */ @SuppressWarnings("unchecked") public Set<Document> updateDocFromRequest(DocumentReference docRef) throws XWikiException { Set<Document> docs = new HashSet<Document>(); Collection<XWikiDocument> xdocs = getDocFormCommand().updateDocFromMap(docRef, getContext().getRequest().getParameterMap(), getContext()); for (XWikiDocument xdoc : xdocs) { docs.add(xdoc.newDocument(getContext())); } return docs; } public Map<String, Set<DocumentReference>> updateAndSaveDocFromRequest() { return updateAndSaveDocFromRequest(null); } @SuppressWarnings("unchecked") public Map<String, Set<DocumentReference>> updateAndSaveDocFromRequest(DocumentReference docRef) { Collection<XWikiDocument> xdocs = Collections.<XWikiDocument>emptyList(); try { xdocs = getDocFormCommand().updateDocFromMap(docRef, getContext().getRequest().getParameterMap(), getContext()); return checkRightsAndSaveXWikiDocCollection(xdocs); } catch (XWikiException xwe) { LOGGER.error("Exception in getDocFormCommand().updateDocFromMap()", xwe); } return Collections.emptyMap(); } private DocFormCommand getDocFormCommand() { if (getContext().get(_DOC_FORM_COMMAND_OBJECT) == null) { getContext().put(_DOC_FORM_COMMAND_OBJECT, new DocFormCommand()); } return (DocFormCommand) getContext().get(_DOC_FORM_COMMAND_OBJECT); } Map<String, Set<DocumentReference>> checkRightsAndSaveXWikiDocCollection( Collection<XWikiDocument> xdocs) throws XWikiException { boolean hasEditOnAllDocs = hasEditOnAllDocs(xdocs); Map<String, Set<DocumentReference>> docs; if (hasEditOnAllDocs) { docs = getDocFormCommand().saveXWikiDocCollection(xdocs); } else { Set<DocumentReference> saveFailed = new HashSet<DocumentReference>(); for (XWikiDocument xdoc : xdocs) { saveFailed.add(xdoc.getDocumentReference()); } docs = new HashMap<String, Set<DocumentReference>>(); docs.put("successful", new HashSet<DocumentReference>()); docs.put("failed", saveFailed); } return docs; } boolean hasEditOnAllDocs(Collection<XWikiDocument> xdocs) throws XWikiException { boolean hasEditOnAllDocs = true; for (XWikiDocument xdoc : xdocs) { if (getDocFormCommand().notNewOrCreateAllowed(xdoc)) { hasEditOnAllDocs &= getContext().getWiki().getRightService().hasAccessLevel("edit", getContext().getUser(), webUtilsService.serializeRef(xdoc.getDocumentReference()), getContext()); } } return hasEditOnAllDocs; } }