001
014
015 package com.liferay.portal.webdav.methods;
016
017 import com.liferay.portal.NoSuchLockException;
018 import com.liferay.portal.kernel.log.Log;
019 import com.liferay.portal.kernel.log.LogFactoryUtil;
020 import com.liferay.portal.kernel.servlet.ServletResponseUtil;
021 import com.liferay.portal.kernel.util.ContentTypes;
022 import com.liferay.portal.kernel.util.FileUtil;
023 import com.liferay.portal.kernel.util.GetterUtil;
024 import com.liferay.portal.kernel.util.StringBundler;
025 import com.liferay.portal.kernel.util.Time;
026 import com.liferay.portal.kernel.util.Validator;
027 import com.liferay.portal.kernel.webdav.Status;
028 import com.liferay.portal.kernel.webdav.WebDAVException;
029 import com.liferay.portal.kernel.webdav.WebDAVRequest;
030 import com.liferay.portal.kernel.webdav.WebDAVStorage;
031 import com.liferay.portal.kernel.webdav.WebDAVUtil;
032 import com.liferay.portal.kernel.xml.Document;
033 import com.liferay.portal.kernel.xml.Element;
034 import com.liferay.portal.kernel.xml.SAXReaderUtil;
035 import com.liferay.portal.model.Lock;
036 import com.liferay.util.xml.XMLFormatter;
037
038 import java.util.List;
039
040 import javax.servlet.http.HttpServletRequest;
041 import javax.servlet.http.HttpServletResponse;
042
043
046 public class LockMethodImpl implements Method {
047
048 @Override
049 public int process(WebDAVRequest webDavRequest) throws WebDAVException {
050 try {
051 return doProcess(webDavRequest);
052 }
053 catch (Exception e) {
054 throw new WebDAVException(e);
055 }
056 }
057
058 protected int doProcess(WebDAVRequest webDavRequest) throws Exception {
059 WebDAVStorage storage = webDavRequest.getWebDAVStorage();
060
061 if (!storage.isSupportsClassTwo()) {
062 return HttpServletResponse.SC_METHOD_NOT_ALLOWED;
063 }
064
065 HttpServletRequest request = webDavRequest.getHttpServletRequest();
066 HttpServletResponse response = webDavRequest.getHttpServletResponse();
067
068 Lock lock = null;
069 Status status = null;
070
071 String lockUuid = webDavRequest.getLockUuid();
072 long timeout = WebDAVUtil.getTimeout(request);
073
074 if (Validator.isNull(lockUuid)) {
075
076
077
078 String owner = null;
079 String xml = new String(
080 FileUtil.getBytes(request.getInputStream()));
081
082 if (Validator.isNotNull(xml)) {
083 if (_log.isDebugEnabled()) {
084 _log.debug("Request XML\n" + XMLFormatter.toString(xml));
085 }
086
087 Document document = SAXReaderUtil.read(xml);
088
089 Element rootElement = document.getRootElement();
090
091 boolean exclusive = false;
092
093 Element lockscopeElement = rootElement.element("lockscope");
094
095 for (Element element : lockscopeElement.elements()) {
096 String name = GetterUtil.getString(element.getName());
097
098 if (name.equals("exclusive")) {
099 exclusive = true;
100 }
101 }
102
103 if (!exclusive) {
104 return HttpServletResponse.SC_BAD_REQUEST;
105 }
106
107 Element ownerElement = rootElement.element("owner");
108
109 owner = ownerElement.getTextTrim();
110
111 if (Validator.isNull(owner)) {
112 List<Element> hrefElements = ownerElement.elements("href");
113
114 for (Element hrefElement : hrefElements) {
115 owner =
116 "<D:href>" + hrefElement.getTextTrim() +
117 "</D:href>";
118 }
119 }
120 }
121 else {
122 _log.error("Empty request XML");
123
124 return HttpServletResponse.SC_PRECONDITION_FAILED;
125 }
126
127 status = storage.lockResource(webDavRequest, owner, timeout);
128
129 lock = (Lock)status.getObject();
130 }
131 else {
132 try {
133
134
135
136 lock = storage.refreshResourceLock(
137 webDavRequest, lockUuid, timeout);
138
139 status = new Status(HttpServletResponse.SC_OK);
140 }
141 catch (WebDAVException wde) {
142 if (wde.getCause() instanceof NoSuchLockException) {
143 return HttpServletResponse.SC_PRECONDITION_FAILED;
144 }
145 else {
146 throw wde;
147 }
148 }
149 }
150
151
152
153 if (lock == null) {
154 return status.getCode();
155 }
156
157 long depth = WebDAVUtil.getDepth(request);
158
159 String xml = getResponseXML(lock, depth);
160
161 if (_log.isDebugEnabled()) {
162 _log.debug("Response XML\n" + xml);
163 }
164
165 String lockToken = "<" + WebDAVUtil.TOKEN_PREFIX + lock.getUuid() + ">";
166
167 response.setContentType(ContentTypes.TEXT_XML_UTF8);
168 response.setHeader("Lock-Token", lockToken);
169 response.setStatus(status.getCode());
170
171 if (_log.isDebugEnabled()) {
172 _log.debug("Returning lock token " + lockToken);
173 }
174
175 try {
176 ServletResponseUtil.write(response, xml);
177 }
178 catch (Exception e) {
179 if (_log.isWarnEnabled()) {
180 _log.warn(e);
181 }
182 }
183
184 return status.getCode();
185 }
186
187 protected String getResponseXML(Lock lock, long depth) throws Exception {
188 StringBundler sb = new StringBundler(20);
189
190 long timeoutSecs = lock.getExpirationTime() / Time.SECOND;
191
192 sb.append("<?xml version=\"1.0\" encoding=\"utf-8\" ?>");
193 sb.append("<D:prop xmlns:D=\"DAV:\">");
194 sb.append("<D:lockdiscovery>");
195 sb.append("<D:activelock>");
196 sb.append("<D:locktype><D:write/></D:locktype>");
197 sb.append("<D:lockscope><D:exclusive/></D:lockscope>");
198
199 if (depth < 0) {
200 sb.append("<D:depth>Infinity</D:depth>");
201 }
202
203 sb.append("<D:owner>");
204 sb.append(lock.getOwner());
205 sb.append("</D:owner>");
206 sb.append("<D:timeout>");
207
208 if (timeoutSecs > 0) {
209 sb.append("Second-" + timeoutSecs);
210 }
211 else {
212 sb.append("Infinite");
213 }
214
215 sb.append("</D:timeout>");
216 sb.append("<D:locktoken><D:href>");
217 sb.append(WebDAVUtil.TOKEN_PREFIX);
218 sb.append(lock.getUuid());
219 sb.append("</D:href></D:locktoken>");
220 sb.append("</D:activelock>");
221 sb.append("</D:lockdiscovery>");
222 sb.append("</D:prop>");
223
224 return XMLFormatter.toString(sb.toString());
225 }
226
227 private static Log _log = LogFactoryUtil.getLog(LockMethodImpl.class);
228
229 }