Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCamille Letavernier2016-05-12 07:40:27 -0400
committerCamille Letavernier2016-05-12 07:40:27 -0400
commit260d8dac6c27e3fbdd0fd976f23d07306d8b7366 (patch)
tree9a97e1baf72b67fd39766a69969c90845261fa80 /plugins/developer/org.eclipse.papyrus.releng.tools
parente0b624886ae935deb07918e4c7c585d40a73e312 (diff)
downloadorg.eclipse.papyrus-260d8dac6c27e3fbdd0fd976f23d07306d8b7366.tar.gz
org.eclipse.papyrus-260d8dac6c27e3fbdd0fd976f23d07306d8b7366.tar.xz
org.eclipse.papyrus-260d8dac6c27e3fbdd0fd976f23d07306d8b7366.zip
Bug 492723: [Releng Tools] Improve the *.tpd updater to support updating
an entire project at once https://bugs.eclipse.org/bugs/show_bug.cgi?id=492723 - Refactor the UpdateDependencies logic out of the handler, to allow programmatic usage - Add a new global handler to update *.tpd files and generate *.targets for them in a single operation Change-Id: I61b110bbfe7270b15bb917ce898c922cc27c8211 Signed-off-by: Camille Letavernier <camille.letavernier@cea.fr>
Diffstat (limited to 'plugins/developer/org.eclipse.papyrus.releng.tools')
-rw-r--r--plugins/developer/org.eclipse.papyrus.releng.tools/plugin.xml31
-rw-r--r--plugins/developer/org.eclipse.papyrus.releng.tools/src/org/eclipse/papyrus/releng/tools/internal/handler/AddSetupRepositoryUpdateAnnotationHandler.java3
-rw-r--r--plugins/developer/org.eclipse.papyrus.releng.tools/src/org/eclipse/papyrus/releng/tools/internal/handler/UpdateDependenciesHandler.java216
-rw-r--r--plugins/developer/org.eclipse.papyrus.releng.tools/src/org/eclipse/papyrus/releng/tools/internal/popup/actions/DependencyUpdater.java2
-rw-r--r--plugins/developer/org.eclipse.papyrus.releng.tools/src/org/eclipse/papyrus/releng/tools/internal/popup/actions/GenerateTargetsHandler.java337
-rw-r--r--plugins/developer/org.eclipse.papyrus.releng.tools/src/org/eclipse/papyrus/releng/tools/internal/popup/actions/UpdateDependencies.java243
6 files changed, 617 insertions, 215 deletions
diff --git a/plugins/developer/org.eclipse.papyrus.releng.tools/plugin.xml b/plugins/developer/org.eclipse.papyrus.releng.tools/plugin.xml
index 772f111bf31..3fd1600cba4 100644
--- a/plugins/developer/org.eclipse.papyrus.releng.tools/plugin.xml
+++ b/plugins/developer/org.eclipse.papyrus.releng.tools/plugin.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?> <!--
- Copyright (c) 2011, 2014 Mia-Software, CEA LIST and others.
+ Copyright (c) 2011, 2016 Mia-Software, CEA LIST 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
@@ -62,6 +62,30 @@
</iterate>
</visibleWhen>
</command>
+ <command
+ commandId="org.eclipse.papyrus.releng.tools.generateTargets"
+ style="push">
+ <visibleWhen
+ checkEnabled="false">
+ <iterate
+ ifEmpty="false"
+ operator="and">
+ <adapt
+ type="org.eclipse.core.resources.IResource">
+ <or>
+ <test
+ property="org.eclipse.core.resources.extension"
+ value="tpd">
+ </test>
+ <test
+ property="org.eclipse.core.resources.name"
+ value="*releng*">
+ </test>
+ </or>
+ </adapt>
+ </iterate>
+ </visibleWhen>
+ </command>
</menuContribution>
</extension>
<extension
@@ -76,6 +100,11 @@
id="org.eclipse.papyrus.releng.tools.addSetupRepositoryUpdateAnnotation"
name="Configure Update from Aggregation Build Model">
</command>
+ <command
+ defaultHandler="org.eclipse.papyrus.releng.tools.internal.popup.actions.GenerateTargetsHandler"
+ id="org.eclipse.papyrus.releng.tools.generateTargets"
+ name="Generate all Target files">
+ </command>
</extension>
</plugin>
diff --git a/plugins/developer/org.eclipse.papyrus.releng.tools/src/org/eclipse/papyrus/releng/tools/internal/handler/AddSetupRepositoryUpdateAnnotationHandler.java b/plugins/developer/org.eclipse.papyrus.releng.tools/src/org/eclipse/papyrus/releng/tools/internal/handler/AddSetupRepositoryUpdateAnnotationHandler.java
index 02b1024449e..bc0d8e22361 100644
--- a/plugins/developer/org.eclipse.papyrus.releng.tools/src/org/eclipse/papyrus/releng/tools/internal/handler/AddSetupRepositoryUpdateAnnotationHandler.java
+++ b/plugins/developer/org.eclipse.papyrus.releng.tools/src/org/eclipse/papyrus/releng/tools/internal/handler/AddSetupRepositoryUpdateAnnotationHandler.java
@@ -56,6 +56,7 @@ import org.eclipse.oomph.p2.RepositoryList;
import org.eclipse.oomph.targlets.Targlet;
import org.eclipse.papyrus.releng.tools.internal.Activator;
import org.eclipse.papyrus.releng.tools.internal.popup.actions.OomphSetupUpdater;
+import org.eclipse.papyrus.releng.tools.internal.popup.actions.UpdateDependencies;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
@@ -77,7 +78,7 @@ public class AddSetupRepositoryUpdateAnnotationHandler extends AbstractHandler {
Shell activeShell = HandlerUtil.getActiveShell(event);
try {
- IFile aggrFile = UpdateDependenciesHandler.chooseAggregationBuildFile(UpdateDependenciesHandler.findAggregationBuildFiles(), activeShell);
+ IFile aggrFile = UpdateDependencies.chooseAggregationBuildFile(UpdateDependencies.findAggregationBuildFiles(), activeShell);
if (aggrFile != null) {
ResourceSet rset = new ResourceSetImpl();
diff --git a/plugins/developer/org.eclipse.papyrus.releng.tools/src/org/eclipse/papyrus/releng/tools/internal/handler/UpdateDependenciesHandler.java b/plugins/developer/org.eclipse.papyrus.releng.tools/src/org/eclipse/papyrus/releng/tools/internal/handler/UpdateDependenciesHandler.java
index 8431c835db8..7b59df2e00f 100644
--- a/plugins/developer/org.eclipse.papyrus.releng.tools/src/org/eclipse/papyrus/releng/tools/internal/handler/UpdateDependenciesHandler.java
+++ b/plugins/developer/org.eclipse.papyrus.releng.tools/src/org/eclipse/papyrus/releng/tools/internal/handler/UpdateDependenciesHandler.java
@@ -14,53 +14,20 @@
*******************************************************************************/
package org.eclipse.papyrus.releng.tools.internal.handler;
-import java.lang.reflect.Modifier;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.LinkedList;
import java.util.List;
-import java.util.Map;
-import org.eclipse.b3.aggregator.Aggregation;
-import org.eclipse.b3.aggregator.AggregatorPackage;
-import org.eclipse.b3.aggregator.transformer.TransformationManager;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.OperationCanceledException;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.resource.Resource;
-import org.eclipse.emf.ecore.resource.ResourceSet;
-import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
-import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.LabelProvider;
-import org.eclipse.osgi.util.NLS;
-import org.eclipse.papyrus.releng.tools.internal.Activator;
-import org.eclipse.papyrus.releng.tools.internal.Messages;
-import org.eclipse.papyrus.releng.tools.internal.popup.actions.DependencyUpdater;
+import org.eclipse.papyrus.releng.tools.internal.popup.actions.UpdateDependencies;
import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.dialogs.ElementListSelectionDialog;
import org.eclipse.ui.handlers.HandlerUtil;
-import org.osgi.framework.Bundle;
-import com.google.common.base.Function;
-import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
public class UpdateDependenciesHandler extends AbstractHandler {
@@ -69,187 +36,14 @@ public class UpdateDependenciesHandler extends AbstractHandler {
public Object execute(ExecutionEvent event) throws ExecutionException {
ISelection selection = HandlerUtil.getCurrentSelection(event);
Shell activeShell = HandlerUtil.getActiveShell(event);
- List<IFile> updated = Lists.newArrayListWithExpectedSize(4);
- IFile aggregationBuildFile = null;
- boolean cancelled = false;
- try {
- if (selection instanceof IStructuredSelection) {
- IStructuredSelection structuredSelection = (IStructuredSelection) selection;
- List<IFile> files = ImmutableList.copyOf(Iterables.filter(structuredSelection.toList(), IFile.class));
- if (!files.isEmpty()) {
- List<IFile> aggregationBuildFiles = findAggregationBuildFiles();
- aggregationBuildFile = chooseAggregationBuildFile(aggregationBuildFiles, activeShell);
- if (aggregationBuildFile == null) {
- cancelled = true;
- } else {
- Aggregation aggregation = loadAggregationModel(aggregationBuildFile);
- if (aggregation != null) {
- Map<Object, Object> context = Maps.newHashMap();
- for (IFile file : files) {
- if (updateFile(file, aggregation, activeShell, context)) {
- updated.add(file);
- }
- }
- }
- }
- }
- }
- } catch (OperationCanceledException e) {
- cancelled = true;
- } catch (Exception e) {
- Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Error", e)); //$NON-NLS-1$
- MessageDialog.openError(activeShell, Messages.UpdateRMapAction_error, e.getLocalizedMessage());
- }
-
- if (updated.isEmpty()) {
- // Don't waste the user's attention on this if he cancelled
- if (!cancelled) {
- MessageDialog.openInformation(activeShell, "No Files Updated", "No files were updated for new dependencies.");
- }
- } else {
- String fileList = Joiner.on(", ").join(Iterables.transform(updated, new Function<IFile, IPath>() {
- @Override
- public IPath apply(IFile input) {
- return input.getFullPath();
- }
- }));
- MessageDialog.openInformation(activeShell, Messages.UpdateRMapAction_mapWasUpdatedTitle, NLS.bind(Messages.UpdateRMapAction_mapWasUpdated, fileList, aggregationBuildFile.getFullPath().toString()));
+ if (selection instanceof IStructuredSelection) {
+ IStructuredSelection structuredSelection = (IStructuredSelection) selection;
+ List<IFile> filesToUpdate = ImmutableList.copyOf(Iterables.filter(structuredSelection.toList(), IFile.class));
+ new UpdateDependencies().updateDependencies(filesToUpdate, activeShell);
}
return null;
}
- protected static List<IFile> findAggregationBuildFiles() throws CoreException {
- List<IFile> aggregationBuildFiles = new ArrayList<>();
- IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
- for (IProject project : projects) {
- if (!project.isOpen()) {
- continue;
- }
- IResource[] members = project.members();
- for (IResource resource : members) {
- if (resource.getType() == IResource.FILE && resource.getName().endsWith(".b3aggr")) { //$NON-NLS-1$
- aggregationBuildFiles.add((IFile) resource);
- }
- }
- }
- return aggregationBuildFiles;
- }
-
- protected static IFile chooseAggregationBuildFile(final List<IFile> aggregationBuildFiles, Shell activeShell) {
- if (aggregationBuildFiles.size() == 0) {
- MessageDialog.openWarning(activeShell, Messages.UpdateRMapAction_noBuildModelFound, Messages.UpdateRMapAction_noBuildModelFoundLong);
- return null;
- }
- LabelProvider labelProvider = new LabelProvider() {
-
- @Override
- public String getText(final Object element) {
- if (element instanceof IFile) {
- IFile file = (IFile) element;
- return file.getProject().getName() + "/" + file.getName(); //$NON-NLS-1$
- }
- return super.getText(element);
- }
- };
-
- ElementListSelectionDialog dialog = new ElementListSelectionDialog(activeShell, labelProvider);
- dialog.setTitle(Messages.UpdateRMapAction_chooseBuildModel);
- dialog.setMessage(Messages.UpdateRMapAction_chooseBuildModelLong);
- dialog.setElements(aggregationBuildFiles.toArray());
- dialog.open();
- return (IFile) dialog.getFirstResult();
- }
-
- protected static Aggregation loadAggregationModel(IFile aggregationBuildFile) throws CoreException {
- Aggregation result = null;
-
- // make sure the EPackage is initialized
- AggregatorPackage.eINSTANCE.getEFactoryInstance();
- URI uri = URI.createPlatformResourceURI(aggregationBuildFile.getFullPath().toString(), true);
-
- final ResourceSet resourceSet = new ResourceSetImpl();
- Resource resource = null;
- try {
- // with the latest version of the metamodel
- resource = resourceSet.getResource(uri, true);
- resource.load(null);
- } catch (Exception e) {
- // with an older version of the metamodel
- try {
- TransformationManager transformationManager = new TransformationManager(uri);
- resource = transformationManager.transformResource(true);
- } catch (Exception e1) {
- throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Error loading b3aggr. Make sure you have the latest version of B3 installed. : " + e.getLocalizedMessage(), e1)); //$NON-NLS-1$
- }
- }
-
- if (resource.getContents().size() == 0) {
- throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "The b3aggr resource is empty")); //$NON-NLS-1$
- }
-
- EObject root = resource.getContents().get(0);
- if (root instanceof Aggregation) {
- result = (Aggregation) root;
- } else {
- throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "The b3aggr resource does not contain an aggregation model")); //$NON-NLS-1$
- }
-
- return result;
- }
-
- protected boolean updateFile(IFile selectedFile, Aggregation aggregationModel, Shell activeShell, Map<Object, Object> context) throws CoreException {
- boolean result = false;
-
- List<DependencyUpdater<?>> updaters = findDependencyUpdater(selectedFile);
- for (DependencyUpdater<?> updater : updaters) {
- updater.updateDocument(activeShell, selectedFile, aggregationModel.getAllContributions(true), context);
- result = true;
- }
-
- return result;
- }
-
- protected List<DependencyUpdater<?>> findDependencyUpdater(IFile mapFile) throws CoreException {
- final String path = "org/eclipse/papyrus/releng/tools/internal/popup/actions/"; //$NON-NLS-1$
-
- Bundle bundle = Activator.getDefault().getBundle();
-
- // Try dev mode, first
- Enumeration<URL> urls = bundle.findEntries("bin/" + path, "*.class", false);
- if (urls == null) {
- // Deployed mode
- urls = bundle.findEntries(path, "*.class", false);
- }
-
- List<DependencyUpdater<?>> updaters = new LinkedList<>();
-
- while (urls.hasMoreElements()) {
- URL classURL = urls.nextElement();
- URI classURI = URI.createURI(classURL.toExternalForm(), true);
-
- try {
- String className = classURI.trimFileExtension().lastSegment();
-
- if (!"DependencyUpdater".equals(className) && !"XMLDependencyUpdater".equals(className) && className.endsWith("Updater")) {
- Class<? extends DependencyUpdater> updaterClass = bundle.loadClass(path.replace('/', '.') + className).asSubclass(DependencyUpdater.class);
- if (!Modifier.isAbstract(updaterClass.getModifiers())) {
- DependencyUpdater<?> updater = updaterClass.newInstance();
- if (updater.canUpdate(mapFile)) {
- updaters.add(updater);
- }
- }
- }
- } catch (ClassNotFoundException e) {
- throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "No such class: " + classURI.lastSegment(), e));
- } catch (IllegalAccessException | InstantiationException e) {
- throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Failed to instantiated " + classURI.lastSegment(), e));
- } catch (Throwable t) { // Classes with missing optional dependencies. Simple Warning
- Activator.getDefault().getLog().log(new Status(IStatus.WARNING, Activator.PLUGIN_ID, "Failed to instantiate " + classURI.lastSegment(), t));
- }
- }
-
- return updaters;
- }
}
diff --git a/plugins/developer/org.eclipse.papyrus.releng.tools/src/org/eclipse/papyrus/releng/tools/internal/popup/actions/DependencyUpdater.java b/plugins/developer/org.eclipse.papyrus.releng.tools/src/org/eclipse/papyrus/releng/tools/internal/popup/actions/DependencyUpdater.java
index 3979ba1bb75..67ae1abfcb4 100644
--- a/plugins/developer/org.eclipse.papyrus.releng.tools/src/org/eclipse/papyrus/releng/tools/internal/popup/actions/DependencyUpdater.java
+++ b/plugins/developer/org.eclipse.papyrus.releng.tools/src/org/eclipse/papyrus/releng/tools/internal/popup/actions/DependencyUpdater.java
@@ -164,8 +164,6 @@ public abstract class DependencyUpdater<T> {
return "updateFrom(\"<contributionName>\",<index>)"; //$NON-NLS-1$
}
-
-
private boolean promptToReplaceSingle(Shell parentShell, LocationUpdate<T> locationUpdate, Map<Object, Object> context) {
String message = NLS.bind("{0}\n\nUpdate anyways?", locationUpdate.strategy.getUpdateConfirmationMessage(locationUpdate.update, locationUpdate.oldLocation, locationUpdate.newLocation)); //$NON-NLS-1$
boolean result = MessageDialog.openQuestion(parentShell, "Confirm Location Update", message);
diff --git a/plugins/developer/org.eclipse.papyrus.releng.tools/src/org/eclipse/papyrus/releng/tools/internal/popup/actions/GenerateTargetsHandler.java b/plugins/developer/org.eclipse.papyrus.releng.tools/src/org/eclipse/papyrus/releng/tools/internal/popup/actions/GenerateTargetsHandler.java
new file mode 100644
index 00000000000..28e9e42356e
--- /dev/null
+++ b/plugins/developer/org.eclipse.papyrus.releng.tools/src/org/eclipse/papyrus/releng/tools/internal/popup/actions/GenerateTargetsHandler.java
@@ -0,0 +1,337 @@
+/*****************************************************************************
+ * Copyright (c) 2016 CEA LIST 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:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.releng.tools.internal.popup.actions;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.IJobChangeEvent;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.core.runtime.jobs.JobChangeAdapter;
+import org.eclipse.core.runtime.jobs.JobGroup;
+import org.eclipse.emf.common.util.BasicDiagnostic;
+import org.eclipse.emf.common.util.Diagnostic;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.papyrus.releng.tools.internal.Activator;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+import com.google.inject.Injector;
+
+import fr.obeo.releng.targetplatform.TargetPlatformBundleActivator;
+import fr.obeo.releng.targetplatform.pde.Converter;
+
+/**
+ * A global handler, enabled on a set of IResources (Project/Folder/File), which recursively:
+ *
+ * - Finds all *.tpd files
+ * - Updates them from the selected Simrel/B3 model
+ * - Generates all *.target files
+ * - Generates an Eclipse-Server version for each *.target file (In an eclipse/*.target folder)
+ *
+ * The Eclipse-Server version of the target is similar to the default one, except it uses
+ * the file:/ protocol instead of http:// for all access to download.eclipse.org,
+ * for improved performances when building on Eclipse Servers
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class GenerateTargetsHandler extends AbstractHandler {
+
+ /**
+ * @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+ *
+ * @param event
+ * @return
+ * @throws ExecutionException
+ */
+ @Override
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ ISelection selection = HandlerUtil.getCurrentSelection(event);
+ if (selection instanceof IStructuredSelection) {
+ IStructuredSelection sSelection = (IStructuredSelection) selection;
+ Iterator<?> iterator = sSelection.iterator();
+
+ List<IFile> tpdFiles = new ArrayList<>();
+
+ try {
+
+ while (iterator.hasNext()) {
+ Object next = iterator.next();
+
+ if (next instanceof IResource) {
+ collectTPDFiles((IResource) next, tpdFiles);
+ }
+ }
+
+ final Shell activeShell = HandlerUtil.getActiveShell(event);
+
+ if (!tpdFiles.isEmpty()) {
+ new UpdateDependencies().updateDependencies(tpdFiles, activeShell); // Update all TPD Files from Simrel
+
+ String jobTitle = String.format("Generate %s target files", tpdFiles.size());
+ Job topLevelJob = new Job(jobTitle) {
+ /**
+ * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
+ *
+ * @param monitor
+ * @return
+ */
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ int maxThreads = 2; // Multi-threading is not really relevant, most time is spent in downloading artifacts
+
+ JobGroup tpdConverters = new JobGroup("Generate Targets", maxThreads, tpdFiles.size());
+ for (IFile tpdFile : tpdFiles) {
+ generate(tpdFile, tpdConverters); // Generate *.target files
+ }
+
+ try {
+ tpdConverters.join(0, monitor);
+ } catch (InterruptedException e) {
+ return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Unexpected exception", e);
+ }
+
+ return tpdConverters.getResult();
+ }
+ };
+
+ topLevelJob.setUser(true);
+ topLevelJob.addJobChangeListener(new JobChangeAdapter() {
+ /**
+ * @see org.eclipse.core.runtime.jobs.JobChangeAdapter#done(org.eclipse.core.runtime.jobs.IJobChangeEvent)
+ *
+ * @param event
+ */
+ @Override
+ public void done(IJobChangeEvent event) {
+ if (Display.getCurrent() != null) {
+ done(event.getResult());
+ } else {
+ Display.getDefault().asyncExec(() -> {
+ done(event.getResult());
+ });
+ }
+ }
+
+ void done(IStatus status) {
+ String title = "Generate targets";
+ switch (status.getCode()) {
+ case IStatus.OK:
+ case IStatus.INFO:
+ MessageDialog.openInformation(activeShell, title, "Operation complete");
+ break;
+ case IStatus.CANCEL:
+ MessageDialog.openInformation(activeShell, title, "Operation canceled");
+ break;
+ case IStatus.ERROR:
+ MessageDialog.openError(activeShell, title, "The operation completed with errors. Check error log for details");
+ break;
+ case IStatus.WARNING:
+ MessageDialog.openWarning(activeShell, title, "The operation completed with warnings. Check error log for details");
+ break;
+ }
+ }
+ });
+ topLevelJob.schedule();
+
+ }
+ } catch (CoreException e) {
+ Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Unexpected exception", e));
+ }
+
+ }
+
+ return null;
+
+ }
+
+ /**
+ * Finds all *.tpd files, recursively, in the given IResource (IFile, IFolder, IProject...)
+ * The collected *.tpd IFiles are stored in the result List
+ *
+ * @param resource
+ * @param result
+ * @throws CoreException
+ */
+ protected void collectTPDFiles(IResource resource, List<IFile> result) throws CoreException {
+ if (resource instanceof IFile) {
+ IFile file = (IFile) resource;
+ if ("tpd".equals(file.getFileExtension())) { //$NON-NLS-1$
+ result.add(file);
+ }
+ } else if (resource instanceof IContainer) {
+ collectTPDFiles((IContainer) resource, result);
+ }
+ }
+
+ /**
+ * Finds all *.tpd files, recursively, in the given IContainer (IFolder, IProject...)
+ * The collected *.tpd IFiles are stored in the result List
+ *
+ * @param resource
+ * @param result
+ * @throws CoreException
+ */
+ protected void collectTPDFiles(IContainer parent, List<IFile> result) throws CoreException {
+ for (IResource child : parent.members()) {
+ collectTPDFiles(child, result);
+ }
+ }
+
+ /**
+ * Inits a job for converting a single *.tpd file to a *.target file
+ * Also creates an Eclipse Server version of each *.target file (Using file:/ protocol instead of http://)
+ *
+ * @param file
+ * A *.tpd IFile
+ * @param jobGroup
+ * The job group used to managed all *.tpd to *.target conversion jobs
+ * @throws CoreException
+ */
+ protected void generate(IFile file, JobGroup jobGroup) {
+ // The Converter currently only supports File URIs (No platform resource)
+ // URI tpdURI = URI.createPlatformResourceURI(file.getFullPath().toString(), true);
+
+ String filePath = file.getLocation().toFile().getAbsolutePath();
+ URI tpdURI = URI.createFileURI(filePath);
+
+ Converter converter = new Converter();
+
+ Injector injector = TargetPlatformBundleActivator.getInstance().getInjector(TargetPlatformBundleActivator.TARGET_PLATFORM_LANGUAGE_NAME);
+ injector.injectMembers(converter);
+
+ Job job = new Job("Generate Target Platform for " + file.getLocation().lastSegment()) {
+
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ Diagnostic result = converter.generateTargetDefinitionFile(tpdURI, new NullProgressMonitor());
+ if (result.getSeverity() >= Diagnostic.WARNING) {
+ Activator.getDefault().getLog().log(BasicDiagnostic.toIStatus(result));
+ }
+
+ try {
+ file.getParent().refreshLocal(IResource.DEPTH_ONE, null);
+ generateEclipseTarget(file);
+ } catch (CoreException ex) {
+ return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Unexpected exception", ex);//$NON-NLS-1$
+ }
+
+ return BasicDiagnostic.toIStatus(result);
+ }
+ };
+
+ job.setJobGroup(jobGroup);
+ job.schedule();
+ }
+
+ /**
+ * Generates an Eclipse-Server version of the *.target file for the given *.tpd file (Assuming the
+ * standard *.target file has already been generated)
+ *
+ * The Eclipse-Server version of the target is similar to the default one, except it uses
+ * the file:/ protocol instead of http:// for all access to download.eclipse.org,
+ * for improved performances when building on Eclipse Servers
+ *
+ * @param tpdFile
+ * @throws CoreException
+ */
+ protected void generateEclipseTarget(IFile tpdFile) throws CoreException {
+ String targetSuffix = "eclipse"; //$NON-NLS-1$
+
+ IContainer parent = tpdFile.getParent();
+
+ String fileName = tpdFile.getFullPath().removeFileExtension().addFileExtension("target").lastSegment(); //$NON-NLS-1$
+
+ IFile portableTargetFile = parent.getFile(new Path(fileName));
+
+ IFolder eclipseFolder = parent.getParent().getFolder(new Path(targetSuffix));
+ if (!eclipseFolder.exists()) {
+ eclipseFolder.create(true, true, new NullProgressMonitor());
+ }
+
+ IFile eclipseTargetFile = eclipseFolder.getFile(fileName.replaceAll("portable", targetSuffix));
+
+ InputStream convertedStream = convert(portableTargetFile.getContents(), "http://download.eclipse.org/", "file:/home/data/httpd/download.eclipse.org/");
+
+ if (eclipseTargetFile.exists()) {
+
+ eclipseTargetFile.setContents(convertedStream, IResource.NONE, null);
+ } else {
+ eclipseTargetFile.create(convertedStream, true, null);
+ }
+
+ eclipseFolder.refreshLocal(IResource.DEPTH_ONE, null);
+ }
+
+ /**
+ * Returns an InputStream similar to the source stream, replacing all occurrences of the source pattern
+ * with the target pattern
+ *
+ * @param source
+ * @param sourcePattern
+ * @param targetPattern
+ * @return
+ * @throws CoreException
+ */
+ protected InputStream convert(InputStream source, String sourcePattern, String targetPattern) throws CoreException {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(source));
+
+ StringBuilder builder = new StringBuilder();
+ String line;
+
+ String patternSt = sourcePattern.replaceAll("\\.", "\\."); //$NON-NLS-1$ //$NON-NLS-2$
+ Pattern pattern = Pattern.compile(patternSt);
+
+ try {
+ while ((line = reader.readLine()) != null) {
+ Matcher matcher = pattern.matcher(line);
+ String newLine = matcher.replaceAll(targetPattern);
+ builder.append(newLine).append("\n"); //$NON-NLS-1$
+ }
+ } catch (IOException ex) {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Unexpected error", ex));
+ }
+
+ ByteArrayInputStream result = new ByteArrayInputStream(builder.toString().getBytes());
+
+ return result;
+ }
+
+}
diff --git a/plugins/developer/org.eclipse.papyrus.releng.tools/src/org/eclipse/papyrus/releng/tools/internal/popup/actions/UpdateDependencies.java b/plugins/developer/org.eclipse.papyrus.releng.tools/src/org/eclipse/papyrus/releng/tools/internal/popup/actions/UpdateDependencies.java
new file mode 100644
index 00000000000..cad56874b2b
--- /dev/null
+++ b/plugins/developer/org.eclipse.papyrus.releng.tools/src/org/eclipse/papyrus/releng/tools/internal/popup/actions/UpdateDependencies.java
@@ -0,0 +1,243 @@
+/*******************************************************************************
+ * Copyright (c) 2015-2016 Christian W. Damus 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:
+ * Nicolas Bros (Mia-Software) - Bug 366567 - [Releng] Tool to update rmaps
+ * Camille Letavernier (CEA LIST) - camille.letavernier@cea.fr - Generalize to handle POMs
+ * Christian W. Damus (CEA) - Add support for updating Oomph setup models
+ * Christian W. Damus - Support updating of multiple selected files
+ * Camille Letavernier (CEA LIST) - Move the behavior from a Handler to a dedicated class
+ *
+ *******************************************************************************/
+package org.eclipse.papyrus.releng.tools.internal.popup.actions;
+
+import java.lang.reflect.Modifier;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.b3.aggregator.Aggregation;
+import org.eclipse.b3.aggregator.AggregatorPackage;
+import org.eclipse.b3.aggregator.transformer.TransformationManager;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.papyrus.releng.tools.internal.Activator;
+import org.eclipse.papyrus.releng.tools.internal.Messages;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.dialogs.ElementListSelectionDialog;
+import org.osgi.framework.Bundle;
+
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+/**
+ * @author Camille Letavernier
+ *
+ */
+public class UpdateDependencies {
+ public void updateDependencies(List<IFile> filesToUpdate, Shell activeShell) {
+ IFile aggregationBuildFile = null;
+ boolean cancelled = false;
+
+ List<IFile> updated = Lists.newArrayListWithExpectedSize(4);
+
+ try {
+ if (!filesToUpdate.isEmpty()) {
+ List<IFile> aggregationBuildFiles = findAggregationBuildFiles();
+ aggregationBuildFile = chooseAggregationBuildFile(aggregationBuildFiles, activeShell);
+ if (aggregationBuildFile == null) {
+ cancelled = true;
+ } else {
+ Aggregation aggregation = loadAggregationModel(aggregationBuildFile);
+ if (aggregation != null) {
+ Map<Object, Object> context = Maps.newHashMap();
+ for (IFile file : filesToUpdate) {
+ if (updateFile(file, aggregation, activeShell, context)) {
+ updated.add(file);
+ }
+ }
+ }
+ }
+ }
+
+ } catch (OperationCanceledException e) {
+ cancelled = true;
+ } catch (Exception e) {
+ Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Error", e)); //$NON-NLS-1$
+ MessageDialog.openError(activeShell, Messages.UpdateRMapAction_error, e.getLocalizedMessage());
+ }
+
+ if (updated.isEmpty()) {
+ // Don't waste the user's attention on this if he cancelled
+ if (!cancelled) {
+ MessageDialog.openInformation(activeShell, "No Files Updated", "No files were updated for new dependencies.");
+ }
+ } else {
+ String fileList = Joiner.on(", ").join(Iterables.transform(updated, new Function<IFile, IPath>() {
+ @Override
+ public IPath apply(IFile input) {
+ return input.getFullPath();
+ }
+ }));
+ MessageDialog.openInformation(activeShell, Messages.UpdateRMapAction_mapWasUpdatedTitle, NLS.bind(Messages.UpdateRMapAction_mapWasUpdated, fileList, aggregationBuildFile.getFullPath().toString()));
+ }
+ }
+
+ public static List<IFile> findAggregationBuildFiles() throws CoreException {
+ List<IFile> aggregationBuildFiles = new ArrayList<>();
+ IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+ for (IProject project : projects) {
+ if (!project.isOpen()) {
+ continue;
+ }
+ IResource[] members = project.members();
+ for (IResource resource : members) {
+ if (resource.getType() == IResource.FILE && resource.getName().endsWith(".b3aggr")) { //$NON-NLS-1$
+ aggregationBuildFiles.add((IFile) resource);
+ }
+ }
+ }
+ return aggregationBuildFiles;
+ }
+
+ public static IFile chooseAggregationBuildFile(final List<IFile> aggregationBuildFiles, Shell activeShell) {
+ if (aggregationBuildFiles.size() == 0) {
+ MessageDialog.openWarning(activeShell, Messages.UpdateRMapAction_noBuildModelFound, Messages.UpdateRMapAction_noBuildModelFoundLong);
+ return null;
+ }
+ LabelProvider labelProvider = new LabelProvider() {
+
+ @Override
+ public String getText(final Object element) {
+ if (element instanceof IFile) {
+ IFile file = (IFile) element;
+ return file.getProject().getName() + "/" + file.getName(); //$NON-NLS-1$
+ }
+ return super.getText(element);
+ }
+ };
+
+ ElementListSelectionDialog dialog = new ElementListSelectionDialog(activeShell, labelProvider);
+ dialog.setTitle(Messages.UpdateRMapAction_chooseBuildModel);
+ dialog.setMessage(Messages.UpdateRMapAction_chooseBuildModelLong);
+ dialog.setElements(aggregationBuildFiles.toArray());
+ dialog.open();
+ return (IFile) dialog.getFirstResult();
+ }
+
+ protected static Aggregation loadAggregationModel(IFile aggregationBuildFile) throws CoreException {
+ Aggregation result = null;
+
+ // make sure the EPackage is initialized
+ AggregatorPackage.eINSTANCE.getEFactoryInstance();
+ URI uri = URI.createPlatformResourceURI(aggregationBuildFile.getFullPath().toString(), true);
+
+ final ResourceSet resourceSet = new ResourceSetImpl();
+ Resource resource = null;
+ try {
+ // with the latest version of the metamodel
+ resource = resourceSet.getResource(uri, true);
+ resource.load(null);
+ } catch (Exception e) {
+ // with an older version of the metamodel
+ try {
+ TransformationManager transformationManager = new TransformationManager(uri);
+ resource = transformationManager.transformResource(true);
+ } catch (Exception e1) {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Error loading b3aggr. Make sure you have the latest version of B3 installed. : " + e.getLocalizedMessage(), e1)); //$NON-NLS-1$
+ }
+ }
+
+ if (resource.getContents().size() == 0) {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "The b3aggr resource is empty")); //$NON-NLS-1$
+ }
+
+ EObject root = resource.getContents().get(0);
+ if (root instanceof Aggregation) {
+ result = (Aggregation) root;
+ } else {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "The b3aggr resource does not contain an aggregation model")); //$NON-NLS-1$
+ }
+
+ return result;
+ }
+
+ protected boolean updateFile(IFile selectedFile, Aggregation aggregationModel, Shell activeShell, Map<Object, Object> context) throws CoreException {
+ boolean result = false;
+
+ List<DependencyUpdater<?>> updaters = findDependencyUpdater(selectedFile);
+ for (DependencyUpdater<?> updater : updaters) {
+ updater.updateDocument(activeShell, selectedFile, aggregationModel.getAllContributions(true), context);
+ result = true;
+ }
+
+ return result;
+ }
+
+ protected List<DependencyUpdater<?>> findDependencyUpdater(IFile mapFile) throws CoreException {
+ final String path = "org/eclipse/papyrus/releng/tools/internal/popup/actions/"; //$NON-NLS-1$
+
+ Bundle bundle = Activator.getDefault().getBundle();
+
+ // Try dev mode, first
+ Enumeration<URL> urls = bundle.findEntries("bin/" + path, "*.class", false);
+ if (urls == null) {
+ // Deployed mode
+ urls = bundle.findEntries(path, "*.class", false);
+ }
+
+ List<DependencyUpdater<?>> updaters = new LinkedList<>();
+
+ while (urls.hasMoreElements()) {
+ URL classURL = urls.nextElement();
+ URI classURI = URI.createURI(classURL.toExternalForm(), true);
+
+ try {
+ String className = classURI.trimFileExtension().lastSegment();
+
+ if (!"DependencyUpdater".equals(className) && !"XMLDependencyUpdater".equals(className) && className.endsWith("Updater")) {
+ Class<? extends DependencyUpdater> updaterClass = bundle.loadClass(path.replace('/', '.') + className).asSubclass(DependencyUpdater.class);
+ if (!Modifier.isAbstract(updaterClass.getModifiers())) {
+ DependencyUpdater<?> updater = updaterClass.newInstance();
+ if (updater.canUpdate(mapFile)) {
+ updaters.add(updater);
+ }
+ }
+ }
+ } catch (ClassNotFoundException e) {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "No such class: " + classURI.lastSegment(), e));
+ } catch (IllegalAccessException | InstantiationException e) {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Failed to instantiated " + classURI.lastSegment(), e));
+ } catch (Throwable t) { // Classes with missing optional dependencies. Simple Warning
+ Activator.getDefault().getLog().log(new Status(IStatus.WARNING, Activator.PLUGIN_ID, "Failed to instantiate " + classURI.lastSegment(), t));
+ }
+ }
+
+ return updaters;
+ }
+}

Back to the top