com.xerox.amazonws.sdb.Domain.java Source code

Java tutorial

Introduction

Here is the source code for com.xerox.amazonws.sdb.Domain.java

Source

//
// typica - A client library for Amazon Web Services
// Copyright (C) 2007 Xerox Corporation
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License 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 com.xerox.amazonws.sdb;

import java.io.InputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import javax.xml.bind.JAXBException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.GetMethod;

import com.xerox.amazonws.common.AWSQueryConnection;
import com.xerox.amazonws.typica.sdb.jaxb.QueryResponse;

/**
 * This class provides an interface with the Amazon SDB service. It provides methods for
 * listing and deleting items.
 *
 * @author D. Kavanagh
 * @author developer@dotech.com
 */
public class Domain extends AWSQueryConnection {

    private static Log logger = LogFactory.getLog(Domain.class);

    private String domainName;
    private int maxThreads = 30;
    private ThreadPoolExecutor executor;

    protected Domain(String domainName, String awsAccessId, String awsSecretKey, boolean isSecure, String server)
            throws SDBException {
        super(awsAccessId, awsSecretKey, isSecure, server, isSecure ? 443 : 80);
        this.domainName = domainName;
        SimpleDB.setVersionHeader(this);
    }

    /**
     * Gets the name of the domain represented by this object.
     *
      * @return the name of the domain
     */
    public String getName() {
        return domainName;
    }

    /**
     * Gets the max number of threads to use for the threaded operations.
     *
      * @return max number of threads being used
     */
    public int getMaxThreads() {
        return maxThreads;
    }

    /**
     * Sets the max number of threads to use for the threaded operations.
     *
     * @param threads the new max to set
     */
    public void setMaxThreads(int threads) {
        maxThreads = threads;
    }

    /**
     * Method for getting an Item object without getting a list of them.
     *
     * @param identifier id of the item
      * @return the object representing the item
     * @throws SDBException wraps checked exceptions
     */
    public Item getItem(String identifier) throws SDBException {
        Item ret = new Item(identifier, domainName, getAwsAccessKeyId(), getSecretAccessKey(), isSecure(),
                getServer());
        ret.setSignatureVersion(getSignatureVersion());
        ret.setHttpClient(getHttpClient());
        return ret;
    }

    /**
     * Gets a list of all items in this domain
     *
      * @return the object containing the items, a more token, etc.
     * @throws SDBException wraps checked exceptions
     */
    public QueryResult listItems() throws SDBException {
        return listItems(null);
    }

    /**
     * Gets a list of items in this domain filtered by the query string.
     *
     * @param queryString the filter statement
      * @return the object containing the items, a more token, etc.
     * @throws SDBException wraps checked exceptions
     */
    public QueryResult listItems(String queryString) throws SDBException {
        return listItems(queryString, null);
    }

    /**
     * Gets a list of items in this domain filtered by the query string.
     *
     * @param queryString the filter statement
     * @param nextToken the token used to return more items in the query result set
      * @return the object containing the items, a more token, etc.
     * @throws SDBException wraps checked exceptions
     */
    public QueryResult listItems(String queryString, String nextToken) throws SDBException {
        return listItems(queryString, null, 0);
    }

    /**
     * Gets a list of items in this domain filtered by the query string.
     *
     * @param queryString the filter statement
     * @param nextToken the token used to return more items in the query result set
     * @param maxResults a limit to the number of results to return now
      * @return the object containing the items, a more token, etc.
     * @throws SDBException wraps checked exceptions
     */
    public QueryResult listItems(String queryString, String nextToken, int maxResults) throws SDBException {
        Map<String, String> params = new HashMap<String, String>();
        params.put("DomainName", domainName);
        params.put("QueryExpression", (queryString == null) ? "" : queryString);
        if (nextToken != null) {
            params.put("NextToken", nextToken);
        }
        if (maxResults > 0) {
            params.put("MaxNumberOfItems", "" + maxResults);
        }
        GetMethod method = new GetMethod();
        try {
            QueryResponse response = makeRequest(method, "Query", params, QueryResponse.class);
            return new QueryResult(response.getQueryResult().getNextToken(),
                    Item.createList(response.getQueryResult().getItemNames().toArray(new String[] {}), domainName,
                            getAwsAccessKeyId(), getSecretAccessKey(), isSecure(), getServer(),
                            getSignatureVersion(), getHttpClient()));
        } catch (JAXBException ex) {
            throw new SDBException("Problem parsing returned message.", ex);
        } catch (HttpException ex) {
            throw new SDBException(ex.getMessage(), ex);
        } catch (IOException ex) {
            throw new SDBException(ex.getMessage(), ex);
        } finally {
            method.releaseConnection();
        }
    }

