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