1
14
15 package com.liferay.portal.webdav.methods;
16
17 import com.liferay.portal.NoSuchLockException;
18 import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
19 import com.liferay.portal.kernel.log.Log;
20 import com.liferay.portal.kernel.log.LogFactoryUtil;
21 import com.liferay.portal.kernel.util.ContentTypes;
22 import com.liferay.portal.kernel.util.FileUtil;
23 import com.liferay.portal.kernel.util.GetterUtil;
24 import com.liferay.portal.kernel.util.StringBundler;
25 import com.liferay.portal.kernel.util.Time;
26 import com.liferay.portal.kernel.util.Validator;
27 import com.liferay.portal.model.Lock;
28 import com.liferay.portal.webdav.Status;
29 import com.liferay.portal.webdav.WebDAVException;
30 import com.liferay.portal.webdav.WebDAVRequest;
31 import com.liferay.portal.webdav.WebDAVStorage;
32 import com.liferay.portal.webdav.WebDAVUtil;
33 import com.liferay.util.servlet.ServletResponseUtil;
34 import com.liferay.util.xml.XMLFormatter;
35
36 import java.util.List;
37
38 import javax.servlet.http.HttpServletRequest;
39 import javax.servlet.http.HttpServletResponse;
40
41 import org.dom4j.Document;
42 import org.dom4j.Element;
43 import org.dom4j.io.SAXReader;
44
45
50 public class LockMethodImpl implements Method {
51
52 public int process(WebDAVRequest webDavRequest) throws WebDAVException {
53 try {
54 return doProcess(webDavRequest);
55 }
56 catch (Exception e) {
57 throw new WebDAVException(e);
58 }
59 }
60
61 protected int doProcess(WebDAVRequest webDavRequest) throws Exception {
62 WebDAVStorage storage = webDavRequest.getWebDAVStorage();
63
64 if (!storage.isSupportsClassTwo()) {
65 return HttpServletResponse.SC_METHOD_NOT_ALLOWED;
66 }
67
68 HttpServletRequest request = webDavRequest.getHttpServletRequest();
69 HttpServletResponse response = webDavRequest.getHttpServletResponse();
70
71 Lock lock = null;
72 Status status = null;
73
74 String lockUuid = webDavRequest.getLockUuid();
75 long timeout = WebDAVUtil.getTimeout(request);
76
77 if (Validator.isNull(lockUuid)) {
78
79
81 String owner = null;
82 String xml = new String(
83 FileUtil.getBytes(request.getInputStream()));
84
85 if (Validator.isNotNull(xml)) {
86 if (_log.isDebugEnabled()) {
87 _log.debug(
88 "Request XML\n" + XMLFormatter.toString(xml));
89 }
90
91 SAXReader reader = new SAXReader();
92
93 Document doc = reader.read(new UnsyncStringReader(xml));
94
95 Element root = doc.getRootElement();
96
97 boolean exclusive = false;
98
99 List<Element> lockscopeEls = root.element(
100 "lockscope").elements();
101
102 for (Element scopeEl : lockscopeEls) {
103 String name = GetterUtil.getString(scopeEl.getName());
104
105 if (name.equals("exclusive")) {
106 exclusive = true;
107 }
108 }
109
110 if (!exclusive) {
111 return HttpServletResponse.SC_BAD_REQUEST;
112 }
113
114 Element ownerEl = root.element("owner");
115
116 owner = ownerEl.getTextTrim();
117
118 if (Validator.isNull(owner)) {
119 List<Element> childEls = ownerEl.elements("href");
120
121 for (Element childEl : childEls) {
122 owner =
123 "<D:href>" + childEl.getTextTrim() + "</D:href>";
124 }
125 }
126 }
127 else {
128 _log.error("Empty request XML");
129
130 return HttpServletResponse.SC_PRECONDITION_FAILED;
131 }
132
133 status = storage.lockResource(webDavRequest, owner, timeout);
134
135 lock = (Lock)status.getObject();
136 }
137 else {
138 try {
139
141 lock = storage.refreshResourceLock(
142 webDavRequest, lockUuid, timeout);
143
144 status = new Status(HttpServletResponse.SC_OK);
145 }
146 catch (WebDAVException wde) {
147 if (wde.getCause() instanceof NoSuchLockException) {
148 return HttpServletResponse.SC_PRECONDITION_FAILED;
149 }
150 else {
151 throw wde;
152 }
153 }
154 }
155
156
158 if (lock == null) {
159 return status.getCode();
160 }
161
162 long depth = WebDAVUtil.getDepth(request);
163
164 String xml = getResponseXML(lock, depth);
165
166 if (_log.isDebugEnabled()) {
167 _log.debug("Response XML\n" + xml);
168 }
169
170 String lockToken = "<" + WebDAVUtil.TOKEN_PREFIX + lock.getUuid() + ">";
171
172 response.setContentType(ContentTypes.TEXT_XML_UTF8);
173 response.setHeader("Lock-Token", lockToken);
174 response.setStatus(status.getCode());
175
176 if (_log.isDebugEnabled()) {
177 _log.debug("Returning lock token " + lockToken);
178 }
179
180 try {
181 ServletResponseUtil.write(response, xml);
182 }
183 catch (Exception e) {
184 if (_log.isWarnEnabled()) {
185 _log.warn(e);
186 }
187 }
188
189 return status.getCode();
190 }
191
192 protected String getResponseXML(Lock lock, long depth) throws Exception {
193 StringBundler sb = new StringBundler(20);
194
195 long timeoutSecs = lock.getExpirationTime() / Time.SECOND;
196
197 sb.append("<?xml version=\"1.0\" encoding=\"utf-8\" ?>");
198 sb.append("<D:prop xmlns:D=\"DAV:\">");
199 sb.append("<D:lockdiscovery>");
200 sb.append("<D:activelock>");
201 sb.append("<D:locktype><D:write/></D:locktype>");
202 sb.append("<D:lockscope><D:exclusive/></D:lockscope>");
203
204 if (depth < 0) {
205 sb.append("<D:depth>Infinity</D:depth>");
206 }
207
208 sb.append("<D:owner>");
209 sb.append(lock.getOwner());
210 sb.append("</D:owner>");
211 sb.append("<D:timeout>Second-");
212 sb.append(timeoutSecs);
213 sb.append("</D:timeout>");
214 sb.append("<D:locktoken><D:href>");
215 sb.append(WebDAVUtil.TOKEN_PREFIX);
216 sb.append(lock.getUuid());
217 sb.append("</D:href></D:locktoken>");
218 sb.append("</D:activelock>");
219 sb.append("</D:lockdiscovery>");
220 sb.append("</D:prop>");
221
222 return XMLFormatter.toString(sb.toString());
223 }
224
225 private static Log _log = LogFactoryUtil.getLog(LockMethodImpl.class);
226
227 }