diff options
| author | Christian W. Damus | 2016-09-30 18:43:16 +0000 |
|---|---|---|
| committer | Christian W. Damus | 2016-09-30 19:35:13 +0000 |
| commit | 8d98588b9370ce74f80498794a7f2b0da7055e5b (patch) | |
| tree | 2f4d7b7f059c9fad3c778272f846731313c3b753 | |
| parent | 271700736f0d9605aba32c9f08078f1bc286d92f (diff) | |
| download | org.eclipse.papyrus-rt-8d98588b9370ce74f80498794a7f2b0da7055e5b.tar.gz org.eclipse.papyrus-rt-8d98588b9370ce74f80498794a7f2b0da7055e5b.tar.xz org.eclipse.papyrus-rt-8d98588b9370ce74f80498794a7f2b0da7055e5b.zip | |
Bug 501119: [Core] AnsiCLibrary not available as a registered library
https://bugs.eclipse.org/bugs/show_bug.cgi?id=501119
Ensure that library resources are loaded in the model-set on the
initial assignment of the default language as is done whenever the
user model is opened. Also, handle resource loading errors from a
partially loaded but broken library or profile resource.
Change-Id: Ic12ceb2951cf12fb8176a5a360e2ceaeb941b0a5
2 files changed, 175 insertions, 29 deletions
diff --git a/plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/src/org/eclipse/papyrusrt/umlrt/core/internal/defaultlanguage/DefaultLanguageService.java b/plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/src/org/eclipse/papyrusrt/umlrt/core/internal/defaultlanguage/DefaultLanguageService.java index 90523707a..a8763ffe6 100644 --- a/plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/src/org/eclipse/papyrusrt/umlrt/core/internal/defaultlanguage/DefaultLanguageService.java +++ b/plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/src/org/eclipse/papyrusrt/umlrt/core/internal/defaultlanguage/DefaultLanguageService.java @@ -8,12 +8,13 @@ * * Contributors: * CEA LIST - Initial API and implementation - * Christian W. Damus - bug 476984 + * Christian W. Damus - bugs 476984, 501119 *****************************************************************************/ package org.eclipse.papyrusrt.umlrt.core.internal.defaultlanguage; import java.util.List; +import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.PlatformObject; @@ -176,16 +177,8 @@ public class DefaultLanguageService extends PlatformObject implements IDefaultLa if (root != null) { ModelSet modelSet = registry.getService(ModelSet.class); IDefaultLanguage language = getDefaultLanguage(root, modelSet); - - IStatus libraryStatus = loadDefaultLanguageLibrary(root, modelSet, language); - if (libraryStatus != null && !libraryStatus.isOK()) { - Activator.log.error("Error while loading default language libraries:" + libraryStatus, null); - } + initLanguage(root, modelSet, language); } - // remove the error notification: the root package will be found later, after uml resource update - // else { - // Activator.log.error("starting DefaultLanguageModelSetSnippet: impossible to find root package", null); - // } Activator.log.trace(IDebugOptions.PAPYRUS_RT_DEFAULT_LANGUAGE, "DefaultLanguageService#startService() finished"); } @@ -232,13 +225,31 @@ public class DefaultLanguageService extends PlatformObject implements IDefaultLa } // retrieve root if (language != null) { + ResourceSet rset = EMFHelper.getResourceSet(root); + + // Basic initialization as on every opening of the model + initLanguage(root, rset, language); + + // Apply required profiles + MultiStatus status = null; for (String profileURI : language.getProfilesToApply()) { - // unapply the given profile if it can be found - Resource modelResource = EMFHelper.getResourceSet(root).getResource(URI.createURI(profileURI), true); - if (modelResource.getContents().get(0) instanceof Profile) { - PackageUtil.applyProfile(root, (Profile) modelResource.getContents().get(0), true); + // Apply the given profile if it can be found + try { + Resource modelResource = loadResource(rset, URI.createURI(profileURI)); + if (modelResource.getContents().get(0) instanceof Profile) { + PackageUtil.applyProfile(root, (Profile) modelResource.getContents().get(0), true); + } + } catch (CoreException e) { + if (status == null) { + status = new MultiStatus(Activator.PLUGIN_ID, IStatus.ERROR, "Error while loading profiles from DefaultLanguage: " + language.getName(), null); + } + status.add(e.getStatus()); } } + + if (status != null) { + Activator.log.log(status); + } } } @@ -340,29 +351,86 @@ public class DefaultLanguageService extends PlatformObject implements IDefaultLa * * @param root * the root element of the model - * @param modelSet - * the model set in which the library should be loaded + * @param resourceSet + * the resource set in which the library should be loaded * @param defaultLanguage * the default language that requires the libraries to be load * @return the status of the load operation */ - protected IStatus loadDefaultLanguageLibrary(Package root, ModelSet modelSet, IDefaultLanguage defaultLanguage) { + protected IStatus loadDefaultLanguageLibrary(Package root, ResourceSet resourceSet, IDefaultLanguage defaultLanguage) { Activator.log.trace(IDebugOptions.PAPYRUS_RT_DEFAULT_LANGUAGE, "loading default language libraries..."); - ResourceSet resourceSet = modelSet; IStatus status = null; for (String libraryURI : defaultLanguage.getLibrariesToImport()) { URI uri = URI.createURI(libraryURI); if (uri != null) { - Resource resource = resourceSet.getResource(uri, true); - if (resource == null || resource.getContents().isEmpty()) { + try { + loadResource(resourceSet, uri); + } catch (CoreException e) { if (status == null) { status = new MultiStatus(Activator.PLUGIN_ID, IStatus.ERROR, "Error while loading libraries from DefaultLanguage: " + defaultLanguage.getName(), null); } - ((MultiStatus) status).add(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Impossible to load library :" + uri)); + ((MultiStatus) status).add(e.getStatus()); } } } Activator.log.trace(IDebugOptions.PAPYRUS_RT_DEFAULT_LANGUAGE, "loading default language libraries: " + (status == null ? "OK" : status)); - return status; + return (status == null) ? Status.OK_STATUS : status; + } + + /** + * Loads a default-language resource. + * + * @param rset + * the resource set in which to load it + * @param uri + * the URI of the resource to load + * + * @return the resource; never {@code null} + * + * @throws CoreException + * on any problem in loading the resource, even if it + * was partially loaded (loaded with errors) + */ + private Resource loadResource(ResourceSet rset, URI uri) throws CoreException { + Resource result = null; + + try { + result = rset.getResource(uri, true); + } catch (Exception e) { + // Exception is handled in the resource errors, below. + // Here, just get the failed resource + result = rset.getResource(uri, false); + } + + if ((result == null) || result.getContents().isEmpty() || !result.getErrors().isEmpty()) { + // Resource diagnostics typically are exceptions + Throwable exception = result.getErrors().stream() + .filter(Throwable.class::isInstance).map(Throwable.class::cast) + .findAny().orElse(null); + throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Failed to load default language resource: " + uri, exception)); + } + + return result; + } + + /** + * React to the detection or assignment of the default {@link language} of + * the user model. This performs actions that are required on installation + * of the language in the first place and also whenever the language service + * is initialized (on opening a user model). + * + * @param rootPackage + * the root package of the user model + * @param resourceSet + * the context resource-set + * @param language + * the model's default language + */ + private void initLanguage(Package rootPackage, ResourceSet resourceSet, IDefaultLanguage language) { + // Try to load the associage library model(s) + IStatus libraryStatus = loadDefaultLanguageLibrary(rootPackage, resourceSet, language); + if (!libraryStatus.isOK()) { + Activator.log.error("Error while loading default language libraries:" + libraryStatus, null); + } } } diff --git a/tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/src/org/eclipse/papyrusrt/umlrt/core/tests/defaultlanguage/DefaultLanguageTest.java b/tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/src/org/eclipse/papyrusrt/umlrt/core/tests/defaultlanguage/DefaultLanguageTest.java index b95c3bd98..18909360d 100644 --- a/tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/src/org/eclipse/papyrusrt/umlrt/core/tests/defaultlanguage/DefaultLanguageTest.java +++ b/tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/src/org/eclipse/papyrusrt/umlrt/core/tests/defaultlanguage/DefaultLanguageTest.java @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2016 CEA LIST. + * Copyright (c) 2016 CEA LIST, 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 @@ -8,12 +8,22 @@ * * Contributors: * CEA LIST - Initial API and implementation + * Christian W. Damus - bug 501119 *****************************************************************************/ package org.eclipse.papyrusrt.umlrt.core.tests.defaultlanguage; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertThat; +import static org.junit.Assume.assumeThat; +import java.util.List; +import java.util.Optional; + +import org.eclipse.emf.common.command.Command; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.transaction.RecordingCommand; import org.eclipse.papyrus.infra.emf.utils.ServiceUtilsForEObject; import org.eclipse.papyrusrt.umlrt.core.defaultlanguage.IDefaultLanguage; import org.eclipse.papyrusrt.umlrt.core.defaultlanguage.IDefaultLanguageService; @@ -28,12 +38,80 @@ public class DefaultLanguageTest extends AbstractPapyrusRTCoreTest { @Test public void testDefaultLanguageNoLanguageApplied() throws Exception { - IDefaultLanguageService service = ServiceUtilsForEObject.getInstance().getService(IDefaultLanguageService.class, rootModel); - if (service == null) { - fail("impossible to find default language service"); - } - IDefaultLanguage language = service.getActiveDefaultLanguage(rootModel); + IDefaultLanguage language = getService().getActiveDefaultLanguage(rootModel); assertEquals("Default language should be the no language", NoDefautLanguage.INSTANCE, language); } + /** + * Verifies, if the C++ language plug-in is installed in the current configuration, that + * its libraries are loaded in the resource set when the language is set. + * + * @see <a href="http://eclip.se/501119">bug 501119</a> + */ + @Test + public void librariesLoadedWhenLanguageSet() throws Exception { + IDefaultLanguageService service = getService(); + Optional<? extends IDefaultLanguage> cpp = service.getAvailableDefaultLanguages().stream() + .filter(l -> "umlrt-cpp".equals(l.getId())) + .findAny(); + + assumeThat("C++ language is not available", cpp.isPresent(), is(true)); + + Command setLanguage = new RecordingCommand(transactionalEditingDomain, "Set Language") { + + @Override + protected void doExecute() { + service.installLanguage(rootModel, cpp.get()); + } + }; + + int originalResourceCount = modelset.getResources().size(); + List<Resource> newResources = null; + + try { + // Set the language + transactionalEditingDomain.getCommandStack().execute(setLanguage); + + // Check that the library was loaded + newResources = modelset.getResources().subList( + originalResourceCount, modelset.getResources().size()); + Optional<Resource> lib = newResources.stream() + .filter(r -> r.getURI().lastSegment().equals("AnsiCLibrary.uml")) + .findAny(); + assertThat("C++ language library not loaded", lib.isPresent(), is(true)); + } finally { + // Clean up all that we did so as not to interfere with other tests + + try { + if (transactionalEditingDomain.getCommandStack().canUndo()) { + transactionalEditingDomain.getCommandStack().undo(); + } + } finally { + // Undo does not unload resources that were loaded by the command + newResources = modelset.getResources().subList( + originalResourceCount, modelset.getResources().size()); + + newResources.forEach(Resource::unload); + newResources.clear(); + } + } + } + + // + // Test framework + // + + IDefaultLanguageService getService() { + IDefaultLanguageService result = null; + + try { + result = ServiceUtilsForEObject.getInstance().getService(IDefaultLanguageService.class, rootModel); + } catch (Exception e) { + e.printStackTrace(); + } + + assertThat("Could not get Default Language Service", result, notNullValue()); + + return result; + } } |
