You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@velocity.apache.org by SainTiss <sa...@gmx.net> on 2004/03/17 11:41:30 UTC

on recursion once more

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

Since it seems LocalDirective doesn't work as it should, I'm going to look 
into the possibility of delegating the recursion work to a java tool, as was 
recommended before.

However, one problem strikes me: If I am indeed supposed to let the java tool 
calculate all output of the recursive part, then doesn't that mean *all* 
output in between also needs to be done by the tool?

Allow me to clarify myself: The kind of output I need is Java code, similar to 
this:

switch (myVar) {
case 1: // do something
		break;
case 2:
	#parse("otherTemplate")
		break;
case 3:
	switch (myVar2) {
	case 1: 
		#parse("otherTemplate")
			break;
	case 2: // do something
			break;
	}
		break;
}

So the point is that switch statements can be nested, which is what I need 
recursion for. So the solution would be to have a java tool which recursively 
calculates the nested switch statements. But within these statements, another 
template should be processed, which makes use of variables set during 
generation of the switch statements. So doesn't that mean the only option is 
to let the java tool generate all code from "otherTemplate" too then? That 
would be quite catastrophic, because that makes up the lionshare of my 
project, which means I effectively lose velocity's power...

So I hope I'm mistaken here, and there's a way to let a tool just calculate 
the structure of the switches, while still allowing "otherTemplate" to do its 
work... Is that possible? And if so, is there maybe an example available 
somewhere?

Many thanks,

Hans

