| Summary: | Unable to launch Acceleo template if under RTC version control | ||
|---|---|---|---|
| Product: | [Modeling] Acceleo | Reporter: | Rainer Menke <rainer> |
| Component: | Core | Assignee: | Project Inbox <acceleo-inbox> |
| Status: | CLOSED FIXED | QA Contact: | |
| Severity: | normal | ||
| Priority: | P3 | CC: | stephane.begaudeau |
| Version: | unspecified | ||
| Target Milestone: | --- | ||
| Hardware: | PC | ||
| OS: | Windows XP | ||
| Whiteboard: | |||
A first fix has been contributed on R3_1_maintenance, it will be available in the next nightly build https://hudson.eclipse.org/hudson/job/m2t-acceleo-3.1/229/ I'll mark this issue as resolved after a more careful look at this: >>>The question remains open, whether the schemata of the >>>URI of getLocationURI are restricted to "file://" or something else, or the >>>determination of the location of the installed bundle should be determined in >>>another way Based on the fact, we separated the sandboxes ( this is how it is called under RTC ) from the workspace, the initial solution didn't work correctly, because it assumed, that the projects reside in the workspace. We fixed this issue with the code for the class org.eclipse.acceleo.common.internal.utils.workspace.AcceleoWorkspaceUtil
/**
* Installs the bundle corresponding to the model.
*
* @param model
* Model of the bundle to be installed.
*/
private void installBundle(IPluginModelBase model) {
try {
final IResource candidateManifest = model.getUnderlyingResource();
final IProject project = candidateManifest.getProject();
URL url = null;
try {
url = project.getLocationURI().toURL();
} catch (MalformedURLException e) {
URI uri = project.getLocationURI();
if( "sourcecontrol".equals( uri.getScheme() ) ) {
uri = new URI( uri.getQuery() );
} else {
uri = new URI("file", "/" //$NON-NLS-1$//$NON-NLS-2$
+ ResourcesPlugin.getWorkspace().getRoot().getLocation().append(
project.getFullPath().toString()), null);
}
url = uri.toURL();
}
final String candidateLocationReference = REFERENCE_URI_PREFIX
+ URLDecoder.decode(url.toExternalForm(), System.getProperty("file.encoding")); //$NON-NLS-1$
Bundle bundle = getBundle(candidateLocationReference);
/*
* Install the bundle if needed. Note that we'll check bundle dependencies in two phases as even
* if there cannot be cyclic dependencies through the "require-bundle" header, there could be
* through the "import package" header.
*/
if (bundle == null) {
checkRequireBundleDependencies(model);
bundle = installBundle(candidateLocationReference);
setBundleClasspath(project, bundle);
workspaceInstalledBundles.put(model, bundle);
checkImportPackagesDependencies(model);
}
refreshPackages(new Bundle[] {bundle, });
} catch (BundleException e) {
AcceleoCommonPlugin.log(new Status(IStatus.WARNING, AcceleoCommonPlugin.PLUGIN_ID,
AcceleoCommonMessages.getString("WorkspaceUtil.InstallationFailure", model //$NON-NLS-1$
.getBundleDescription().getName()), e));
} catch (URISyntaxException e) {
AcceleoCommonPlugin.log(e, false);
} catch (MalformedURLException e) {
AcceleoCommonPlugin.log(e, false);
} catch (UnsupportedEncodingException e) {
AcceleoCommonPlugin.log(e, false);
}
}
This solution will work, but it isn't as nice as it could be, because it would be better, if the scheme sourcecontrol: as a URIHandler
A fix has been contributed on HEAD and R3_2_maintenance. It will be available with Acceleo 3.2.1 and 3.3.0 I discussed this issue with a collegue, who mentioned a implementation for RTC from the m2e project. I implemented and tested it unter eclipse with RTC 3.0.1.2, and it worked Based on the fact, that less constants are required, this seems to be a better solution, even ( or due to the fact ) if it requires EFS ( org.eclipse.core.filesystem ):
private void installBundle(IPluginModelBase model) {
try {
final IResource candidateManifest = model.getUnderlyingResource();
final IProject project = candidateManifest.getProject();
URI uri = candidateManifest.getProject().getLocationURI();
IFileStore store = EFS.getStore( uri );
File file = store.toLocalFile(0, null);
URL url = file.toURI().toURL();
final String candidateLocationReference = REFERENCE_URI_PREFIX
+ URLDecoder.decode(url.toExternalForm()
, System.getProperty("file.encoding")); //$NON-NLS-1$
Bundle bundle = getBundle(candidateLocationReference);
/*
* Install the bundle if needed. Note that we'll check bundle dependencies in two phases as even
* if there cannot be cyclic dependencies through the "require-bundle" header, there could be
* through the "import package" header.
*/
if (bundle == null) {
checkRequireBundleDependencies(model);
bundle = installBundle(candidateLocationReference);
setBundleClasspath(project, bundle);
workspaceInstalledBundles.put(model, bundle);
checkImportPackagesDependencies(model);
}
refreshPackages(new Bundle[] {bundle, });
} catch (BundleException e) {
AcceleoCommonPlugin.log(new Status(IStatus.WARNING, AcceleoCommonPlugin.PLUGIN_ID,
AcceleoCommonMessages.getString("WorkspaceUtil.InstallationFailure", model //$NON-NLS-1$
.getBundleDescription().getName()), e));
} catch (CoreException ex) {
AcceleoCommonPlugin.log(ex, false);
} catch (MalformedURLException e) {
AcceleoCommonPlugin.log(e, false);
} catch (UnsupportedEncodingException e) {
AcceleoCommonPlugin.log(e, false);
}
}
Sorry for the frequent changes ...
I've used your code as a source of inspiration to change the method installBundle(...) to this:
private void installBundle(IPluginModelBase model) {
try {
final IResource candidateManifest = model.getUnderlyingResource();
final IProject project = candidateManifest.getProject();
URL url = null;
try {
url = project.getLocationURI().toURL();
} catch (MalformedURLException e) {
// See https://bugs.eclipse.org/bugs/show_bug.cgi?id=354360
try {
URI uri = project.getLocationURI();
IFileStore store = EFS.getStore(uri);
File file = store.toLocalFile(0, null);
if (file != null) {
url = file.toURI().toURL();
}
} catch (CoreException ex) {
// Logging both exceptions just to be sure
AcceleoCommonPlugin.log(e, false);
AcceleoCommonPlugin.log(ex, false);
}
}
I prefer to keep the old behavior in place as it works for most of our users and we switch to your code in case of error since I don't want to take any risks with this critical behavior by switching all the time to Eclipse File System APIs since I am not familiar with those. The fix has been contributed on HEAD and R3_2_maintenance. It will be available in Acceleo 3.2.1 and 3.3.0
Marking this issue as resolved now. Closing resolved bugs |
Build Identifier: M20110210-1200 If an Acceleo project is unter version control of IBM RTC, than it is not possible, to run a "Launch Acceleo Application" due to the fact, that getLocationURI returns a URI has a schema "sourcecontrol://". This could not resolved in the method installBundle in the class org.eclipse.acceleo.common.internal.utils.workspace.AcceleoWorkspaceUtil by the toURL method. I changed the existing implementation of the mentioned method to ... private void installBundle(IPluginModelBase model) { try { final IResource candidateManifest = model.getUnderlyingResource(); final IProject project = candidateManifest.getProject(); URL url = null; try { url = project.getLocationURI().toURL(); } catch( MalformedURLException e ) { URI uri = new URI( "file" , "/"+ResourcesPlugin.getWorkspace().getRoot().getLocation().append( project.getFullPath().toString() ), null ); url = uri.toURL(); } final String candidateLocationReference = REFERENCE_URI_PREFIX + URLDecoder.decode( url.toExternalForm(), System.getProperty("file.encoding")); //$NON-NLS-1$ Bundle bundle = getBundle(candidateLocationReference); which solved my problem. The question remains open, whether the schemata of the URI of getLocationURI are restricted to "file://" or something else, or the determination of the location of the installed bundle should be determined in another way Reproducible: Always Steps to Reproduce: 1. Install RTC 3.0 ( jazz.net ) 2. Generate an Acceleo project 3. Share the project under RTC 4. Execute the Template