/**
 * File:    ProcessExtensions.java
 * Created: 26.02.2008
 *
 *
/*******************************************************************************
 * Copyright (c) 2005-2011
 * Eclipse Java Workflow Tooling (JWT) Project <www.eclipse.org/jwt>
 *
 * 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:
 *    Mickaël Istria, Open Wide, Lyon, France
 *      - Creation and implementation
 *******************************************************************************/
package org.eclipse.jwt.wam.monitoring;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jwt.wam.api.WorkflowService;
import org.eclipse.jwt.wam.monitoring.serviceAPI.WorkflowServiceProvider;
import org.eclipse.ui.WorkbenchException;

public class ProcessExtensions {

	private static final String TRANSFORMATION_NAME_ATTRIBUTE = "name";
	private static final String CLASS_ATTRIBUTE = "class";
	private static final String DESCRIPTION_ATTRIBUTE = "description";

	public static void process(String EXTENSION_POINT,
			WorkflowServiceProviderRegistry workflowServiceRetrieverRegistry)
			throws WorkbenchException {
		IExtensionRegistry registry = Platform.getExtensionRegistry();
		IExtensionPoint extensionPoint = registry
				.getExtensionPoint(EXTENSION_POINT);
		IConfigurationElement[] members = extensionPoint
				.getConfigurationElements();
		// For each service:
		for (int m = 0; m < members.length; m++) {
			IConfigurationElement member = members[m];
			String functionName = member
					.getAttribute(TRANSFORMATION_NAME_ATTRIBUTE);
			WorkflowServiceProvider proxy = new WorkflowServiceRetrieverProxy(
					member);
			proxy.setDescription(member.getAttribute(DESCRIPTION_ATTRIBUTE));
			WorkflowServiceProviderRegistry.getInstance().addWorkflowServiceProvider(
					functionName, proxy);
		}
	}

	private static class WorkflowServiceRetrieverProxy extends
			WorkflowServiceProvider {
		private WorkflowServiceProvider delegate = null; // The real
		// callback.
		private IConfigurationElement element; // Function's configuration.
		private boolean invoked = false; // Called already.

		public WorkflowServiceRetrieverProxy(IConfigurationElement element) {
			this.element = element;
		}

		private final WorkflowServiceProvider getDelegate() throws Exception {
			if (invoked) {
				return delegate;
			}
			invoked = true;
			try {
				Object callback = element
						.createExecutableExtension(CLASS_ATTRIBUTE);
				if (!(callback instanceof WorkflowServiceProvider)) {
					throw new Exception(
							"WorkflowServiceRetriever creation error");
				}
				delegate = (WorkflowServiceProvider) callback;
			} catch (CoreException ex) {
				throw ex;
			}
			return delegate;
		}

		@Override
		public WorkflowService getWorkflowService() {
			try {
				getDelegate();
			} catch (Exception e) {
				e.printStackTrace();
				return null;
			}
			return delegate.getWorkflowService();
		}
	}
}
