/**
 *                                                                            
 * Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 *                                                                            
 * 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:   
 * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation 
 */
package org.eclipse.osbp.dsl.metadata.service;

import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.Set;

import javax.inject.Inject;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.osbp.dsl.semantic.common.types.LTypedPackage;
import org.eclipse.osbp.dsl.semantic.dto.LDto;
import org.eclipse.osbp.dsl.xtext.types.bundles.BundleSpaceTypeProvider;
import org.eclipse.osbp.preferences.ProductConfiguration;
import org.eclipse.osbp.runtime.common.extender.IExtenderConstants;
import org.eclipse.osbp.ui.api.metadata.IDSLMetadataService;
import org.eclipse.osbp.xtext.builder.metadata.services.AbstractBuilderParticipant;
import org.eclipse.osbp.xtext.builder.metadata.services.IBuilderParticipant;
import org.eclipse.osbp.xtext.builder.metadata.services.IMetadataBuilderService;
import org.eclipse.osbp.xtext.chart.Chart;
import org.eclipse.osbp.xtext.chart.ChartDSLPackage;
import org.eclipse.osbp.xtext.chart.ChartPackage;
import org.eclipse.osbp.xtext.datamartdsl.DatamartDefinition;
import org.eclipse.osbp.xtext.datamartdsl.DatamartPackage;
import org.eclipse.osbp.xtext.dialogdsl.Dialog;
import org.eclipse.osbp.xtext.dialogdsl.DialogDSLPackage;
import org.eclipse.osbp.xtext.dialogdsl.DialogPackage;
import org.eclipse.osbp.xtext.i18n.I18NKeyGenerator;
import org.eclipse.osbp.xtext.organizationdsl.Organization;
import org.eclipse.osbp.xtext.perspective.Perspective;
import org.eclipse.osbp.xtext.perspective.PerspectiveDslPackage;
import org.eclipse.osbp.xtext.perspective.PerspectivePackage;
import org.eclipse.osbp.xtext.reportdsl.Report;
import org.eclipse.osbp.xtext.reportdsl.ReportDSLPackage;
import org.eclipse.osbp.xtext.reportdsl.ReportPackage;
import org.eclipse.osbp.xtext.table.Table;
import org.eclipse.osbp.xtext.table.TableDSLPackage;
import org.eclipse.osbp.xtext.table.TableGrid;
import org.eclipse.osbp.xtext.table.TablePackage;
import org.eclipse.osbp.xtext.topologydsl.Topology;
import org.eclipse.osbp.xtext.topologydsl.TopologyDSLPackage;
import org.eclipse.osbp.xtext.topologydsl.TopologyPackage;
import org.eclipse.xtext.common.types.JvmDeclaredType;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.util.Pair;
import org.eclipse.xtext.util.Tuples;
import org.osgi.framework.Bundle;
import org.osgi.framework.ServiceRegistration;
import org.osgi.framework.wiring.BundleWiring;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The Class DSLBuilderParticipant.
 */
@SuppressWarnings("restriction")
@Component(service = { IBuilderParticipant.class }, property = { "service.ranking:Integer=1000" })
public class DSLBuilderParticipant extends AbstractBuilderParticipant {

	/** The Constant log. */
	private final static Logger log = LoggerFactory.getLogger(DSLBuilderParticipant.class);

	/** The metadata builder service. */
	@Inject
	private IMetadataBuilderService metadataBuilderService;

	/** The context. */
	private ComponentContext context;

	/** The dsl service register. */
	private ServiceRegistration<IDSLMetadataService> dslServiceRegister;

	/** The dsl bundles. */
	private Map<String, List<Bundle>> dslBundles = new HashMap<String, List<Bundle>>();

	/** The translations. */
	private HashMap<String, Properties> translations = new HashMap<>();

	/**
	 * Activate.
	 *
	 * @param context
	 *            the context
	 */
	@Activate
	protected void activate(ComponentContext context) {
		this.context = context;
	}

