/*******************************************************************************
 * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
 * 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:
 *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.xsl.internal.launching.registry;

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.wst.xsl.internal.launching.LaunchingPlugin;

public abstract class AbstractRegistryReader
{
	public static final String ATT_CLASS = "class"; //$NON-NLS-1$
	public static final String TAG_DESCRIPTION = "description"; //$NON-NLS-1$

	protected static void logError(IConfigurationElement element, String text)
	{
		IExtension extension = element.getDeclaringExtension();
		StringBuffer buf = new StringBuffer();
		buf.append("Plugin " + extension.getNamespaceIdentifier() + Messages.getString("AbstractRegistryReader.3") + extension.getExtensionPointUniqueIdentifier()); //$NON-NLS-1$ //$NON-NLS-2$
		buf.append("\n" + text); //$NON-NLS-1$
		LaunchingPlugin.log(new CoreException(new Status(IStatus.ERROR, LaunchingPlugin.PLUGIN_ID, IStatus.OK, buf.toString(), null)));
	}

	protected static void logMissingAttribute(IConfigurationElement element, String attributeName)
	{
		logError(element, Messages.getString("AbstractRegistryReader.5") + attributeName + Messages.getString("AbstractRegistryReader.6")); //$NON-NLS-1$ //$NON-NLS-2$
	}

	protected static void logMissingElement(IConfigurationElement element, String elementName)
	{
		logError(element, Messages.getString("AbstractRegistryReader.7") + elementName + Messages.getString("AbstractRegistryReader.8")); //$NON-NLS-1$ //$NON-NLS-2$
	}

	protected static void logUnknownElement(IConfigurationElement element)
	{
		logError(element, Messages.getString("AbstractRegistryReader.9") + element.getName()); //$NON-NLS-1$
	}

	public static IExtension[] orderExtensions(IExtension[] extensions)
	{
		IExtension[] sortedExtension = new IExtension[extensions.length];
		System.arraycopy(extensions, 0, sortedExtension, 0, extensions.length);
		Comparator<IExtension> comparer = new Comparator<IExtension>()
		{
			public int compare(IExtension arg0, IExtension arg1)
			{
				String s1 = arg0.getNamespaceIdentifier();
				String s2 = arg1.getNamespaceIdentifier();
				return s1.compareToIgnoreCase(s2);
			}
		};
		Collections.sort(Arrays.asList(sortedExtension), comparer);
		return sortedExtension;
	}

	protected abstract boolean readElement(IConfigurationElement element);

	protected void readElementChildren(IConfigurationElement element)
	{
		readElements(element.getChildren());
	}

	protected void readElements(IConfigurationElement[] elements)
	{
		for (int i = 0; i < elements.length; i++)
		{
			if (!readElement(elements[i]))
				logUnknownElement(elements[i]);
		}
	}

	protected void readExtension(IExtension extension)
	{
		readElements(extension.getConfigurationElements());
	}

	public void readRegistry(IExtensionRegistry registry, String pluginId, String extensionPoint)
	{
		IExtensionPoint point = registry.getExtensionPoint(pluginId, extensionPoint);
		if (point == null)
			return;
		IExtension[] extensions = point.getExtensions();
		extensions = orderExtensions(extensions);
		for (IExtension element : extensions)
			readExtension(element);
	}

	public static String getDescription(IConfigurationElement configElement)
	{
		IConfigurationElement[] children = configElement.getChildren(TAG_DESCRIPTION);
		if (children.length >= 1)
		{
			return children[0].getValue();
		}
		return ""; //$NON-NLS-1$
	}

	public static String getClassValue(IConfigurationElement configElement, String classAttributeName)
	{
		String className = configElement.getAttribute(classAttributeName);
		if (className != null)
			return className;
		IConfigurationElement[] candidateChildren = configElement.getChildren(classAttributeName);
		if (candidateChildren.length == 0)
			return null;

		return candidateChildren[0].getAttribute(ATT_CLASS);
	}
}