1
22
23 package com.liferay.portal.webdav.methods;
24
25 import com.liferay.portal.NoSuchGroupException;
26 import com.liferay.portal.kernel.util.GetterUtil;
27 import com.liferay.portal.kernel.util.StringPool;
28 import com.liferay.portal.kernel.util.Validator;
29 import com.liferay.portal.model.Group;
30 import com.liferay.portal.service.GroupLocalServiceUtil;
31 import com.liferay.portal.webdav.BaseResourceImpl;
32 import com.liferay.portal.webdav.Resource;
33 import com.liferay.portal.webdav.WebDAVException;
34 import com.liferay.portal.webdav.WebDAVRequest;
35 import com.liferay.portal.webdav.WebDAVStorage;
36 import com.liferay.portal.webdav.WebDAVUtil;
37 import com.liferay.util.servlet.ServletResponseUtil;
38 import com.liferay.util.xml.DocUtil;
39 import com.liferay.util.xml.XMLFormatter;
40
41 import java.io.StringReader;
42
43 import java.text.DateFormat;
44 import java.text.SimpleDateFormat;
45
46 import java.util.ArrayList;
47 import java.util.Iterator;
48 import java.util.List;
49 import java.util.Locale;
50
51 import javax.servlet.http.HttpServletRequest;
52 import javax.servlet.http.HttpServletResponse;
53
54 import org.apache.commons.logging.Log;
55 import org.apache.commons.logging.LogFactory;
56
57 import org.dom4j.Document;
58 import org.dom4j.DocumentFactory;
59 import org.dom4j.Element;
60 import org.dom4j.Namespace;
61 import org.dom4j.QName;
62 import org.dom4j.io.SAXReader;
63
64
70 public class PropfindMethodImpl implements Method {
71
72 public void process(WebDAVRequest webDavReq) throws WebDAVException {
73 try {
74 HttpServletResponse res = webDavReq.getHttpServletResponse();
75
76 String xml = getResponseXML(webDavReq);
77
78 res.setContentType("text/xml; charset=UTF-8");
79 res.setStatus(WebDAVUtil.SC_MULTI_STATUS);
80
81 try {
82 ServletResponseUtil.write(res, xml);
83 }
84 catch (Exception e) {
85 if (_log.isWarnEnabled()) {
86 _log.warn(e);
87 }
88 }
89 }
90 catch (Exception e) {
91 throw new WebDAVException(e);
92 }
93 }
94
95 protected void addResponse(
96 Resource resource, List props, Element multistatus,
97 DateFormat createDateFormat, DateFormat modifiedDateFormat)
98 throws Exception {
99
100 Element response = multistatus.addElement("D:response");
101
102 DocUtil.add(response, "D:href", resource.getHREF());
103
104 Element propstat = response.addElement("D:propstat");
105
106 Element prop = propstat.addElement("D:prop");
107
108 DocUtil.add(prop, "D:displayname", resource.getDisplayName());
109 DocUtil.add(
110 prop, "D:creationdate",
111 createDateFormat.format(resource.getCreateDate()));
112 DocUtil.add(
113 prop, "D:getlastmodified",
114 modifiedDateFormat.format(resource.getModifiedDate()));
115
116 if (resource.isFolder()) {
117 DocUtil.add(prop, "D:getcontenttype", "httpd/unix-directory");
118 }
119 else {
120 DocUtil.add(
121 prop, "D:getcontentlength", String.valueOf(resource.getSize()));
122 }
123
124 Element resourcetype = prop.addElement("D:resourcetype");
125
126 if (resource.isFolder()) {
127 resourcetype.addElement("D:collection");
128 }
129
130 if (props.size() == 0) {
131 DocUtil.add(prop, "D:getetag", "\"19504-0-a4075c30\"");
132
133 Element supportedlock = prop.addElement("D:supportedlock");
134
135 Element lockentry = supportedlock.addElement("D:lockentry");
136
137 Element lockscope = lockentry.addElement("D:lockscope");
138
139 lockscope.addElement("D:exclusive");
140
141 Element locktype = lockentry.addElement("D:locktype");
142
143 locktype.addElement("D:write");
144
145 lockentry = supportedlock.addElement("D:lockentry");
146
147 lockscope = lockentry.addElement("D:lockscope");
148
149 lockscope.addElement("D:shared");
150
151 locktype = lockentry.addElement("D:locktype");
152
153 locktype.addElement("D:write");
154
155 prop.addElement("D:lockdiscovery");
156 }
157
158 DocUtil.add(propstat, "D:status", "HTTP/1.1 200 OK");
159
160 if (props.size() > 0) {
161 propstat = response.addElement("D:propstat");
162
163 prop = propstat.addElement("D:prop");
164
165 for (int i = 0; i < props.size(); i++) {
166 String propName = (String)props.get(i);
167
168 prop.addElement("D:" + propName);
169 }
170
171 DocUtil.add(propstat, "D:status", "HTTP/1.1 404 Not Found");
172 }
173 }
174
175 protected void addResponse(String href, Element multistatus)
176 throws Exception {
177
178 Element response = multistatus.addElement("D:response");
179
180 DocUtil.add(response, "D:href", href);
181
182 Element propstat = response.addElement("D:propstat");
183
184 DocUtil.add(propstat, "D:status", "HTTP/1.1 404 Not Found");
185 }
186
187 protected int getDepth(WebDAVRequest webDavReq) {
188 HttpServletRequest req = webDavReq.getHttpServletRequest();
189
190 String depth = req.getHeader("Depth");
191
192 if (_log.isDebugEnabled()) {
193 _log.debug("Depth " + depth);
194 }
195
196 return GetterUtil.getInteger(depth, 1);
197 }
198
199 protected DateFormat getCreateDateFormat() {
200 return new SimpleDateFormat(_CREATE_DATE_FORMAT, Locale.US);
201 }
202
203 protected DateFormat getModifiedDateFormat() {
204 return new SimpleDateFormat(_MODIFIED_DATE_FORMAT, Locale.US);
205 }
206
207 protected List getProps(WebDAVRequest webDavReq) throws Exception {
208 HttpServletRequest req = webDavReq.getHttpServletRequest();
209
210 List props = new ArrayList();
211
212 String xml = WebDAVUtil.getRequestXML(req);
213
214 if (Validator.isNull(xml)) {
215 return props;
216 }
217
218 SAXReader reader = new SAXReader();
219
220 Document doc = reader.read(new StringReader(xml));
221
222 Element root = doc.getRootElement();
223
224 Element prop = root.element("prop");
225
226 Iterator itr = prop.elements().iterator();
227
228 while (itr.hasNext()) {
229 Element el = (Element)itr.next();
230
231 props.add(el.getName());
232 }
233
234 return props;
235 }
236
237 protected String getResponseXML(WebDAVRequest webDavReq) throws Exception {
238 WebDAVStorage storage = webDavReq.getWebDAVStorage();
239 long companyId = webDavReq.getCompanyId();
240 long groupId = webDavReq.getGroupId();
241 DateFormat createDateFormat = getCreateDateFormat();
242 DateFormat modifiedDateFormat = getModifiedDateFormat();
243
244 List props = getProps(webDavReq);
245
246 DocumentFactory docFactory = DocumentFactory.getInstance();
247
248 Document doc = docFactory.createDocument();
249
250 Element multistatus = docFactory.createElement(
251 new QName("multistatus", new Namespace("D", "DAV:")));
252
253 doc.setRootElement(multistatus);
254
255 if (companyId <= 0) {
256 return getResponseXML(doc);
257 }
258
259 if (groupId == 0) {
260 addResponse(
261 new BaseResourceImpl(
262 storage.getRootPath() + StringPool.SLASH + companyId,
263 String.valueOf(companyId), true),
264 props, multistatus, createDateFormat, modifiedDateFormat);
265
266 if (props.size() > 0) {
267 Iterator itr = storage.getCommunities(webDavReq).iterator();
268
269 while (itr.hasNext()) {
270 Resource resource = (Resource)itr.next();
271
272 addResponse(
273 resource, props, multistatus, createDateFormat,
274 modifiedDateFormat);
275 }
276 }
277
278 return getResponseXML(doc);
279 }
280
281 Resource resource = storage.getResource(webDavReq);
282
283 if ((resource == null) && !webDavReq.isGroupPath()) {
284 String href = storage.getRootPath() + webDavReq.getPath();
285
286 if (_log.isWarnEnabled()) {
287 _log.warn("No resource found for " + webDavReq.getPath());
288 }
289
290 addResponse(href, multistatus);
291
292 return getResponseXML(doc);
293 }
294
295 if (resource != null) {
296 addResponse(
297 resource, props, multistatus, createDateFormat,
298 modifiedDateFormat);
299 }
300 else if (webDavReq.isGroupPath()) {
301 try {
302 Group group = GroupLocalServiceUtil.getGroup(groupId);
303
304 addResponse(
305 new BaseResourceImpl(
306 storage.getRootPath() + StringPool.SLASH + companyId +
307 StringPool.SLASH + groupId,
308 group.getName(), true),
309 props, multistatus, createDateFormat, modifiedDateFormat);
310 }
311 catch (NoSuchGroupException nsge) {
312 String href = storage.getRootPath() + webDavReq.getPath();
313
314 if (_log.isWarnEnabled()) {
315 _log.warn("No group found for " + href);
316 }
317
318 addResponse(href, multistatus);
319 }
320 }
321
322 Iterator itr = storage.getResources(webDavReq).iterator();
323
324 while (itr.hasNext()) {
325 resource = (Resource)itr.next();
326
327 addResponse(
328 resource, props, multistatus, createDateFormat,
329 modifiedDateFormat);
330 }
331
332 return getResponseXML(doc);
333 }
334
335 protected String getResponseXML(Document doc) throws Exception {
336 String xml = XMLFormatter.toString(doc, " ");
337
338 if (_log.isDebugEnabled()) {
339 _log.debug("Response XML\n" + xml);
340 }
341
342 return xml;
343 }
344
345 private static final String _CREATE_DATE_FORMAT =
346 "yyyy-MM-dd'T'HH:mm:ss'Z'";
347
348 private static final String _MODIFIED_DATE_FORMAT =
349 "EEE, dd MMM yyyy HH:mm:ss zzz";
350
351 private static Log _log = LogFactory.getLog(PropfindMethodImpl.class);
352
353 }