BinaryValueServlet.java
9.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
/*
* Decompiled with CFR 0_118.
*
* Could not load the following classes:
* javax.jcr.AccessDeniedException
* javax.servlet.ServletException
* javax.servlet.http.HttpServletResponse
* org.apache.felix.scr.annotations.Component
* org.apache.felix.scr.annotations.Properties
* org.apache.felix.scr.annotations.Property
* org.apache.felix.scr.annotations.Reference
* org.apache.felix.scr.annotations.Service
* org.apache.sling.api.SlingHttpServletRequest
* org.apache.sling.api.SlingHttpServletResponse
* org.apache.sling.api.resource.Resource
* org.apache.sling.api.resource.ResourceResolver
* org.apache.sling.api.servlets.HtmlResponse
* org.apache.sling.api.servlets.SlingAllMethodsServlet
* org.slf4j.Logger
* org.slf4j.LoggerFactory
*/
package com.day.cq.wcm.undo.impl;
import com.day.cq.wcm.undo.BinaryHandlingException;
import com.day.cq.wcm.undo.BinaryValueManager;
import java.io.IOException;
import javax.jcr.AccessDeniedException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.servlets.HtmlResponse;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Component(metatype=0)
@Service
@Properties(value={@Property(name="sling.servlet.paths", value={"/libs/wcm/undo/bvm"}), @Property(name="sling.servlet.methods", value={"POST"})})
public class BinaryValueServlet
extends SlingAllMethodsServlet {
private static final String PRM_OPERATION = "operation";
private static final String PRM_PARAGRAPH = "par";
private static final String PRM_SRC_PATH = "srcPath";
private static final String PRM_TARGET_PATH = "targetPath";
private static final String PRM_GLOBAL = "global";
private static final String PRM_ORIGINAL_REF = "originalBlob";
private static final String PRM_DELETE_PATHS = "deletePaths";
private static final String PRMVAL_SAVE = "save";
private static final String PRMVAL_RESTORE = "restore";
private static final String PRMVAL_DELETE = "delete";
private static final String PRMVAL_TRUE = "true";
@Reference
private BinaryValueManager binaryValueManager;
private static final Logger log = LoggerFactory.getLogger(BinaryValueServlet.class);
protected void doPost(SlingHttpServletRequest req, SlingHttpServletResponse resp) throws ServletException, IOException {
String op = req.getParameter("operation");
if (op == null) {
throw new ServletException("Missing operation.");
}
if (!("save".equals(op) || "restore".equals(op) || "delete".equals(op))) {
throw new ServletException("Invalid operation: " + op);
}
String parPath = req.getParameter("par");
if (parPath == null && !"delete".equals(op)) {
throw new ServletException("Missing paragraph.");
}
String srcPath = req.getParameter("srcPath");
if (srcPath == null && !"delete".equals(op)) {
throw new ServletException("Missing source path.");
}
if (srcPath != null && srcPath.length() == 0) {
srcPath = null;
}
if (srcPath == null && "save".equals(op)) {
throw new ServletException("Invalid source path for save operation.");
}
String targetPath = null;
boolean isGlobalRestore = false;
if ("restore".equals(op)) {
targetPath = req.getParameter("targetPath");
if (targetPath == null) {
throw new ServletException("Missing target path for restore operation.");
}
String globalParam = req.getParameter("global");
if (globalParam != null) {
isGlobalRestore = globalParam.equals("true");
}
}
String originalRef = req.getParameter("originalBlob");
String[] deletePaths = req.getParameterValues("deletePaths");
if ("delete".equals(op) && (deletePaths == null || deletePaths.length == 0)) {
throw new ServletException("Missing paths for delete operation.");
}
ResourceResolver resolver = req.getResource().getResourceResolver();
Resource par = parPath != null ? resolver.getResource(parPath) : null;
String path = "";
HtmlResponse htmlPage = new HtmlResponse();
try {
if ("save".equals(op)) {
boolean isSaveable = true;
if (originalRef != null) {
isSaveable = this.binaryValueManager.isChanged(par, srcPath, originalRef);
}
if (isSaveable) {
String id = this.binaryValueManager.save(par, srcPath);
path = parPath;
if (id != null) {
htmlPage.setTitle("Binary undo value saved.");
htmlPage.setPath(id);
htmlPage.onCreated(id);
htmlPage.setCreateRequest(true);
} else {
htmlPage.setTitle("Skipped removed binary undo value.");
htmlPage.setPath("");
htmlPage.onDeleted("");
htmlPage.setCreateRequest(false);
}
} else {
log.debug("Binary at '{}/{}' has not been changed, removing original data", (Object)par.getPath(), (Object)srcPath);
this.binaryValueManager.delete(resolver, originalRef);
htmlPage.setTitle("Binary undo value remains unchanged.");
htmlPage.setPath(originalRef);
htmlPage.onDeleted(originalRef);
htmlPage.setCreateRequest(false);
}
} else if ("restore".equals(op)) {
path = targetPath;
htmlPage.setPath("");
if (srcPath != null) {
Resource undoData = resolver.getResource(srcPath);
this.binaryValueManager.restore(undoData, par, targetPath);
htmlPage.onModified(targetPath);
htmlPage.setTitle("Binary undo value restored.");
htmlPage.setPath("");
htmlPage.setCreateRequest(false);
} else {
this.binaryValueManager.delete(par, targetPath, !isGlobalRestore);
htmlPage.onDeleted(targetPath);
htmlPage.setTitle("Binary undo value removed.");
htmlPage.setPath("");
htmlPage.setCreateRequest(false);
}
} else if ("delete".equals(op)) {
for (String pathToDelete : deletePaths) {
this.binaryValueManager.delete(resolver, pathToDelete);
htmlPage.onDeleted(pathToDelete);
}
htmlPage.setTitle("Binary undo values removed.");
htmlPage.setPath("");
htmlPage.setCreateRequest(false);
}
htmlPage.setLocation(path);
int pathSepPos = path.lastIndexOf("/");
String parentLoc = pathSepPos >= 0 ? path.substring(0, pathSepPos) : "";
htmlPage.setParentLocation(parentLoc);
}
catch (BinaryHandlingException bhe) {
if (par == null && parPath != null) {
log.info("Could not retrieve paragraph '{}'. It may have been deleted due to a concurrent (delete or move) operation.", (Object)parPath);
} else if (bhe.getCause() instanceof AccessDeniedException) {
log.info("Cannot save binary data for undo. Please ensure that all users that are eligible for undo have write permissions on the directory that is configured for saving undo data. Note that improper configuration may impose a security risk.");
} else {
log.error("Could not execute binary value operation: " + op, (Throwable)bhe);
}
htmlPage.setTitle("save".equals(op) ? "Could not save undo data." : "Could not restore undo data.");
htmlPage.setError((Throwable)bhe);
}
catch (Exception e) {
htmlPage.setTitle("Internal error.");
htmlPage.setError((Throwable)e);
log.error("Internal error while executing operation '" + op + "'", (Throwable)e);
}
htmlPage.send((HttpServletResponse)resp, true);
}
protected void bindBinaryValueManager(BinaryValueManager binaryValueManager) {
this.binaryValueManager = binaryValueManager;
}
protected void unbindBinaryValueManager(BinaryValueManager binaryValueManager) {
if (this.binaryValueManager == binaryValueManager) {
this.binaryValueManager = null;
}
}
}