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