	/**
	 * Deactivate.
	 *
	 * @param context
	 *            the context
	 */
	@Deactivate
	protected void deactivate(ComponentContext context) {
		metadataBuilderService.removeFromBundleSpace(context.getBundleContext().getBundle());
		this.context = null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.osbp.xtext.builder.metadata.services.AbstractBuilderParticipant
	 * #getModels(org.osgi.framework.Bundle)
	 */
	@Override
	public List<URL> getModels(Bundle suspect) {
		List<URL> results = new ArrayList<URL>();
		BundleWiring wiring = suspect.adapt(BundleWiring.class);
		suspect.getState();
		if (wiring == null) {
			return results;
		}
		log.debug("visiting bundle " + suspect.getSymbolicName());
		// bundles containing model information
		if (containsHeader(suspect, IExtenderConstants.FACTORY_MODEL_EXTENDER)) {
			for (String extension : getExtensions(suspect, IExtenderConstants.FACTORY_MODEL_EXTENDER)) {
				extension = extension.trim();
				if (!extension.isEmpty()) {
					List<URL> entries = wiring.findEntries("/", "*." + extension, BundleWiring.LISTRESOURCES_RECURSE);
					boolean hadEntries = false;
					for (URL entry : entries) {
						if (!entry.getPath().contains("META-INF")) {
							log.debug("found entry " + entry.getPath() + " from bundle " + suspect.getSymbolicName());
							results.add(entry);
							hadEntries = true;
						}
					}
					if (hadEntries) {
						if (dslBundles.containsKey(extension)) {
							if (!dslBundles.get(extension).contains(suspect)) {
								dslBundles.get(extension).add(suspect);
							}
						} else {
							List<Bundle> list = new ArrayList<Bundle>();
							list.add(suspect);
							dslBundles.put(extension, list);
						}
						loadTranslations(suspect);
					}
				}
			}
		}
		// bundles necessary in runtime to be called dynamically via uri
		if (containsHeader(suspect, IExtenderConstants.FACTORY_BUNDLE_EXTENDER)) {
			for (String extension : getExtensions(suspect, IExtenderConstants.FACTORY_BUNDLE_EXTENDER)) {
				extension = extension.trim();
				if (!extension.isEmpty()) {
					if (dslBundles.containsKey(extension)) {
						if (!dslBundles.get(extension).contains(suspect)) {
							dslBundles.get(extension).add(suspect);
						}
					} else {
						List<Bundle> list = new ArrayList<Bundle>();
						list.add(suspect);
						dslBundles.put(extension, list);
					}
				}
			}
		}
		// bundles containing translations
		if (containsHeader(suspect, IExtenderConstants.FACTORY_TRANSLATIONS)) {
			loadTranslations(suspect);
		}

		Set<String> fragments = new HashSet<String>();
		for (Iterator<URL> iterator = results.iterator(); iterator.hasNext();) {
			URL url = iterator.next();
			URI uri = URI.createURI(url.toString());
			if (fragments.contains(uri.lastSegment())) {
				iterator.remove();
			}
			fragments.add(uri.lastSegment());
		}

		return results;
	}

	/**
	 * Load translations from a bundle. Tries to find an i18n directory with
	 * different language properties.
	 *
	 * @param suspect
	 *            the suspect
	 */
	void loadTranslations(Bundle suspect) {
		BundleWiring bundleWiring = suspect.adapt(BundleWiring.class);
		ClassLoader classLoader = bundleWiring.getClassLoader();
		for (String language : ProductConfiguration.getLanguages().keySet()) {
			Properties properties = null;
			if (translations.containsKey(language)) {
				properties = translations.get(language);
			} else {
				properties = new Properties();
			}
			try {
				ResourceBundle resource = ResourceBundle.getBundle("i18n.I18N", Locale.forLanguageTag(language), classLoader);
				Enumeration<String> keyIterator = resource.getKeys();
				while (keyIterator.hasMoreElements()) {
					String element = keyIterator.nextElement();
					String value = resource.getString(element);
					properties.put(element, value);
				}
				if (!properties.isEmpty()) {
					translations.put(language, properties);
				}
			} catch (MissingResourceException e) {
				log.error("bundle "+suspect.getSymbolicName()+" has no resource for locale "+language);
			}
		}
	}

	/**
	 * Returns true, if the bundle contains the header.
	 *
	 * @param bundle
	 *            the bundle
	 * @param header
	 *            the header
	 * @return true, if successful
	 */
	private boolean containsHeader(Bundle bundle, String header) {
		Dictionary<String, String> headers = bundle.getHeaders();
		Enumeration<String> keys = headers.keys();
		while (keys.hasMoreElements()) {
			String key = keys.nextElement();
			if (key.equals(header)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Gets the extensions.
	 *
	 * @param bundle
	 *            the bundle
	 * @param header
	 *            the header
	 * @return the extensions
	 */
	private List<String> getExtensions(Bundle bundle, String header) {
		return new ArrayList<String>(Arrays.asList(bundle.getHeaders().get(header).split(",")));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.osbp.xtext.builder.metadata.services.AbstractBuilderParticipant
	 * #notifyLifecyle(org.eclipse.osbp.xtext.builder.metadata.services.
	 * IBuilderParticipant.LifecycleEvent)
	 */
	@Override
	public void notifyLifecyle(LifecycleEvent event) {
		if (event.getState() == IBuilderParticipant.LifecycleEvent.INITIALIZE) {
			initialize();
		} else if (event.getState() == IBuilderParticipant.LifecycleEvent.BUNDLES_SCANNED) {
			DSLMetadataService datatypesService = new DSLMetadataService();
			dslServiceRegister = context.getBundleContext().registerService(IDSLMetadataService.class, datatypesService, null);

		} else if (event.getState() == IBuilderParticipant.LifecycleEvent.DEACTIVATED) {
			if (dslServiceRegister != null) {
				dslServiceRegister.unregister();
				dslServiceRegister = null;
			}

			if (metadataBuilderService != null) {
				metadataBuilderService.removeFromBundleSpace(context.getBundleContext().getBundle());
			}
		}
	}

	/**
	 * Initialize.
	 */
	private void initialize() {
		StandaloneGrammarsSetup.setup();
		metadataBuilderService.addToBundleSpace(context.getBundleContext().getBundle());
	}

	/**
	 * Provided as an OSGi service to returnmodels for the given qualified name.
	 */
	public class DSLMetadataService implements IDSLMetadataService {

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#getMetadata(
		 * java.lang.String, org.eclipse.emf.ecore.EClass)
		 */
		@Override
		public EObject getMetadata(String id, EClass eclass) {
			EObject eObject = metadataBuilderService.getMetadata(id, eclass);
			return eObject;
		}

		@Override
		public URL getResourceURL(EObject eObject, String resourceExtension, String extension) {
			String fqn = NamingConventions.toFQN(eObject);
			String resourcePath = fqn.replaceAll("\\.","/")+"."+resourceExtension;
			if (dslBundles.containsKey(extension)) {
				for (Bundle bundle : dslBundles.get(extension)) {
					BundleWiring bundleWiring = bundle.adapt(BundleWiring.class);
					ClassLoader classLoader = bundleWiring.getClassLoader();
					URL url = classLoader.getResource(resourcePath);
					if(url != null) {
						return url;
					}
				}
			}
			log.error("resource url "+resourcePath+" could not be found in bundles with extension "+extension);
			return null;
		}

		@Override
		public Object getClassInstance(EObject eObject, String extension) {
			String className = getClassName(eObject, "");
			if (dslBundles.containsKey(extension)) {
				try {
					for (Bundle bundle : dslBundles.get(extension)) {
						BundleWiring bundleWiring = bundle.adapt(BundleWiring.class);
						ClassLoader classLoader = bundleWiring.getClassLoader();
						Class<?> clz = classLoader.loadClass(className);
						try {
							return clz.newInstance();
						} catch (InstantiationException	| IllegalAccessException e) {
							log.error("class "+className+" could not be instantiated");
							if(e.getCause() != null) {
								log.error("because "+e.getCause());
							}
						}
					}
				} catch (ClassNotFoundException e) {
				}
			}
			log.error("class "+className+" could not be found for extension "+extension);
			return null;
		}
		/**
		 * Gets the class URI. As more than one bundle could carry a model
		 * instance, we must try to load the requested class to be sure to have
		 * the right bundle for this class.
		 *
		 * @param className
		 *            the class name
		 * @param extension
		 *            the extension
		 * @return the class URI as string
		 */
		@Override
		public String getClassURI(String className, String extension) {
			if (dslBundles.containsKey(extension)) {
				for (Bundle bundle : dslBundles.get(extension)) {
					try {
						BundleWiring bundleWiring = bundle.adapt(BundleWiring.class);
						ClassLoader classLoader = bundleWiring.getClassLoader();
						classLoader.loadClass(className);
						return "bundleclass://" + bundle.getSymbolicName() + "/" + className;
					} catch (ClassNotFoundException e) {
					}
				}
			}
			return null;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#getClassURI(
		 * org.eclipse.emf.ecore.EObject, java.lang.String)
		 */
		@Override
		public String getClassURI(EObject eObject, String kind) {
			return getClassURI(getClassName(eObject, kind), NamingConventions.toExtension(eObject));
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#getAllDescriptions
		 * (org.eclipse.emf.ecore.EClass)
		 */
		@Override
		public Iterable<IEObjectDescription> getAllDescriptions(EClass eClass) {
			return metadataBuilderService.getAllDescriptions(eClass);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#getClassName
		 * (org.eclipse.emf.ecore.EObject, java.lang.String)
		 */
		@Override
		public String getClassName(EObject eObject, String kind) {
			return NamingConventions.toClassName(eObject);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#
		 * getFullyQualifiedName(org.eclipse.emf.ecore.EObject)
		 */
		@Override
		public String getFullyQualifiedName(EObject eObject) {
			return NamingConventions.toFQN(eObject);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#resolve(org.
		 * eclipse.emf.ecore.EObject)
		 */
		@Override
		public EObject resolve(EObject proxy) {
			return metadataBuilderService.resolve(proxy);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#getAll(org.eclipse
		 * .emf.ecore.EClass)
		 */
		@Override
		public Iterable<EObject> getAll(EClass eClass) {
			return metadataBuilderService.getAll(eClass);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#translate(java
		 * .lang.String, java.lang.String)
		 */
		@Override
		public String translate(String localeString, String key) {
			if (localeString == null) {
				return key;
			}
			String k = I18NKeyGenerator.key(key);
			// special solution for auto generated dto
			if (k.endsWith("_dto")) {
				k = k.substring(0, k.length() - 4);
			}
			String ranges = localeString + ";q=1.0";
			List<Locale.LanguageRange> languageRanges = Locale.LanguageRange.parse(ranges);
			String localeTag = Locale.lookupTag(languageRanges, translations.keySet());
			Properties properties = translations.get(localeTag);
			if (properties.containsKey(k)) {
				String value = properties.getProperty(k);
				return value;
			}
			return key;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#getTranslations
		 * ()
		 */
		@Override
		public Map<String, Properties> getTranslations() {
			return translations;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#getTypeProvider
		 * ()
		 */
		@Override
		public BundleSpaceTypeProvider getTypeProvider() {
			return metadataBuilderService.getTypeProvider();
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#getAllTypeNames
		 * (java.lang.String, java.lang.String)
		 */
		@Override
		public Map<String, String> getAllTypeNames(String localeTag, String typeName) {
			HashMap<String, String> subTypesNames = new HashMap<>();
			subTypesNames.put(translate(localeTag, typeName.substring(typeName.lastIndexOf('.') + 1)), typeName);
			JvmDeclaredType type = (JvmDeclaredType) metadataBuilderService.getTypeProvider().findTypeByName(typeName);
			Set<JvmDeclaredType> subTypes = metadataBuilderService.findSubTypes(type);
			for (JvmDeclaredType subType : subTypes) {
				subTypesNames.put(translate(localeTag, subType.getSimpleName()), subType.getQualifiedName());
			}
			return subTypesNames;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#createType(java
		 * .lang.String)
		 */
		@Override
		public Class<?> createType(String typeName) throws ClassNotFoundException {
			return metadataBuilderService.getBundleSpace().forName(typeName);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#
		 * getDslGrammarElements
		 * (org.eclipse.osbp.ui.api.metadata.IDSLMetadataService.DSLLiterals)
		 */
		@SuppressWarnings("rawtypes")
		@Override
		public List<Pair> getDslGrammarElementNames(IDSLMetadataService.DSLLiterals literal) {
			List<Pair> result = new ArrayList<>();
			switch (literal) {
			case PERSPECTIVES:
				for (EObject obj : getAll(PerspectiveDslPackage.Literals.PERSPECTIVE)) {
					Perspective perspective = ((Perspective) obj);
					result.add(Tuples.pair(perspective.getName(), NamingConventions.getPerspectiveFQN(perspective)));
				}
			}
			return result;
		}
	}

	/**
	 * The Class NamingConventions.
	 */
	private static class NamingConventions {

		/**
		 * To extension.
		 *
		 * @param eObject
		 *            the e object
		 * @return the string
		 */
		public static String toExtension(EObject eObject) {
			EPackage pkg = eObject.eClass().getEPackage();

			if (pkg == ChartDSLPackage.eINSTANCE) {
				return "chart";
			} else if (pkg == DialogDSLPackage.eINSTANCE) {
				return "dialog";
			} else if (pkg == ReportDSLPackage.eINSTANCE) {
				return "report";
			} else if (pkg == TableDSLPackage.eINSTANCE) {
				return "table";
			} else if (pkg == TopologyDSLPackage.eINSTANCE) {
				return "topology";
			}

			throw new IllegalArgumentException("No registered naming logic for " + eObject);
		}

		/**
		 * To FQN.
		 *
		 * @param eObject
		 *            the e object
		 * @return the string
		 */
		public static String toFQN(EObject eObject) {
			if (eObject == null) {
				return null;
			}

			if (eObject instanceof Chart) {
				return getChartFQN(eObject);
			} else if (eObject instanceof Dialog) {
				return getDialogFQN(eObject);
			} else if (eObject instanceof LDto) {
				return getDtoFQN(eObject);
			} else if (eObject instanceof Report) {
				return getReportFQN(eObject);
			} else if (eObject instanceof Table) {
				return getTableFQN(eObject);
			} else if (eObject instanceof Topology) {
				return getTopologyFQN(eObject);
			} else if (eObject instanceof DatamartDefinition) {
				return getDatamartFQN(eObject);
			}
			throw new IllegalArgumentException("No registered naming logic for " + eObject);
		}

		/**
		 * To class name.
		 *
		 * @param eObject
		 *            the e object
		 * @return the string
		 */
		public static String toClassName(EObject eObject) {
			if (eObject == null) {
				return null;
			}

			if (eObject instanceof Chart) {
				return getChartClassName(eObject);
			} else if (eObject instanceof Dialog) {
				return getDialogClassName(eObject);
			} else if (eObject instanceof Report) {
				return getReportClassName(eObject);
			} else if (eObject instanceof Table) {
				return getTableClassName(eObject);
			} else if (eObject instanceof Organization) {
				return getOrganizationClassName(eObject);
			} else if (eObject instanceof Topology) {
				return getTopologyClassName(eObject);
			} else if (eObject instanceof DatamartDefinition) {
				return getDatamartClassName(eObject);
			}
			throw new IllegalArgumentException("No registered naming logic for " + eObject);
		}

		/**
		 * Gets the dto FQN.
		 *
		 * @param eObject
		 *            the e object
		 * @return the dto FQN
		 */
		private static String getDtoFQN(EObject eObject) {
			LDto dto = (LDto) eObject;
			if (dto == null) {
				return "";
			}
			LTypedPackage pkg = (LTypedPackage) dto.eContainer();
			return pkg.getName() + "." + dto.getName();
		}

		/**
		 * Gets the table FQN.
		 *
		 * @param eObject
		 *            the e object
		 * @return the table FQN
		 */
		private static String getTableFQN(EObject eObject) {
			Table dto = (Table) eObject;
			if (dto == null) {
				return "";
			}
			TablePackage pkg = (TablePackage) dto.eContainer();
			return pkg.getName() + "." + dto.getName();
		}

		/**
		 * Gets the chart FQN.
		 *
		 * @param eObject
		 *            the e object
		 * @return the chart FQN
		 */
		private static String getChartFQN(EObject eObject) {
			Chart dto = (Chart) eObject;
			if (dto == null) {
				return "";
			}
			ChartPackage pkg = (ChartPackage) dto.eContainer();
			return pkg.getName() + "." + dto.getName();
		}

		/**
		 * Gets the report FQN.
		 *
		 * @param eObject
		 *            the e object
		 * @return the report FQN
		 */
		private static String getReportFQN(EObject eObject) {
			Report dto = (Report) eObject;
			if (dto == null) {
				return "";
			}
			ReportPackage pkg = (ReportPackage) dto.eContainer();
			return pkg.getName() + "." + dto.getName();
		}

		/**
		 * Gets the dialog FQN.
		 *
		 * @param eObject
		 *            the e object
		 * @return the dialog FQN
		 */
		private static String getDialogFQN(EObject eObject) {
			Dialog dto = (Dialog) eObject;
			if (dto == null) {
				return "";
			}
			DialogPackage pkg = (DialogPackage) dto.eContainer();
			return pkg.getName() + "." + dto.getName();
		}

		/**
		 * Gets the dialog FQN.
		 *
		 * @param eObject
		 *            the e object
		 * @return the dialog FQN
		 */
		private static String getPerspectiveFQN(EObject eObject) {
			Perspective perspective = (Perspective) eObject;
			if (perspective == null) {
				return "";
			}
			PerspectivePackage pkg = (PerspectivePackage) perspective.eContainer();
			return pkg.getName() + "." + perspective.getName();
		}

		/**
		 * Gets the topology FQN.
		 *
		 * @param eObject
		 *            the e object
		 * @return the topology FQN
		 */
		private static String getTopologyFQN(EObject eObject) {
			Topology dto = (Topology) eObject;
			if (dto == null) {
				return "";
			}
			TopologyPackage pkg = (TopologyPackage) dto.eContainer();
			return pkg.getName() + "." + dto.getName();
		}

		/**
		 * Gets the datamart FQN.
		 *
		 * @param eObject the e object
		 * @return the datamart FQN
		 */
		private static String getDatamartFQN(EObject eObject) {
			DatamartDefinition datamart = (DatamartDefinition) eObject;
			if (datamart == null) {
				return "";
			}
			DatamartPackage pkg = (DatamartPackage) datamart.eContainer();
			return pkg.getName() + "." + datamart.getName();
		}

		/**
		 * Gets the topology class name.
		 *
		 * @param eObject
		 *            the e object
		 * @return the topology class name
		 */
		private static String getTopologyClassName(EObject eObject) {
			return getTopologyFQN(eObject) + "Topology";
		}

		/**
		 * Gets the datamart class name.
		 *
		 * @param eObject the e object
		 * @return the datamart class name
		 */
		private static String getDatamartClassName(EObject eObject) {
			return getDatamartFQN(eObject) + "Datamart";
		}

		/**
		 * Gets the report class name.
		 *
		 * @param eObject
		 *            the e object
		 * @return the report class name
		 */
		private static String getReportClassName(EObject eObject) {
			return getReportFQN(eObject) + "Report";
		}

		/**
		 * Gets the chart class name.
		 *
		 * @param eObject
		 *            the e object
		 * @return the chart class name
		 */
		private static String getChartClassName(EObject eObject) {
			return getChartFQN(eObject) + "Chart";
		}

		/**
		 * Gets the organization class name.
		 *
		 * @param eObject
		 *            the e object
		 * @return the organization class name
		 */
		private static String getOrganizationClassName(EObject eObject) {
			return getChartFQN(eObject) + "Organization";
		}

		/**
		 * Gets the table class name.
		 *
		 * @param eObject
		 *            the e object
		 * @return the table class name
		 */
		private static String getTableClassName(EObject eObject) {
			Table table = (Table) eObject;
			if (table.getTabletype() instanceof TableGrid) {
				return getTableFQN(eObject) + "Grid";
			} else {
				return getTableFQN(eObject) + "Table";
			}
		}

		/**
		 * Gets the dialog class name.
		 *
		 * @param eObject
		 *            the e object
		 * @return the dialog class name
		 */
		private static String getDialogClassName(EObject eObject) {
			return getDialogFQN(eObject) + "Dialog";
		}
	}

}