- -- 
Ark Linux - Linux for the Masses (http://arklinux.org)

Capitalism: 
You don't have any cows. The bank will not lend you money to buy cows, 
because you don't have any cows to put up as collateral.

Representative Democracy:
You have two cows. Your neighbors pick someone to tell you who gets the milk. 

In a world without walls and fences, who needs windows and gates?

Hans Schippers
2LIC INF
UA 2003-2004
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (GNU/Linux)

iD8DBQFAWCtaXlnUYIbmLOQRAi7QAJ9JzxD5gaKk+vqy3/NYiUTknn6eIgCggclv
H8y0ce/nsO6SR9XraK0PgHg=
=xJ0b
-----END PGP SIGNATURE-----


---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-user-help@jakarta.apache.org


Re: on recursion once more

Posted by SainTiss <sa...@arklinux.org>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Wednesday 17 March 2004 15:09, Mike Kienenberger wrote:
>
> What's the input look like?
> What form is it in?

Actually, the input is a UML diagram, which specifies the control flow as an 
activity diagram. Each activity, however, specifies additional actions, which 
is why I use the "otherTemplate" for each activity...
The switch statements implement the control flow.

The UML diagram is accessed via Java interfaces...

Hans


- -- 
Ark Linux - Linux for the Masses (http://arklinux.org)

Capitalism: 
You don't have any cows. The bank will not lend you money to buy cows, 
because you don't have any cows to put up as collateral.

Representative Democracy:
You have two cows. Your neighbors pick someone to tell you who gets the milk. 

In a world without walls and fences, who needs windows and gates?

Hans Schippers
2LIC INF
UA 2003-2004
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (GNU/Linux)

iD8DBQFAWIsyXlnUYIbmLOQRApckAJ9Hn1KOV8l7lRJ4vvCZLmR1cx1fHACfZLQW
XSP4q2OiYJrvu4HFDCR4pTg=
=eKpY
-----END PGP SIGNATURE-----


---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-user-help@jakarta.apache.org


Re: on recursion once more

Posted by SainTiss <sa...@gmx.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

yes, using a stack effectively simulates "real" recursion I guess :)

I'll keep that in mind... Thanks again...

Hans

On Wednesday 17 March 2004 21:15, Mike Kienenberger wrote:
> SainTiss <sa...@gmx.net> wrote:
> > So, without nesting, the velocity template could look like this:
> >
> > int currentId = $tool.getStartActivity().getId();
> > while (currentId != $tool.getEndActivity().getId()) {
> > 	switch(currentId) {
> > 		case 1:
> > #set($activity = $tool.getActivityForId(1))
> > #parse("otherTemplate") ## "otherTemplate" uses the $activity variable
> > 			currentId = $tool.getNextActivity($activity).getId();
> > 			break;
> > 		case 2:
> > #set($activity = $tool.getActivityForId(1))
> > #parse("otherTemplate")
> > 			currentId = $tool.getNextActivity($activity).getId();
> > 			break;
> > 		## and so on...
> > 	}
> > }
> >
> > So the point is, that for these activities which contain a nested control
> > flow, I'd like to apply this algorithm recursively. But I can't just use
> > a
> >
> > macro, because then variables like $activity (but there others as well)
>
> would
>
> > get overwritten while applying the recursion...
> >
> > If I understand you correctly, you assumed "otherTemplate" could just
>
> generate
>
> > a new switch statement if needed, but that is not the case, since
> > "otherTemplate" isn't concerned with the control flow anymore, but with
>
> just
>
> > one activity instead...
>
> Well, there's still plenty of ways to handle it.
> You can still do this completely in the java tool since it doesn't look
> like the code generated changes from statement to statement.
>
> Or you can put a stack tool into the context, make a "switch" template that
> operates on the top activity in the stack, and recursively calls itself.
> The switch template could be a #macro if your velocity supports recursive
> macro calls or it could just be a template that #parses itself.
>
> $stack.push($activity)
> #parse("switch.vm")
>
>
> in "switch.vm"
> ============
> #set ($currentActivity = $stack.pop()
> [...]
> 	case x:
> [...]
> 		#if we should generate another switch
> $stack.push($nextActivity)
> #parse("switch.vm")
> 		#end
> [...]
> ============
>
> I'd probably use the stack method since it keeps the generated code out of
> the tool.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: velocity-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: velocity-user-help@jakarta.apache.org

- -- 
Ark Linux - Linux for the Masses (http://arklinux.org)

Capitalism: 
You don't have any cows. The bank will not lend you money to buy cows, 
because you don't have any cows to put up as collateral.

Representative Democracy:
You have two cows. Your neighbors pick someone to tell you who gets the milk. 

In a world without walls and fences, who needs windows and gates?

Hans Schippers
2LIC INF
UA 2003-2004
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (GNU/Linux)

iD8DBQFAWMRSXlnUYIbmLOQRArwlAJ9g+/OiVVnWRIu7n4+1E1v1Sb4KHgCeIOEW
07UZuvs5D8wlGGizeaktBtI=
=nrq0
-----END PGP SIGNATURE-----


---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-user-help@jakarta.apache.org


Re: on recursion once more

Posted by Mike Kienenberger <mk...@alaska.net>.
SainTiss <sa...@gmx.net> wrote:
> So, without nesting, the velocity template could look like this:
> 
> int currentId = $tool.getStartActivity().getId();
> while (currentId != $tool.getEndActivity().getId()) {
> 	switch(currentId) {
> 		case 1:
> #set($activity = $tool.getActivityForId(1))
> #parse("otherTemplate") ## "otherTemplate" uses the $activity variable
> 			currentId = $tool.getNextActivity($activity).getId();
> 			break;
> 		case 2:
> #set($activity = $tool.getActivityForId(1))
> #parse("otherTemplate")
> 			currentId = $tool.getNextActivity($activity).getId();
> 			break;
> 		## and so on...
> 	}
> }
> 
> So the point is, that for these activities which contain a nested control 
> flow, I'd like to apply this algorithm recursively. But I can't just use a 

> macro, because then variables like $activity (but there others as well) 
would 
> get overwritten while applying the recursion...
> 
> If I understand you correctly, you assumed "otherTemplate" could just 
generate 
> a new switch statement if needed, but that is not the case, since 
> "otherTemplate" isn't concerned with the control flow anymore, but with 
just 
> one activity instead...

Well, there's still plenty of ways to handle it.
You can still do this completely in the java tool since it doesn't look like 
the code generated changes from statement to statement.

Or you can put a stack tool into the context, make a "switch" template that 
operates on the top activity in the stack, and recursively calls itself.   
The switch template could be a #macro if your velocity supports recursive 
macro calls or it could just be a template that #parses itself.

$stack.push($activity)
#parse("switch.vm")


in "switch.vm"
============
#set ($currentActivity = $stack.pop()
[...]
	case x:
[...]
		#if we should generate another switch
$stack.push($nextActivity)
#parse("switch.vm")
		#end
[...]
============

I'd probably use the stack method since it keeps the generated code out of 
the tool.

---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-user-help@jakarta.apache.org


Re: on recursion once more

Posted by SainTiss <sa...@gmx.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

I probably should have made a few things more clear:
The control flow is actually determined by *all* activities. That means that 
one activity maps to a "case", rather than a complete "switch". The easiest 
way to consider the nesting problem, is probably to assume that certain 
activities can hold a whole new activity diagram, which describe a new, 
nested, control flow (which maps to a "switch", and each activity to a 
"case").

The behaviour of one particular activity is something else, which is why I put 
the code generation for that in "otherTemplate".

About the input: actually, the UML diagram is stored in a repository, which 
can be accessed through java calls. I've got a helper tool which does these 
accesses, and I call this tool from within velocity. So that's how I get the 
input...

So, without nesting, the velocity template could look like this:

int currentId = $tool.getStartActivity().getId();
while (currentId != $tool.getEndActivity().getId()) {
	switch(currentId) {
		case 1:
#set($activity = $tool.getActivityForId(1))
#parse("otherTemplate") ## "otherTemplate" uses the $activity variable
			currentId = $tool.getNextActivity($activity).getId();
			break;
		case 2:
#set($activity = $tool.getActivityForId(1))
#parse("otherTemplate")
			currentId = $tool.getNextActivity($activity).getId();
			break;
		## and so on...
	}
}

So the point is, that for these activities which contain a nested control 
flow, I'd like to apply this algorithm recursively. But I can't just use a 
macro, because then variables like $activity (but there others as well) would 
get overwritten while applying the recursion...

If I understand you correctly, you assumed "otherTemplate" could just generate 
a new switch statement if needed, but that is not the case, since 
"otherTemplate" isn't concerned with the control flow anymore, but with just 
one activity instead...

Unless I misunderstood, and you think your approach would still work?

Thanks,

Hans

On Wednesday 17 March 2004 20:04, Mike Kienenberger wrote:
> Mike Kienenberger <mk...@alaska.net> wrote:
> > SainTiss <sa...@gmx.net> wrote:
> > > Allow me to clarify myself: The kind of output I need is Java code,
> >
> > similar to
> >
> > > this:
> > >
> > > switch (myVar) {
> > > case 1: // do something
> > > 		break;
> > > case 2:
> > > 	#parse("otherTemplate")
> > > 		break;
> > > case 3:
> > > 	switch (myVar2) {
> > > 	case 1:
> > > 		#parse("otherTemplate")
> > > 			break;
> > > 	case 2: // do something
> > > 			break;
> > > 	}
> > > 		break;
> > > }
> >
> > What's the input look like?
> > What form is it in?
>
> SainTiss <sa...@arklinux.org> wrote:
> > Actually, the input is a UML diagram, which specifies the control flow as
>
> an
>
> > activity diagram. Each activity, however, specifies additional actions,
>
> which
>
> > is why I use the "otherTemplate" for each activity...
> > The switch statements implement the control flow.
> >
> > The UML diagram is accessed via Java interfaces...
>
> It sounds like each case is predetermined.  Any customization would occur
> in the "otherTemplate" so there's no reason why the tool can't just
> generate all of the output.
>
> I still don't understand what form your input is in, but I'd say you could
> write a tool with a method signature something like this:
>
> $code.generateSwitchFor(String baseActivity)
>
> which would generate code like:
>
> 	switch ([baseActivity.getActionType()]}) {
> 	case 1:
> 		#parse("template.[baseActivity].1")
> 	 		break;
> 	case 2:
> 		#parse("template.[baseActivity].2")
> 			break;
> 	case 3:
> 		#parse("template.[baseActivity].3")
> 			break;
> 	}
>
>
> If case 3 contains the same kind of statement, then the
> template.[baseActivity].3 would just contain another
> "$code.generateSwitchFor(String baseActivity3)" reference.
>
> #parse("template.[baseActivity].3") would probably be replaced by java code
> that did the same thing.   (Ie, mergeTemplate on a copy of the template.)
>
>
> You might even be able to avoid creating a tool and just do this with the
> eval() or recurse() method, but I've never used either of them.
>
> org.apache.velocity.tools.generic.RenderTool.eval()
>
>
> http://jakarta.apache.org/velocity/tools/javadoc/org/apache/velocity/tools/
>generic/RenderTool.html
>
> Here's an off-the-cuff best guess how you might do this.
>
>
> #set($qt = '"')
> #set($currentActivity = $contextReferenceToCurrentActivity)
> 	switch
> (${currentActivity.javaReferenceToTargetActivityObject}.getActionType()) {
> #foreach ($action in $currentActivity.getActionList())
> 	case $action:
> 		$render.recurse($ctx,
> "#parse(${qt}template.${currentActivity.getTemplateNamePrefix()}.${action.g
>etTemplateNameSuffix()}${qt})") break;
> #end##foreach ($action in $currentActivity.getActionList())
> 	}
>
>
>
>
> ${currentActivity.javaReferenceToTargetActivityObject}.getActionType()
> should somehow translate to myVar, but there's no enough information to
> guess how that might be done, or even if it's determined based on
> currentActivity.
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: velocity-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: velocity-user-help@jakarta.apache.org

