1
19
20 package com.liferay.portal.webdav.methods;
21
22 import com.liferay.portal.PortalException;
23 import com.liferay.portal.SystemException;
24 import com.liferay.portal.kernel.util.ContentTypes;
25 import com.liferay.portal.kernel.util.FileUtil;
26 import com.liferay.portal.kernel.util.StringPool;
27 import com.liferay.portal.kernel.util.Tuple;
28 import com.liferay.portal.kernel.util.Validator;
29 import com.liferay.portal.kernel.xml.Document;
30 import com.liferay.portal.kernel.xml.Element;
31 import com.liferay.portal.kernel.xml.Namespace;
32 import com.liferay.portal.kernel.xml.SAXReaderUtil;
33 import com.liferay.portal.model.WebDAVProps;
34 import com.liferay.portal.service.WebDAVPropsLocalServiceUtil;
35 import com.liferay.portal.webdav.InvalidRequestException;
36 import com.liferay.portal.webdav.LockException;
37 import com.liferay.portal.webdav.Resource;
38 import com.liferay.portal.webdav.WebDAVException;
39 import com.liferay.portal.webdav.WebDAVRequest;
40 import com.liferay.portal.webdav.WebDAVStorage;
41 import com.liferay.portal.webdav.WebDAVUtil;
42 import com.liferay.util.servlet.ServletResponseUtil;
43 import com.liferay.util.xml.XMLFormatter;
44
45 import java.util.HashSet;
46 import java.util.Iterator;
47 import java.util.List;
48 import java.util.Set;
49
50 import javax.servlet.http.HttpServletRequest;
51 import javax.servlet.http.HttpServletResponse;
52
53 import org.apache.commons.logging.Log;
54 import org.apache.commons.logging.LogFactory;
55
56
62 public class ProppatchMethodImpl extends BasePropMethodImpl {
63
64 public int process(WebDAVRequest webDavRequest) throws WebDAVException {
65 try {
66 HttpServletResponse response =
67 webDavRequest.getHttpServletResponse();
68
69 Set<Tuple> props = processInstructions(webDavRequest);
70
71 String xml = getResponseXML(webDavRequest, props);
72
73
75 response.setContentType(ContentTypes.TEXT_XML_UTF8);
76 response.setStatus(WebDAVUtil.SC_MULTI_STATUS);
77
78 if (_log.isInfoEnabled()) {
79 _log.info("Status code " + WebDAVUtil.SC_MULTI_STATUS);
80 }
81
82 try {
83 ServletResponseUtil.write(response, xml);
84 }
85 catch (Exception e) {
86 if (_log.isWarnEnabled()) {
87 _log.warn(e);
88 }
89 }
90
91 return -1;
92 }
93 catch (InvalidRequestException ire) {
94 if (_log.isInfoEnabled()) {
95 _log.info(ire.getMessage(), ire);
96 }
97
98 return HttpServletResponse.SC_BAD_REQUEST;
99 }
100 catch (LockException le) {
101 return WebDAVUtil.SC_LOCKED;
102 }
103 catch (Exception e) {
104 throw new WebDAVException(e);
105 }
106 }
107
108 protected WebDAVProps getStoredProperties(WebDAVRequest webDavRequest)
109 throws PortalException, SystemException {
110
111 WebDAVStorage storage = webDavRequest.getWebDAVStorage();
112
113 Resource resource = storage.getResource(webDavRequest);
114
115 WebDAVProps webDavProps = null;
116
117 if (resource.getPrimaryKey() <= 0) {
118 if (_log.isWarnEnabled()) {
119 _log.warn("There is no primary key set for resource");
120 }
121
122 throw new InvalidRequestException();
123 }
124 else if (resource.isLocked()) {
125 throw new LockException();
126 }
127
128 webDavProps = WebDAVPropsLocalServiceUtil.getWebDAVProps(
129 webDavRequest.getCompanyId(), resource.getClassName(),
130 resource.getPrimaryKey());
131
132 return webDavProps;
133 }
134
135 protected Set<Tuple> processInstructions(WebDAVRequest webDavRequest)
136 throws InvalidRequestException, LockException {
137
138 try {
139 Set<Tuple> newProps = new HashSet<Tuple>();
140
141 HttpServletRequest request = webDavRequest.getHttpServletRequest();
142
143 WebDAVProps webDavProps = getStoredProperties(webDavRequest);
144
145 String xml = new String(
146 FileUtil.getBytes(request.getInputStream()));
147
148 if (Validator.isNull(xml)) {
149 return newProps;
150 }
151
152 if (_log.isInfoEnabled()) {
153 _log.info(
154 "Request XML: \n" +
155 XMLFormatter.toString(xml, StringPool.FOUR_SPACES));
156 }
157
158 Document doc = SAXReaderUtil.read(xml);
159
160 Element root = doc.getRootElement();
161
162 Iterator<Element> itr = root.elements().iterator();
163
164 while (itr.hasNext()) {
165 Element instruction = itr.next();
166
167 List<Element> list = instruction.elements();
168
169 if (list.size() != 1) {
170 throw new InvalidRequestException(
171 "There should only be one <prop /> per set or remove " +
172 "instruction.");
173 }
174
175 Element prop = list.get(0);
176
177 if (!prop.getName().equals("prop") ||
178 !prop.getNamespaceURI().equals(
179 WebDAVUtil.DAV_URI.getURI())) {
180
181 throw new InvalidRequestException(
182 "Invalid <prop /> element " + prop);
183 }
184
185 list = prop.elements();
186
187 if (list.size() != 1) {
188 throw new InvalidRequestException(
189 "<prop /> should only have one subelement.");
190 }
191
192 Element customProp = list.get(0);
193
194 String name = customProp.getName();
195 String prefix = customProp.getNamespacePrefix();
196 String uri = customProp.getNamespaceURI();
197 String text = customProp.getText();
198
199 Namespace namespace = null;
200
201 if (uri.equals(WebDAVUtil.DAV_URI.getURI())) {
202 namespace = WebDAVUtil.DAV_URI;
203 }
204 else if (Validator.isNull(prefix)) {
205 namespace = SAXReaderUtil.createNamespace(uri);
206 }
207 else {
208 namespace = SAXReaderUtil.createNamespace(prefix, uri);
209 }
210
211 if (instruction.getName().equals("set")) {
212 if (Validator.isNull(text)) {
213 webDavProps.addProp(name, prefix, uri);
214 }
215 else {
216 webDavProps.addProp(name, prefix, uri, text);
217 }
218
219 newProps.add(new Tuple(customProp.getName(), namespace));
220 }
221 else if (instruction.getName().equals("remove")) {
222 webDavProps.removeProp(name, prefix, uri);
223 }
224 else {
225 throw new InvalidRequestException(
226 "Instead of set/remove instruction, received " +
227 instruction);
228 }
229 }
230
231 WebDAVPropsLocalServiceUtil.storeWebDAVProps(webDavProps);
232
233 return newProps;
234 }
235 catch (LockException le) {
236 throw le;
237 }
238 catch (Exception e) {
239 throw new InvalidRequestException(e);
240 }
241 }
242
243 private static Log _log = LogFactory.getLog(ProppatchMethodImpl.class);
244
245 }