Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 354360

Summary: Unable to launch Acceleo template if under RTC version control
Product: [Modeling] Acceleo Reporter: Rainer Menke <rainer>
Component: CoreAssignee: 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:

Description Rainer Menke CLA 2011-08-10 07:17:01 EDT
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
Comment 1 Stephane Begaudeau CLA 2011-08-11 11:27:51 EDT
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
Comment 2 Rainer Menke CLA 2012-02-16 11:02:21 EST
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
Comment 3 Stephane Begaudeau CLA 2012-02-20 04:27:54 EST
A fix has been contributed on HEAD and R3_2_maintenance. It will be available with Acceleo 3.2.1 and 3.3.0
Comment 4 Rainer Menke CLA 2012-02-28 10:01:15 EST
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 ...
Comment 5 Stephane Begaudeau CLA 2012-02-29 04:36:09 EST
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
Comment 6 Stephane Begaudeau CLA 2012-05-22 07:38:19 EDT
Marking this issue as resolved now.
Comment 7 Laurent Goubet CLA 2015-05-27 08:57:58 EDT
Closing resolved bugs