Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 333649 - Cannot represent characters for backspace, form feed and others in mtl files
Summary: Cannot represent characters for backspace, form feed and others in mtl files
Status: CLOSED WONTFIX
Alias: None
Product: Acceleo
Classification: Modeling
Component: Core (show other bugs)
Version: unspecified   Edit
Hardware: Macintosh Mac OS X - Carbon (unsup.)
: P3 major
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 308674 (view as bug list)
Depends on:
Blocks:
 
Reported: 2011-01-06 08:33 EST by Michel Parisien CLA
Modified: 2016-03-31 04:48 EDT (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Michel Parisien CLA 2011-01-06 08:33:00 EST
Build Identifier: M20100909-0800

When a backspace character or form feed character is used in an mtl file, it fails when it tries to export to xml to produce the emtl file. This can be triggered in at least two ways and I have not found any temporary work around (which I am desperate to find).

This bug appears to have been also found in another project (XText): bug 327080.


Reproducible: Always

Steps to Reproduce:
In the following two examples:
   [query s1(input : String) : String = 'VALUE1' /]
   [template public s2(s : String)]VALUE2[/template]

* Where VALUE1 is a backslash "\" followed by one of the following: "b" (backspace), "f" (form feed), or anything in the range "000".."037" except for "011" (tab), "012" (linefeed) and "015" (carriage return).
* Where VALUE1 or VALUE2 is one of the unescaped values of these characters (for example, copy-pasting the backspace character into the document).

The error looks as follows:
Errors occurred during the build.
Errors running builder 'Acceleo Builder' on project 'myproject'.
java.lang.RuntimeException: An invalid XML character (Unicode: 0x8) was found in the element content:
	at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl$Escape.convert(XMLSaveImpl.java:3298)
	at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.getDatatypeValue(XMLSaveImpl.java:3082)
	at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveDataTypeSingle(XMLSaveImpl.java:1678)
	at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveFeatures(XMLSaveImpl.java:1265)
	at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveElementID(XMLSaveImpl.java:2685)
	at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveElement(XMLSaveImpl.java:1174)
	at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveElement(XMLSaveImpl.java:1035)
	at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveContainedSingle(XMLSaveImpl.java:2372)
	at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveFeatures(XMLSaveImpl.java:1527)
	at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveElementID(XMLSaveImpl.java:2685)
	at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveElement(XMLSaveImpl.java:1174)
	at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveElement(XMLSaveImpl.java:1035)
	at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveContainedMany(XMLSaveImpl.java:2386)
	at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveFeatures(XMLSaveImpl.java:1533)
	at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveElementID(XMLSaveImpl.java:2685)
	at org.eclipse.emf.ecore.xmi.impl.XMISaveImpl.writeTopObjects(XMISaveImpl.java:90)
	at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.traverse(XMLSaveImpl.java:592)
	at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.save(XMLSaveImpl.java:256)
	at org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl.doSave(XMLResourceImpl.java:206)
	at org.eclipse.acceleo.model.mtl.resource.EMtlResourceImpl.doSave(EMtlResourceImpl.java:88)
	at org.eclipse.emf.ecore.resource.impl.ResourceImpl.save(ResourceImpl.java:1406)
	at org.eclipse.emf.ecore.resource.impl.ResourceImpl.save(ResourceImpl.java:993)
	at org.eclipse.acceleo.parser.AcceleoParser.parse(AcceleoParser.java:216)
	at org.eclipse.acceleo.parser.AcceleoParser.parse(AcceleoParser.java:87)
	at org.eclipse.acceleo.internal.ide.ui.builders.AcceleoCompileOperation.doCompileResources(AcceleoCompileOperation.java:170)
	at org.eclipse.acceleo.internal.ide.ui.builders.AcceleoCompileOperation.run(AcceleoCompileOperation.java:126)
	at org.eclipse.acceleo.internal.ide.ui.builders.AcceleoBuilder.incrementalBuild(AcceleoBuilder.java:243)
	at org.eclipse.acceleo.internal.ide.ui.builders.AcceleoBuilder.build(AcceleoBuilder.java:94)
	at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:629)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:172)
	at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:203)
	at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:255)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:258)
	at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:311)
	at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:343)
	at org.eclipse.core.internal.events.AutoBuildJob.doBuild(AutoBuildJob.java:144)
	at org.eclipse.core.internal.events.AutoBuildJob.run(AutoBuildJob.java:242)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)
Comment 1 Laurent Goubet CLA 2011-01-06 09:38:55 EST
*** Bug 308674 has been marked as a duplicate of this bug. ***
Comment 2 Michel Parisien CLA 2011-01-06 10:24:57 EST
I notice in bug 308674 you wrote "It does block serialization of the emtl file, but isn't a priority." Is that because you know of some way, any way, to get one of these characters into a target document? Even if there was a function like char(0), that would be helpful. The only idea I have is to specify a java function to be called from the mtl file to output these characters, but talk about overkill.
Comment 3 Laurent Goubet CLA 2011-01-07 04:34:09 EST
Michel,

