1   /**
2    * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.webdav.methods;
24  
25  import com.liferay.lock.model.Lock;
26  import com.liferay.portal.kernel.util.ContentTypes;
27  import com.liferay.portal.kernel.util.FileUtil;
28  import com.liferay.portal.kernel.util.GetterUtil;
29  import com.liferay.portal.kernel.util.Time;
30  import com.liferay.portal.kernel.util.Validator;
31  import com.liferay.portal.webdav.WebDAVException;
32  import com.liferay.portal.webdav.WebDAVRequest;
33  import com.liferay.portal.webdav.WebDAVStorage;
34  import com.liferay.portal.webdav.WebDAVUtil;
35  import com.liferay.util.servlet.ServletResponseUtil;
36  import com.liferay.util.xml.XMLFormatter;
37  
38  import java.io.StringReader;
39  
40  import java.util.List;
41  
42  import javax.servlet.http.HttpServletRequest;
43  import javax.servlet.http.HttpServletResponse;
44  
45  import org.apache.commons.logging.Log;
46  import org.apache.commons.logging.LogFactory;
47  
48  import org.dom4j.Document;
49  import org.dom4j.Element;
50  import org.dom4j.io.SAXReader;
51  
52  /**
53   * <a href="LockMethodImpl.java.html"><b><i>View Source</i></b></a>
54   *
55   * @author Alexander Chow
56   *
57   */
58  public class LockMethodImpl implements Method {
59  
60      public int process(WebDAVRequest webDavRequest) throws WebDAVException {
61          try {
62              return doProcess(webDavRequest);
63          }
64          catch (Exception e) {
65              throw new WebDAVException(e);
66          }
67      }
68  
69      protected int doProcess(WebDAVRequest webDavRequest) throws Exception {
70          WebDAVStorage storage = webDavRequest.getWebDAVStorage();
71  
72          if (!storage.isSupportsClassTwo()) {
73              return HttpServletResponse.SC_METHOD_NOT_ALLOWED;
74          }
75  
76          int statusCode = HttpServletResponse.SC_PRECONDITION_FAILED;
77  
78          HttpServletRequest request = webDavRequest.getHttpServletRequest();
79          HttpServletResponse response = webDavRequest.getHttpServletResponse();
80  
81          Lock lock = null;
82  
83          String lockUuid = webDavRequest.getLockUuid();
84          long timeout = WebDAVUtil.getTimeout(request);
85  
86          if (Validator.isNull(lockUuid)) {
87              String owner = null;
88  
89              String xml = new String(
90                  FileUtil.getBytes(request.getInputStream()));
91  
92              if (Validator.isNull(xml)) {
93                  _log.error("Empty request XML");
94  
95                  return statusCode;
96              }
97              else {
98                  if (_log.isDebugEnabled()) {
99                      _log.debug(
100                         "Request XML\n" + XMLFormatter.toString(xml));
101                 }
102 
103                 SAXReader reader = new SAXReader();
104 
105                 Document doc = reader.read(new StringReader(xml));
106 
107                 Element root = doc.getRootElement();
108 
109                 boolean exclusive = false;
110 
111                 List<Element> lockscopeEls = root.element(
112                     "lockscope").elements();
113 
114                 for (Element scopeEl : lockscopeEls) {
115                     String name = GetterUtil.getString(scopeEl.getName());
116 
117                     if (name.equals("exclusive")) {
118                         exclusive = true;
119                     }
120                 }
121 
122                 if (!exclusive) {
123                     return HttpServletResponse.SC_BAD_REQUEST;
124                 }
125 
126                 Element ownerEl = root.element("owner");
127 
128                 owner = ownerEl.getTextTrim();
129 
130                 if (Validator.isNull(owner)) {
131                     List<Element> childEls = ownerEl.elements("href");
132 
133                     for (Element childEl : childEls) {
134                         owner =
135                             "<D:href>" + childEl.getTextTrim() + "</D:href>";
136                     }
137                 }
138             }
139 
140             lock = storage.lockResource(webDavRequest, owner, timeout);
141         }
142         else {
143             lock = storage.refreshResourceLock(
144                 webDavRequest, lockUuid, timeout);
145         }
146 
147         if (lock == null) {
148             return WebDAVUtil.SC_LOCKED;
149         }
150 
151         long depth = WebDAVUtil.getDepth(request);
152 
153         String xml = getResponseXML(lock, depth);
154 
155         if (_log.isDebugEnabled()) {
156             _log.debug("Response XML\n" + xml);
157         }
158 
159         response.setContentType(ContentTypes.TEXT_XML_UTF8);
160         response.setStatus(HttpServletResponse.SC_OK);
161 
162         response.setHeader(
163             "Lock-Token", "<" + WebDAVUtil.TOKEN_PREFIX + lock.getUuid() + ">");
164 
165         try {
166             ServletResponseUtil.write(response, xml);
167         }
168         catch (Exception e) {
169             if (_log.isWarnEnabled()) {
170                 _log.warn(e);
171             }
172         }
173 
174         return -1;
175     }
176 
177     protected String getResponseXML(Lock lock, long depth) throws Exception {
178         StringBuilder sb = new StringBuilder();
179 
180         long timeoutSecs = lock.getExpirationTime() / Time.SECOND;
181 
182         sb.append("<?xml version=\"1.0\" encoding=\"utf-8\" ?>");
183         sb.append("<D:prop xmlns:D=\"DAV:\">");
184         sb.append("<D:lockdiscovery>");
185         sb.append("<D:activelock>");
186         sb.append("<D:locktype><D:write/></D:locktype>");
187         sb.append("<D:lockscope><D:exclusive/></D:lockscope>");
188 
189         if (depth < 0) {
190             sb.append("<D:depth>Infinity</D:depth>");
191         }
192 
193         sb.append("<D:owner>" + lock.getOwner() + "</D:owner>");
194         sb.append("<D:timeout>Second-" + timeoutSecs + "</D:timeout>");
195         sb.append(
196             "<D:locktoken><D:href>" + WebDAVUtil.TOKEN_PREFIX + lock.getUuid() +
197             "</D:href></D:locktoken>");
198         sb.append("</D:activelock>");
199         sb.append("</D:lockdiscovery>");
200         sb.append("</D:prop>");
201 
202         return XMLFormatter.toString(sb.toString());
203     }
204 
205     private static Log _log = LogFactory.getLog(LockMethodImpl.class);
206 
207 }