- -- 
Ark Linux - Linux for the Masses (http://arklinux.org)

Capitalism: 
You don't have any cows. The bank will not lend you money to buy cows, 
because you don't have any cows to put up as collateral.

Representative Democracy:
You have two cows. Your neighbors pick someone to tell you who gets the milk. 

In a world without walls and fences, who needs windows and gates?

Hans Schippers
2LIC INF
UA 2003-2004
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (GNU/Linux)

iD8DBQFAWKsOXlnUYIbmLOQRAgBEAKCXLS7YdTRNhHFGeJaNKibWeD6wXACghg9z
GKMetMLVUwq1RKffCYI+FtM=
=UtoC
-----END PGP SIGNATURE-----


---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-user-help@jakarta.apache.org


Re: on recursion once more

Posted by Mike Kienenberger <mk...@alaska.net>.
Mike Kienenberger <mk...@alaska.net> wrote:
> SainTiss <sa...@gmx.net> wrote:
> > Allow me to clarify myself: The kind of output I need is Java code, 
> similar to 
> > this:
> > 
> > switch (myVar) {
> > case 1: // do something
> > 		break;
> > case 2:
> > 	#parse("otherTemplate")
> > 		break;
> > case 3:
> > 	switch (myVar2) {
> > 	case 1: 
> > 		#parse("otherTemplate")
> > 			break;
> > 	case 2: // do something
> > 			break;
> > 	}
> > 		break;
> > }
> 
> What's the input look like?
> What form is it in?

SainTiss <sa...@arklinux.org> wrote:
> Actually, the input is a UML diagram, which specifies the control flow as 
an 
> activity diagram. Each activity, however, specifies additional actions, 
which 
> is why I use the "otherTemplate" for each activity...
> The switch statements implement the control flow.
> 
> The UML diagram is accessed via Java interfaces...

It sounds like each case is predetermined.  Any customization would occur in 
the "otherTemplate" so there's no reason why the tool can't just generate 
all of the output.

I still don't understand what form your input is in, but I'd say you could 
write a tool with a method signature something like this:

$code.generateSwitchFor(String baseActivity)

which would generate code like:

	switch ([baseActivity.getActionType()]}) {
	case 1:
		#parse("template.[baseActivity].1")
	 		break;
	case 2:
		#parse("template.[baseActivity].2")
			break;
	case 3:
		#parse("template.[baseActivity].3")
			break;
	}


