Blame src/libbluray/bdj/java/javax/media/Manager.java

Packit 5e46da
/*
Packit 5e46da
 * This file is part of libbluray
Packit 5e46da
 *
Packit 5e46da
 * This library is free software; you can redistribute it and/or
Packit 5e46da
 * modify it under the terms of the GNU Lesser General Public
Packit 5e46da
 * License as published by the Free Software Foundation; either
Packit 5e46da
 * version 2.1 of the License, or (at your option) any later version.
Packit 5e46da
 *
Packit 5e46da
 * This library is distributed in the hope that it will be useful,
Packit 5e46da
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 5e46da
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 5e46da
 * Lesser General Public License for more details.
Packit 5e46da
 *
Packit 5e46da
 * You should have received a copy of the GNU Lesser General Public
Packit 5e46da
 * License along with this library. If not, see
Packit 5e46da
 * <http://www.gnu.org/licenses/>.
Packit 5e46da
 */
Packit 5e46da
Packit 5e46da
package javax.media;
Packit 5e46da
Packit 5e46da
import java.io.IOException;
Packit 5e46da
import java.net.URL;
Packit 5e46da
import java.util.Vector;
Packit 5e46da
Packit 5e46da
import javax.media.protocol.DataSource;
Packit 5e46da
import javax.media.protocol.URLDataSource;
Packit 5e46da
Packit 5e46da
import org.videolan.Logger;
Packit 5e46da
Packit 5e46da
/**
Packit 5e46da
 * This file is a stripped down version of the Manager class from FMJ (fmj-sf.net)
Packit 5e46da
 * @author Ken Larson
Packit 5e46da
 *
Packit 5e46da
 */
