001
014
015 package com.liferay.portal.webdav.methods;
016
017 import com.liferay.portal.NoSuchLockException;
018 import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
019 import com.liferay.portal.kernel.log.Log;
020 import com.liferay.portal.kernel.log.LogFactoryUtil;
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.model.Lock;
033 import com.liferay.util.servlet.ServletResponseUtil;
034 import com.liferay.util.xml.XMLFormatter;
035
036 import java.util.List;
037
038 import javax.servlet.http.HttpServletRequest;
039 import javax.servlet.http.HttpServletResponse;
040
041 import org.dom4j.Document;
042 import org.dom4j.Element;
043 import org.dom4j.io.SAXReader;
044
045
048 public class LockMethodImpl implements Method {
049
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(
086 "Request XML\n" + XMLFormatter.toString(xml));
087 }
088
089 SAXReader reader = new SAXReader();
090
091 Document doc = reader.read(new UnsyncStringReader(xml));
092
093 Element root = doc.getRootElement();
094
095 boolean exclusive = false;
096
097 List<Element> lockscopeEls = root.element(
098 "lockscope").elements();
099
100 for (Element scopeEl : lockscopeEls) {
101 String name = GetterUtil.getString(scopeEl.getName());
102
103 if (name.equals("exclusive")) {
104 exclusive = true;
105 }
106 }
107
108 if (!exclusive) {
109 return HttpServletResponse.SC_BAD_REQUEST;
110 }
111
112 Element ownerEl = root.element("owner");
113
114 owner = ownerEl.getTextTrim();
115
116 if (Validator.isNull(owner)) {
117 List<Element> childEls = ownerEl.elements("href");
118
119 for (Element childEl : childEls) {
120 owner =
121 "<D:href>" + childEl.getTextTrim() + "</D:href>";
122 }
123 }
124 }
125 else {
126 _log.error("Empty request XML");
127
128 return HttpServletResponse.SC_PRECONDITION_FAILED;
129 }
130
131 status = storage.lockResource(webDavRequest, owner, timeout);
132
133 lock = (Lock)status.getObject();
134 }
135 else {
136 try {
137
138
139 lock = storage.refreshResourceLock(
140 webDavRequest, lockUuid, timeout);
141
142 status = new Status(HttpServletResponse.SC_OK);
143 }
144 catch (WebDAVException wde) {
145 if (wde.getCause() instanceof NoSuchLockException) {
146 return HttpServletResponse.SC_PRECONDITION_FAILED;
147 }
148 else {
149 throw wde;
150 }
151 }
152 }
153
154
155
156 if (lock == null) {
157 return status.getCode();
158 }
159
160 long depth = WebDAVUtil.getDepth(request);
161
162 String xml = getResponseXML(lock, depth);
163
164 if (_log.isDebugEnabled()) {
165 _log.debug("Response XML\n" + xml);
166 }
167
168 String lockToken = "<" + WebDAVUtil.TOKEN_PREFIX + lock.getUuid() + ">";
169
170 response.setContentType(ContentTypes.TEXT_XML_UTF8);
171 response.setHeader("Lock-Token", lockToken);
172 response.setStatus(status.getCode());
173
174 if (_log.isDebugEnabled()) {
175 _log.debug("Returning lock token " + lockToken);
176 }
177
178 try {
179 ServletResponseUtil.write(response, xml);
180 }
181 catch (Exception e) {
182 if (_log.isWarnEnabled()) {
183 _log.warn(e);
184 }
185 }
186
187 return status.getCode();
188 }
189
190 protected String getResponseXML(Lock lock, long depth) throws Exception {
191 StringBundler sb = new StringBundler(20);
192
193 long timeoutSecs = lock.getExpirationTime() / Time.SECOND;
194
195 sb.append("<?xml version=\"1.0\" encoding=\"utf-8\" ?>");
196 sb.append("<D:prop xmlns:D=\"DAV:\">");
197 sb.append("<D:lockdiscovery>");
198 sb.append("<D:activelock>");
199 sb.append("<D:locktype><D:write/></D:locktype>");
200 sb.append("<D:lockscope><D:exclusive/></D:lockscope>");
201
202 if (depth < 0) {
203 sb.append("<D:depth>Infinity</D:depth>");
204 }
205
206 sb.append("<D:owner>");
207 sb.append(lock.getOwner());
208 sb.append("</D:owner>");
209 sb.append("<D:timeout>Second-");
210 sb.append(timeoutSecs);
211 sb.append("</D:timeout>");
212 sb.append("<D:locktoken><D:href>");
213 sb.append(WebDAVUtil.TOKEN_PREFIX);
214 sb.append(lock.getUuid());
215 sb.append("</D:href></D:locktoken>");
216 sb.append("</D:activelock>");
217 sb.append("</D:lockdiscovery>");
218 sb.append("</D:prop>");
219
220 return XMLFormatter.toString(sb.toString());
221 }
222
223 private static Log _log = LogFactoryUtil.getLog(LockMethodImpl.class);
224
225 }