If case 3 contains the same kind of statement, then the 
template.[baseActivity].3 would just contain another 
"$code.generateSwitchFor(String baseActivity3)" reference.

#parse("template.[baseActivity].3") would probably be replaced by java code 
that did the same thing.   (Ie, mergeTemplate on a copy of the template.)


You might even be able to avoid creating a tool and just do this with the 
eval() or recurse() method, but I've never used either of them.

org.apache.velocity.tools.generic.RenderTool.eval()

http://jakarta.apache.org/velocity/tools/javadoc/org/apache/velocity/tools/generic/RenderTool.html

Here's an off-the-cuff best guess how you might do this.


#set($qt = '"')
#set($currentActivity = $contextReferenceToCurrentActivity)
	switch 
(${currentActivity.javaReferenceToTargetActivityObject}.getActionType()) {
#foreach ($action in $currentActivity.getActionList())
	case $action:
		$render.recurse($ctx, 
"#parse(${qt}template.${currentActivity.getTemplateNamePrefix()}.${action.getTemplateNameSuffix()}${qt})")
	 		break;
#end##foreach ($action in $currentActivity.getActionList())
	}




${currentActivity.javaReferenceToTargetActivityObject}.getActionType() 
should somehow translate to myVar, but there's no enough information to 
guess how that might be done, or even if it's determined based on 
currentActivity.



---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-user-help@jakarta.apache.org


Re: on recursion once more

Posted by Mike Kienenberger <mk...@alaska.net>.
SainTiss <sa...@gmx.net> wrote:
> Allow me to clarify myself: The kind of output I need is Java code, 
similar to 
> this:
> 
> switch (myVar) {
> case 1: // do something
> 		break;
> case 2:
> 	#parse("otherTemplate")
> 		break;
> case 3:
> 	switch (myVar2) {
> 	case 1: 
> 		#parse("otherTemplate")
> 			break;
> 	case 2: // do something
> 			break;
> 	}
> 		break;
> }

What's the input look like?
What form is it in?

---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-user-help@jakarta.apache.org