Project: AirCastingAndroidClient
/*
 * Copyright 2011 Ytai Ben-Tsvi. All rights reserved. 
 *   
 *  
 * Redistribution and use in source and binary forms, with or without modification, are 
 * permitted provided that the following conditions are met: 
 *  
 *    1. Redistributions of source code must retain the above copyright notice, this list of 
 *       conditions and the following disclaimer. 
 *  
 *    2. Redistributions in binary form must reproduce the above copyright notice, this list 
 *       of conditions and the following disclaimer in the documentation and/or other materials 
 *       provided with the distribution. 
 *  
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR 
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 *  
 * The views and conclusions contained in the software and documentation are those of the 
 * authors and should not be interpreted as representing official policies, either expressed 
 * or implied. 
 */
package ioio.lib.util; 
 
import android.util.Log; 
import ioio.lib.api.IOIOFactory; 
import ioio.lib.spi.IOIOConnectionBootstrap; 
import ioio.lib.spi.IOIOConnectionFactory; 
import ioio.lib.spi.NoRuntimeSupportException; 
 
import java.util.Collection; 
import java.util.LinkedList; 
 
/**
 * A utility class for managing available connection types to IOIO. 
 * <p/> 
 * <b>For advanced usage only!</b> 
 * <p/> 
 * This class facilitates dynamic linkage and instantiation of different IOIO 
 * connection types. {@link ioio.lib.spi.IOIOConnectionBootstrap} classes enable creation of 
 * {@link ioio.lib.spi.IOIOConnectionFactory} instances, from which concrete 
 * {@link ioio.lib.api.IOIOConnection}s are created. The binding to 
 * {@link ioio.lib.spi.IOIOConnectionBootstrap} is dynamic, thus enabling linkage to succeed 
 * with or without those bootstraps. Likewise, during runtime, the absence of 
 * bootstraps is handled gracefully. 
 * <p/> 
 * A typical usage will call {@link #addBootstraps(String[])} with a list of 
 * class names to be sought from a static initializer block. It may then call 
 * {@link #getBootstraps()} to obtain any bootstrap classes that are available 
 * in runtime, in case the bootstrap classes themselves need some runtime 
 * handling. Last, the {@link #getConnectionFactories()} will return a 
 * collection of {@link ioio.lib.spi.IOIOConnectionFactory}, each representing one possible 
 * communication channel to a IOIO. 
 */
 
public class IOIOConnectionRegistry 
  /**
   * Get all available connection specifications. This is a list of all 
   * currently available communication channels in which a IOIO may be 
   * available. The client typically passes elements of this collection to 
   * {@link IOIOFactory#create(ioio.lib.api.IOIOConnection)}, possibly after filtering 
   * based on the specification's properties. 
   * 
   * @return A collection of specifications. 
   */
 
  public static Collection<IOIOConnectionFactory> getConnectionFactories() 
  { 
    Collection<IOIOConnectionFactory> result = new LinkedList<IOIOConnectionFactory>(); 
    for (IOIOConnectionBootstrap bootstrap : bootstraps_) 
    { 
      bootstrap.getFactories(result); 
    } 
    return result; 
  } 
 
  /**
   * For advanced usage only! Used for special runtime handling of bootstrap 
   * classes. 
   * 
   * @return The bootstraps. 
   */
 
  public static Collection<IOIOConnectionBootstrap> getBootstraps() 
  { 
    return bootstraps_; 
  } 
 
  /**
   * For advanced usage only! Add platform-specific connection bootstrap 
   * classes. Call before calling {@link #getConnectionFactories()}. 
   */
 
  public static void addBootstraps(String[] classNames) 
  { 
    for (String className : classNames) 
    { 
      addBootstrap(className); 
    } 
  } 
 
  private static final String TAG = "IOIOConnectionRegistry"
 
  private static Collection<IOIOConnectionBootstrap> bootstraps_; 
 
  static 
  { 
    bootstraps_ = new LinkedList<IOIOConnectionBootstrap>(); 
  } 
 
  private static void addBootstrap(String className) 
  { 
    try 
    { 
      Class<? extends IOIOConnectionBootstrap> bootstrapClass = Class 
          .forName(className).asSubclass( 
              IOIOConnectionBootstrap.class); 
      bootstraps_.add(bootstrapClass.newInstance()); 
      Log.d(TAG, "Successfully added bootstrap class: " + className); 
    } 
    catch (ClassNotFoundException e) 
    { 
      Log.d(TAG, "Bootstrap class not found: " + className + ". Not adding."); 
    } 
    catch (NoRuntimeSupportException e) 
    { 
      Log.d(TAG, "No runtime support for: " + className + ". Not adding."); 
    } 
    catch (Throwable e) 
    { 
      Log.e(TAG, "Exception caught while attempting to initialize accessory connection factory", e); 
    } 
  } 
 
}