Package org.apache.felix.io

Source Code of org.apache.felix.io.ConnectorServiceImpl

/**
*  Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You 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.apache.felix.io;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.microedition.io.Connection;
import javax.microedition.io.ConnectionNotFoundException;
import javax.microedition.io.Connector;
import javax.microedition.io.InputConnection;
import javax.microedition.io.OutputConnection;

import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.service.io.ConnectionFactory;
import org.osgi.service.io.ConnectorService;
import org.osgi.util.tracker.ServiceTracker;

/**
* <p>
* The Connector Service should be called to create and open <code>javax.microedition.io.Connection</code> objects.
* </p>
*
* @see ConnectorService
* @version $Rev$ $Date$
*/
public class ConnectorServiceImpl implements ConnectorService
{

    ServiceTracker m_connFactoryTracker;

    /**
     * Constructs new ConnectorService.
     *
     * @param context
     *            bundleContext @see {@link BundleContext}.
     */
    public ConnectorServiceImpl(BundleContext context)
    {
        this.m_connFactoryTracker = new ServiceTracker(context, ConnectionFactory.class.getName(), null);
        m_connFactoryTracker.open();
    }

    /**
     * Stops ConnectorService. This method closes {@link ConnectionFactory} serviceTracker.
     *
     * @see ServiceTracker#close()
     */
    public void stop()
    {
        m_connFactoryTracker.close();
    }

    /**
     * @see org.osgi.service.io.ConnectorService#openDataInputStream(java.lang.String)
     */
    public DataInputStream openDataInputStream(String name) throws IOException
    {
        Connection connection = open(name, READ, false);
        if (!(connection instanceof InputConnection))
        {
            try
            {
                connection.close();
            } catch (IOException ioex)
            {

            }

            throw new IOException("Connection doesn't implement InputConnection" + connection.getClass());
        }

        return ((InputConnection) connection).openDataInputStream();
    }

    /**
     * @see org.osgi.service.io.ConnectorService#openDataOutputStream(java.lang.String)
     */
    public DataOutputStream openDataOutputStream(String name) throws IOException
    {
        Connection connection = open(name, WRITE, false);
        if (!(connection instanceof OutputConnection))
        {
            try
            {
                connection.close();
            } catch (IOException ioex)
            {

            }

            throw new IOException("Connection doesn't implement OutputConnection" + connection.getClass());
        }

        return ((OutputConnection) connection).openDataOutputStream();
    }

    /**
     * @see org.osgi.service.io.ConnectorService#openInputStream(java.lang.String)
     */
    public InputStream openInputStream(String name) throws IOException
    {
        Connection connection = open(name, READ, false);
        if (!(connection instanceof InputConnection))
        {
            try
            {
                connection.close();
            } catch (IOException ioex)
            {

            }

            throw new IOException("Connection doesn't implement InputConnection" + connection.getClass());
        }

        return ((InputConnection) connection).openInputStream();
    }

    /**
     * @see org.osgi.service.io.ConnectorService#openOutputStream(java.lang.String)
     */
    public OutputStream openOutputStream(String name) throws IOException
    {
        Connection connection = open(name, WRITE, false);
        if (!(connection instanceof OutputConnection))
        {
            try
            {
                connection.close();
            } catch (IOException ioex)
            {

            }

            throw new IOException("Connection doesn't implement OutputConnection" + connection.getClass());
        }

        return ((OutputConnection) connection).openOutputStream();
    }

    /**
     * @see org.osgi.service.io.ConnectorService#open(String)
     */
    public Connection open(String name) throws IOException
    {
        return open(name, READ_WRITE, false);
    }

    /**
     * @see org.osgi.service.io.ConnectorService#open(String, int)
     */
    public Connection open(String name, int mode) throws IOException
    {
        return open(name, mode, false);
    }

