blob: 6e650a12e3eff26da10f8c74e1bb4465c599640c [file] [log] [blame]
/*****************************************************************************
* Copyright (c) 2015 CEA LIST.
*
* 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:
* Thomas Daniellou (CEA LIST) - Initial API and implementation
*****************************************************************************/
package org.eclipse.papyrus.adltool.reversible.factory;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.osgi.service.resolver.BundleDescription;
import org.eclipse.osgi.service.resolver.ExportPackageDescription;
import org.eclipse.osgi.service.resolver.ImportPackageSpecification;
import org.eclipse.papyrus.adltool.reversible.project.FragmentPlugin;
import org.eclipse.papyrus.adltool.reversible.project.LoadedPlugin;
import org.eclipse.papyrus.adltool.reversible.project.ReversibleFeature;
import org.eclipse.papyrus.adltool.reversible.project.ReversiblePlugin;
import org.eclipse.papyrus.adltool.reversible.project.ReversibleProject;
import org.eclipse.papyrus.adltool.reversible.project.WorkspacePlugin;
import org.eclipse.papyrus.adltool.ADL4EclipseUtils;
import org.eclipse.papyrus.adltool.reversible.extension.LoadedExtension;
import org.eclipse.papyrus.adltool.reversible.extension.WorkspaceExtension;
import org.eclipse.papyrus.adltool.reversible.extension.ReversibleExtension;
import org.eclipse.papyrus.adltool.reversible.extensionpoint.LoadedExtensionPoint;
import org.eclipse.papyrus.adltool.reversible.extensionpoint.ReversibleExtensionPoint;
import org.eclipse.papyrus.adltool.reversible.extensionpoint.WorkspaceExtensionPoint;
import org.eclipse.papyrus.adltool.reversible.packages.ExportPackage;
import org.eclipse.papyrus.adltool.reversible.packages.ImportPackage;
import org.eclipse.papyrus.adltool.reversible.packages.ReversiblePackage;
import org.eclipse.pde.core.plugin.IPluginExtension;
import org.eclipse.pde.core.plugin.IPluginExtensionPoint;
import org.eclipse.pde.core.project.IBundleProjectDescription;
import org.eclipse.pde.core.project.IPackageExportDescription;
import org.eclipse.pde.core.project.IPackageImportDescription;
import org.eclipse.pde.internal.core.ifeature.IFeature;
import org.osgi.framework.Bundle;
/**
* A factory for creating reversibles.
*/
@SuppressWarnings("restriction")
public class ReversibleFactory {
/**
* The type of reversible package (either EXPORT or IMPORT).
*/
public enum ReversiblePackageType { EXPORT, IMPORT };
/**
* Map containing all the reversible features.
*/
private Map<String, ReversibleProject> features;
/**
* Map containing all the reversible plug-ins.
*/
private Map<String, ReversibleProject> plugins;
/**
* Map containing all the extensions.
*/
private Map<String, ReversibleExtension> extensions;
/**
* Map containing all the extension points.
*/
private Map<String, ReversibleExtensionPoint> extensionPoints;
/**
* Map containing all the imported packages.
*/
private Map<String, ReversiblePackage> importedPackages;
/**
* Map containing all the exported packages.
*/
private Map<String, ReversiblePackage> exportedPackages;
/**
* The singleton instance of the factory.
*/
private static ReversibleFactory instance = null;
/**
* Return the singleton instance of the factory.
*
* @return the singleton instance of the factory
*/
public static ReversibleFactory getInstance() {
if (instance == null) {
instance = new ReversibleFactory();
}
return instance;
}
/**
* Constructor.
*/
private ReversibleFactory() {
plugins = new HashMap<>();
features = new HashMap<>();
extensions = new HashMap<>();
extensionPoints = new HashMap<>();
importedPackages = new HashMap<>();
exportedPackages = new HashMap<>();
}
/**
* Gets a reversible feature project.
*
* @param id the id of the reversible project to be returned
* @return the reversible project to which the specified id is mapped, or null if the project does not exist.
*/
public ReversibleProject getFeature(String id) {
return features.get(id);
}
/**
* Gets a reversible plug-in project.
*
* @param id the id of the reversible project to be returned
* @return the reversible project to which the specified id is mapped, or null if the project does not exist.
*/
public ReversibleProject getPlugin(String id) {
return plugins.get(id);
}
/**
* Gets a reversible extension point.
*
* @param id the id of the reversible extension point to be returned
* @return the reversible extension point with the corresponding id or null
* if the extension point does not exist.
*/
public ReversibleExtensionPoint getExtensionPoint(String id) {
return extensionPoints.get(id);
}
/**
* Gets a reversible extension.
*
* @param id the id of the reversible extension to be returned
* @return the reversible extension with the corresponding id or null if the
* extension point does not exist.
*/
public ReversibleExtension getExtension(String id) {
return extensions.get(id);
}
/**
* Remove a plug-in from the map.
*
* @param id the id of the reversible plug-in to remove
*/
public void removePlugin(String id) {
ReversibleProject reversible = getPlugin(id);
if (reversible instanceof ReversiblePlugin) {
ReversiblePlugin reversiblePlugin = (ReversiblePlugin) reversible;
// TODO: Remove project's package, but some package can have the same name.
for (ReversibleExtensionPoint extensionPoint : reversiblePlugin.getExtensionPoints()) {
removeExtensionPoint(extensionPoint.getId());
}
for (ReversibleExtension extension : reversiblePlugin.getExtensions()) {
removeExtension(extension.getId());
}
}
plugins.remove(id);
}
/**
* Removes a feature from the map.
*
* @param id the id of the reversible feature to remove
*/
public void removeFeature(String id) {
features.remove(id);
}
/**
* Removes an extension point from the map.
*
* @param id the id of the reversible extension point to remove
*/
private void removeExtensionPoint(String id) {
extensionPoints.remove(id);
}
/**
* Removes an extension from the map.
*
* @param id the id of the reversible extension to remove
*/
private void removeExtension(String id) {
extensions.remove(id);
}
/**
* Builds a reversible adapter from a workspace plug-in project and stores
* it in a map. The plug-in's extension points and extensions will also
* be adapted and saved in other maps.
*
* @param pluginDescription the description of the OSGi bundle
* @return the reversible plug-in project
*/
public ReversiblePlugin makeReversible(IBundleProjectDescription pluginDescription) {
ReversiblePlugin project = new WorkspacePlugin(pluginDescription);
registerPlugin(project);
return project;
}
/**
* Builds a reversible adapter from a bundle project and save it.
*
* @param bundle the OSGi bundle
* @return the reversible bundle project
*/
public ReversiblePlugin makeReversible(Bundle bundle) {
ReversiblePlugin project = new LoadedPlugin(bundle);
registerPlugin(project);
return project;
}
/**
* Builds a reversible feature project.
*
* @param feature
* @return the reversible feature project
*/
public ReversibleProject makeReversible(IFeature feature) {
ReversibleProject project = new ReversibleFeature(feature);
registerFeature(project);
return project;
}
/**
* Builds a reversible plug-in extension point.
*
* @param pluginExtensionPoint
* @return the reversible plug-in extension point
*/
public ReversibleExtensionPoint makeReversible(IPluginExtensionPoint pluginExtensionPoint) {
ReversibleExtensionPoint reversibleExtensionPoint = new WorkspaceExtensionPoint(pluginExtensionPoint);
registerExtensionPoint(reversibleExtensionPoint);
return reversibleExtensionPoint;
}
/**
* Builds a reversible bundle extension point.
*
* @param extensionPoint
* @return the reversible bundle extension point
*/
public ReversibleExtensionPoint makeReversible(IExtensionPoint extensionPoint) {
ReversibleExtensionPoint reversibleExtensionPoint = new LoadedExtensionPoint(extensionPoint);
registerExtensionPoint(reversibleExtensionPoint);
return reversibleExtensionPoint;
}
/**
* Builds a reversible bundle extension.
*
* @param bundleExtension
* @return the reversible bundle extension
*/
public ReversibleExtension makeReversible(IExtension bundleExtension) {
ReversibleExtension extension = new LoadedExtension(bundleExtension);
registerExtension(extension);
return extension;
}
/**
* Builds a reversible plug-in extension.
*
* @param pluginExtension
* @return
*/
public ReversibleExtension makeReversible(IPluginExtension pluginExtension) {
ReversibleExtension extension = new WorkspaceExtension(pluginExtension);
registerExtension(extension);
return extension;
}
/**
* Builds a reversible workspace imported package.
*
* @param importPackage
* @return
*/
public ReversiblePackage makeReversible(IPackageImportDescription importPackage) {
ReversiblePackage importedPackage = new ImportPackage(importPackage);
registerImportedPackage(importedPackage);
return importedPackage;
}
/**
* Builds a reversible workspace exported package.
*
* @param exportPackage
* @return
*/
public ReversiblePackage makeReversible(IPackageExportDescription exportPackage) {
ReversiblePackage exportedPackage = new ExportPackage(exportPackage);
registerExportedPackage(exportedPackage);
return exportedPackage;
}
/**
* Builds a reversible exported package.
*
* @param exportPackage
* @return
*/
public ReversiblePackage makeReversible(ExportPackageDescription exportPackage) {
ReversiblePackage exportedPackage = new ExportPackage(exportPackage);
registerExportedPackage(exportedPackage);
return exportedPackage;
}
/**
*
* @param importPackage
* @return
*/
public ReversiblePackage makeReversible(ImportPackageSpecification importPackage) {
ReversiblePackage importedPackage = new ImportPackage(importPackage);
registerImportedPackage(importedPackage);
return importedPackage;
}
/**
*
* @param bundleDescription
* @return
*/
public ReversibleProject makeReversible(BundleDescription bundleDescription) {
ReversiblePlugin plugin = new FragmentPlugin(bundleDescription);
registerPlugin(plugin);
// Save the extension points
IPluginExtensionPoint[] pluginExtensionPoints = ADL4EclipseUtils.findExtensionPointsForPlugin(plugin.getId());
List<ReversibleExtensionPoint> extensionPoints = new ArrayList<>();
for (IPluginExtensionPoint pluginExtensionPoint : pluginExtensionPoints) {
ReversibleExtensionPoint extensionPoint = makeReversible(pluginExtensionPoint);
extensionPoint.setParent(plugin);
extensionPoints.add(extensionPoint);
}
plugin.setExtensionPoints(extensionPoints);
// Save the extensions
IPluginExtension[] pluginExtensions = ADL4EclipseUtils.findExtensionsForPlugin(plugin.getId());
List<ReversibleExtension> extensions = new ArrayList<>();
for (IPluginExtension extension : pluginExtensions) {
ReversibleExtension reversibleExtension = makeReversible(extension);
reversibleExtension.setParent(plugin);
extensions.add(reversibleExtension);
}
plugin.setExtensions(extensions);
return plugin;
}
/**
* Create a reversible package from a {@link ReversiblePackageType type}.
*
* @param id the name of the package
* @param type the type of the package
* @return
*/
public ReversiblePackage makeReversible(String id, ReversiblePackageType type) {
ReversiblePackage reversiblePackage;
if (ReversiblePackageType.EXPORT == type) {
reversiblePackage = new ExportPackage(id);
registerExportedPackage(reversiblePackage);
} else {
reversiblePackage = new ImportPackage(id);
registerImportedPackage(reversiblePackage);
}
return reversiblePackage;
}
/**
* Saves a reversible plug-in in a map.
*
* @param plugin
*/
private void registerPlugin(ReversibleProject plugin) {
ReversibleProject savedPlugin = plugins.get(plugin.getId());
if (savedPlugin == null || savedPlugin.equals(plugin)) {
plugins.put(plugin.getId(), plugin);
}
}
/**
* Saves a reversible feature in a map.
*
* @param feature
*/
private void registerFeature(ReversibleProject feature) {
ReversibleProject savedFeature = features.get(feature.getId());
if (savedFeature == null || savedFeature.equals(feature)) {
features.put(feature.getId(), feature);
}
// else: name & type conflict
}
/**
* Saves an extension point in a map.
*
* @param extensionPoint
*/
private void registerExtensionPoint(ReversibleExtensionPoint extensionPoint) {
ReversibleExtensionPoint savedExtensionPoint = extensionPoints.get(extensionPoint.getId());
if (savedExtensionPoint == null || savedExtensionPoint.equals(extensionPoint)) {
extensionPoints.put(extensionPoint.getId(), extensionPoint);
}
}
/**
* Saves an extension in a map.
*
* @param extension
*/
private void registerExtension(ReversibleExtension extension) {
ReversibleExtension savedExtension = extensions.get(extension.getId());
if (savedExtension == null || savedExtension.equals(extension)) {
extensions.put(extension.getId(), extension);
}
}
/**
* Saves an imported package in a map.
*
* @param importedPackage
*/
private void registerImportedPackage(ReversiblePackage importedPackage) {
ReversiblePackage savedPackage = importedPackages.get(importedPackage.getId());
if (savedPackage == null || savedPackage.equals(importedPackage)) {
importedPackages.put(importedPackage.getId(), importedPackage);
}
}
/**
* Saves an exported package in a map.
*
* @param exportedPackage
*/
private void registerExportedPackage(ReversiblePackage exportedPackage) {
ReversiblePackage savedPackage = exportedPackages.get(exportedPackage.getId());
if (savedPackage == null || savedPackage.equals(exportedPackage)) {
exportedPackages.put(exportedPackage.getId(), exportedPackage);
}
}
}