    /**
     * Gets attributes of given items. This method threads off the get requests and
     * aggregates the responses.
     *
     * @param items the list of items to get attributes for
      * @return the map of items with lists of attributes
     * @throws SDBException wraps checked exceptions
     */
    public Map<String, List<ItemAttribute>> getItemsAttributes(List<String> items) throws SDBException {
        Map<String, List<ItemAttribute>> results = new Hashtable<String, List<ItemAttribute>>();
        ThreadPoolExecutor pool = getThreadPoolExecutor();
        pool.setRejectedExecutionHandler(new RejectionHandler());

        Counter running = new Counter(0);
        for (String item : items) {
            while (pool.getActiveCount() == pool.getMaximumPoolSize()) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException ex) {
                }
            }
            synchronized (running) {
                running.increment();
            }
            pool.execute(new AttrWorker(getItem(item), running, results, null));
            Thread.yield();
        }
        while (true) {
            if (running.getValue() == 0) {
                break;
            }
            try {
                Thread.sleep(500);
            } catch (InterruptedException ex) {
            }
        }
        if (this.executor == null) {
            pool.shutdown();
        }
        return results;
    }

    /**
     * Gets attributes of given items. This method threads off the get requests and
     * aggregates the responses.
     *
     * @param items the list of items to get attributes for
     * @param listener class that will be notified when items are ready
     * @throws SDBException wraps checked exceptions
     */
    public void getItemsAttributes(List<String> items, ItemListener listener) throws SDBException {
        ThreadPoolExecutor pool = getThreadPoolExecutor();
        pool.setRejectedExecutionHandler(new RejectionHandler());

        Counter running = new Counter(0);
        for (String item : items) {
            while (pool.getActiveCount() == pool.getMaximumPoolSize()) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException ex) {
                }
            }
            synchronized (running) {
                running.increment();
            }
            pool.execute(new AttrWorker(getItem(item), running, null, listener));
            Thread.yield();
        }
        while (true) {
            if (running.getValue() == 0) {
                break;
            }
            try {
                Thread.sleep(500);
            } catch (InterruptedException ex) {
            }
        }
        if (this.executor == null) {
            pool.shutdown();
        }
    }

    /**
     * Gets attributes of items specified in the query string. This method threads off the
     * get requests and aggregates the responses.
     *
     * @param queryString the filter statement
     * @param listener class that will be notified when items are ready
     * @throws SDBException wraps checked exceptions
     */
    public void listItemsAttributes(String queryString, ItemListener listener) throws SDBException {
        ThreadPoolExecutor pool = getThreadPoolExecutor();
        pool.setRejectedExecutionHandler(new RejectionHandler());
        String nextToken = "";
        Counter running = new Counter(0);
        do {
            try {
                QueryResult result = listItems(queryString, nextToken, 250);
                List<Item> items = result.getItemList();
                for (Item i : items) {
                    while (pool.getActiveCount() == pool.getMaximumPoolSize()) {
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException ex) {
                        }
                    }
                    synchronized (running) {
                        running.increment();
                    }
                    pool.execute(new AttrWorker(i, running, null, listener));
                    Thread.yield();
                }
                nextToken = result.getNextToken();
            } catch (SDBException ex) {
                System.out.println("Query '" + queryString + "' Failure: ");
                ex.printStackTrace();
            }
        } while (nextToken != null && nextToken.trim().length() > 0);
        while (true) {
            if (running.getValue() == 0) {
                break;
            }
            try {
                Thread.sleep(500);
            } catch (InterruptedException ex) {
            }
        }
        if (this.executor == null) {
            pool.shutdown();
        }
    }

    /**
     * Deletes an item.
     *
     * @param identifier the name of the item to be deleted
     * @throws SDBException wraps checked exceptions
     */
    public void deleteItem(String identifier) throws SDBException {
        getItem(identifier).deleteAttributes(null);
    }

    static List<Domain> createList(String[] domainNames, String awsAccessKeyId, String awsSecretAccessKey,
            boolean isSecure, String server, int signatureVersion, HttpClient hc) throws SDBException {
        ArrayList<Domain> ret = new ArrayList<Domain>();
        for (int i = 0; i < domainNames.length; i++) {
            Domain dom = new Domain(domainNames[i], awsAccessKeyId, awsSecretAccessKey, isSecure, server);
            dom.setSignatureVersion(signatureVersion);
            dom.setHttpClient(hc);
            ret.add(dom);
        }
        return ret;
    }

    public ThreadPoolExecutor getThreadPoolExecutor() {
        if (executor != null) {
            return executor;
        } else {
            return new ThreadPoolExecutor(maxThreads, maxThreads, 5, TimeUnit.SECONDS,
                    new ArrayBlockingQueue(maxThreads));
        }
    }

    public void setThreadPoolExecutor(ThreadPoolExecutor executor) {
        this.executor = executor;
    }

    protected class RejectionHandler implements RejectedExecutionHandler {
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            // ok, on the rare occasion, just run it here!
            r.run();
        }
    }
}