content: package jp.aegif.nemaki.aws.tools.backup;
  
  import java.io.File;
  import java.io.IOException;
  import java.net.URI;
  import java.net.URISyntaxException;
  import java.util.ArrayList;
  import java.util.List;
  
  import org.apache.http.client.utils.URIUtils;
  
  import jp.aegif.nemaki.bjornloka.dump.*;
  import com.amazonaws.AmazonClientException;
  import com.amazonaws.AmazonServiceException;
  import com.amazonaws.auth.profile.ProfileCredentialsProvider;
  import com.amazonaws.event.ProgressEvent;
  import com.amazonaws.event.ProgressListener;
  import com.amazonaws.regions.Region;
  import com.amazonaws.regions.Regions;
  import com.amazonaws.services.s3.AmazonS3;
  import com.amazonaws.services.s3.AmazonS3Client;
  import com.amazonaws.services.s3.model.PutObjectRequest;
  import com.amazonaws.services.s3.transfer.TransferManager;
  import com.amazonaws.services.s3.transfer.Upload;
  
  import org.json.*;
  import javax.ws.rs.client.*;
  import javax.ws.rs.core.*;
  
  public class BackupCouchDbToS3Util {
  	static String DefaultCouchDbUrl = "http://localhost:5984/";
  	static String DefaultProfileName = "NemakiWare";
  
  	public void backup(String bucketName) {
  		try {
  			URI uri = new URI(DefaultCouchDbUrl);
  			backup(bucketName, uri, DefaultProfileName, new String[0]);
  		} catch (Exception ex) {
  		}
  	}
  
  	public void backup(String bucketName, URI url) {
  		backup(bucketName, url, DefaultProfileName, new String[0]);
  	}
  
  	public void backup(String bucketName, URI url, String profileName) {
  		backup(bucketName, url, profileName, new String[0]);
  	}
  
  	public void backup(String bucketName, URI url, String profileName, String targets) {
  		if (targets == null | targets == "") {
  			backup(bucketName, url, profileName, new String[0]);
  		} else {
  			backup(bucketName, url, profileName, targets.split(",", -1));
  		}
  	}
  
  	public void backup(String bucketName, URI couchUrl, String profileName, String[] targets) {
  		String[] targetDbs = targets;
  		AmazonS3 s3client = new AmazonS3Client(new ProfileCredentialsProvider(profileName));
  		TransferManager tm = new TransferManager(s3client);
  
  		try{
  		String uriScheme = couchUrl.getScheme();
  
  		if (targetDbs == null || targetDbs.length == 0) {
  			URI targetRestURL = couchUrl;
  			if (uriScheme.equals("file")) {
  				try {
  					targetRestURL = new URI(DefaultCouchDbUrl);
  				} catch (URISyntaxException e) {
  				}
  			}
  			List<String> list = getAllTargets(targetRestURL);
  			targetDbs = (String[]) list.toArray(new String[0]);
  		}
  
  		for (String repositoryName : targetDbs) {
  			System.out.println("[" + repositoryName + "] Backup started. ");
  
  			if (repositoryName == null || repositoryName == "")
  				continue;
  
  			File file;
  			try {
  				if (uriScheme.equals("http") || uriScheme.equals("https")) {
  					file = File.createTempFile(repositoryName, ".bk.dump");
  					String couchURI = couchUrl.toString();
  					DumpAction action = DumpAction.getInstance(couchURI, repositoryName, file, false);
  					action.dump();
  				} else if (uriScheme.equals("file")) {
  					couchUrl = couchUrl.resolve(repositoryName + ".couch");
  					file = new File(couchUrl);
  				} else {
  					System.out.printf("Error : Invalid scheme :  %s \n", uriScheme);
  					continue;
  				}
  
  				if (file.exists()) {
  					uploadS3(tm, file, bucketName, repositoryName);
  				} else {
  					System.out.println("Error : Backup file not found");
  					System.out.println(file.getPath());
  					System.out.println(couchUrl.toString());
  					continue;
  				}
  			} catch (IOException e) {
  				e.printStackTrace();
  			}
  		}
  		}finally{
  			tm.shutdownNow(true);
  		}
  	}
  
  	public List<String> getAllTargets(URI couchUrl) {
  		Client client = ClientBuilder.newClient();
  		String jsonArrayString = client.target(couchUrl).path("_all_dbs").request(MediaType.APPLICATION_JSON_TYPE)
  				.get(String.class);
  		JSONArray jsonArray = new JSONArray(jsonArrayString);
  		List<String> list = new ArrayList<String>();
  		for (int i = 0; i < jsonArray.length(); i++) {
  			list.add(jsonArray.getString(i));
  		}
  		return list;
  	}
  
  	public void uploadS3(TransferManager tm, File file, String bucketName, String repositoryName) {
  		try {
  			PutObjectRequest request = new PutObjectRequest(bucketName, repositoryName, file);
  			request.setGeneralProgressListener(new BackupFileUploadProgressListener(repositoryName));
  			System.out.println("[" + repositoryName + "] Upload started. ");
  			Upload uploader = tm.upload(request);
  			try {
  				uploader.waitForCompletion();
  				System.out.println("[" + repositoryName + "] Upload complete. ");
  			} catch (AmazonClientException amazonClientException) {
  				System.out.println("[" + repositoryName + "] Unable to upload file, upload was aborted. ");
  				amazonClientException.printStackTrace();
  			} catch (InterruptedException e) {
  				System.out.println("[" + repositoryName + "] Unable to upload file, upload was interrupted. ");
  				e.printStackTrace();
  			}
  			uploader = null;
  
  		} catch (AmazonServiceException ase) {
  			System.out.println("Caught an AmazonServiceException, which " + "means your request made it "
  					+ "to Amazon S3, but was rejected with an error response" + " for some reason.");
  			System.out.println("Error Message:    " + ase.getMessage());
  			System.out.println("HTTP Status Code: " + ase.getStatusCode());
  			System.out.println("AWS Error Code:   " + ase.getErrorCode());
  			System.out.println("Error Type:       " + ase.getErrorType());
  			System.out.println("Request ID:       " + ase.getRequestId());
  		} catch (AmazonClientException ace) {
  			System.out.println("Caught an AmazonClientException, which " + "means the client encountered "
  					+ "an internal error while trying to " + "communicate with S3, "
  					+ "such as not being able to access the network.");
  			System.out.println("Error Message: " + ace.getMessage());
  		}
  	}
  }
  