/*******************************************************************************
 * Copyright (c) 2003, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.osgi.framework.internal.protocol;

import java.lang.reflect.Method;
import java.net.ContentHandler;
import java.net.URLConnection;
import java.util.*;
import org.eclipse.osgi.framework.adaptor.FrameworkAdaptor;
import org.eclipse.osgi.framework.internal.core.Msg;
import org.eclipse.osgi.framework.log.FrameworkLogEntry;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.BundleContext;
import org.osgi.service.url.URLConstants;
import org.osgi.util.tracker.ServiceTracker;

/**
 * The ContentHandlerFactory is registered with the JVM to provide content handlers
 * to requestors.  The ContentHandlerFactory will first look for built-in content handlers.
 * If a built in handler exists, this factory will return null.  Otherwise, this ContentHandlerFactory
 * will search the service registry for a maching Content-Handler and, if found, return a 
 * proxy for that content handler.
 */
// TODO rename this class!!!  its really confusing to name the impl the same as the interface
public class ContentHandlerFactory extends MultiplexingFactory implements java.net.ContentHandlerFactory {
	private ServiceTracker contentHandlerTracker;

	private static final String contentHandlerClazz = "java.net.ContentHandler"; //$NON-NLS-1$
	private static final String CONTENT_HANDLER_PKGS = "java.content.handler.pkgs"; //$NON-NLS-1$
	private static final String DEFAULT_VM_CONTENT_HANDLERS = "sun.net.www.content"; //$NON-NLS-1$

	private static final List ignoredClasses = Arrays.asList(new Class[] {MultiplexingContentHandler.class, ContentHandlerFactory.class, URLConnection.class});

	private Hashtable proxies;
	private java.net.ContentHandlerFactory parentFactory;

	public ContentHandlerFactory(BundleContext context, FrameworkAdaptor adaptor) {
		super(context, adaptor);

		proxies = new Hashtable(5);

		//We need to track content handler registrations
		contentHandlerTracker = new ServiceTracker(context, contentHandlerClazz, null);
		contentHandlerTracker.open();
	}

	/**
	 * @see java.net.ContentHandlerFactory#createContentHandler(String)
	 */
	//TODO method is too long... consider reducing indentation (returning quickly) and moving complex steps to private methods
	public ContentHandler createContentHandler(String contentType) {
		//first, we check to see if there exists a built in content handler for
		//this content type.  we can not overwrite built in ContentHandlers
		String builtInHandlers = StreamHandlerFactory.secureAction.getProperty(CONTENT_HANDLER_PKGS);
		builtInHandlers = builtInHandlers == null ? DEFAULT_VM_CONTENT_HANDLERS : DEFAULT_VM_CONTENT_HANDLERS + '|' + builtInHandlers;
		Class clazz = null;
		if (builtInHandlers != null) {
			//replace '/' with a '.' and all characters not allowed in a java class name
			//with a '_'.

			// find all characters not allowed in java names
			String convertedContentType = contentType.replace('.', '_');
			convertedContentType = convertedContentType.replace('/', '.');
			convertedContentType = convertedContentType.replace('-', '_');
			StringTokenizer tok = new StringTokenizer(builtInHandlers, "|"); //$NON-NLS-1$
			while (tok.hasMoreElements()) {
				StringBuffer name = new StringBuffer();
				name.append(tok.nextToken());
				name.append("."); //$NON-NLS-1$
				name.append(convertedContentType);
				try {
					clazz = StreamHandlerFactory.secureAction.loadSystemClass(name.toString());
					if (clazz != null) {
						return (null); //this class exists, it is a built in handler, let the JVM handle it	
					}
				} catch (ClassNotFoundException ex) {
					//keep looking
				}
			}
		}

		if (isMultiplexing())
			return new MultiplexingContentHandler(contentType, this);

		return createInternalContentHandler(contentType);
	}

	public ContentHandler createInternalContentHandler(String contentType) {
		//first check to see if the handler is in the cache
		ContentHandlerProxy proxy = (ContentHandlerProxy) proxies.get(contentType);
		if (proxy != null) {
			return (proxy);
		}
		org.osgi.framework.ServiceReference[] serviceReferences = contentHandlerTracker.getServiceReferences();
		if (serviceReferences != null) {
			for (int i = 0; i < serviceReferences.length; i++) {
				Object prop = serviceReferences[i].getProperty(URLConstants.URL_CONTENT_MIMETYPE);
				if (prop instanceof String)
					prop = new String[] {(String) prop}; // TODO should this be a warning?
				if (!(prop instanceof String[])) {
					String message = NLS.bind(Msg.URL_HANDLER_INCORRECT_TYPE, new Object[] {URLConstants.URL_CONTENT_MIMETYPE, contentHandlerClazz, serviceReferences[i].getBundle()});
					adaptor.getFrameworkLog().log(new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.WARNING, 0, message, 0, null, null));
					continue;
				}
				String[] contentHandler = (String[]) prop;
				for (int j = 0; j < contentHandler.length; j++) {
					if (contentHandler[j].equals(contentType)) {
						proxy = new ContentHandlerProxy(contentType, serviceReferences[i], context);
						proxies.put(contentType, proxy);
						return (proxy);
					}
				}
			}
		}
		// if parent is present do parent lookup before returning a proxy
		if (parentFactory != null) {
			ContentHandler parentHandler = parentFactory.createContentHandler(contentType);
			if (parentHandler != null)
				return parentHandler;
		}
		//If we can't find the content handler in the service registry, return Proxy with DefaultContentHandler set.
		//We need to do this because if we return null, we won't get called again for this content type.
		proxy = new ContentHandlerProxy(contentType, null, context);
		proxies.put(contentType, proxy);
		return (proxy);
	}

	public synchronized ContentHandler findAuthorizedContentHandler(String contentType) {
		Object factory = findAuthorizedFactory(ignoredClasses);
		if (factory == null)
			return null;

		if (factory == this)
			return createInternalContentHandler(contentType);

		try {
			Method createInternalContentHandlerMethod = factory.getClass().getMethod("createInternalContentHandler", new Class[] {String.class}); //$NON-NLS-1$
			return (ContentHandler) createInternalContentHandlerMethod.invoke(factory, new Object[] {contentType});
		} catch (Exception e) {
			adaptor.getFrameworkLog().log(new FrameworkLogEntry(ContentHandlerFactory.class.getName(), "findAuthorizedContentHandler-loop", FrameworkLogEntry.ERROR, e, null)); //$NON-NLS-1$
			throw new RuntimeException(e.getMessage());
		}
	}

	public Object getParentFactory() {
		return parentFactory;
	}

	public void setParentFactory(Object parentFactory) {
		if (this.parentFactory == null) // only allow it to be set once
			this.parentFactory = (java.net.ContentHandlerFactory) parentFactory;
	}
}
