/* * Copyright (c) 2006, KNOPFLERFISH project * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - 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. * * - Neither the name of the KNOPFLERFISH project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "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 THE * COPYRIGHT OWNER 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. */ package org.knopflerfish.bundle.io; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Hashtable; import java.util.ArrayList; import javax.microedition.io.Connector; import javax.microedition.io.Connection; import javax.microedition.io.InputConnection; import javax.microedition.io.OutputConnection; import javax.microedition.io.ConnectionNotFoundException; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.framework.ServiceReference; import org.osgi.framework.ServiceListener; import org.osgi.framework.ServiceEvent; import org.osgi.framework.InvalidSyntaxException; import org.osgi.service.io.ConnectorService; import org.osgi.service.io.ConnectionFactory; class ConnectorServiceImpl implements ConnectorService { private static BundleContext bc = null; public ConnectorServiceImpl(BundleContext bc) { this.bc = bc; } public Connection open(String uri) throws IOException { return open(uri, ConnectorService.READ_WRITE); } public Connection open(String uri, int mode) throws IOException { return open(uri, mode, false); } public Connection open(String uri, int mode, boolean timeouts) throws IOException { if (mode != Connector.READ && mode != Connector.WRITE && mode != Connector.READ_WRITE) throw new IllegalArgumentException("Variable mode has an invalid value"); int schemeSeparator = uri.indexOf(':'); if (schemeSeparator < 0) { throw new IllegalArgumentException("Not a valid URI"); } String scheme = uri.substring(0, schemeSeparator); ConnectionFactory factory = getFactory(scheme); Connection retval = null; if (factory != null) { retval = factory.createConnection(uri, mode, timeouts); } else { // fall back to Connector. try { retval = Connector.open(uri, mode, timeouts); } catch (Exception e) { throw new ConnectionNotFoundException(); } } if (retval == null) throw new ConnectionNotFoundException(); else return retval; } private ConnectionFactory getFactory(String scheme) { ServiceReference[] refs = null; try { refs = bc.getServiceReferences(ConnectionFactory.class.getName(), null); } catch (InvalidSyntaxException e) { // this should not be happening } if (refs == null) { return null; } ArrayList list = new ArrayList(); // matching services for (int i = 0; i < refs.length; i++) { String[] tmp = (String[])refs[i].getProperty(ConnectionFactory.IO_SCHEME); for (int o = 0; o < tmp.length; o++) { if (scheme.equalsIgnoreCase(tmp[o])) { list.add(refs[i]); break; } } } if (list.isEmpty()) { return null; } ServiceReference bestRef = (ServiceReference)list.get(0); if (list.size() == 1) return (ConnectionFactory)bc.getService(bestRef); int bestRanking = getRanking(bestRef); int rank; ServiceReference ref; for (int i = 1; i < list.size(); i++) { ref = (ServiceReference)list.get(i); rank = getRanking(ref); if (rank > bestRanking) { // by highest rank, then lowest service id. bestRanking = rank; bestRef = ref; } else { if (rank == bestRanking) { Long l1 = (Long)ref.getProperty(Constants.SERVICE_ID); Long l2 = (Long)bestRef.getProperty(Constants.SERVICE_ID); if (l1.compareTo(l2) < 0) { bestRef = ref; } } } } return (ConnectionFactory)bc.getService(bestRef); } /* Returns 0 (default value) if there is not rank for the specificed service or if it has an invalid rank. */ private int getRanking(ServiceReference ref) { Object rank = (Object)ref.getProperty(Constants.SERVICE_RANKING); if (rank == null) return 0; if (rank instanceof Integer) return ((Integer)rank).intValue(); else return 0; } public DataInputStream openDataInputStream(String name) throws IOException { Connection con = open(name, ConnectorService.READ, false); if (con instanceof InputConnection) { DataInputStream stream = ((InputConnection)con).openDataInputStream(); con.close(); return stream; } con.close(); throw new IOException("Given scheme does not support input"); } public DataOutputStream openDataOutputStream(String name) throws IOException { Connection con = open(name, ConnectorService.WRITE, false); if (con instanceof OutputConnection) { DataOutputStream stream = ((OutputConnection)con).openDataOutputStream(); con.close(); return stream; } con.close(); throw new IOException("Given scheme does not support output"); } public InputStream openInputStream(String name) throws IOException { Connection con = open(name, ConnectorService.READ, false); if (con instanceof InputConnection) { InputStream stream = ((InputConnection)con).openInputStream(); con.close(); return stream; } con.close(); throw new IOException("Given scheme does not support input"); } public OutputStream openOutputStream(String name) throws IOException { Connection con = open(name, ConnectorService.WRITE, false); if (con instanceof OutputConnection) { OutputStream stream = ((OutputConnection)con).openOutputStream(); con.close(); return stream; } con.close(); throw new IOException("Given scheme does not support output"); } }