    /**
     * @see org.osgi.service.io.ConnectorService#open(String, int, boolean)
     */
    public Connection open(String name, int mode, boolean timeouts) throws IOException
    {
        if (name == null)
        {
            throw new IllegalArgumentException("URI for the connection can't be null!");
        }

        // resolving scheme name
        int index = name.indexOf(":");
        if (index == -1)
        {
            throw new IllegalArgumentException("Can't resolve scheme name");
        }

        String scheme = name.substring(0, index);

        ConnectionFactory connFactory = resolveConnectionFactory(scheme);
        Connection connection = null;
        if (connFactory != null)
        {
            connection = connFactory.createConnection(name, mode, timeouts);
        }
        // if connection is not provided go to javax.microedition.io.Connector
        if (connection == null)
        {
            try
            {
                connection = Connector.open(name, mode, timeouts);
            } catch (Exception ex)
            {

            }

        } else
        {
            return connection;
        }

        throw new ConnectionNotFoundException("Failed to create connection " + name);
    }

    /**
     * <p>
     * Resolves {@link ConnectionFactory} based on IO scheme name. If multiple ConnectionFactory services register with
     * the same scheme, method select the ConnectionFactory with highest value for service.ranking service registration
     * property or if more than one ConnectionFactory service has the highest value, the ConnectionFactory service with
     * the lowest service.id is selected.
     * </p>
     *
     * @param scheme
     *            name of IO scheme.
     * @return {@link ConnectionFactory} which matched provided scheme.
     */
    private ConnectionFactory resolveConnectionFactory(String scheme)
    {
        ServiceReference[] references = m_connFactoryTracker.getServiceReferences();
        if (references == null || references.length == 0)
        {
            return null;
        }

        ServiceReference matchingRef = null;
        for (int i = 0; i < references.length; i++)
        {
            if (containsScheme(references[i], scheme))
            {
                if (matchingRef != null)
                {
                    int matchRanking = getServiceRanking(matchingRef);
                    int foundRanking = getServiceRanking(references[i]);
                    if (foundRanking > matchRanking)
                    {
                        matchingRef = references[i];
                    } else if (foundRanking == matchRanking && compareServiceId(references[i], matchingRef))
                    {
                        matchingRef = references[i];
                    }
                } else
                {
                    matchingRef = references[i];
                }
            }
        }
        if (matchingRef != null)
        {
            return (ConnectionFactory) m_connFactoryTracker.getService(matchingRef);
        }
        return null;
    }

    /**
     * Checks if provided {@link ServiceReference} contains in its service properties provided scheme name.
     *
     * @param ref
     *            {@link ServiceReference}.
     * @param scheme
     *            name of IO scheme.
     * @return true if contains scheme name, false if not.
     */
    private boolean containsScheme(ServiceReference ref, String scheme)
    {
        Object property = ref.getProperty(ConnectionFactory.IO_SCHEME);
        if (property != null && property.equals(scheme))
        {
            return true;
        } else
        {
            if (property != null && property instanceof String[])
            {
                String[] schemes = (String[]) property;
                for (int index = 0; index < schemes.length; index++)
                {
                    if (schemes[index].equals(scheme))
                    {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * Compare service.id of two {@link ServiceReference}'s.
     *
     * @param foundRef
     *            {@link ServiceReference}.
     * @param prevRef
     *            {@link ServiceReference}.
     * @return true if first reference has lowest service.id than second, false if not.
     */
    private boolean compareServiceId(ServiceReference foundRef, ServiceReference prevRef)
    {
        Long foundServiceId = (Long) foundRef.getProperty(Constants.SERVICE_ID);
        Long prevServiceId = (Long) prevRef.getProperty(Constants.SERVICE_ID);
        if (foundServiceId.longValue() < prevServiceId.longValue())
        {
            return true;
        }

        return false;
    }

    /**
     * Gets service.ranking from provided {@link ServiceReference}.
     *
     * @param ref
     *            {@link ServiceReference}.
     * @return service.ranking property value.
     */
    private int getServiceRanking(ServiceReference ref)
    {
        Object property = ref.getProperty(Constants.SERVICE_RANKING);
        if (property == null || !(property instanceof Integer))
        {
            return 0;
        } else
        {
            return ((Integer) property).intValue();
        }
    }

}
TOP

Related Classes of org.apache.felix.io.ConnectorServiceImpl

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.