[Acceleo 3] Prevent elements from being parsed more than once [message #554381] |
Sun, 22 August 2010 18:06 |
No real name Messages: 8 Registered: August 2010 |
Junior Member |
|
|
Hello
Firstable I want to excuse myself for my bad english language skills. Im a student from Germany and I use Acceleo within my Master Thesis. I ran into a problem that I couldn't solve with the help of the documentation or the existing forum posts. I really hope someone can help me.
The Problem I have is the following:
I try to generate XML Code : I have written one Template which parses the relevant Modelelements and generates the XML Tags and . All XML Tags and the Child elements of an XML Tag are generated via a reflexsive template call. Lets assume we have the following XML Tags <foo> , <bar1>,<bar2>,<bar3> . In general I want to create the following XML Structures
The XML element <foo> "wraps" each other Tag (bar1,bar2,bar3)
<foo>
<bar></bar>
</foo>
<foo>
<bar1></bar1>
</foo>
<foo>
<bar2></bar2>
</foo>
The XML element <foo> "holds" each other Tag (bar1,bar2,bar3)
<foo>
<bar1></bar1><bar2></bar2><bar3></bar3>
</foo>
The XML element <foo> "hods" no other Tag
<foo></foo>
<bar1></bar1>
.......
The Following "Pseude Code" discribes the Template for the Genration of the XML Code and its Structure. I really hope this makes things clear.
........
[template public genTags(element : Element)]
[if (element.isWrapsEachChild())]
[for (child : Element | element.getChildren())]
[genOpeningTag(element)/]
[genTags (child)/]
[genClosingTag(element)/]
[/for]
[elseif (element.isHoldsChildren()) ]
[genOpeningTag(element)/]
[for (child : Element | element.getChildren())]
[genTags (child)/]
[/for]
[genClosingTag(element)/]
[else if(element.isHoldsNoChildren()) ]
[genOpeningTag(element)/]
[genClosingTag(element)/]
[/if]
[for (child : Element | element.getChildren())]
[genTags (child)/]
[/for]
[/if]
[/template]
The Problem is that I have two for loops which are parsing the child elements, Therefore the child elements are parsed more than once and therefore also created more than once. I know that it is not possible in Acceleo to define a global Variable to store the elements which are already generated. Furthermore Variables are final. Furthermore its not possible to break or stop a loop. Is there any way to define a condition which prevents elements from beeing parsed again ?
I have also tried to pass the generated Elements via a parameter each time I call the template recursively without any luck. I also tried to store and read the id of the already generated Elements in a separate File. I called a Java service Method for this. In order to keeps things synchronized I put a wait() after the flush() (To wait until the Operating System has finished writing into the file). But it seems that the template call is still faster then writing into the file I assume that a Java method which is called by a Template is run in a separate Thread. Is this right ? The following two methods I use to read and write the ids in a separate file
public void write(String elementId) {
FileWriter writer;
try {
writer = new FileWriter("path to exisiting file", true);
writer.write(elementId + "\n");
writer.flush();
writer.close();
wait(1000);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public boolean read(String elementId) {
FileReader fr;
boolean found = false;
try {
fr = new FileReader("path to existing File");
BufferedReader br = new BufferedReader(fr);
String s;
while ((s = br.readLine()) != null && found == false) {
if (s.trim().replace("\n", "").equals(id.trim().replace("\n", "")))
{ found = true;
}
}
fr.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return found;
}
Another thing I tried was to store the ids of generated elements in a Databasetable. I also called a java service method in the Template to do that. The following method I used to
public void writeID(String id) {
Connection conn;
try { Class.forName("com.mysql.jdbc.Driver").newInstance();
String url = "jdbc:mysql://URL FOR DB";
conn = DriverManager.getConnection(url, "username", "password");
Statement st = conn.createStatement();
st.executeUpdate("INSERT IGNORE INTO IDTABLE" + "VALUES ('" + id + "')");
conn.close();
} catch (ClassNotFoundException ex) {
System.err.println(ex.getMessage());
} catch (IllegalAccessException ex) {
System.err.println(ex.getMessage());
} catch (InstantiationException ex) {
System.err.println(ex.getMessage());
} finally {
return;
}
}
For some reason the Java Service method is not executed correctly. Its not going into the try block. When I execute the method as a Java Program it works. Actually im stuck and I'm really thankfull for any help.
[Updated on: Sun, 22 August 2010 18:32] Report message to a moderator
|
|
|
|
|
|
|
Re: [Acceleo 3] Prevent elements from being parsed more than once [message #555526 is a reply to message #554678] |
Fri, 27 August 2010 03:04 |
No real name Messages: 8 Registered: August 2010 |
Junior Member |
|
|
public static List<String> list = new ArrayList<String>();
public boolean hasBeenGenerated(String id) {
boolean result = false;
for (String str : list) {
if (str == id) {
result = true;
}
if (!result) {
list.add(id);
}
}
return result;
}
[query public hasBeenGenerated(id : String) : Boolean = invoke('org.pim.uml2.common.Utility',
'hasBeenGenerated(java.lang.String)', Sequence{id})/]
i tried to implement the utility class but when i call the java service via the query the tempate returns me an empty string. I dont know what im doing wrong. Please help me
[Updated on: Fri, 27 August 2010 03:28] Report message to a moderator
|
|
|
|
|
|
|
Re: [Acceleo 3] Prevent elements from beeing parsed more then once [message #555921 is a reply to message #554381] |
Mon, 30 August 2010 09:05 |
|
This is a multi-part message in MIME format.
--------------060001010207030007070809
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Hi Andre,
Taking this thread "en route" isn't really easy ... I think there's a
lot of confusion here with the java services, databases and whatnot.
If I understand the core question well, you have a problem with this
generating tags more than once for a given element :
[template public genTags(element : Element)]
[if (element.isWrapsEachChild())]
[for (child : Element | element.getChildren())]
[genOpeningTag(element)/]
[genTags (child)/]
[genClosingTag(element)/]
[/for]
[elseif (element.isHoldsChildren()) ]
[genOpeningTag(element)/]
[for (child : Element | element.getChildren())]
[genTags (child)/]
[/for]
[genClosingTag(element)/]
[else if(element.isHoldsNoChildren()) ]
[genOpeningTag(element)/]
[genClosingTag(element)/]
[/if]
[for (child : Element | element.getChildren())]
[genTags (child)/]
[/for]
[/if]
[/template]
I copy/pasted the code from your first post.
1 - Was that copy pasted from your module? if yes, Acceleo shouldn't
compile, you have an orphan "[/if]" at the end of this template.
2 - Exactly which for loop poses a problem to you? if it is the last,
couldn't you put this last loop in an "else" clause of your main if/else?
3 - You can set guards on for loops, couldn't it help? [for (child :
Element | ...) ? (element.isWrapsEachChild())/] for example.
Couldn't you use :
[template public genTags(element : Element)]
[if (element.isWrapsEachChild())]
[for (child : Element | element.getChildren())]
[genOpeningTag(element)/]
[genTags (child)/]
[genClosingTag(element)/]
[/for]
[else]
[genOpeningTag(element)/]
[if (element.isHoldsChildren()]
[element.getChildren().genTags()/]
[/if]
[genClosingTag(element)/]
[/if]
[/template]
Please hold the question(s) concise :p.
Laurent Goubet
Obeo
--------------060001010207030007070809
Content-Type: text/x-vcard; charset=utf-8;
name="laurent_goubet.vcf"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="laurent_goubet.vcf"
YmVnaW46dmNhcmQNCmZuOkxhdXJlbnQgR291YmV0DQpuOkdvdWJldDtMYXVy ZW50DQpvcmc6
PGEgaHJlZj0iaHR0cDovL3d3dy5vYmVvLmZyIj5PYmVvPC9hPg0KZW1haWw7 aW50ZXJuZXQ6
bGF1cmVudC5nb3ViZXRAb2Jlby5mcg0KdXJsOmh0dHA6Ly93d3cub2Jlby5m cg0KdmVyc2lv
bjoyLjENCmVuZDp2Y2FyZA0KDQo=
--------------060001010207030007070809--
|
|
|
Powered by
FUDForum. Page generated in 0.05102 seconds