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