Packit 5e46da
public final class Manager {
Packit 5e46da
    public static Player createPlayer(URL sourceURL) throws IOException,
Packit 5e46da
            NoPlayerException {
Packit 5e46da
        return createPlayer(new MediaLocator(sourceURL));
Packit 5e46da
    }
Packit 5e46da
Packit 5e46da
    public static Player createPlayer(MediaLocator sourceLocator)
Packit 5e46da
            throws IOException, NoPlayerException {
Packit 5e46da
        final String protocol = sourceLocator.getProtocol();
Packit 5e46da
        final Vector dataSourceList = getDataSourceList(protocol);
Packit 5e46da
        for (int i = 0; i < dataSourceList.size(); ++i) {
Packit 5e46da
            String dataSourceClassName = (String) dataSourceList.get(i);
Packit 5e46da
            try {
Packit 5e46da
                final Class dataSourceClass = Class.forName(dataSourceClassName);
Packit 5e46da
                final DataSource dataSource = (DataSource) dataSourceClass.newInstance();
Packit 5e46da
                dataSource.setLocator(sourceLocator);
Packit 5e46da
                dataSource.connect();
Packit 5e46da
                return createPlayer(dataSource);
Packit 5e46da
Packit 5e46da
                // TODO: JMF seems to disconnect data sources in this method, based on this stack trace:
Packit 5e46da
//              java.lang.NullPointerException
Packit 5e46da
//              at com.sun.media.protocol.rtp.DataSource.disconnect(DataSource.java:207)
Packit 5e46da
//              at javax.media.Manager.createPlayer(Manager.java:425)
Packit 5e46da
//              at net.sf.fmj.ui.application.ContainerPlayer.createNewPlayer(ContainerPlayer.java:357)
Packit 5e46da
            } catch (NoPlayerException e) {
Packit 5e46da
                // no need to log, will be logged by call to createPlayer.
Packit 5e46da
                continue;
Packit 5e46da
            } catch (ClassNotFoundException e) {
Packit 5e46da
                logger.warning("createPlayer: " + e);    // no need for call stack
Packit 5e46da
                continue;
Packit 5e46da
            } catch (IOException e) {
Packit 5e46da
                logger.warning(""  + e);
Packit 5e46da
                continue;
Packit 5e46da
            } catch (NoClassDefFoundError e) {
Packit 5e46da
                logger.warning(""  + e);
Packit 5e46da
                continue;
Packit 5e46da
            } catch (Exception e) {
Packit 5e46da
                logger.warning(""  + e);
Packit 5e46da
                continue;
Packit 5e46da
            }
Packit 5e46da
        }
Packit 5e46da
Packit 5e46da
        // if none found, try URLDataSource:
Packit 5e46da
        final URL url;
Packit 5e46da
        try {
Packit 5e46da
            url = sourceLocator.getURL();
Packit 5e46da
        } catch (Exception e) {
Packit 5e46da
            logger.warning("" + e);
Packit 5e46da
            throw new NoPlayerException();
Packit 5e46da
        }
Packit 5e46da
        final URLDataSource dataSource = new URLDataSource(url);
Packit 5e46da
        dataSource.connect();   // TODO: there is a problem because we connect to the datasource here, but
Packit 5e46da
                                // the following call may try twice or more to use the datasource with a player, once
Packit 5e46da
                                // for the right content type, and multiple times for unknown.  The first attempt (for example) may actually
Packit 5e46da
                                // read data, in which case the second one will be missing data when it reads.
Packit 5e46da
                                // really, the datasource needs to be recreated.
Packit 5e46da
                                // The workaround for now is that URLDataSource (and others) allows repeated connect() calls.
Packit 5e46da
        return createPlayer(dataSource);
Packit 5e46da
    }
Packit 5e46da
Packit 5e46da
    public static Player createPlayer(DataSource source) throws IOException, NoPlayerException {
Packit 5e46da
        return createPlayer(source, source.getContentType());
Packit 5e46da
    }
Packit 5e46da
Packit 5e46da
    public static DataSource createDataSource(URL sourceURL)
Packit 5e46da
            throws IOException, NoDataSourceException {
Packit 5e46da
        return createDataSource(new MediaLocator(sourceURL));
Packit 5e46da
    }
Packit 5e46da
Packit 5e46da
    public static DataSource createDataSource(MediaLocator sourceLocator)
Packit 5e46da
            throws IOException, NoDataSourceException {
Packit 5e46da
        final String protocol = sourceLocator.getProtocol();
Packit 5e46da
        final Vector dataSourceList = getDataSourceList(protocol);
Packit 5e46da
        for (int i = 0; i < dataSourceList.size(); ++i) {
Packit 5e46da
            String dataSourceClassName = (String) dataSourceList.get(i);
Packit 5e46da
            try {
Packit 5e46da
                final Class dataSourceClass = Class.forName(dataSourceClassName);
Packit 5e46da
                final DataSource dataSource = (DataSource) dataSourceClass.newInstance();
Packit 5e46da
                dataSource.setLocator(sourceLocator);
Packit 5e46da
                dataSource.connect();
Packit 5e46da
                return dataSource;
Packit 5e46da
            } catch (ClassNotFoundException e) {
Packit 5e46da
                logger.warning("createDataSource: "  + e);    // no need for call stack
Packit 5e46da
                continue;
Packit 5e46da
            } catch (IOException e) {
Packit 5e46da
                logger.warning("" + e);
Packit 5e46da
                continue;
Packit 5e46da
            } catch (NoClassDefFoundError e) {
Packit 5e46da
                logger.warning("" + e);
Packit 5e46da
                continue;
Packit 5e46da
            } catch (Exception e) {
Packit 5e46da
                logger.warning("" + e);
Packit 5e46da
                continue;
Packit 5e46da
            }
Packit 5e46da
        }
Packit 5e46da
Packit 5e46da
        // if none found, try URLDataSource:
Packit 5e46da
        final URL url;
Packit 5e46da
        try {
Packit 5e46da
            url = sourceLocator.getURL();
Packit 5e46da
        } catch (Exception e) {
Packit 5e46da
            logger.warning("" + e);
Packit 5e46da
            throw new NoDataSourceException();
Packit 5e46da
        }
Packit 5e46da
        final URLDataSource dataSource = new URLDataSource(url);
Packit 5e46da
        dataSource.connect();
Packit 5e46da
        return dataSource;
Packit 5e46da
    }
Packit 5e46da
Packit 5e46da
    public static TimeBase getSystemTimeBase() {
Packit 5e46da
        return systemTimeBase;
Packit 5e46da
    }
Packit 5e46da
Packit 5e46da
    public static Vector getDataSourceList(String protocolName) {
Packit 5e46da
        return getClassList(protocolName, PackageManager.getProtocolPrefixList(), "protocol", "DataSource");
Packit 5e46da
    }
Packit 5e46da
Packit 5e46da
    public static Vector getHandlerClassList(String contentName) {
Packit 5e46da
        return getClassList(toPackageFriendly(contentName), PackageManager.getContentPrefixList(), "content", "Handler");
Packit 5e46da
    }
Packit 5e46da
Packit 5e46da
    private static Player createPlayer(DataSource source, String contentType)
Packit 5e46da
        throws IOException, NoPlayerException {
Packit 5e46da
        final Vector handlerClassList = getHandlerClassList(contentType);
Packit 5e46da
        for (int i = 0; i < handlerClassList.size(); ++i) {
Packit 5e46da
            final String handlerClassName = (String) handlerClassList.get(i);
Packit 5e46da
Packit 5e46da
            try {
Packit 5e46da
                System.out.println(handlerClassName);
Packit 5e46da
                final Class handlerClass = Class.forName(handlerClassName);
Packit 5e46da
                if (!Player.class.isAssignableFrom(handlerClass) &&
Packit 5e46da
                    !MediaProxy.class.isAssignableFrom(handlerClass)) {
Packit 5e46da
                    continue;   // skip any classes that will not be matched below.
Packit 5e46da
                }
Packit 5e46da
                final MediaHandler handler = (MediaHandler) handlerClass.newInstance();
Packit 5e46da
                handler.setSource(source);
Packit 5e46da
Packit 5e46da
                if (handler instanceof Player) {
Packit 5e46da
                    return (Player) handler;
Packit 5e46da
                } else if (handler instanceof MediaProxy) {
Packit 5e46da
                    final MediaProxy mediaProxy = (MediaProxy) handler;
Packit 5e46da
                    return createPlayer(mediaProxy.getDataSource());
Packit 5e46da
                }
Packit 5e46da
            } catch (ClassNotFoundException e) {
Packit 5e46da
                // no need for call stack
Packit 5e46da
                logger.warning("createPlayer: "  + e);
Packit 5e46da
                continue;
Packit 5e46da
            } catch (IncompatibleSourceException e) {
Packit 5e46da
                // no need for call stack
Packit 5e46da
                logger.warning("createPlayer(" + source + ", " + contentType + "): "  + e);
Packit 5e46da
                continue;
Packit 5e46da
            } catch (IOException e) {
Packit 5e46da
                logger.warning("" + e);
Packit 5e46da
                continue;
Packit 5e46da
            } catch (NoPlayerException e) {
Packit 5e46da
                // no need to log, will be logged by call to createPlayer.
Packit 5e46da
                continue;
Packit 5e46da
            } catch (NoClassDefFoundError e) {
Packit 5e46da
                logger.warning("" + e);
Packit 5e46da
                continue;
Packit 5e46da
            } catch (Exception e) {
Packit 5e46da
                logger.warning("" + e);
Packit 5e46da
                continue;
Packit 5e46da
            }
Packit 5e46da
        }
Packit 5e46da
        logger.error("No player found for " + contentType + " / " + source.getLocator());
Packit 5e46da
        throw new NoPlayerException("No player found for " + source.getLocator());
Packit 5e46da
    }
Packit 5e46da
Packit 5e46da
    private static char toPackageFriendly(char c) {
Packit 5e46da
        if (c >= 'a' && c <= 'z')
Packit 5e46da
            return c;
Packit 5e46da
        else if (c >= 'A' && c <= 'Z')
Packit 5e46da
            return c;
Packit 5e46da
        else if (c >= '0' && c <= '9')
Packit 5e46da
            return c;
Packit 5e46da
        else if (c == '.')
Packit 5e46da
            return c;
Packit 5e46da
        else if (c == '/')
Packit 5e46da
            return '.';
Packit 5e46da
        else
Packit 5e46da
            return '_';
Packit 5e46da
    }
Packit 5e46da
Packit 5e46da
    private static String toPackageFriendly(String contentName) {
Packit 5e46da
        final StringBuffer b = new StringBuffer();
Packit 5e46da
        for (int i = 0; i < contentName.length(); ++i) {
Packit 5e46da
            final char c = contentName.charAt(i);
Packit 5e46da
            b.append(toPackageFriendly(c));
Packit 5e46da
        }
Packit 5e46da
        return b.toString();
Packit 5e46da
    }
Packit 5e46da
Packit 5e46da
    public static Vector getClassList(String contentName, Vector packages, String component2, String className) {
Packit 5e46da
        final Vector result = new Vector();
Packit 5e46da
        //result.add("media." + component2 + "." + contentName + "." + className);
Packit 5e46da
Packit 5e46da
        for (int i = 0; i < packages.size(); ++i) {
Packit 5e46da
            result.add(((String) packages.get(i)) + ".media." + component2 + "." + contentName + "." + className);
Packit 5e46da
        }
Packit 5e46da
Packit 5e46da
        return result;
Packit 5e46da
    }
Packit 5e46da
Packit 5e46da
    public static final String UNKNOWN_CONTENT_NAME = "unknown";
Packit 5e46da
Packit 5e46da
    private static final TimeBase systemTimeBase = new SystemTimeBase();
Packit 5e46da
    private static final Logger logger = Logger.getLogger(Manager.class.getName());
Packit 5e46da
}