Java tutorial
/* * Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Portions copyright 2006-2009 James Murty. Please see LICENSE.txt * for applicable license terms and NOTICE.txt for applicable notices. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ package cn.ctyun.amazonaws.services.s3.model.transform; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.text.ParseException; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.helpers.XMLReaderFactory; import cn.ctyun.amazonaws.AmazonClientException; import cn.ctyun.amazonaws.services.identitymanagement.model.AccessKey; import cn.ctyun.amazonaws.services.identitymanagement.model.AccessKeyMetadata; import cn.ctyun.amazonaws.services.identitymanagement.model.CreateAccessKeyResult; import cn.ctyun.amazonaws.services.identitymanagement.model.ListAccessKeysResult; import cn.ctyun.amazonaws.services.s3.internal.Constants; import cn.ctyun.amazonaws.services.s3.internal.DeleteObjectsResponse; import cn.ctyun.amazonaws.services.s3.internal.ObjectExpirationResult; import cn.ctyun.amazonaws.services.s3.internal.ServerSideEncryptionResult; import cn.ctyun.amazonaws.services.s3.internal.ServiceUtils; import cn.ctyun.amazonaws.services.s3.model.AccessControlList; import cn.ctyun.amazonaws.services.s3.model.AmazonS3Exception; import cn.ctyun.amazonaws.services.s3.model.Bucket; import cn.ctyun.amazonaws.services.s3.model.BucketCrossOriginConfiguration; import cn.ctyun.amazonaws.services.s3.model.BucketLifecycleConfiguration; import cn.ctyun.amazonaws.services.s3.model.BucketLoggingConfiguration; import cn.ctyun.amazonaws.services.s3.model.BucketNotificationConfiguration; import cn.ctyun.amazonaws.services.s3.model.BucketTaggingConfiguration; import cn.ctyun.amazonaws.services.s3.model.BucketVersioningConfiguration; import cn.ctyun.amazonaws.services.s3.model.BucketWebsiteConfiguration; import cn.ctyun.amazonaws.services.s3.model.CORSRule; import cn.ctyun.amazonaws.services.s3.model.CanonicalGrantee; import cn.ctyun.amazonaws.services.s3.model.CompleteMultipartUploadResult; import cn.ctyun.amazonaws.services.s3.model.CtyunBucketTriggerConfiguration; import cn.ctyun.amazonaws.services.s3.model.CtyunGetUsageResult; import cn.ctyun.amazonaws.services.s3.model.CtyunRemoteSite; import cn.ctyun.amazonaws.services.s3.model.CtyunTriggerMetadata; import cn.ctyun.amazonaws.services.s3.model.DeleteObjectsResult; import cn.ctyun.amazonaws.services.s3.model.EmailAddressGrantee; import cn.ctyun.amazonaws.services.s3.model.Grantee; import cn.ctyun.amazonaws.services.s3.model.GroupGrantee; import cn.ctyun.amazonaws.services.s3.model.InitiateMultipartUploadResult; import cn.ctyun.amazonaws.services.s3.model.MultiObjectDeleteException; import cn.ctyun.amazonaws.services.s3.model.MultipartUpload; import cn.ctyun.amazonaws.services.s3.model.MultipartUploadListing; import cn.ctyun.amazonaws.services.s3.model.ObjectListing; import cn.ctyun.amazonaws.services.s3.model.Owner; import cn.ctyun.amazonaws.services.s3.model.PartListing; import cn.ctyun.amazonaws.services.s3.model.PartSummary; import cn.ctyun.amazonaws.services.s3.model.Permission; import cn.ctyun.amazonaws.services.s3.model.RedirectRule; import cn.ctyun.amazonaws.services.s3.model.RoutingRule; import cn.ctyun.amazonaws.services.s3.model.RoutingRuleCondition; import cn.ctyun.amazonaws.services.s3.model.S3Object; import cn.ctyun.amazonaws.services.s3.model.S3ObjectSummary; import cn.ctyun.amazonaws.services.s3.model.S3VersionSummary; import cn.ctyun.amazonaws.services.s3.model.StorageClass; import cn.ctyun.amazonaws.services.s3.model.TagSet; import cn.ctyun.amazonaws.services.s3.model.VersionListing; import cn.ctyun.amazonaws.services.s3.model.BucketLifecycleConfiguration.Rule; import cn.ctyun.amazonaws.services.s3.model.BucketLifecycleConfiguration.Transition; import cn.ctyun.amazonaws.services.s3.model.BucketNotificationConfiguration.TopicConfiguration; import cn.ctyun.amazonaws.services.s3.model.CORSRule.AllowedMethods; import cn.ctyun.amazonaws.services.s3.model.DeleteObjectsResult.DeletedObject; import cn.ctyun.amazonaws.services.s3.model.MultiObjectDeleteException.DeleteError; /** * XML Sax parser to read XML documents returned by S3 via the REST interface, * converting these documents into objects. */ public class XmlResponsesSaxParser { private static final Log log = LogFactory.getLog(XmlResponsesSaxParser.class); private XMLReader xr = null; private boolean sanitizeXmlDocument = true; /** * Constructs the XML SAX parser. * * @throws AmazonClientException */ public XmlResponsesSaxParser() throws AmazonClientException { // Ensure we can load the XML Reader. try { xr = XMLReaderFactory.createXMLReader(); } catch (SAXException e) { throw new AmazonClientException("Couldn't initialize a SAX driver to create an XMLReader", e); } } /** * Parses an XML document from an input stream using a document handler. * * @param handler * the handler for the XML document * @param inputStream * an input stream containing the XML document to parse * * @throws AmazonClientException * any parsing, IO or other exceptions are wrapped in an * S3ServiceException. */ protected void parseXmlInputStream(DefaultHandler handler, InputStream inputStream) throws AmazonClientException { try { if (log.isDebugEnabled()) { log.debug("Parsing XML response document with handler: " + handler.getClass()); } BufferedReader breader = new BufferedReader( new InputStreamReader(inputStream, Constants.DEFAULT_ENCODING)); xr.setContentHandler(handler); xr.setErrorHandler(handler); xr.parse(new InputSource(breader)); } catch (Throwable t) { try { inputStream.close(); } catch (IOException e) { if (log.isErrorEnabled()) { log.error("Unable to close response InputStream up after XML parse failure", e); } } throw new AmazonClientException("Failed to parse XML document with handler " + handler.getClass(), t); } } protected InputStream sanitizeXmlDocument(DefaultHandler handler, InputStream inputStream) throws AmazonClientException { if (!sanitizeXmlDocument) { // No sanitizing will be performed, return the original input stream unchanged. return inputStream; } else { if (log.isDebugEnabled()) { log.debug("Sanitizing XML document destined for handler " + handler.getClass()); } InputStream sanitizedInputStream = null; try { /* * Read object listing XML document from input stream provided into a * string buffer, so we can replace troublesome characters before * sending the document to the XML parser. */ StringBuilder listingDocBuffer = new StringBuilder(); BufferedReader br = new BufferedReader( new InputStreamReader(inputStream, Constants.DEFAULT_ENCODING)); char[] buf = new char[8192]; int read = -1; while ((read = br.read(buf)) != -1) { listingDocBuffer.append(buf, 0, read); } br.close(); /* * Replace any carriage return (\r) characters with explicit XML * character entities, to prevent the SAX parser from * misinterpreting 0x0D characters as 0x0A and being unable to * parse the XML. */ String listingDoc = listingDocBuffer.toString().replaceAll("\r", "
"); sanitizedInputStream = new ByteArrayInputStream(listingDoc.getBytes(Constants.DEFAULT_ENCODING)); } catch (Throwable t) { try { inputStream.close(); } catch (IOException e) { if (log.isErrorEnabled()) { log.error("Unable to close response InputStream after failure sanitizing XML document", e); } } throw new AmazonClientException( "Failed to sanitize XML document destined for handler " + handler.getClass(), t); } return sanitizedInputStream; } } /** * Checks if the specified string is empty or null and if so, returns null. * Otherwise simply returns the string. * * @param s * The string to check. * @return Null if the specified string was null, or empty, otherwise * returns the string the caller passed in. */ private String checkForEmptyString(String s) { if (s == null) return null; if (s.length() == 0) return null; return s; } /** * Safely parses the specified string as an integer and returns the value. * If a NumberFormatException occurs while parsing the integer, an error is * logged and -1 is returned. * * @param s * The string to parse and return as an integer. * * @return The integer value of the specified string, otherwise -1 if there * were any problems parsing the string as an integer. */ private int parseInt(String s) { try { return Integer.parseInt(s); } catch (NumberFormatException nfe) { log.error("Unable to parse integer value '" + s + "'", nfe); } return -1; } /** * Safely parses the specified string as a long and returns the value. If a * NumberFormatException occurs while parsing the long, an error is logged * and -1 is returned. * * @param s * The string to parse and return as a long. * * @return The long value of the specified string, otherwise -1 if there * were any problems parsing the string as a long. */ private long parseLong(String s) { try { return Long.parseLong(s); } catch (NumberFormatException nfe) { log.error("Unable to parse long value '" + s + "'", nfe); } return -1; } /** * Parses a ListBucket response XML document from an input stream. * * @param inputStream * XML data input stream. * @return the XML handler object populated with data parsed from the XML * stream. * @throws AmazonClientException */ public ListBucketHandler parseListBucketObjectsResponse(InputStream inputStream) throws AmazonClientException { ListBucketHandler handler = new ListBucketHandler(); parseXmlInputStream(handler, sanitizeXmlDocument(handler, inputStream)); return handler; } /** * Parses a ListVersions response XML document from an input stream. * * @param inputStream * XML data input stream. * @return the XML handler object populated with data parsed from the XML * stream. * @throws AmazonClientException */ public ListVersionsHandler parseListVersionsResponse(InputStream inputStream) throws AmazonClientException { ListVersionsHandler handler = new ListVersionsHandler(); parseXmlInputStream(handler, sanitizeXmlDocument(handler, inputStream)); return handler; } /** * Parses a ListAllMyBuckets response XML document from an input stream. * * @param inputStream * XML data input stream. * @return the XML handler object populated with data parsed from the XML * stream. * @throws AmazonClientException */ public ListAllMyBucketsHandler parseListMyBucketsResponse(InputStream inputStream) throws AmazonClientException { ListAllMyBucketsHandler handler = new ListAllMyBucketsHandler(); parseXmlInputStream(handler, sanitizeXmlDocument(handler, inputStream)); return handler; } /** * Parses an AccessControlListHandler response XML document from an input * stream. * * @param inputStream * XML data input stream. * @return the XML handler object populated with data parsed from the XML * stream. * * @throws AmazonClientException */ public AccessControlListHandler parseAccessControlListResponse(InputStream inputStream) throws AmazonClientException { AccessControlListHandler handler = new AccessControlListHandler(); parseXmlInputStream(handler, inputStream); return handler; } /** * Parses a LoggingStatus response XML document for a bucket from an input * stream. * * @param inputStream * XML data input stream. * @return the XML handler object populated with data parsed from the XML * stream. * * @throws AmazonClientException */ public BucketLoggingConfigurationHandler parseLoggingStatusResponse(InputStream inputStream) throws AmazonClientException { BucketLoggingConfigurationHandler handler = new BucketLoggingConfigurationHandler(); parseXmlInputStream(handler, inputStream); return handler; } public BucketLifecycleConfigurationHandler parseBucketLifecycleConfigurationResponse(InputStream inputStream) { BucketLifecycleConfigurationHandler handler = new BucketLifecycleConfigurationHandler(); parseXmlInputStream(handler, inputStream); return handler; } public BucketCrossOriginConfigurationHandler parseBucketCrossOriginConfigurationResponse( InputStream inputStream) { BucketCrossOriginConfigurationHandler handler = new BucketCrossOriginConfigurationHandler(); parseXmlInputStream(handler, inputStream); return handler; } public String parseBucketLocationResponse(InputStream inputStream) throws AmazonClientException { BucketLocationHandler handler = new BucketLocationHandler(); parseXmlInputStream(handler, inputStream); return handler.getLocation(); } public BucketVersioningConfigurationHandler parseVersioningConfigurationResponse(InputStream inputStream) throws AmazonClientException { BucketVersioningConfigurationHandler handler = new BucketVersioningConfigurationHandler(); parseXmlInputStream(handler, inputStream); return handler; } public BucketWebsiteConfigurationHandler parseWebsiteConfigurationResponse(InputStream inputStream) throws AmazonClientException { BucketWebsiteConfigurationHandler handler = new BucketWebsiteConfigurationHandler(); parseXmlInputStream(handler, inputStream); return handler; } public CtyunBucketTriggerConfigurationHandler parseTriggerConfigurationResponse(InputStream inputStream) throws AmazonClientException { CtyunBucketTriggerConfigurationHandler handler = new CtyunBucketTriggerConfigurationHandler(); parseXmlInputStream(handler, inputStream); return handler; } public BucketNotificationConfigurationHandler parseNotificationConfigurationResponse(InputStream inputStream) throws AmazonClientException { BucketNotificationConfigurationHandler handler = new BucketNotificationConfigurationHandler(); parseXmlInputStream(handler, inputStream); return handler; } public BucketTaggingConfigurationHandler parseTaggingConfigurationResponse(InputStream inputStream) throws AmazonClientException { BucketTaggingConfigurationHandler handler = new BucketTaggingConfigurationHandler(); parseXmlInputStream(handler, inputStream); return handler; } public DeleteObjectsHandler parseDeletedObjectsResult(InputStream inputStream) { DeleteObjectsHandler handler = new DeleteObjectsHandler(); parseXmlInputStream(handler, inputStream); return handler; } public CopyObjectResultHandler parseCopyObjectResponse(InputStream inputStream) throws AmazonClientException { CopyObjectResultHandler handler = new CopyObjectResultHandler(); parseXmlInputStream(handler, inputStream); return handler; } public CompleteMultipartUploadHandler parseCompleteMultipartUploadResponse(InputStream inputStream) throws AmazonClientException { CompleteMultipartUploadHandler handler = new CompleteMultipartUploadHandler(); parseXmlInputStream(handler, inputStream); return handler; } public InitiateMultipartUploadHandler parseInitiateMultipartUploadResponse(InputStream inputStream) throws AmazonClientException { InitiateMultipartUploadHandler handler = new InitiateMultipartUploadHandler(); parseXmlInputStream(handler, inputStream); return handler; } public ListMultipartUploadsHandler parseListMultipartUploadsResponse(InputStream inputStream) throws AmazonClientException { ListMultipartUploadsHandler handler = new ListMultipartUploadsHandler(); parseXmlInputStream(handler, inputStream); return handler; } public ListPartsHandler parseListPartsResponse(InputStream inputStream) throws AmazonClientException { ListPartsHandler handler = new ListPartsHandler(); parseXmlInputStream(handler, inputStream); return handler; } /** * @param inputStream * * @return true if the bucket's is configured as Requester Pays, false if it * is configured as Owner pays. * * @throws AmazonClientException */ public boolean parseRequestPaymentConfigurationResponse(InputStream inputStream) throws AmazonClientException { RequestPaymentConfigurationHandler handler = new RequestPaymentConfigurationHandler(); parseXmlInputStream(handler, inputStream); return handler.isRequesterPays(); } /** * Parses a CtyunListAccessKey response XML document from an input stream. * * @param inputStream * XML data input stream. * @return the XML handler object populated with data parsed from the XML * stream. * @throws AmazonClientException */ public CtyunListAccessKeyHandler parseCtyunListAccessKey(InputStream inputStream) throws AmazonClientException { CtyunListAccessKeyHandler handler = new CtyunListAccessKeyHandler(); parseXmlInputStream(handler, sanitizeXmlDocument(handler, inputStream)); return handler; } /** * Parses a CtyunGetUsage response XML document from an input stream. * * @param inputStream * XML data input stream. * @return the XML handler object populated with data parsed from the XML * stream. * @throws AmazonClientException */ public CtyunGetUsageHandler parseCtyunGetUsage(InputStream inputStream) throws AmazonClientException { CtyunGetUsageHandler handler = new CtyunGetUsageHandler(); parseXmlInputStream(handler, sanitizeXmlDocument(handler, inputStream)); return handler; } /** * Parses a CtyunCreateAccessKey response XML document from an input stream. * * @param inputStream * XML data input stream. * @return the XML handler object populated with data parsed from the XML * stream. * @throws AmazonClientException */ public CtyunCreateAccessKeyHandler parseCtyunCreateAccessKey(InputStream inputStream) throws AmazonClientException { CtyunCreateAccessKeyHandler handler = new CtyunCreateAccessKeyHandler(); parseXmlInputStream(handler, sanitizeXmlDocument(handler, inputStream)); return handler; } // //////////// // Handlers // // //////////// /** * Handler for ListBucket response XML documents. The document is parsed * into {@link S3Object}s available via the {@link #getObjects()} method. */ public class ListBucketHandler extends DefaultHandler { private S3ObjectSummary currentObject = null; private Owner currentOwner = null; private StringBuilder currText = null; private boolean insideCommonPrefixes = false; private ObjectListing objectListing = new ObjectListing(); private List<String> commonPrefixes = new ArrayList<String>(); // Listing properties. private String bucketName = null; private String requestPrefix = null; private String requestMarker = null; private int requestMaxKeys = 0; private String requestDelimiter = null; private boolean listingTruncated = false; private String lastKey = null; private String nextMarker = null; public ListBucketHandler() { super(); this.currText = new StringBuilder(); } public ObjectListing getObjectListing() { objectListing.setBucketName(bucketName); objectListing.setCommonPrefixes(commonPrefixes); objectListing.setDelimiter(requestDelimiter); objectListing.setMarker(requestMarker); objectListing.setMaxKeys(requestMaxKeys); objectListing.setPrefix(requestPrefix); objectListing.setTruncated(listingTruncated); /* * S3 only includes the NextMarker XML element if the request * specified a delimiter, but for consistency we'd like to always * give easy access to the next marker if we're returning a list of * results that's truncated. */ if (nextMarker != null) { objectListing.setNextMarker(nextMarker); } else if (listingTruncated) { String nextMarker = null; if (objectListing.getObjectSummaries().isEmpty() == false) { nextMarker = objectListing.getObjectSummaries() .get(objectListing.getObjectSummaries().size() - 1).getKey(); } else if (objectListing.getCommonPrefixes().isEmpty() == false) { nextMarker = objectListing.getCommonPrefixes() .get(objectListing.getCommonPrefixes().size() - 1); } else { log.error( "S3 response indicates truncated results, but contains no object summaries or common prefixes."); } objectListing.setNextMarker(nextMarker); } return objectListing; } /** * If the listing is truncated this method will return the marker that * should be used in subsequent bucket list calls to complete the * listing. * * @return null if the listing is not truncated, otherwise the next * marker if it's available or the last object key seen if the * next marker isn't available. */ public String getMarkerForNextListing() { if (listingTruncated) { if (nextMarker != null) { return nextMarker; } else if (lastKey != null) { return lastKey; } else { if (log.isWarnEnabled()) { log.warn("Unable to find Next Marker or Last Key for truncated listing"); } return null; } } else { return null; } } /** * @return true if the listing document was truncated, and therefore * only contained a subset of the available S3 objects. */ public boolean isListingTruncated() { return listingTruncated; } /** * @return the S3 objects contained in the listing. */ public List<S3ObjectSummary> getObjects() { return objectListing.getObjectSummaries(); } public String[] getCommonPrefixes() { return commonPrefixes.toArray(new String[commonPrefixes.size()]); } public String getRequestPrefix() { return requestPrefix; } public String getRequestMarker() { return requestMarker; } public String getNextMarker() { return nextMarker; } public long getRequestMaxKeys() { return requestMaxKeys; } @Override public void startDocument() { } @Override public void endDocument() { } @Override public void startElement(String uri, String name, String qName, Attributes attrs) { if (name.equals("Contents")) { currentObject = new S3ObjectSummary(); currentObject.setBucketName(bucketName); } else if (name.equals("Owner")) { currentOwner = new Owner(); currentObject.setOwner(currentOwner); } else if (name.equals("CommonPrefixes")) { insideCommonPrefixes = true; } } @Override public void endElement(String uri, String name, String qName) { String elementText = this.currText.toString(); // Listing details if (name.equals("Name")) { bucketName = elementText; if (log.isDebugEnabled()) { log.debug("Examining listing for bucket: " + bucketName); } } else if (!insideCommonPrefixes && name.equals("Prefix")) { requestPrefix = checkForEmptyString(elementText); } else if (name.equals("Marker")) { requestMarker = checkForEmptyString(elementText); } else if (name.equals("NextMarker")) { nextMarker = elementText; } else if (name.equals("MaxKeys")) { requestMaxKeys = parseInt(elementText); } else if (name.equals("Delimiter")) { requestDelimiter = checkForEmptyString(elementText); } else if (name.equals("IsTruncated")) { String isTruncatedStr = elementText.toLowerCase(Locale.getDefault()); if (isTruncatedStr.startsWith("false")) { listingTruncated = false; } else if (isTruncatedStr.startsWith("true")) { listingTruncated = true; } else { throw new RuntimeException("Invalid value for IsTruncated field: " + isTruncatedStr); } } // Object details. else if (name.equals("Contents")) { objectListing.getObjectSummaries().add(currentObject); } else if (name.equals("Key")) { currentObject.setKey(elementText); lastKey = elementText; } else if (name.equals("LastModified")) { try { currentObject.setLastModified(ServiceUtils.parseIso8601Date(elementText)); } catch (ParseException e) { throw new RuntimeException( "Non-ISO8601 date for LastModified in bucket's object listing output: " + elementText, e); } } else if (name.equals("ETag")) { currentObject.setETag(ServiceUtils.removeQuotes(elementText)); } else if (name.equals("Size")) { currentObject.setSize(parseLong(elementText)); } else if (name.equals("StorageClass")) { currentObject.setStorageClass(elementText); } // Owner details. else if (name.equals("ID")) { if (currentOwner == null) { currentOwner = new Owner(); currentObject.setOwner(currentOwner); } currentOwner.setId(elementText); } else if (name.equals("DisplayName")) { currentOwner.setDisplayName(elementText); } // Common prefixes. else if (insideCommonPrefixes && name.equals("Prefix")) { commonPrefixes.add(elementText); } else if (name.equals("CommonPrefixes")) { insideCommonPrefixes = false; } this.currText = new StringBuilder(); } @Override public void characters(char ch[], int start, int length) { this.currText.append(ch, start, length); } } /** * Handler for ListAllMyBuckets response XML documents. The document is * parsed into {@link Bucket}s available via the {@link #getBuckets()} * method. */ public class ListAllMyBucketsHandler extends DefaultHandler { private Owner bucketsOwner = null; private Bucket currentBucket = null; private StringBuilder currText = null; private List<Bucket> buckets = null; public ListAllMyBucketsHandler() { super(); buckets = new ArrayList<Bucket>(); this.currText = new StringBuilder(); } /** * @return the buckets listed in the document. */ public List<Bucket> getBuckets() { return buckets; } /** * @return the owner of the buckets. */ public Owner getOwner() { return bucketsOwner; } @Override public void startDocument() { } @Override public void endDocument() { } @Override public void startElement(String uri, String name, String qName, Attributes attrs) { if (name.equals("Bucket")) { currentBucket = new Bucket(); } else if (name.equals("Owner")) { bucketsOwner = new Owner(); } } @Override public void endElement(String uri, String name, String qName) { String elementText = this.currText.toString(); // Listing details. if (name.equals("ID")) { bucketsOwner.setId(elementText); } else if (name.equals("DisplayName")) { bucketsOwner.setDisplayName(elementText); } // Bucket item details. else if (name.equals("Bucket")) { currentBucket.setOwner(bucketsOwner); buckets.add(currentBucket); } else if (name.equals("Name")) { currentBucket.setName(elementText); } else if (name.equals("CreationDate")) { elementText += ".000Z"; try { currentBucket.setCreationDate(ServiceUtils.parseIso8601Date(elementText)); } catch (ParseException e) { throw new RuntimeException( "Non-ISO8601 date for CreationDate in list buckets output: " + elementText, e); } } this.currText = new StringBuilder(); } @Override public void characters(char ch[], int start, int length) { this.currText.append(ch, start, length); } } /** * Handler for AccessControlList response XML documents. The document is * parsed into an {@link AccessControlList} object available via the * {@link #getAccessControlList()} method. */ public class AccessControlListHandler extends DefaultHandler { private AccessControlList accessControlList = null; private Owner owner = null; private Grantee currentGrantee = null; private Permission currentPermission = null; private StringBuilder currText = null; private boolean insideACL = false; public AccessControlListHandler() { super(); this.currText = new StringBuilder(); } /** * @return an object representing the ACL document. */ public AccessControlList getAccessControlList() { return accessControlList; } @Override public void startDocument() { } @Override public void endDocument() { } @Override public void startElement(String uri, String name, String qName, Attributes attrs) { if (name.equals("Owner")) { owner = new Owner(); } else if (name.equals("AccessControlList")) { accessControlList = new AccessControlList(); accessControlList.setOwner(owner); insideACL = true; } else if (name.equals("Grantee")) { String type = XmlResponsesSaxParser.findAttributeValue("xsi:type", attrs); if ("AmazonCustomerByEmail".equals(type)) { currentGrantee = new EmailAddressGrantee(null); } else if ("CanonicalUser".equals(type)) { currentGrantee = new CanonicalGrantee(null); } else if ("Group".equals(type)) { /* * Nothing to do for GroupGrantees here since we * can't construct an empty enum value early. */ } } } @Override public void endElement(String uri, String name, String qName) { String elementText = this.currText.toString(); // Owner details. if (name.equals("ID") && !insideACL) { owner.setId(elementText); } else if (name.equals("DisplayName") && !insideACL) { owner.setDisplayName(elementText); } // ACL details. else if (name.equals("ID")) { currentGrantee.setIdentifier(elementText); } else if (name.equals("EmailAddress")) { currentGrantee.setIdentifier(elementText); } else if (name.equals("URI")) { /* * Only GroupGrantees contain an URI element in them, and we * can't construct currentGrantee during startElement for a * GroupGrantee since it's an enum. */ currentGrantee = GroupGrantee.parseGroupGrantee(elementText); } else if (name.equals("DisplayName")) { ((CanonicalGrantee) currentGrantee).setDisplayName(elementText); } else if (name.equals("Permission")) { currentPermission = Permission.parsePermission(elementText); } else if (name.equals("Grant")) { accessControlList.grantPermission(currentGrantee, currentPermission); currentGrantee = null; currentPermission = null; } else if (name.equals("AccessControlList")) { insideACL = false; } this.currText = new StringBuilder(); } @Override public void characters(char ch[], int start, int length) { this.currText.append(ch, start, length); } } /** * Handler for LoggingStatus response XML documents for a bucket. The * document is parsed into an {@link BucketLoggingConfiguration} object available * via the {@link #getBucketLoggingConfiguration()} method. */ public class BucketLoggingConfigurationHandler extends DefaultHandler { private BucketLoggingConfiguration bucketLoggingConfiguration = null; private String targetBucket = null; private String targetPrefix = null; private String triggerTargetBucket = null; private String triggerTargetPrefix = null; private String triggerSourceBucket = null; private String triggerSourcePrefix = null; private StringBuilder currText = null; public BucketLoggingConfigurationHandler() { this.currText = new StringBuilder(); } /** * @return * an object representing the bucket's LoggingStatus document. */ public BucketLoggingConfiguration getBucketLoggingConfiguration() { return bucketLoggingConfiguration; } @Override public void startDocument() { } @Override public void endDocument() { } @Override public void startElement(String uri, String name, String qName, Attributes attrs) { if (name.equals("BucketLoggingStatus")) { bucketLoggingConfiguration = new BucketLoggingConfiguration(); } } @Override public void endElement(String uri, String name, String qName) { String elementText = this.currText.toString(); if (name.equals("TargetBucket")) { targetBucket = elementText; } else if (name.equals("TargetPrefix")) { targetPrefix = elementText; } else if (name.equals("TriggerTargetBucket")) { triggerTargetBucket = elementText; } else if (name.equals("TriggerTargetPrefix")) { triggerTargetPrefix = elementText; } else if (name.equals("TriggerSourceBucket")) { triggerSourceBucket = elementText; } else if (name.equals("TriggerSourcePrefix")) { triggerSourcePrefix = elementText; } else if (name.equals("LoggingEnabled")) { bucketLoggingConfiguration.setDestinationBucketName(targetBucket); bucketLoggingConfiguration.setLogFilePrefix(targetPrefix); bucketLoggingConfiguration.setCtyunTriggerDestinationBucketName(triggerTargetBucket); bucketLoggingConfiguration.setCtyunTriggerDestinationLogFilePrefix(triggerTargetPrefix); bucketLoggingConfiguration.setCtyunTriggerSourceBucketName(triggerSourceBucket); bucketLoggingConfiguration.setCtyunTriggerSourceLogFilePrefix(triggerSourcePrefix); } this.currText = new StringBuilder(); } @Override public void characters(char ch[], int start, int length) { this.currText.append(ch, start, length); } } /** * Handler for CreateBucketConfiguration response XML documents for a * bucket. The document is parsed into a String representing the bucket's * location, available via the {@link #getLocation()} method. */ public class BucketLocationHandler extends DefaultHandler { private String location = null; private StringBuilder currText = null; public BucketLocationHandler() { super(); this.currText = new StringBuilder(); } /** * @return * the bucket's location. */ public String getLocation() { return location; } @Override public void startDocument() { } @Override public void endDocument() { } @Override public void startElement(String uri, String name, String qName, Attributes attrs) { if (name.equals("CreateBucketConfiguration")) { } } @Override public void endElement(String uri, String name, String qName) { String elementText = this.currText.toString(); if (name.equals("LocationConstraint")) { if (elementText.length() == 0) { location = null; } else { location = elementText; } } this.currText = new StringBuilder(); } @Override public void characters(char ch[], int start, int length) { this.currText.append(ch, start, length); } } public class CopyObjectResultHandler extends DefaultHandler implements ServerSideEncryptionResult, ObjectExpirationResult { // Data items for successful copy private String etag = null; private Date lastModified = null; private String versionId = null; private String serverSideEncryption; private Date expirationTime; private String expirationTimeRuleId; // Data items for failed copy private String errorCode = null; private String errorMessage = null; private String errorRequestId = null; private String errorHostId = null; private boolean receivedErrorResponse = false; private StringBuilder currText = null; public CopyObjectResultHandler() { super(); this.currText = new StringBuilder(); } public Date getLastModified() { return lastModified; } public String getVersionId() { return versionId; } public void setVersionId(String versionId) { this.versionId = versionId; } @Override public String getServerSideEncryption() { return serverSideEncryption; } @Override public void setServerSideEncryption(String serverSideEncryption) { this.serverSideEncryption = serverSideEncryption; } @Override public Date getExpirationTime() { return expirationTime; } @Override public void setExpirationTime(Date expirationTime) { this.expirationTime = expirationTime; } @Override public String getExpirationTimeRuleId() { return expirationTimeRuleId; } @Override public void setExpirationTimeRuleId(String expirationTimeRuleId) { this.expirationTimeRuleId = expirationTimeRuleId; } public String getETag() { return etag; } public String getErrorCode() { return errorCode; } public String getErrorHostId() { return errorHostId; } public String getErrorMessage() { return errorMessage; } public String getErrorRequestId() { return errorRequestId; } public boolean isErrorResponse() { return receivedErrorResponse; } @Override public void startDocument() { } @Override public void endDocument() { } @Override public void startElement(String uri, String name, String qName, Attributes attrs) { if (name.equals("CopyObjectResult")) { receivedErrorResponse = false; } else if (name.equals("Error")) { receivedErrorResponse = true; } } @Override public void endElement(String uri, String name, String qName) { String elementText = this.currText.toString(); if (name.equals("LastModified")) { try { lastModified = ServiceUtils.parseIso8601Date(elementText); } catch (ParseException e) { throw new RuntimeException( "Non-ISO8601 date for LastModified in copy object output: " + elementText, e); } } else if (name.equals("ETag")) { etag = ServiceUtils.removeQuotes(elementText); } else if (name.equals("Code")) { errorCode = elementText; } else if (name.equals("Message")) { errorMessage = elementText; } else if (name.equals("RequestId")) { errorRequestId = elementText; } else if (name.equals("HostId")) { errorHostId = elementText; } this.currText = new StringBuilder(); } @Override public void characters(char ch[], int start, int length) { this.currText.append(ch, start, length); } } /** * Handler for RequestPaymentConfiguration response XML documents for a * bucket. The document is parsed into a boolean value: true if the bucket's * is configured as Requester Pays, false if it is configured as Owner pays. * This boolean value is available via the {@link #isRequesterPays()} * method. */ public class RequestPaymentConfigurationHandler extends DefaultHandler { private String payer = null; private StringBuilder currText = null; public RequestPaymentConfigurationHandler() { super(); this.currText = new StringBuilder(); } /** * @return true if the bucket's is configured as Requester Pays, false * if it is configured as Owner pays. */ public boolean isRequesterPays() { return "Requester".equals(payer); } @Override public void startDocument() { } @Override public void endDocument() { } @Override public void startElement(String uri, String name, String qName, Attributes attrs) { if (name.equals("RequestPaymentConfiguration")) { } } @Override public void endElement(String uri, String name, String qName) { String elementText = this.currText.toString(); if (name.equals("Payer")) { payer = elementText; } this.currText = new StringBuilder(); } @Override public void characters(char ch[], int start, int length) { this.currText.append(ch, start, length); } } /** * Handler for ListVersionsResult XML document. */ public class ListVersionsHandler extends DefaultHandler { private VersionListing versionListing; private List<S3VersionSummary> versionSummaries; private S3VersionSummary currentVersionSummary; private Owner owner; private StringBuilder text; private boolean insideCommonPrefixes = false; public VersionListing getListing() { return versionListing; } @Override public void startDocument() { versionListing = new VersionListing(); versionSummaries = new ArrayList<S3VersionSummary>(); text = new StringBuilder(); } @Override public void startElement(String uri, String name, String qName, Attributes attrs) { if (name.equals("ListVersionsResult")) { } else if (name.equals("CommonPrefixes")) { insideCommonPrefixes = true; } else if (name.equals("Name")) { } else if (name.equals("Prefix")) { } else if (name.equals("Delimiter")) { } else if (name.equals("KeyMarker")) { } else if (name.equals("VersionIdMarker")) { } else if (name.equals("MaxKeys")) { } else if (name.equals("NextKeyMarker")) { } else if (name.equals("NextVersionIdMarker")) { } else if (name.equals("IsTruncated")) { } else if (name.equals("Version")) { currentVersionSummary = new S3VersionSummary(); currentVersionSummary.setBucketName(versionListing.getBucketName()); } else if (name.equals("DeleteMarker")) { currentVersionSummary = new S3VersionSummary(); currentVersionSummary.setBucketName(versionListing.getBucketName()); currentVersionSummary.setIsDeleteMarker(true); } else if (name.equals("Key")) { } else if (name.equals("VersionId")) { } else if (name.equals("IsLatest")) { } else if (name.equals("LastModified")) { } else if (name.equals("ETag")) { } else if (name.equals("Size")) { } else if (name.equals("Owner")) { this.owner = new Owner(); } else if (name.equals("StorageClass")) { } else if (name.equals("ID")) { } else if (name.equals("DisplayName")) { } else { log.warn("Ignoring unexpected tag <" + name + ">"); } text.setLength(0); } @Override public void endElement(String uri, String name, String qName) throws SAXException { if (name.equals("ListVersionsResult")) { versionListing.setVersionSummaries(versionSummaries); } else if (name.equals("Name")) { versionListing.setBucketName(text.toString()); } else if (!insideCommonPrefixes && name.equals("Prefix")) { versionListing.setPrefix(checkForEmptyString(text.toString())); } else if (insideCommonPrefixes && name.equals("Prefix")) { versionListing.getCommonPrefixes().add(checkForEmptyString(text.toString())); } else if (name.equals("CommonPrefixes")) { insideCommonPrefixes = false; } else if (name.equals("KeyMarker")) { versionListing.setKeyMarker(checkForEmptyString(text.toString())); } else if (name.equals("VersionIdMarker")) { versionListing.setVersionIdMarker(checkForEmptyString(text.toString())); } else if (name.equals("MaxKeys")) { versionListing.setMaxKeys(Integer.parseInt(text.toString())); } else if (name.equals("Delimiter")) { versionListing.setDelimiter(checkForEmptyString(text.toString())); } else if (name.equals("NextKeyMarker")) { versionListing.setNextKeyMarker(text.toString()); } else if (name.equals("NextVersionIdMarker")) { versionListing.setNextVersionIdMarker(text.toString()); } else if (name.equals("IsTruncated")) { versionListing.setTruncated("true".equals(text.toString())); } else if (name.equals("Version")) { assert (currentVersionSummary != null); versionSummaries.add(currentVersionSummary); currentVersionSummary = null; } else if (name.equals("DeleteMarker")) { assert (currentVersionSummary != null); versionSummaries.add(currentVersionSummary); currentVersionSummary = null; } else if (name.equals("Key")) { assert (currentVersionSummary != null); currentVersionSummary.setKey(text.toString()); } else if (name.equals("VersionId")) { assert (currentVersionSummary != null); currentVersionSummary.setVersionId(text.toString()); } else if (name.equals("IsLatest")) { assert (currentVersionSummary != null); currentVersionSummary.setIsLatest("true".equals(text.toString())); } else if (name.equals("LastModified")) { assert (currentVersionSummary != null); try { currentVersionSummary.setLastModified(ServiceUtils.parseIso8601Date(text.toString())); } catch (ParseException e) { throw new SAXException( "Non-ISO8601 date for LastModified in copy object output: " + text.toString(), e); } } else if (name.equals("ETag")) { assert (currentVersionSummary != null); assert (!currentVersionSummary.isDeleteMarker()); currentVersionSummary.setETag(ServiceUtils.removeQuotes(text.toString())); } else if (name.equals("Size")) { assert (currentVersionSummary != null); assert (!currentVersionSummary.isDeleteMarker()); currentVersionSummary.setSize(Long.parseLong(text.toString())); } else if (name.equals("Owner")) { currentVersionSummary.setOwner(owner); owner = null; } else if (name.equals("StorageClass")) { assert (currentVersionSummary != null); assert (!currentVersionSummary.isDeleteMarker()); currentVersionSummary.setStorageClass(text.toString()); } else if (name.equals("ID")) { assert (owner != null); owner.setId(text.toString()); } else if (name.equals("DisplayName")) { assert (owner != null); owner.setDisplayName(text.toString()); } else { log.warn("Ignoring unexpected tag <" + name + ">"); } text.setLength(0); } @Override public void characters(char ch[], int start, int length) { this.text.append(ch, start, length); } } public class BucketWebsiteConfigurationHandler extends DefaultHandler { private BucketWebsiteConfiguration configuration = new BucketWebsiteConfiguration(null); private RoutingRuleCondition condition = null; private RedirectRule redirect = null; private List<RoutingRule> rules = null; private RedirectRule redirectAllRequestsTo = null; RoutingRule rule = null; private StringBuilder text; boolean inIndexDocumentElement = false; boolean inErrorDocumentElement = false; boolean inRoutingRules = false; boolean inRoutingRule = false; boolean inCondition = false; boolean inRedirect = false; boolean inRedirectAllRequestsTo = false; public BucketWebsiteConfiguration getConfiguration() { return configuration; } @Override public void startDocument() { text = new StringBuilder(); } @Override public void startElement(String uri, String name, String qName, Attributes attrs) { if (name.equals("WebsiteConfiguration")) { } else if (name.equals("IndexDocument")) { inIndexDocumentElement = true; } else if (name.equals("Suffix") && inIndexDocumentElement) { } else if (name.equals("ErrorDocument")) { inErrorDocumentElement = true; } else if (name.equals("Key") && inErrorDocumentElement) { } else if (name.equals("RedirectAllRequestsTo")) { redirectAllRequestsTo = new RedirectRule(); inRedirectAllRequestsTo = true; } else if (name.equals("RoutingRules")) { rules = new LinkedList<RoutingRule>(); inRoutingRules = true; } else if (name.equals("RoutingRule") && inRoutingRules) { rule = new RoutingRule(); inRoutingRule = true; } else if (name.equals("Condition") && inRoutingRule) { condition = new RoutingRuleCondition(); inCondition = true; } else if (name.equals("KeyPrefixEquals") && inCondition) { } else if (name.equals("HttpErrorCodeReturnedEquals") && inCondition) { } else if (name.equals("Redirect") && inRoutingRule) { redirect = new RedirectRule(); inRedirect = true; } else if (name.equals("Protocol") && (inRedirect || inRedirectAllRequestsTo)) { } else if (name.equals("HostName") && (inRedirect || inRedirectAllRequestsTo)) { } else if (name.equals("ReplaceKeyPrefixWith") && (inRedirect || inRedirectAllRequestsTo)) { } else if (name.equals("ReplaceKeyWith") && (inRedirect || inRedirectAllRequestsTo)) { } else if (name.equals("HttpRedirectCode") && (inRedirect || inRedirectAllRequestsTo)) { } else { log.warn("Ignoring unexpected tag <" + name + ">"); } } @Override public void endElement(String uri, String name, String qName) throws SAXException { if (name.equals("WebsiteConfiguration")) { } else if (name.equals("IndexDocument")) { inIndexDocumentElement = false; } else if (name.equals("Suffix") && inIndexDocumentElement) { configuration.setIndexDocumentSuffix(text.toString()); } else if (name.equals("ErrorDocument")) { inErrorDocumentElement = false; } else if (name.equals("Key") && inErrorDocumentElement) { configuration.setErrorDocument(text.toString()); } else if (name.equals("KeyPrefixEquals") && inCondition) { condition.setKeyPrefixEquals(text.toString()); } else if (name.equals("HttpErrorCodeReturnedEquals") && inCondition) { condition.setHttpErrorCodeReturnedEquals(text.toString()); } else if (name.equals("Condition") && inRoutingRule) { rule.setCondition(condition); inCondition = false; condition = null; } else if (name.equals("Protocol") && inRedirect) { redirect.setProtocol(text.toString()); } else if (name.equals("Protocol") && inRedirectAllRequestsTo) { redirectAllRequestsTo.setProtocol(text.toString()); } else if (name.equals("HostName") && inRedirect) { redirect.setHostName(text.toString()); } else if (name.equals("HostName") && inRedirectAllRequestsTo) { redirectAllRequestsTo.setHostName(text.toString()); } else if (name.equals("ReplaceKeyPrefixWith") && inRedirect) { redirect.setReplaceKeyPrefixWith(text.toString()); } else if (name.equals("ReplaceKeyPrefixWith") && inRedirectAllRequestsTo) { redirectAllRequestsTo.setReplaceKeyPrefixWith(text.toString()); } else if (name.equals("ReplaceKeyWith") && inRedirect) { redirect.setReplaceKeyWith(text.toString()); } else if (name.equals("ReplaceKeyWith") && inRedirectAllRequestsTo) { redirectAllRequestsTo.setReplaceKeyWith(text.toString()); } else if (name.equals("HttpRedirectCode") && inRedirect) { redirect.setHttpRedirectCode(text.toString()); } else if (name.equals("HttpRedirectCode") && inRedirectAllRequestsTo) { redirectAllRequestsTo.setHttpRedirectCode(text.toString()); } else if (name.equals("Redirect") && inRoutingRule) { rule.setRedirect(redirect); inRedirect = false; redirect = null; } else if (name.equals("RoutingRule") && inRoutingRules) { rules.add(rule); rule = null; inRoutingRule = false; } else if (name.equals("RoutingRules")) { configuration.setRoutingRules(rules); rules = null; inRoutingRules = false; } else if (name.equals("RedirectAllRequestsTo")) { configuration.setRedirectAllRequestsTo(redirectAllRequestsTo); inRedirectAllRequestsTo = false; redirectAllRequestsTo = null; } text.setLength(0); } @Override public void characters(char ch[], int start, int length) { this.text.append(ch, start, length); } } public class BucketVersioningConfigurationHandler extends DefaultHandler { private BucketVersioningConfiguration configuration = new BucketVersioningConfiguration(); private StringBuilder text; public BucketVersioningConfiguration getConfiguration() { return configuration; } @Override public void startDocument() { text = new StringBuilder(); } @Override public void startElement(String uri, String name, String qName, Attributes attrs) { if (name.equals("VersioningConfiguration")) { } else if (name.equals("Status")) { text.setLength(0); } else if (name.equals("MfaDelete")) { text.setLength(0); } else { log.warn("Ignoring unexpected tag <" + name + ">"); } } @Override public void endElement(String uri, String name, String qName) throws SAXException { if (name.equals("Status")) { configuration.setStatus(text.toString()); } else if (name.equals("MfaDelete")) { String mfaDeleteStatus = text.toString(); if (mfaDeleteStatus.equals("Disabled")) { configuration.setMfaDeleteEnabled(false); } else if (mfaDeleteStatus.equals("Enabled")) { configuration.setMfaDeleteEnabled(true); } else { configuration.setMfaDeleteEnabled(null); } } text.setLength(0); } @Override public void characters(char ch[], int start, int length) { this.text.append(ch, start, length); } } /* * <?xml version="1.0" encoding="UTF-8"?> * <CompleteMultipartUploadResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> * <Location>http://Example-Bucket.s3.amazonaws.com/Example-Object</Location> * <Bucket>Example-Bucket</Bucket> * <Key>Example-Object</Key> * <ETag>"3858f62230ac3c915f300c664312c11f-9"</ETag> * </CompleteMultipartUploadResult> * * Or if an error occurred while completing: * * <?xml version="1.0" encoding="UTF-8"?> * <Error> * <Code>InternalError</Code> * <Message>We encountered an internal error. Please try again.</Message> * <RequestId>656c76696e6727732072657175657374</RequestId> * <HostId>Uuag1LuByRx9e6j5Onimru9pO4ZVKnJ2Qz7/C1NPcfTWAtRPfTaOFg==</HostId> * </Error> */ public class CompleteMultipartUploadHandler extends DefaultHandler implements ServerSideEncryptionResult, ObjectExpirationResult { private StringBuilder text; // Successful completion private CompleteMultipartUploadResult result; @Override public String getServerSideEncryption() { if (result != null) return result.getServerSideEncryption(); else return null; } @Override public void setServerSideEncryption(String serverSideEncryption) { if (result != null) result.setServerSideEncryption(serverSideEncryption); } /** * @see cn.ctyun.amazonaws.services.s3.model.CompleteMultipartUploadResult#getExpirationTime() */ @Override public Date getExpirationTime() { if (result != null) return result.getExpirationTime(); return null; } /** * @see cn.ctyun.amazonaws.services.s3.model.CompleteMultipartUploadResult#setExpirationTime(java.util.Date) */ @Override public void setExpirationTime(Date expirationTime) { if (result != null) result.setExpirationTime(expirationTime); } /** * @see cn.ctyun.amazonaws.services.s3.model.CompleteMultipartUploadResult#getExpirationTimeRuleId() */ @Override public String getExpirationTimeRuleId() { if (result != null) return result.getExpirationTimeRuleId(); return null; } /** * @see cn.ctyun.amazonaws.services.s3.model.CompleteMultipartUploadResult#setExpirationTimeRuleId(java.lang.String) */ @Override public void setExpirationTimeRuleId(String expirationTimeRuleId) { if (result != null) result.setExpirationTimeRuleId(expirationTimeRuleId); } // Error during completion private AmazonS3Exception ase; private String hostId; private String requestId; private String errorCode; public CompleteMultipartUploadResult getCompleteMultipartUploadResult() { return result; } public AmazonS3Exception getAmazonS3Exception() { return ase; } @Override public void startDocument() { text = new StringBuilder(); } @Override public void startElement(String uri, String name, String qName, Attributes attrs) { // Success response XML elements if (name.equals("CompleteMultipartUploadResult")) { result = new CompleteMultipartUploadResult(); } else if (name.equals("Location")) { } else if (name.equals("Bucket")) { } else if (name.equals("Key")) { } else if (name.equals("ETag")) { } // Error response XML elements if (name.equals("Error")) { } else if (name.equals("Code")) { } else if (name.equals("Message")) { } else if (name.equals("RequestId")) { } else if (name.equals("HostId")) { } text.setLength(0); } @Override public void endElement(String uri, String name, String qName) throws SAXException { if (result != null) { // Success response XML elements if (name.equals("CompleteMultipartUploadResult")) { } else if (name.equals("Location")) { result.setLocation(text.toString()); } else if (name.equals("Bucket")) { result.setBucketName(text.toString()); } else if (name.equals("Key")) { result.setKey(text.toString()); } else if (name.equals("ETag")) { result.setETag(ServiceUtils.removeQuotes(text.toString())); } } else { // Error response XML elements if (name.equals("Error")) { ase.setErrorCode(errorCode); ase.setRequestId(requestId); ase.setExtendedRequestId(hostId); } else if (name.equals("Code")) { errorCode = text.toString(); } else if (name.equals("Message")) { ase = new AmazonS3Exception(text.toString()); } else if (name.equals("RequestId")) { requestId = text.toString(); } else if (name.equals("HostId")) { hostId = text.toString(); } } } @Override public void characters(char ch[], int start, int length) { this.text.append(ch, start, length); } } /* * <?xml version="1.0" encoding="UTF-8"?> * <InitiateMultipartUploadResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> * <Bucket>example-bucket</Bucket> * <Key>example-object</Key> * <UploadId>VXBsb2FkIElEIGZvciA2aWWpbmcncyBteS1tb3ZpZS5tMnRzIHVwbG9hZA</UploadId> * </InitiateMultipartUploadResult> */ public class InitiateMultipartUploadHandler extends DefaultHandler { private StringBuilder text; private InitiateMultipartUploadResult result; public InitiateMultipartUploadResult getInitiateMultipartUploadResult() { return result; } @Override public void startDocument() { text = new StringBuilder(); } @Override public void startElement(String uri, String name, String qName, Attributes attrs) { if (name.equals("InitiateMultipartUploadResult")) { result = new InitiateMultipartUploadResult(); } else if (name.equals("Bucket")) { } else if (name.equals("Key")) { } else if (name.equals("UploadId")) { } text.setLength(0); } @Override public void endElement(String uri, String name, String qName) throws SAXException { if (name.equals("InitiateMultipartUploadResult")) { } else if (name.equals("Bucket")) { result.setBucketName(text.toString()); } else if (name.equals("Key")) { result.setKey(text.toString()); } else if (name.equals("UploadId")) { result.setUploadId(text.toString()); } } @Override public void characters(char ch[], int start, int length) { this.text.append(ch, start, length); } } /* * HTTP/1.1 200 OK * x-amz-id-2: Uuag1LuByRx9e6j5Onimru9pO4ZVKnJ2Qz7/C1NPcfTWAtRPfTaOFg== * x-amz-request-id: 656c76696e6727732072657175657374 * Date: Tue, 16 Feb 2010 20:34:56 GMT * Content-Length: 1330 * Connection: keep-alive * Server: AmazonS3 * * <?xml version="1.0" encoding="UTF-8"?> * <ListMultipartUploadsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> * <Bucket>bucket</Bucket> * <KeyMarker></KeyMarker> * <Delimiter>/</Delimiter> * <Prefix/> * <UploadIdMarker></UploadIdMarker> * <NextKeyMarker>my-movie.m2ts</NextKeyMarker> * <NextUploadIdMarker>YW55IGlkZWEgd2h5IGVsdmluZydzIHVwbG9hZCBmYWlsZWQ</NextUploadIdMarker> * <MaxUploads>3</MaxUploads> * <IsTruncated>true</IsTruncated> * <Upload> * <Key>my-divisor</Key> * <UploadId>XMgbGlrZSBlbHZpbmcncyBub3QgaGF2aW5nIG11Y2ggbHVjaw</UploadId> * <Owner> * <ID>b1d16700c70b0b05597d7acd6a3f92be</ID> * <DisplayName>delving</DisplayName> * </Owner> * <StorageClass>STANDARD</StorageClass> * <Initiated>Tue, 26 Jan 2010 19:42:19 GMT</Initiated> * </Upload> * <Upload> * <Key>my-movie.m2ts</Key> * <UploadId>VXBsb2FkIElEIGZvciBlbHZpbmcncyBteS1tb3ZpZS5tMnRzIHVwbG9hZA</UploadId> * <Owner> * <ID>b1d16700c70b0b05597d7acd6a3f92be</ID> * <DisplayName>delving</DisplayName> * </Owner> * <StorageClass>STANDARD</StorageClass> * <Initiated>Tue, 16 Feb 2010 20:34:56 GMT</Initiated> * </Upload> * <Upload> * <Key>my-movie.m2ts</Key> * <UploadId>YW55IGlkZWEgd2h5IGVsdmluZydzIHVwbG9hZCBmYWlsZWQ</UploadId> * <Owner> * <ID>b1d16700c70b0b05597d7acd6a3f92be</ID> * <DisplayName>delving</DisplayName> * </Owner> * <StorageClass>STANDARD</StorageClass> * <Initiated>Wed, 27 Jan 2010 03:02:01 GMT</Initiated> * </Upload> * <CommonPrefixes> * <Prefix>photos/</Prefix> * </CommonPrefixes> * <CommonPrefixes> * <Prefix>videos/</Prefix> * </CommonPrefixes> * </ListMultipartUploadsResult> */ public class ListMultipartUploadsHandler extends DefaultHandler { private StringBuilder text; private MultipartUploadListing result; private MultipartUpload currentMultipartUpload; private Owner currentOwner; private Owner currentInitiator; boolean inCommonPrefixes = false; public MultipartUploadListing getListMultipartUploadsResult() { return result; } @Override public void startDocument() { text = new StringBuilder(); } @Override public void startElement(String uri, String name, String qName, Attributes attrs) { if (name.equals("ListMultipartUploadsResult")) { result = new MultipartUploadListing(); } else if (name.equals("Bucket")) { } else if (name.equals("KeyMarker")) { } else if (name.equals("Delimiter")) { } else if (name.equals("UploadIdMarker")) { } else if (name.equals("NextKeyMarker")) { } else if (name.equals("NextUploadIdMarker")) { } else if (name.equals("MaxUploads")) { } else if (name.equals("IsTruncated")) { } else if (name.equals("Upload")) { currentMultipartUpload = new MultipartUpload(); } else if (name.equals("Key")) { } else if (name.equals("UploadId")) { } else if (name.equals("Owner")) { currentOwner = new Owner(); } else if (name.equals("Initiator")) { currentInitiator = new Owner(); } else if (name.equals("ID")) { } else if (name.equals("DisplayName")) { } else if (name.equals("StorageClass")) { } else if (name.equals("Initiated")) { } else if (name.equals("CommonPrefixes")) { inCommonPrefixes = true; } text.setLength(0); } @Override public void endElement(String uri, String name, String qName) throws SAXException { if (name.equals("ListMultipartUploadsResult")) { } else if (name.equals("Bucket")) { result.setBucketName(text.toString()); } else if (name.equals("KeyMarker")) { result.setKeyMarker(checkForEmptyString(text.toString())); } else if (name.equals("Delimiter")) { result.setDelimiter(checkForEmptyString(text.toString())); } else if (name.equals("Prefix") && inCommonPrefixes == false) { result.setPrefix(checkForEmptyString(text.toString())); } else if (name.equals("Prefix") && inCommonPrefixes == true) { result.getCommonPrefixes().add(text.toString()); } else if (name.equals("UploadIdMarker")) { result.setUploadIdMarker(checkForEmptyString(text.toString())); } else if (name.equals("NextKeyMarker")) { result.setNextKeyMarker(checkForEmptyString(text.toString())); } else if (name.equals("NextUploadIdMarker")) { result.setNextUploadIdMarker(checkForEmptyString(text.toString())); } else if (name.equals("MaxUploads")) { result.setMaxUploads(Integer.parseInt(text.toString())); } else if (name.equals("IsTruncated")) { result.setTruncated(Boolean.parseBoolean(text.toString())); } else if (name.equals("Upload")) { result.getMultipartUploads().add(currentMultipartUpload); } else if (name.equals("Key")) { currentMultipartUpload.setKey(text.toString()); } else if (name.equals("UploadId")) { currentMultipartUpload.setUploadId(text.toString()); } else if (name.equals("Owner")) { currentMultipartUpload.setOwner(currentOwner); currentOwner = null; } else if (name.equals("Initiator")) { currentMultipartUpload.setInitiator(currentInitiator); currentInitiator = null; } else if (name.equals("ID") && currentOwner != null) { currentOwner.setId(checkForEmptyString(text.toString())); } else if (name.equals("DisplayName") && currentOwner != null) { currentOwner.setDisplayName(checkForEmptyString(text.toString())); } else if (name.equals("ID") && currentInitiator != null) { currentInitiator.setId(checkForEmptyString(text.toString())); } else if (name.equals("DisplayName") && currentInitiator != null) { currentInitiator.setDisplayName(checkForEmptyString(text.toString())); } else if (name.equals("StorageClass")) { currentMultipartUpload.setStorageClass(text.toString()); } else if (name.equals("Initiated")) { try { currentMultipartUpload.setInitiated(ServiceUtils.parseIso8601Date(text.toString())); } catch (ParseException e) { throw new SAXException("Non-ISO8601 date for Initiated in initiate multipart upload result: " + text.toString(), e); } } else if (name.equals("CommonPrefixes")) { inCommonPrefixes = false; } } @Override public void characters(char ch[], int start, int length) { this.text.append(ch, start, length); } } /* * HTTP/1.1 200 OK * x-amz-id-2: Uuag1LuByRx9e6j5Onimru9pO4ZVKnJ2Qz7/C1NPcfTWAtRPfTaOFg== * x-amz-request-id: 656c76696e6727732072657175657374 * Date: Tue, 16 Feb 2010 20:34:56 GMT * Content-Length: 985 * Connection: keep-alive * Server: AmazonS3 * * <?xml version="1.0" encoding="UTF-8"?> * <ListPartsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> * <Bucket>example-bucket</Bucket> * <Key>example-object</Key> * <UploadId>XXBsb2FkIElEIGZvciBlbHZpbmcncyVcdS1tb3ZpZS5tMnRzEEEwbG9hZA</UploadId> * <Owner> * <ID>x1x16700c70b0b05597d7ecd6a3f92be</ID> * <DisplayName>username</DisplayName> * </Owner> * <Initiator> * <ID>x1x16700c70b0b05597d7ecd6a3f92be</ID> * <DisplayName>username</DisplayName> * </Initiator> * <StorageClass>STANDARD</StorageClass> * <PartNumberMarker>1</PartNumberMarker> * <NextPartNumberMarker>3</NextPartNumberMarker> * <MaxParts>2</MaxParts> * <IsTruncated>true</IsTruncated> * <Part> * <PartNumber>2</PartNumber> * <LastModified>Wed, 27 Jan 2010 03:02:03 GMT</LastModified> * <ETag>"7778aef83f66abc1fa1e8477f296d394"</ETag> * <Size>10485760</Size> * </Part> * <Part> * <PartNumber>3</PartNumber> * <LastModified>Wed, 27 Jan 2010 03:02:02 GMT</LastModified> * <ETag>"aaaa18db4cc2f85cedef654fccc4a4x8"</ETag> * <Size>10485760</Size> * </Part> * </ListPartsResult> */ public class ListPartsHandler extends DefaultHandler { private StringBuilder text; private PartListing result; private Owner currentOwner; private Owner currentInitiator; private PartSummary currentPart; public PartListing getListPartsResult() { return result; } @Override public void startDocument() { text = new StringBuilder(); } @Override public void startElement(String uri, String name, String qName, Attributes attrs) { if (name.equals("ListPartsResult")) { result = new PartListing(); } else if (name.equals("Bucket")) { } else if (name.equals("Key")) { } else if (name.equals("UploadId")) { } else if (name.equals("Owner")) { currentOwner = new Owner(); } else if (name.equals("Initiator")) { currentInitiator = new Owner(); } else if (name.equals("ID")) { } else if (name.equals("DisplayName")) { } else if (name.equals("StorageClass")) { } else if (name.equals("PartNumberMarker")) { } else if (name.equals("NextPartNumberMarker")) { } else if (name.equals("MaxParts")) { } else if (name.equals("IsTruncated")) { } else if (name.equals("Part")) { currentPart = new PartSummary(); } else if (name.equals("PartNumber")) { } else if (name.equals("LastModified")) { } else if (name.equals("ETag")) { } else if (name.equals("Size")) { } text.setLength(0); } private Integer parseInteger(String text) { text = checkForEmptyString(text.toString()); if (text == null) return null; return Integer.parseInt(text); } @Override public void endElement(String uri, String name, String qName) throws SAXException { if (name.equals("ListPartsResult")) { } else if (name.equals("Bucket")) { result.setBucketName(text.toString()); } else if (name.equals("Key")) { result.setKey(text.toString()); } else if (name.equals("UploadId")) { result.setUploadId(text.toString()); } else if (name.equals("Owner")) { result.setOwner(currentOwner); currentOwner = null; } else if (name.equals("Initiator")) { result.setInitiator(currentInitiator); currentInitiator = null; } else if (name.equals("ID") && currentOwner != null) { currentOwner.setId(checkForEmptyString(text.toString())); } else if (name.equals("DisplayName") && currentOwner != null) { currentOwner.setDisplayName(checkForEmptyString(text.toString())); } else if (name.equals("ID") && currentInitiator != null) { currentInitiator.setId(checkForEmptyString(text.toString())); } else if (name.equals("DisplayName") && currentInitiator != null) { currentInitiator.setDisplayName(checkForEmptyString(text.toString())); } else if (name.equals("StorageClass")) { result.setStorageClass(text.toString()); } else if (name.equals("PartNumberMarker")) { result.setPartNumberMarker(parseInteger(text.toString())); } else if (name.equals("NextPartNumberMarker")) { result.setNextPartNumberMarker(parseInteger(text.toString())); } else if (name.equals("MaxParts")) { result.setMaxParts(parseInteger(text.toString())); } else if (name.equals("IsTruncated")) { result.setTruncated(Boolean.parseBoolean(text.toString())); } else if (name.equals("Part")) { result.getParts().add(currentPart); } else if (name.equals("PartNumber")) { currentPart.setPartNumber(Integer.parseInt(text.toString())); } else if (name.equals("LastModified")) { try { currentPart.setLastModified(ServiceUtils.parseIso8601Date(text.toString())); } catch (ParseException e) { throw new SAXException( "Non-ISO8601 date for LastModified in list parts result: " + text.toString(), e); } } else if (name.equals("ETag")) { currentPart.setETag(ServiceUtils.removeQuotes(text.toString())); } else if (name.equals("Size")) { currentPart.setSize(Long.parseLong(text.toString())); } } @Override public void characters(char ch[], int start, int length) { this.text.append(ch, start, length); } } public class BucketNotificationConfigurationHandler extends DefaultHandler { private BucketNotificationConfiguration configuration = new BucketNotificationConfiguration(); private StringBuilder text; private List<TopicConfiguration> topicConfigurations; private String topic; private String event; public BucketNotificationConfiguration getConfiguration() { return configuration; } @Override public void startDocument() { text = new StringBuilder(); } @Override public void startElement(String uri, String name, String qName, Attributes attrs) { if (name.equals("NotificationConfiguration")) { topicConfigurations = new ArrayList<BucketNotificationConfiguration.TopicConfiguration>(1); } else if (name.equals("TopicConfiguration")) { topic = null; event = null; } else if (name.equals("Topic")) { text.setLength(0); } else if (name.equals("Event")) { text.setLength(0); } else { log.warn("Ignoring unexpected tag <" + name + ">"); } } @Override public void endElement(String uri, String name, String qName) throws SAXException { if (name.equals("Topic")) { topic = text.toString(); } else if (name.equals("Event")) { event = text.toString(); } else if (name.equals("TopicConfiguration")) { if (topic != null && event != null) { topicConfigurations.add(new TopicConfiguration(topic, event)); } } else if (name.equals("NotificationConfiguration")) { configuration.setTopicConfigurations(topicConfigurations); } text.setLength(0); } @Override public void characters(char ch[], int start, int length) { this.text.append(ch, start, length); } } public class BucketTaggingConfigurationHandler extends DefaultHandler { private BucketTaggingConfiguration configuration = new BucketTaggingConfiguration(); private StringBuilder text; private List<TagSet> tagSets; private Map<String, String> tags; private String tagKey; private String tagValue; public BucketTaggingConfiguration getConfiguration() { return configuration; } @Override public void startDocument() { text = new StringBuilder(); } @Override public void startElement(String uri, String name, String qName, Attributes attrs) { if (name.equals("Tagging")) { tagSets = new ArrayList<TagSet>(1); } else if (name.equals("TagSet")) { tags = new HashMap<String, String>(1); } else if (name.equals("Tag")) { tagKey = null; tagValue = null; } else if (name.equals("Key")) { text.setLength(0); } else if (name.equals("Value")) { text.setLength(0); } else { log.warn("Ignoring unexpected tag <" + name + ">"); } } @Override public void endElement(String uri, String name, String qName) throws SAXException { if (name.equals("Key")) { tagKey = text.toString(); } else if (name.equals("Value")) { tagValue = text.toString(); } else if (name.equals("Tag")) { if (tagKey != null && tagValue != null) { tags.put(tagKey, tagValue); } } else if (name.equals("TagSet")) { tagSets.add(new TagSet(tags)); } else if (name.equals("Tagging")) { configuration.setTagSets(tagSets); } text.setLength(0); } @Override public void characters(char ch[], int start, int length) { this.text.append(ch, start, length); } } /* HTTP/1.1 200 OK x-amz-id-2: Uuag1LuByRx9e6j5Onimru9pO4ZVKnJ2Qz7/C1NPcfTWAtRPfTaOFg== x-amz-request-id: 656c76696e6727732072657175657374 Date: Tue, 20 Sep 2012 20:34:56 GMT Content-Type: application/xml Transfer-Encoding: chunked Connection: keep-alive Server: AmazonS3 <?xml version="1.0" encoding="UTF-8"?> <DeleteResult> <Deleted> <Key>Key</Key> <VersionId>Version</VersionId> </Deleted> <Error> <Key>Key</Key> <VersionId>Version</VersionId> <Code>Code</Code> <Message>Message</Message> </Error> <Deleted> <Key>Key</Key> <DeleteMarker>true</DeleteMarker> <DeleteMarkerVersionId>Version</DeleteMarkerVersionId> </Deleted> </DeleteResult> */ public class DeleteObjectsHandler extends DefaultHandler { private StringBuilder text; private DeletedObject deletedObject = null; private DeleteError error = null; private List<DeletedObject> deletedObjects = new LinkedList<DeleteObjectsResult.DeletedObject>(); private List<DeleteError> deleteErrors = new LinkedList<MultiObjectDeleteException.DeleteError>(); public DeleteObjectsResponse getDeleteObjectResult() { return new DeleteObjectsResponse(deletedObjects, deleteErrors); } @Override public void startDocument() { text = new StringBuilder(); } @Override public void startElement(String uri, String name, String qName, Attributes attrs) { if (name.equals("Deleted")) { deletedObject = new DeletedObject(); } else if (name.equals("Error")) { error = new DeleteError(); } else if (name.equals("Key")) { } else if (name.equals("VersionId")) { } else if (name.equals("Code")) { } else if (name.equals("Message")) { } else if (name.equals("DeleteMarker")) { } else if (name.equals("DeleteMarkerVersionId")) { } else if (name.equals("DeleteResult")) { } else { log.warn("Unexpected tag: " + name); } text.setLength(0); } @Override public void endElement(String uri, String name, String qName) throws SAXException { if (name.equals("Deleted")) { deletedObjects.add(deletedObject); deletedObject = null; } else if (name.equals("Error")) { deleteErrors.add(error); error = null; } else if (name.equals("Key")) { if (deletedObject != null) { deletedObject.setKey(text.toString()); } else if (error != null) { error.setKey(text.toString()); } } else if (name.equals("VersionId")) { if (deletedObject != null) { deletedObject.setVersionId(text.toString()); } else if (error != null) { error.setVersionId(text.toString()); } } else if (name.equals("Code")) { if (error != null) { error.setCode(text.toString()); } } else if (name.equals("Message")) { if (error != null) { error.setMessage(text.toString()); } } else if (name.equals("DeleteMarker")) { if (deletedObject != null) { deletedObject.setDeleteMarker(text.toString().equals("true")); } } else if (name.equals("DeleteMarkerVersionId")) { if (deletedObject != null) { deletedObject.setDeleteMarkerVersionId(text.toString()); } } } @Override public void characters(char ch[], int start, int length) { this.text.append(ch, start, length); } } /* HTTP/1.1 200 OK x-amz-id-2: Uuag1LuByRx9e6j5Onimru9pO4ZVKnJ2Qz7/C1NPcfTWAtRPfTaOFg== x-amz-request-id: 656c76696e6727732072657175657374 Date: Tue, 20 Sep 2012 20:34:56 GMT Content-Length: xxx Connection: keep-alive Server: AmazonS3 <LifecycleConfiguration> <Rule> <ID>logs-rule</ID> <Prefix>logs/</Prefix> <Status>Enabled</Status> <Transition> <Days>30</Days> <StorageClass>GLACIER</StorageClass> </Transition> <Expiration> <Days>365</Days> </Expiration> </Rule> <Rule> <ID>image-rule</ID> <Prefix>image/</Prefix> <Status>Enabled</Status> <Transition> <Date>2012-12-31T00:00:00.000Z</Date> <StorageClass>GLACIER</StorageClass> </Transition> <Expiration> <Date>2020-12-31T00:00:00.000Z</Date> </Expiration> </Rule> </LifecycleConfiguration> */ public class BucketLifecycleConfigurationHandler extends DefaultHandler { private StringBuilder text; private Rule rule; private List<Rule> rules = new LinkedList<Rule>(); private Transition transition; boolean inTransition = false; public BucketLifecycleConfiguration getConfiguration() { return new BucketLifecycleConfiguration(rules); } @Override public void startDocument() { text = new StringBuilder(); } @Override public void startElement(String uri, String name, String qName, Attributes attrs) { if (name.equals("LifecycleConfiguration")) { } else if (name.equals("Rule")) { rule = new Rule(); } else if (name.equals("ID")) { } else if (name.equals("Prefix")) { } else if (name.equals("Status")) { } else if (name.equals("Transition")) { transition = new Transition(); inTransition = true; } else if (name.equals("StorageClass")) { } else if (name.equals("Date")) { } else if (name.equals("Expiration")) { } else if (name.equals("Days")) { } else { log.warn("Unexpected tag: " + name); } text.setLength(0); } @Override public void endElement(String uri, String name, String qName) throws SAXException { if (name.equals("LifecycleConfiguration")) { } else if (name.equals("Rule")) { rules.add(rule); rule = null; } else if (name.equals("ID")) { rule.setId(text.toString()); } else if (name.equals("Prefix")) { rule.setPrefix(text.toString()); } else if (name.equals("Status")) { rule.setStatus(text.toString()); } else if (name.equals("Transition")) { rule.setTransition(transition); inTransition = false; } else if (name.equals("StorageClass")) { transition.setStorageClass(StorageClass.fromValue(text.toString())); } else if (name.equals("Date")) { if (inTransition == false) { try { rule.setExpirationDate(ServiceUtils.parseIso8601Date(text.toString())); } catch (ParseException e) { rule.setExpirationDate(null); } } else { try { transition.setDate(ServiceUtils.parseIso8601Date(text.toString())); } catch (ParseException e) { transition.setDate(null); } } } else if (name.equals("Expiration")) { } else if (name.equals("Days")) { if (inTransition == false) { rule.setExpirationInDays(Integer.parseInt(text.toString())); } else { transition.setDays(Integer.parseInt(text.toString())); } } else { log.warn("Unexpected tag: " + name); } } @Override public void characters(char ch[], int start, int length) { this.text.append(ch, start, length); } } /* HTTP/1.1 200 OK x-amz-id-2: Uuag1LuByRx9e6j5Onimru9pO4ZVKnJ2Qz7/C1NPcfTWAtRPfTaOFg== x-amz-request-id: 656c76696e6727732072657175657374 Date: Tue, 20 Sep 2011 20:34:56 GMT Content-Length: Some Length Connection: keep-alive Server: AmazonS3 <CORSConfiguration> <CORSRule> <AllowedOrigin>http://www.foobar.com</AllowedOrigin> <AllowedMethod>GET</AllowedMethod> <MaxAgeSeconds>3000</MaxAgeSec> <ExposeHeader>x-amz-server-side-encryption</ExposeHeader> </CORSRule> </CORSConfiguration> */ public class BucketCrossOriginConfigurationHandler extends DefaultHandler { private StringBuilder text; private CORSRule rule; private List<CORSRule> rules = new LinkedList<CORSRule>(); private List<AllowedMethods> allowedMethods = null; private List<String> allowedOrigins = null; private List<String> exposedHeaders = null; private List<String> allowedHeaders = null; public BucketCrossOriginConfiguration getConfiguration() { return new BucketCrossOriginConfiguration(rules); } @Override public void startDocument() { text = new StringBuilder(); } @Override public void startElement(String uri, String name, String qName, Attributes attrs) { if (name.equals("CORSConfiguration")) { } else if (name.equals("CORSRule")) { rule = new CORSRule(); } else if (name.equals("ID")) { } else if (name.equals("AllowedOrigin")) { if (allowedOrigins == null) { allowedOrigins = new LinkedList<String>(); } } else if (name.equals("AllowedMethod")) { if (allowedMethods == null) { allowedMethods = new LinkedList<AllowedMethods>(); } } else if (name.equals("MaxAgeSeconds")) { } else if (name.equals("ExposeHeader")) { if (exposedHeaders == null) { exposedHeaders = new LinkedList<String>(); } } else if (name.equals("AllowedHeader")) { if (allowedHeaders == null) { allowedHeaders = new LinkedList<String>(); } } else { log.warn("Unexpected tag: " + name); } text.setLength(0); } @Override public void endElement(String uri, String name, String qName) throws SAXException { if (name.equals("CORSConfiguration")) { } else if (name.equals("CORSRule")) { rule.setAllowedHeaders(allowedHeaders); rule.setAllowedMethods(allowedMethods); rule.setAllowedOrigins(allowedOrigins); rule.setExposedHeaders(exposedHeaders); allowedHeaders = null; allowedMethods = null; allowedOrigins = null; exposedHeaders = null; rules.add(rule); rule = null; } else if (name.equals("ID")) { rule.setId(text.toString()); } else if (name.equals("AllowedOrigin")) { allowedOrigins.add(text.toString()); } else if (name.equals("AllowedMethod")) { allowedMethods.add(AllowedMethods.fromValue(text.toString())); } else if (name.equals("MaxAgeSeconds")) { rule.setMaxAgeSeconds(Integer.parseInt(text.toString())); } else if (name.equals("ExposeHeader")) { exposedHeaders.add(text.toString()); } else if (name.equals("AllowedHeader")) { allowedHeaders.add(text.toString()); } else { log.warn("Unexpected tag: " + name); } } @Override public void characters(char ch[], int start, int length) { this.text.append(ch, start, length); } } /** * Handler for ListAccessKeysResult XML document. */ public class CtyunListAccessKeyHandler extends DefaultHandler { private ListAccessKeysResult listAccessKeyResult = null; private StringBuilder currText = null; private List<AccessKeyMetadata> accessKeyMetadatas = null; private AccessKeyMetadata accessKeyMetadata = null; public CtyunListAccessKeyHandler() { super(); listAccessKeyResult = new ListAccessKeysResult(); accessKeyMetadata = new AccessKeyMetadata(); this.currText = new StringBuilder(); } public ListAccessKeysResult getAccessKeys() { return listAccessKeyResult; } public void startDocument() { } public void endDocument() { } public void startElement(String uri, String name, String qName, Attributes attrs) { if (name.equals("AccessKeyMetadata")) { accessKeyMetadatas = new ArrayList<AccessKeyMetadata>(); } else if (name.equals("member")) { accessKeyMetadata = new AccessKeyMetadata(); } } public void endElement(String uri, String name, String qName) { String elementText = this.currText.toString().trim(); if (name.equals("AccessKeyId")) { accessKeyMetadata.setAccessKeyId(elementText); } else if (name.equals("UserName")) { accessKeyMetadata.setUserName(elementText); } else if (name.equals("Status")) { accessKeyMetadata.setStatus(elementText); } else if (name.equals("IsPrimary")) { accessKeyMetadata.setCtyunIsPrimary(Boolean.parseBoolean(elementText)); } else if (name.equals("member")) { accessKeyMetadatas.add(accessKeyMetadata); } else if (name.equals("IsTruncated")) { listAccessKeyResult.setIsTruncated(Boolean.parseBoolean(elementText)); } else if (name.equals("AccessKeyMetadata")) { listAccessKeyResult.setAccessKeyMetadata(accessKeyMetadatas); } else if (name.equals("Marker")) { listAccessKeyResult.setMarker(elementText); } this.currText = new StringBuilder(); } public void characters(char ch[], int start, int length) { this.currText.append(ch, start, length); } } /** * Handler for GetUsageResult XML document. */ public class CtyunGetUsageHandler extends DefaultHandler { private CtyunGetUsageResult getUsageResult = null; private StringBuilder currText = null; public CtyunGetUsageHandler() { super(); getUsageResult = new CtyunGetUsageResult(); this.currText = new StringBuilder(); } public CtyunGetUsageResult getUsage() { return getUsageResult; } public void startDocument() { } public void endDocument() { } public void startElement(String uri, String name, String qName, Attributes attrs) { } public void endElement(String uri, String name, String qName) { String elementText = this.currText.toString().trim(); if (name.equals("UserName")) { getUsageResult.setUserName(elementText); } else if (name.equals("Date")) { getUsageResult.setDate(elementText); } else if (name.equals("Capacity")) { getUsageResult.setCapacity(Long.parseLong(elementText)); } else if (name.equals("Upload")) { getUsageResult.setUpload(Long.parseLong(elementText)); } else if (name.equals("Download")) { getUsageResult.setDownload(Long.parseLong(elementText)); } else if (name.equals("GetHeadRequest")) { getUsageResult.setGhRequest(Long.parseLong(elementText)); } else if (name.equals("OtherRequest")) { getUsageResult.setOtherRequest(Long.parseLong(elementText)); } this.currText = new StringBuilder(); } public void characters(char ch[], int start, int length) { this.currText.append(ch, start, length); } } /** * Handler for CreateAccessKeyResult XML document. */ public class CtyunCreateAccessKeyHandler extends DefaultHandler { private StringBuilder currText = null; private CreateAccessKeyResult currentKey = null; private AccessKey accessKey; public CtyunCreateAccessKeyHandler() { super(); this.currText = new StringBuilder(); } public CreateAccessKeyResult getKey() { return currentKey; } public void startDocument() { } public void endDocument() { } public void startElement(String uri, String name, String qName, Attributes attrs) { if (name.equals("AccessKey")) { currentKey = new CreateAccessKeyResult(); accessKey = new AccessKey(); } } public void endElement(String uri, String name, String qName) { String elementText = this.currText.toString().trim(); if (name.equals("AccessKeyId")) { accessKey.setAccessKeyId(elementText); } else if (name.equals("SecretAccessKey")) { accessKey.setSecretAccessKey(elementText); } else if (name.equals("Status")) { accessKey.setStatus(elementText); } else if (name.equals("IsPrimary")) { accessKey.setCtyunIsPrimary(Boolean.parseBoolean(elementText)); } else if (name.equals("AccessKey")) { currentKey.setAccessKey(accessKey); } this.currText = new StringBuilder(); } public void characters(char ch[], int start, int length) { this.currText.append(ch, start, length); } } private static String findAttributeValue(String qnameToFind, Attributes attrs) { for (int i = 0; i < attrs.getLength(); i++) { String qname = attrs.getQName(i); if (qname.trim().equalsIgnoreCase(qnameToFind.trim())) { return attrs.getValue(i); } } return null; } public class CtyunBucketTriggerConfigurationHandler extends DefaultHandler { private CtyunBucketTriggerConfiguration configuration = new CtyunBucketTriggerConfiguration(); private List<CtyunRemoteSite> sites = null; private CtyunRemoteSite site = null; private StringBuilder text; private CtyunTriggerMetadata trigger = null; public CtyunBucketTriggerConfiguration getConfiguration() { return configuration; } @Override public void startDocument() { text = new StringBuilder(); } @Override public void startElement(String uri, String name, String qName, Attributes attrs) { if (name.equals("TriggerConfiguration")) { sites = new ArrayList<CtyunRemoteSite>(); configuration.setTriggers(new ArrayList<CtyunTriggerMetadata>()); } else if (name.equals("Trigger")) { trigger = new CtyunTriggerMetadata(); } else if (name.equals("RemoteSite")) { site = new CtyunRemoteSite(); } } @Override public void endElement(String uri, String name, String qName) throws SAXException { String elementText = this.text.toString().trim(); if (name.equals("TriggerName")) { trigger.setTriggerName(elementText); } else if (name.equals("IsDefault")) { trigger.setDefault(Boolean.parseBoolean(elementText)); } else if (name.equals("RemontEndPoint")) { site.setRemoteEndPoint(elementText); } else if (name.equals("ReplicaMode")) { site.setReplicaMode(elementText); } else if (name.equals("RemoteBucketName")) { site.setRemoteBucketName(elementText); } else if (name.equals("RemoteAK")) { site.setRemoteAK(elementText); } else if (name.equals("RemoteSK")) { site.setRemoteSK(elementText); } else if (name.equals("RemoteSite")) { sites.add(site); } else if (name.equals("Trigger")) { trigger.setRemoteSites(sites); configuration.getTriggers().add(trigger); } this.text = new StringBuilder(); } @Override public void characters(char ch[], int start, int length) { this.text.append(ch, start, length); } } }