It "is not a priority" since it isn't something that we see every day in Acceleo templates, and it will be hard to fix. As for workarounds ... Something like this should allow you to output such characters :

['\\n'] or ['\\']['n']
Comment 4 Michel Parisien CLA 2011-01-07 14:29:27 EST
(In reply to comment #3)
> Michel,
> 
> It "is not a priority" since it isn't something that we see every day in
> Acceleo templates, and it will be hard to fix. As for workarounds ... Something
> like this should allow you to output such characters :
> 
> ['\\n'] or ['\\']['n']

You mean ['\\n'/], right? Or ['\\'/]['n'/]? That seems to only output a backslash character followed by an n character, and not a newline (also, even if it did, there is no difficulty representing these three characters despite being <32 aka <040: \r, \n or \t).
Comment 5 Laurent Goubet CLA 2011-01-10 03:26:14 EST
Hi Michel,

> > ['\\n'] or ['\\']['n']
> 
> You mean ['\\n'/], right? Or ['\\'/]['n'/]?

Yup, forgot the trailing /.

"\\n" is indeed meant to output a backslash followed by "n". If what you wish to output is a new line, remove one of the two backslashes :

['\n'/]
Comment 6 Michel Parisien CLA 2011-01-10 07:46:43 EST
I think you're missing the whole point of the bug. This works fine for a \n, \r and \t, but try to do ['\b' /]. You'll get the error described.
Comment 7 Laurent Goubet CLA 2011-01-10 08:07:42 EST
Michel,

As hinted in comment c3 ... it "should" allow you to :p. I know I have seen this before (thus bug 308674), yet I was not sure about any workaround. if ['\b'/] doesn't work ... then I have no workaround to propose.

I stopped investigating bug 308674 when I saw that the actual issue lied in the serialization of the XML. I don't know if it is an issue with OCL, EMF or the XML serializer underneath, but I do know that it ends up serializing the "\b" string instead of the corresponding XML entity (&#08;), and that causes the deserialization to fail.

As mentionned earlier, this isn't a priority for us because of the fix complexity versus bug frequence ratio. If it _is_ a priority for you, you can either try and fix this yourself (we'll always welcome patches) or buy commercial support from either Obeo (http://obeo.fr/pages/maintenance-and-support/en) or any other company that would propose maintenance support for Acceleo.
Comment 8 Michel Parisien CLA 2011-01-10 09:00:55 EST
Laurent,

I know Acceleo is young (particularly with its support of the OMG spec), so you probably have a lot on your plate that you would like to accomplish such that many things have priority. I sympathize with that.

I just want to focus on something: Acceleo, without any work-around to speak of, makes it absolutely impossible to generate these characters. Isn't this something that should worry you? A number of output formats, you simply cannot support, which would make me think twice if I were to use Acceleo in my company's core tool set.

There are a lot of ways to make support possible without a high cost. Why not add escape and unescape functions to your set of custom functions? That way I could do something like model.value.startsWith('\\b'.unescape()) or model.value.escape().startsWith('\\b').

In other words, there is a difference between "inability to convert certain escaped literal characters", which is only an inconvenience if there is no work-around, and "inability to generate certain characters", which makes a whole set of output formats unavailable to you.

If you are interested in the escape and unescape functions, I can look into what kind of effort is required to add a function to your core set. Otherwise, as I am currently in a situation with a fast-approaching deadline, I'll only be able to help out at the later end of 2011, and in the meantime I'll code a java function to do the work temporarily.

I don't know about helping out with the underlying problem of how stuff is encoded, as I personally just need something that works, not something that works effortlessly (so escape and unescape would be my preference). I'll give the encoding of these troublesome characters a look, but I suspect it would require a lot of effort, and not only because of the code involved, but also... I found a solution in another project that had this problem with encoding backspace characters. They decided to go with encoding all string literals in base64. If I decided to do that, would I get significant resistance to that because you would want to support emtl file format backwards compatibility?

Anyway, I'll look into all this and report back if there are any new developments. Thanks for your quick responses.
Comment 9 Laurent Goubet CLA 2011-01-10 10:10:02 EST
Michel,

If you simply need a quick workaround, you should probably try to output these characters through Java services. I haven't tried myself, so I can't confirm it will work, but Acceleo calls the Java service and simply outputs the String it returns, so I believe special characters would also be returned as is. Something like :

public class MyService {
public String getBackslash() {
return "\b";
}
}

and in your template :

[query public getBackslash() : String = invoke('my.package.MyService', 'getBackslash()', Sequence{})/]
Comment 10 Michel Parisien CLA 2011-01-10 10:13:10 EST
Sorry for not being clear. That's what I meant when I wrote "in the meantime I'll code a java function to do the work temporarily". Thanks.
Comment 11 Laurent Goubet CLA 2016-03-31 04:48:49 EDT
This is due to the XMI serialization of the compiled files and there are no plans to fix this