View Javadoc

1   /**
2    *
3    * Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
4    *
5    * ====================================================================
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   * ====================================================================
18   */
19  package org.jclouds.azureblob.xml;
20  
21  import java.net.URI;
22  import java.util.Date;
23  import java.util.Map;
24  import java.util.Set;
25  
26  import javax.inject.Inject;
27  
28  import org.jclouds.azureblob.domain.BlobProperties;
29  import org.jclouds.azureblob.domain.BlobType;
30  import org.jclouds.azureblob.domain.LeaseStatus;
31  import org.jclouds.azureblob.domain.ListBlobsResponse;
32  import org.jclouds.azureblob.domain.internal.BlobPropertiesImpl;
33  import org.jclouds.azureblob.domain.internal.HashSetListBlobsResponse;
34  import org.jclouds.crypto.CryptoStreams;
35  import org.jclouds.date.DateService;
36  import org.jclouds.http.HttpUtils;
37  import org.jclouds.http.functions.ParseSax;
38  import org.xml.sax.Attributes;
39  import org.xml.sax.SAXException;
40  
41  import com.google.common.collect.Maps;
42  import com.google.common.collect.Sets;
43  
44  /**
45   * Parses the following XML document:
46   * <p/>
47   * EnumerationResults ContainerName="http://myaccount.blob.core.windows.net/mycontainer"
48   * 
49   * @see <a href="http://msdn.microsoft.com/en-us/library/dd135734.aspx#samplerequestandresponse" />
50   * @author Adrian Cole
51   */
52  public class ContainerNameEnumerationResultsHandler extends ParseSax.HandlerWithResult<ListBlobsResponse> {
53     private Set<BlobProperties> blobMetadata = Sets.newLinkedHashSet();
54     private String prefix;
55     private String marker;
56     private int maxResults;
57     private String nextMarker;
58     private URI currentUrl;
59     private URI containerUrl;
60     private Date currentLastModified;
61     private String currentETag;
62  
63     private StringBuilder currentText = new StringBuilder();
64  
65     private final DateService dateParser;
66     private String delimiter;
67     private String currentName;
68     private long currentSize;
69     private String currentContentType;
70     private String currentContentEncoding;
71     private String currentContentLanguage;
72     private BlobType currentBlobType;
73     private boolean inBlob;
74     private boolean inBlobPrefix;
75     private boolean inMetadata;
76     private Set<String> blobPrefixes = Sets.newHashSet();
77     private byte[] currentContentMD5;
78     private Map<String, String> currentMetadata = Maps.newHashMap();
79     private LeaseStatus currentLeaseStatus;
80  
81     @Inject
82     public ContainerNameEnumerationResultsHandler(DateService dateParser) {
83        this.dateParser = dateParser;
84     }
85  
86     public ListBlobsResponse getResult() {
87        return new HashSetListBlobsResponse(blobMetadata, containerUrl, prefix, marker, maxResults, nextMarker,
88                 delimiter, blobPrefixes);
89     }
90  
91     @Override
92     public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
93        if (qName.equals("Blob")) {
94           inBlob = true;
95           inBlobPrefix = false;
96           inMetadata = false;
97        } else if (qName.equals("BlobPrefix")) {
98           inBlob = false;
99           inBlobPrefix = true;
100       } else if (qName.equals("Metadata")) {
101          inBlob = true;
102          inMetadata = true;
103       } else if (qName.equals("EnumerationResults")) {
104          containerUrl = URI.create(attributes.getValue("ContainerName").toString().trim());
105       }
106    }
107 
108    public void endElement(String uri, String name, String qName) {
109       if (inMetadata && !qName.equals("Metadata")) {
110          currentMetadata.put(qName, currentText.toString().trim());
111       } else if (qName.equals("Metadata")) {
112          inMetadata = false;
113       } else if (qName.equals("MaxResults")) {
114          maxResults = Integer.parseInt(currentText.toString().trim());
115       } else if (qName.equals("Marker")) {
116          marker = currentText.toString().trim();
117          marker = (marker.equals("")) ? null : marker;
118       } else if (qName.equals("Prefix")) {
119          prefix = currentText.toString().trim();
120          prefix = (prefix.equals("")) ? null : prefix;
121       } else if (qName.equals("Delimiter")) {
122          delimiter = currentText.toString().trim();
123          delimiter = (delimiter.equals("")) ? null : delimiter;
124       } else if (qName.equals("NextMarker")) {
125          nextMarker = currentText.toString().trim();
126          nextMarker = (nextMarker.equals("")) ? null : nextMarker;
127       } else if (qName.equals("BlobType")) {
128          currentBlobType = BlobType.fromValue(currentText.toString().trim());
129       } else if (qName.equals("LeaseStatus")) {
130          currentLeaseStatus = LeaseStatus.fromValue(currentText.toString().trim());
131       } else if (qName.equals("Blob")) {
132          BlobProperties md = new BlobPropertiesImpl(currentBlobType, currentName, containerUrl.getPath().replace("/",
133                   ""), currentUrl, currentLastModified, currentETag, currentSize, currentContentType,
134                   currentContentMD5, currentContentEncoding, currentContentLanguage, currentLeaseStatus,
135                   currentMetadata);
136          blobMetadata.add(md);
137          currentBlobType = null;
138          currentName = null;
139          currentUrl = null;
140          currentLastModified = null;
141          currentETag = null;
142          currentSize = -1;
143          currentContentType = null;
144          currentContentEncoding = null;
145          currentContentLanguage = null;
146          currentContentMD5 = null;
147          currentLeaseStatus = null;
148          currentMetadata = Maps.newHashMap();
149       } else if (qName.equals("Url")) {
150          currentUrl = HttpUtils.createUri(currentText.toString().trim());
151       } else if (qName.equals("Last-Modified")) {
152          currentLastModified = dateParser.rfc822DateParse(currentText.toString().trim());
153       } else if (qName.equals("Etag")) {
154          currentETag = currentText.toString().trim();
155       } else if (qName.equals("Name")) {
156          if (inBlob)
157             currentName = currentText.toString().trim();
158          else if (inBlobPrefix)
159             blobPrefixes.add(currentText.toString().trim());
160       } else if (qName.equals("Content-Length")) {
161          currentSize = Long.parseLong(currentText.toString().trim());
162       } else if (qName.equals("Content-MD5")) {
163          if (!currentText.toString().trim().equals(""))
164             currentContentMD5 = CryptoStreams.base64(currentText.toString().trim());
165       } else if (qName.equals("Content-Type")) {
166          currentContentType = currentText.toString().trim();
167       } else if (qName.equals("Content-Encoding")) {
168          currentContentEncoding = currentText.toString().trim();
169          if (currentContentEncoding.equals(""))
170             currentContentEncoding = null;
171       } else if (qName.equals("Content-Language")) {
172          currentContentLanguage = currentText.toString().trim();
173          if (currentContentLanguage.equals(""))
174             currentContentLanguage = null;
175       }
176       currentText = new StringBuilder();
177    }
178 
179    public void characters(char ch[], int start, int length) {
180       currentText.append(ch, start, length);
181    }
182 }