Package org.akubraproject.mux

Source Code of org.akubraproject.mux.AbstractMuxConnection

/* $HeadURL::                                                                            $
* $Id$
*
* Copyright (c) 2009-2010 DuraSpace
* http://duraspace.org
*
* In collaboration with Topaz Inc.
* http://www.topazproject.org
*
* 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 org.akubraproject.mux;

import java.io.IOException;

import java.net.URI;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.transaction.Transaction;

import com.google.common.collect.Iterators;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.akubraproject.Blob;
import org.akubraproject.BlobStore;
import org.akubraproject.BlobStoreConnection;
import org.akubraproject.UnsupportedIdException;
import org.akubraproject.impl.AbstractBlobStoreConnection;

/**
* An abstract base class for connections returned by multiplexing BlobStores. Sub-class
* implementations must provide a {@link #getStore} implementation. Additionally for multiplexing
* content addressable stores, sub-classes must override the default implementation of {@link
* org.akubraproject.impl.AbstractBlobStoreConnection#getBlob(java.io.InputStream, long,
* Map)} and direct the call to the appropriate backing store. Note that the returned Blob from
* the backing store must be wrapped so that the {@link
* org.akubraproject.Blob#getConnection()} of the returned Blob will return this connection
* object.
*
* @author Pradeep Krishnan
*
* @see #getStore(URI, Map)
* @see #getStores(String)
* @see #getConnection(BlobStore, Map)
* @see MuxBlob
*/
public abstract class AbstractMuxConnection extends AbstractBlobStoreConnection {
  private static final Logger log = LoggerFactory.getLogger(AbstractBlobStoreConnection.class);

  /**
   * The transaction to pass to while opening connections to the backing stores. Note that
   * this transaction is only passed to transaction capable stores. A null is passed for
   * non-transactional stores.
   *
   * @see #getConnection(BlobStore, Map)
   */
  protected final Transaction txn;

  /**
   * A map of store-ids to connections.
   *
   * @see #getConnection(BlobStore, Map)
   * @see #close()
   */
  protected Map<URI, BlobStoreConnection> cons = new HashMap<URI, BlobStoreConnection>();

  /**
   * Creates a new AbstractMuxConnection object.
   *
   * @param store the mux store
   * @param txn the txn passed in by the user
   */
  public AbstractMuxConnection(BlobStore store, Transaction txn) {
    super(store);
    this.txn = txn;
  }

  /**
   * Gets the backing store where the given blob is persisted.
   *
   * @param blobId the blob id (can be null)
   * @param hints A set of hints to allow the implementation to optimize the operation (can be
   *        null)
   *
   * @return the store. Cannot be null and must be one of the backing stores.
   *
   * @throws IOException for IO errors
   * @throws UnsupportedIdException if blobId is not in a recognized/usable pattern by any of the
   *         backing stores
   */
  public abstract BlobStore getStore(URI blobId, Map<String, String> hints)
                              throws IOException, UnsupportedIdException;

  /**
   * Gets the set of a backing stores matching the given blobId prefix. By default the
   * returned set is the set of all backing stores. Override in sub-classes to narrow down the
   * set.
   *
   * @param prefix the blobId prefix or null
   *
   * @return the set of stores matching the blobId prefix
   */
  public Set<BlobStore> getStores(String prefix) {
    return new HashSet<BlobStore>(((AbstractMuxStore) getBlobStore()).getBackingStores());
  }

  /**
   * Closes this connection and all underlying connections created using {@link
   * #getConnection(BlobStore, Map)}.
   */
  @Override
  public void close() {
    super.close();

    if (cons != null) {
      for (BlobStoreConnection con : cons.values())
        con.close();

      cons.clear();
      cons = null;
    }
  }

  /**
   * Lookup/Create a connection to the given backing store.
   *
   * @param store the backing store
   * @param hints A set of hints to allow the implementation to optimize the operation (can be
   *              null)
   *
   * @return the backing store connection or null
   *
   * @throws IOException on an error in opening a connection to the backing store
   * @throws UnsupportedOperationException on an error in opening a connection to the backing store
   */
  protected BlobStoreConnection getConnection(BlobStore store, Map<String, String> hints)
                                       throws IOException {
    if (store == null)
      return null;

    if (cons == null)
      throw new IllegalStateException("Connection closed.");

    BlobStoreConnection con = cons.get(store.getId());

    if (con == null) {
      con = store.openConnection(txn, hints);
      cons.put(store.getId(), con);
    }

    return con;
  }

  @Override
  public Blob getBlob(URI blobId, Map<String, String> hints)
               throws IOException {
    return new MuxBlob(getConnection(getStore(blobId, hints), hints).getBlob(blobId, hints), this);
  }

  @Override
  public Iterator<URI> listBlobIds(String filterPrefix) throws IOException {
    List<Iterator<URI>> iterators = new ArrayList<Iterator<URI>>();

    for (BlobStore store : getStores(filterPrefix))
      iterators.add(getConnection(store, null).listBlobIds(filterPrefix));

    return Iterators.concat(iterators.iterator());
  }

  @Override
  public void sync() throws IOException {
    if (cons == null)
      throw new IllegalStateException("Connection closed.");

    Exception exc = null;

    for (BlobStoreConnection con : cons.values()) {
      try {
        con.sync();
      } catch (Exception e) {
        if (exc == null)
          exc = e;
        else
          log.warn("Error sync'ing connection " + con, e);
      }
    }

    if (exc instanceof IOException)
      throw (IOException) exc;
    if (exc instanceof RuntimeException)
      throw (RuntimeException) exc;
  }
}
TOP

Related Classes of org.akubraproject.mux.AbstractMuxConnection

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.