/*
 * 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.framework;

import org.apache.felix.framework.util.SecureAction;

import java.io.IOException;
import java.net.ContentHandler;
import java.net.ContentHandlerFactory;
import java.net.URLConnection;
import java.util.StringTokenizer;
import java.util.concurrent.ConcurrentHashMap;

import static org.apache.felix.framework.util.Util.putIfAbsentAndReturn;

/**
 * <p>
 * This class implements a content handler proxy. When the content handler
 * proxy instance is created, it is associated with a particular mime type
 * and will answer all future requests for content of that type. It does
 * not directly handle the content requests, but delegates the requests to
 * an underlying content handler service.
 * </p>
 * <p>
 * The proxy for a particular mime type is used for all framework instances
 * that may contain their own content handler services. When performing a
 * content handler operation, the proxy retrieves the handler service from
 * the framework instance associated with the current call stack and delegates
 * the call to the handler service.
 * </p>
 * <p>
 * The proxy will create simple content handler service trackers for each
 * framework instance. The trackers will listen to service events in its
 * respective framework instance to maintain a reference to the "best"
 * content handler service at any given time.
 * </p>
**/
class URLHandlersContentHandlerProxy extends ContentHandler
{
    private static final Class[] STRING_TYPES = new Class[]{String.class};

    private static final String CONTENT_HANDLER_PACKAGE_PROP = "java.content.handler.pkgs";
    private static final String DEFAULT_CONTENT_HANDLER_PACKAGE = "sun.net.www.content|sun.awt.www.content|com.ibm.oti.net.www.content|gnu.java.net.content|org.apache.harmony.luni.internal.net.www.content|COM.newmonics.www.content";

    private static final ConcurrentHashMap<String, ContentHandler> m_builtIn = new ConcurrentHashMap<String, ContentHandler>();
    private static final String m_pkgs;

    static
    {
        String pkgs = new SecureAction().getSystemProperty(CONTENT_HANDLER_PACKAGE_PROP, "");
        m_pkgs = (pkgs.equals(""))
            ? DEFAULT_CONTENT_HANDLER_PACKAGE
            : pkgs + "|" + DEFAULT_CONTENT_HANDLER_PACKAGE;
    }

    private final ContentHandlerFactory m_factory;

    private final String m_mimeType;
    private final SecureAction m_action;

    public URLHandlersContentHandlerProxy(String mimeType, SecureAction action,
        ContentHandlerFactory factory)
    {
        m_mimeType = mimeType;
        m_action = action;
        m_factory = factory;
    }

    //
    // ContentHandler interface method.
    //

    public Object getContent(URLConnection urlc) throws IOException
    {
        ContentHandler svc = getContentHandlerService();
        if (svc == null)
        {
            return urlc.getInputStream();
        }
        return svc.getContent(urlc);
    }

    /**
     * <p>
     * Private method to retrieve the content handler service from the
     * framework instance associated with the current call stack. A
     * simple service tracker is created and cached for the associated
     * framework instance when this method is called.
     * </p>
     * @return the content handler service from the framework instance
     *         associated with the current call stack or <tt>null</tt>
     *         is no service is available.
    **/
    private ContentHandler getContentHandlerService()
    {
        // Get the framework instance associated with call stack.
        Object framework = URLHandlers.getFrameworkFromContext();

        if (framework == null)
        {
            return getBuiltIn();
        }
        try
        {
            ContentHandler service;
            if (framework instanceof Felix)
            {
                service = (ContentHandler) ((Felix) framework).getContentHandlerService(m_mimeType);
            }
            else
            {
                service = (ContentHandler) m_action.invoke(
                    m_action.getDeclaredMethod(framework.getClass(), "getContentHandlerService", STRING_TYPES),
                    framework, new Object[]{m_mimeType});
            }

            return (service == null) ? getBuiltIn() : service;
        }
        catch (Exception ex)
        {
            // TODO: log this or something
            ex.printStackTrace();
            return null;
        }
    }

    private ContentHandler getBuiltIn()
    {
        ContentHandler result = m_builtIn.get(m_mimeType);

        if (result != null)
        {
            return result;
        }

        if (m_factory != null)
        {
            result = m_factory.createContentHandler(m_mimeType);
            if (result != null)
            {
                return putIfAbsentAndReturn(m_builtIn, m_mimeType, result);
            }
        }
        // Check for built-in handlers for the mime type.
        // Remove periods, slashes, and dashes from mime type.
        String fixedType = m_mimeType.replace('.', '_').replace('/', '.').replace('-', '_');

        // Iterate over built-in packages.
        StringTokenizer pkgTok = new StringTokenizer(m_pkgs, "| ");
        while (pkgTok.hasMoreTokens())
        {
            String pkg = pkgTok.nextToken().trim();
            String className = pkg + "." + fixedType;
            try
            {
                // If a built-in handler is found then cache and return it
                Class handler = m_action.forName(className, null);
                if (handler != null)
                {
                    return putIfAbsentAndReturn(m_builtIn, m_mimeType,
                        (ContentHandler) handler.newInstance());
                }
            }
            catch (Exception ex)
            {
                // This could be a class not found exception or an
                // instantiation exception, not much we can do in either
                // case other than ignore it.
            }
        }
        return null;
    }
}