package com.psddev.cms.tool.page; import java.io.IOException; import java.util.Date; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import com.google.common.collect.ImmutableMap; import com.psddev.cms.tool.SearchResultSelectionItem; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.collect.ImmutableList; import com.psddev.cms.tool.CmsTool; import com.psddev.cms.tool.PageServlet; import com.psddev.cms.tool.Search; import com.psddev.cms.tool.ToolPageContext; import com.psddev.dari.db.ObjectField; import com.psddev.dari.db.ObjectType; import com.psddev.dari.db.Query; import com.psddev.dari.db.State; import com.psddev.dari.util.CompactMap; import com.psddev.dari.util.JspUtils; import com.psddev.dari.util.ObjectUtils; import com.psddev.dari.util.RoutingFilter; @RoutingFilter.Path(application = "cms", value = "contentEditBulk") public class ContentEditBulk extends PageServlet { private static final long serialVersionUID = 1L; private static final Logger LOGGER = LoggerFactory.getLogger(ContentEditBulk.class); public static final List<Operation> COLLECTION_OPERATIONS = ImmutableList.of(Operation.REPLACE, Operation.ADD, Operation.REMOVE, Operation.CLEAR); public static final List<Operation> NON_COLLECTION_OPERATIONS = ImmutableList.of(Operation.REPLACE, Operation.CLEAR); public static final String OPERATION_PARAMETER_PREFIX = "contentEditBulk.op/"; @Override protected String getPermissionId() { return null; } @Override @SuppressWarnings("unchecked") protected void doService(ToolPageContext page) throws IOException, ServletException { List<UUID> ids = page.params(UUID.class, ContentSearchAdvanced.ITEMS_PARAMETER); UUID selectionId = page.param(UUID.class, "selectionId"); Query<?> query; if (selectionId != null) { Set<UUID> itemIds = new HashSet<>(); for (SearchResultSelectionItem item : Query .from(SearchResultSelectionItem.class) .where("selectionId = ?", selectionId) .selectAll()) { itemIds.add(item.getItemId()); } query = Query.fromAll().where("_id = ?", itemIds); } else if (ids.isEmpty()) { String searchString = page.param(String.class, "search"); Search search; if (searchString != null) { search = new Search(); search.getState().putAll((Map<String, Object>) ObjectUtils.fromJson(searchString)); } else { search = new Search(page); } query = search.toQuery(page.getSite()); } else { query = Query.fromAll().where("_id = ?", ids); } long count = query.count(); ObjectType type = ObjectType.getInstance(page.param(UUID.class, "typeId")); State state = State.getInstance(type.createObject(page.param(UUID.class, "id"))); state.clear(); Exception error = null; if (page.isFormPost() && page.param(String.class, "action-save") != null) { try { JspUtils.include( page.getRequest(), page.getResponse(), page, page.toolPath(CmsTool.class, "/WEB-INF/objectPost.jsp"), "object", state.getOriginalObject()); Map<String, Object> values = state.getValues(); Map<String, Object> replaces = new CompactMap<>(); Map<String, Object> adds = new CompactMap<>(); Map<String, Object> removes = new CompactMap<>(); Set<String> clears = new LinkedHashSet<>(); for (ObjectField field : type.getFields()) { String name = field.getInternalName(); Object value = values.get(name); Operation op = page.param(Operation.class, OPERATION_PARAMETER_PREFIX + name); if (op != null) { if (Operation.REPLACE.equals(op)) { replaces.put(name, value); } else if (Operation.ADD.equals(op)) { adds.put(name, value); } else if (Operation.REMOVE.equals(op)) { removes.put(name, value); } else if (Operation.CLEAR.equals(op)) { clears.add(name); } } } ContentEditBulkSubmission status = new ContentEditBulkSubmission(); status.setSubmitSite(page.getSite()); status.setSubmitUser(page.getUser()); status.setSubmitDate(new Date()); status.setQuery(query); status.setCount(count); status.setReplaces(replaces); status.setAdds(adds); status.setRemoves(removes); status.setClears(clears); status.submitTask(); page.getResponse().sendRedirect(page.cmsUrl( "/contentEditBulkSubmissionStatus", "id", status.getId(), "returnUrl", page.param(String.class, "returnUrl"))); return; } catch (Exception e) { error = e; } } page.writeHeader(); page.writeStart("div", "class", "widget content-edit-bulk"); page.writeStart("h1"); page.writeHtml(page.localize( ContentEditBulk.class, ImmutableMap.of("count", count), "title")); page.writeEnd(); page.writeObject(error); String formId = page.createId(); page.writeStart("form", "id", formId, "method", "post", "action", page.url(null, "id", state.getId())); for (String paramName : page.paramNamesList()) { if ("id".equals(paramName) || paramName.startsWith(OPERATION_PARAMETER_PREFIX) || paramName.startsWith(state.getId() + "/") || paramName.startsWith("action-")) { continue; } for (String value : page.params(String.class, paramName)) { page.writeElement("input", "type", "hidden", "name", paramName, "value", value); } } HttpServletRequest request = page.getRequest(); Object oldId = request.getAttribute("bsp.contentEditBulk.id"); try { request.setAttribute("bsp.contentEditBulk.id", state.getId()); JspUtils.include( request, page.getResponse(), page, page.toolPath(CmsTool.class, "/WEB-INF/objectForm.jsp"), "object", state.getOriginalObject()); } finally { request.setAttribute("bsp.contentEditBulk.id", oldId); } page.writeStart("div", "class", "actions"); page.writeStart("button", "class", "action icon icon-action-save", "name", "action-save", "value", "true"); page.writeHtml(page.localize(ContentEditBulk.class, "action.bulkSave")); page.writeEnd(); page.writeEnd(); page.writeEnd(); page.writeEnd(); page.writeFooter(); } public enum Operation { REPLACE("Replace"), ADD("Add"), REMOVE("Remove"), CLEAR("Clear"); private final String label; private Operation(String label) { this.label = label; } @Override public String toString() { return label; } } }