/* * 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); } } }