/*******************************************************************************
 * Copyright (c) 2003, 2005 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
 *******************************************************************************/
/*
 * Created on Jun 9, 2003
 *
 * To change the template for this generated file go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
package org.eclipse.jst.j2ee.internal;

import java.util.ArrayList;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPluginResourceHandler;


/**
 * @author jsholl
 * 
 * To change the template for this generated type comment go to Window>Preferences>Java>Code
 * Generation>Code and Comments
 */
public class J2EEModulePostImportHelper {

	private static final String WEB = J2EEPluginResourceHandler.J2EEModulePostImportHelper_0;
	private static final String EJB = J2EEPluginResourceHandler.J2EEModulePostImportHelper_1;
	private static final String APP_CLIENT = J2EEPluginResourceHandler.J2EEModulePostImportHelper_2;
	private static final String CONNECTOR = J2EEPluginResourceHandler.J2EEModulePostImportHelper_3;

	private static IConfigurationElement[] webExtensions = null;
	private static IConfigurationElement[] ejbExtensions = null;
	private static IConfigurationElement[] appClientExtensions = null;
	private static IConfigurationElement[] connectorExtensions = null;

	private static boolean firstTimeLoading = true;

	public static void notifyWebExtensions(IProject project) {
		if (webExtensions == null) {
			loadConfiguration(WEB);
		}
		notifyExtensions(webExtensions, project);
	}

	public static void notifyEjbExtensions(IProject project) {
		if (ejbExtensions == null) {
			loadConfiguration(EJB);
		}
		notifyExtensions(ejbExtensions, project);
	}

	public static void notifyAppClientExtensions(IProject project) {
		if (appClientExtensions == null) {
			loadConfiguration(APP_CLIENT);
		}
		notifyExtensions(appClientExtensions, project);
	}

	public static void notifyConnectorExtensions(IProject project) {
		if (connectorExtensions == null) {
			loadConfiguration(CONNECTOR);
		}
		notifyExtensions(connectorExtensions, project);
	}

	private static void notifyExtensions(IConfigurationElement[] postImportElement, IProject project) {
		for (int i = 0; i < postImportElement.length; i++) {
			try {
				J2EEModulePostImportHandler postCreate = (J2EEModulePostImportHandler) postImportElement[i].createExecutableExtension("className"); //$NON-NLS-1$
				postCreate.moduleImported(project);
			} catch (CoreException e) {
				e.printStackTrace();
			}
		}
	}

	private static void loadConfiguration(final String loadingModuleType) {
		boolean shouldLogErrors = firstTimeLoading;
		firstTimeLoading = false;

		IExtension[] importExtensions =Platform.getExtensionRegistry().getExtensionPoint("J2EEModulePostImport").getExtensions(); //$NON-NLS-1$

		ArrayList interestedExtensions = new ArrayList();
		for (int i = 0; i < importExtensions.length; i++) {
			IExtension extension = importExtensions[i];
			IConfigurationElement[] configElements = extension.getConfigurationElements();
			boolean isExtensionInterested = false;
			IConfigurationElement postImportElement = null;
			int moduleCount = 0;
			for (int j = 0; j < configElements.length; j++) {
				try {
					IConfigurationElement element = configElements[j];
					if (element.getName().equalsIgnoreCase("postImport")) { //$NON-NLS-1$
						postImportElement = element;
					} else if (element.getName().equalsIgnoreCase(("module"))) { //$NON-NLS-1$
						moduleCount++;
						if (!isExtensionInterested) {
							String moduleType = element.getAttribute("type"); //$NON-NLS-1$
							if (WEB == loadingModuleType && WEB.equalsIgnoreCase(moduleType)) {
								isExtensionInterested = true;
							} else if (EJB == loadingModuleType && EJB.equalsIgnoreCase(moduleType)) {
								isExtensionInterested = true;
							} else if (APP_CLIENT == loadingModuleType && APP_CLIENT.equalsIgnoreCase(moduleType)) {
								isExtensionInterested = true;
							} else if (CONNECTOR == loadingModuleType && CONNECTOR.equalsIgnoreCase(moduleType)) {
								isExtensionInterested = true;
							}
						}
					}
				} catch (Exception e) {
					if (shouldLogErrors) {
						e.printStackTrace();
					}
				}
			}

			//if no module types are defined the default is to listen to all of them.
			if (!isExtensionInterested && 0 == moduleCount) {
				isExtensionInterested = true;
			}

			if (isExtensionInterested) {
				try {
					//try instantiating the class before adding it to the list.
					postImportElement.createExecutableExtension("className"); //$NON-NLS-1$
					interestedExtensions.add(postImportElement);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}

		IConfigurationElement[] configElements = new IConfigurationElement[interestedExtensions.size()];
		for (int i = 0; i < configElements.length; i++) {
			configElements[i] = (IConfigurationElement) interestedExtensions.get(i);
		}
		if (WEB == loadingModuleType) {
			webExtensions = configElements;
		} else if (EJB == loadingModuleType) {
			ejbExtensions = configElements;
		} else if (APP_CLIENT == loadingModuleType) {
			appClientExtensions = configElements;
		} else if (CONNECTOR == loadingModuleType) {
			connectorExtensions = configElements;
		}
	}
}
