1 /* ownCloud Android client application 
   2  *   Copyright (C) 2011  Bartek Przybylski 
   4  *   This program is free software: you can redistribute it and/or modify 
   5  *   it under the terms of the GNU General Public License as published by 
   6  *   the Free Software Foundation, either version 3 of the License, or 
   7  *   (at your option) any later version. 
   9  *   This program is distributed in the hope that it will be useful, 
  10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of 
  11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  12  *   GNU General Public License for more details. 
  14  *   You should have received a copy of the GNU General Public License 
  15  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. 
  19 package eu
.alefzero
.webdav
; 
  21 import java
.io
.IOException
; 
  22 import java
.io
.InputStream
; 
  23 import java
.text
.ParseException
; 
  24 import java
.text
.SimpleDateFormat
; 
  25 import java
.util
.Date
; 
  26 import java
.util
.LinkedList
; 
  27 import java
.util
.List
; 
  28 import java
.util
.Locale
; 
  30 import javax
.xml
.parsers
.DocumentBuilder
; 
  31 import javax
.xml
.parsers
.DocumentBuilderFactory
; 
  32 import javax
.xml
.parsers
.ParserConfigurationException
; 
  34 import org
.w3c
.dom
.Document
; 
  35 import org
.w3c
.dom
.Element
; 
  36 import org
.w3c
.dom
.Node
; 
  37 import org
.w3c
.dom
.NodeList
; 
  38 import org
.xml
.sax
.SAXException
; 
  40 import eu
.alefzero
.webdav
.TreeNode
.NodeProperty
; 
  42 import android
.text
.Html
; 
  43 import android
.util
.Log
; 
  45 public class WebdavUtils 
{ 
  47   public static final String RESPONSE 
= "response"; 
  48   public static final String HREF 
= "href"; 
  49   public static final String IS_HIDDEN 
= "ishidden"; 
  50   public static final String RESOURCE_TYPE 
= "resourcetype"; 
  51   public static final String CONTENT_TYPE 
= "getcontenttype"; 
  52   public static final String CONTENT_LENGTH 
= "getcontentlength"; 
  53   public static final String LAST_MODIFIED 
= "getlastmodified"; 
  54   public static final String LAST_ACCESS 
= "lastaccessed"; 
  55   public static final String CREATE_DATE 
= "creationdate"; 
  57   public static final String PROPSTAT 
= "propstat"; 
  58   public static final String STATUS 
= "status"; 
  59   public static final String PROP 
= "prop"; 
  61   private static final String DAV_NAMESPACE_PREFIX 
= "DAV:"; 
  63   public static final SimpleDateFormat DISPLAY_DATE_FORMAT 
= new SimpleDateFormat("dd.MM.yyyy hh:mm"); 
  64   private static final SimpleDateFormat DATETIME_FORMATS
[] = { 
  65       new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale
.US
), 
  66       new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale
.US
), 
  67       new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.sss'Z'", Locale
.US
), 
  68       new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale
.US
), 
  69       new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale
.US
), 
  70       new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale
.US
), 
  71       new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale
.US
)}; 
  73   public static String 
prepareXmlForPropFind() { 
  74     String ret 
= "<?xml version=\"1.0\" ?><D:propfind xmlns:D=\"DAV:\"><D:allprop/></D:propfind>"; 
  78   public static String 
prepareXmlForPatch() { 
  79     return "<?xml version=\"1.0\" ?><D:propertyupdate xmlns:D=\"DAV:\"></D:propertyupdate>"; 
  82   private static Date 
parseResponseDate(String date
) { 
  83     Date returnDate 
= null
; 
  84     for (int i 
= 0; i 
< DATETIME_FORMATS
.length
; ++i
) { 
  86         returnDate 
= DATETIME_FORMATS
[i
].parse(date
); 
  88       } catch (ParseException e
) {} 
  93   private static String 
determineDAVPrefix(Element e
) { 
  94     for (int i 
= 0; i 
< e
.getAttributes().getLength(); ++i
) { 
  95       String attrName 
= e
.getAttributes().item(i
).getNodeName(); 
  96       if (e
.getAttribute(attrName
).equals(DAV_NAMESPACE_PREFIX
)) { 
  97         return attrName
.substring(attrName
.lastIndexOf(':')+1) + ":"; 
 103   public static List
<TreeNode
> parseResponseToNodes(InputStream response
) { 
 104     LinkedList
<TreeNode
> rList 
= new LinkedList
<TreeNode
>(); 
 105     DocumentBuilderFactory factory 
= DocumentBuilderFactory
.newInstance(); 
 106     DocumentBuilder builder
; 
 108       builder 
= factory
.newDocumentBuilder(); 
 109       Document document 
= builder
.parse(response
); 
 110       String davPrefix 
= determineDAVPrefix(document
.getDocumentElement()); 
 112       NodeList nodes 
= document
.getElementsByTagName(davPrefix 
+ RESPONSE
); 
 113       Log
.i("WebdavUtils", "Parsing " + nodes
.getLength() + " response nodes"); 
 115       for (int i 
= 0; i 
< nodes
.getLength(); ++i
) { 
 116         Node currentNode 
= nodes
.item(i
); 
 117         TreeNode resultNode 
=  new TreeNode(); 
 118         parseResourceType(currentNode
, resultNode
, davPrefix
); 
 119         parseResourceDates(currentNode
, resultNode
, davPrefix
); 
 120         parseDisplayName(currentNode
, resultNode
, davPrefix
); 
 121         rList
.add(resultNode
); 
 125     } catch (ParserConfigurationException e
) { 
 127     } catch (SAXException e
) { 
 129     } catch (IOException e
) { 
 135   private static void parseDisplayName(Node currentNode
, TreeNode resultNode
, 
 137     Element currentElement 
= (Element
) currentNode
; 
 138     if (currentElement
.getElementsByTagName(davPrefix 
+ HREF
).getLength() != 0) { 
 139       String filepath 
= currentElement
.getElementsByTagName(davPrefix 
+ HREF
).item(0).getFirstChild().getNodeValue(); 
 140       resultNode
.setProperty(NodeProperty
.NAME
, filepath
); 
 144   private static void parseResourceDates(Node currentNode
, TreeNode resultNode
, String davPrefix
) { 
 145     Element currentElement 
= (Element
)currentNode
; 
 146     if (currentElement
.getElementsByTagName(davPrefix 
+ LAST_MODIFIED
).getLength() != 0) { 
 147       Date date 
= parseResponseDate( 
 148           currentElement
.getElementsByTagName(davPrefix 
+ LAST_MODIFIED
).item(0).getFirstChild().getNodeValue()); 
 149       resultNode
.setProperty(NodeProperty
.LAST_MODIFIED_DATE
, DISPLAY_DATE_FORMAT
.format(date
)); 
 151     if (currentElement
.getElementsByTagName(davPrefix 
+ CREATE_DATE
).getLength() != 0) { 
 152       Date date 
= parseResponseDate( 
 153           currentElement
.getElementsByTagName(davPrefix 
+ CREATE_DATE
).item(0).getFirstChild().getNodeValue()); 
 154       resultNode
.setProperty(NodeProperty
.CREATE_DATE
, DISPLAY_DATE_FORMAT
.format(date
)); 
 158   private static void parseResourceType(Node currentNode
, TreeNode resultNode
, String davPrefix
) { 
 159     Element currentElement 
= (Element
)currentNode
; 
 160     if (currentElement
.getElementsByTagName(davPrefix 
+ RESOURCE_TYPE
).getLength() != 0 && 
 161         currentElement
.getElementsByTagName(davPrefix 
+ RESOURCE_TYPE
).item(0).hasChildNodes()) { 
 162       resultNode
.setProperty(NodeProperty
.RESOURCE_TYPE
, "DIR"); 
 164       if (currentElement
.getElementsByTagName(davPrefix 
+ CONTENT_TYPE
).getLength() != 0) { 
 165         resultNode
.setProperty(NodeProperty
.RESOURCE_TYPE
,  
 166             currentElement
.getElementsByTagName(davPrefix 
+ CONTENT_TYPE
).item(0).getFirstChild().getNodeValue()); 
 168       if (currentElement
.getElementsByTagName(davPrefix 
+ CONTENT_LENGTH
).getLength() != 0) { 
 169         resultNode
.setProperty(NodeProperty
.CONTENT_LENGTH
,  
 170             currentElement
.getElementsByTagName(davPrefix 
+ CONTENT_LENGTH
).item(0).getFirstChild().getNodeValue());