<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Jonathan Buhacoff wrote:
<blockquote cite="mid:3AA9875D-31A5-49BC-8000-AE756E177656@buhacoff.net"
type="cite">
<div>
<div><br>
</div>
<div>On Oct 22, 2009, at 12:23 PM, Vincent DARON wrote:</div>
<br class="Apple-interchange-newline">
<br>
<blockquote type="cite">
<div bgcolor="#ffffff" text="#000000">I'm quite new to
StringTemplate, the first need for that feature was
internationalization of Enumerations<br>
<br>
</div>
</blockquote>
<div><br>
</div>
<div>I know you're not using Java... In Java this is easy with
ResourceBundle. Find or make the equivalent in your platform ; this
doesn't require a modification to StringTemplate.</div>
</div>
</blockquote>
Resources exists in .NET as well, this is not the problem here. using
typeof(Enum) allow the creation of ONE AttributeRenderer for ALL the
Enum used in my attributes.<br>
<blockquote cite="mid:3AA9875D-31A5-49BC-8000-AE756E177656@buhacoff.net"
type="cite">
<div><br>
<blockquote type="cite">
<div bgcolor="#ffffff" text="#000000"> (All Types starting with
"My" are custom classes here to ease reading)<br>
<br>
I simply try to do <br>
<br>
<tt>StringTemplate.SetAttributeRenderer(typeof(Enum),new
MyI18nEnumRenderer());</tt><br>
<br>
It did'nt works and I had to do <br>
<br>
<tt>StringTemplate.SetAttributeRenderer(typeof(MyEnum1),new
MyI18nEnumRenderer());<br>
StringTemplate.SetAttributeRenderer(typeof(MyEnum2),new
MyI18nEnumRenderer());<br>
StringTemplate.SetAttributeRenderer(typeof(MyEnum3),new
MyI18nEnumRenderer());<br>
...</tt><br>
<br>
The second need for that feature was for Formatting purposes<br>
<br>
<tt>StringTemplate.SetAttributeRenderer(typeof(IFormatProvider),new
MyFormatProviderRenderer());</tt><br>
<br>
</div>
</blockquote>
<div><br>
</div>
<div>You can create a new type MyFormattedType that implements your
IFormatProvider interface. Then register your <span
class="Apple-style-span" style="font-family: monospace;">MyFormatProviderRenderer<span
class="Apple-style-span" style="font-family: Helvetica;"> renderer
for MyFormattedType. Then wrap all your types that implement
IFormatProvider with a MyFormattedType type object. That will do what
you want, and after you set it up once it's easy to reuse.</span></span></div>
<div><br>
</div>
</div>
</blockquote>
<br>
This is maybe specific to .NET as well, IFormattable for example, is an
interface that is implemented by all the basic types (int, string,
Datetime , ...) to specify what is the formatting to use when calling
the method ToString().<br>
<br>
When I'm using StringTemplate, I'm using Graph objects as Attributes :<br>
<br>
<tt>class Address{<br>
public string Street;<br>
public int Number;<br>
...<br>
}<br>
<br>
class Person{<br>
public string Name;<br>
public Address Address;<br>
} <br>
</tt><br>
<br>
in my template there are plenty of call to <tt>$Person.Name$</tt> or <tt>$Person.Address.Street$</tt><br>
<br>
It's not possible to wrap all types that implement IFormatProvider
(wrap "int" or "string" ?)<br>
<br>
<blockquote cite="mid:3AA9875D-31A5-49BC-8000-AE756E177656@buhacoff.net"
type="cite">
<div><br>
<blockquote type="cite">
<div bgcolor="#ffffff" text="#000000"> did'nt works either...<br>
<br>
It's after that second problem that I looked into Sources and propose
my approach.<br>
<br>
I do not think that it could be a speed problem, with a behavior like
mine, people using AttributeRenderer will probably use less Renderer.
The problem about priority is a little more embarrassing. Maybe using 2
lists instead of a Dictionary (Type and Renderer) ? People are adding
AttributeRenderer in the order they will be processed.<br>
</div>
</blockquote>
<div><br>
</div>
<div>No, people are adding AttributeRenderers in any order because
they go in a map and the order doesn't matter. Only the interface
renderers would have to go in an ordered list. And in that case it's
easier to provide an ordered List to ST with all your interface
renderers already in it than to duplicate a list implementation in ST
with add, remove, insertAt, etc. methods. <br>
</div>
</div>
</blockquote>
Users of StringTemplate shouldn't be aware that it's a map behind ;-).
But you're right, using a list may break the code of some people.<br>
<blockquote cite="mid:3AA9875D-31A5-49BC-8000-AE756E177656@buhacoff.net"
type="cite">
<div><br>
<blockquote type="cite">
<div bgcolor="#ffffff" text="#000000"> <br>
<tt>StringTemplate st = new ...<br>
<br>
st.SetAttributeRenderer(typeof(MyClass), new MyRenderer());<br>
st.SetAttributeRenderer(typeof(IMyInterface), new MyIRenderer());<br>
st.SetAttributeRenderer(typeof(object), new MyDefaultRenderer());<br>
<br>
st.ToString();</tt><br>
<br>
</div>
</blockquote>
<div><br>
</div>
<div>I wouldn't mix the class and interface renderers; already
mentioned the reasons in my last post. </div>
<br>
<blockquote type="cite">
<div bgcolor="#ffffff" text="#000000"> In this example the
MyDefaultRenderer will be called for all Attributes that are not of
type MyClass and do not implements IMyInterface. It look quite
intuitive to me. The only difference is that the order of Setting
Renderer matters.<br>
</div>
</blockquote>
<div><br>
</div>
<div>I think a better way, which you can do right now, is for you to
subclass StringTemplate and override setAttribute to automatically wrap
your objects that implement a specific interface with a class for which
you register a renderer. You can handle or ignore priority issues and
it won't require a change to StringTemplate. <br>
</div>
</div>
</blockquote>
Again, it's not possible to wrap object graph easily.<br>
<br>
It seems that my proposition is maybe too much .NET oriented.<br>
<br>
Thanks for answers and precisions.<br>
<br>
Vincent<br>
<br>
<blockquote cite="mid:3AA9875D-31A5-49BC-8000-AE756E177656@buhacoff.net"
type="cite">
<div><br>
<blockquote type="cite">
<div bgcolor="#ffffff" text="#000000"> <br>
It's only suggestion :-) and any other ideas to solve these "problems"
are welcome.<br>
<br>
</div>
</blockquote>
<div><br>
</div>
<div><br>
</div>
<br>
<blockquote type="cite">
<div bgcolor="#ffffff" text="#000000"> Thanks,<br>
<br>
Vincent<br>
<br>
PS: Accessing source from trunk is possible ? How ?<br>
<br>
<br>
<br>
<br>
Jonathan Buhacoff wrote:
<blockquote
cite="mid:DAE8224D-ABD0-40DA-883E-8C4A650B680B@buhacoff.net"
type="cite">
<pre wrap="">If it's integrated with the class renderers as I showed in my diff,
there's a little extra work to do. On the other hand, most classes
only implement handful of interfaces, and since this code doesn't do
any string processing it will probably be fast enough.
Or, if it's implemented as a separate map of renderers, then it will
only slow down processing if the programmer has registered any
interface renderers. But that seems a little messy to me, maybe more
messy than the speed savings is worth.
Finally, the other issue with interface renderers is priority - as
proposed now, we have no control over which renderer will be found
first, and if a class implements more than one interface with a
registered renderer, the output will be non-deterministic. I think
that's a bad thing.
The way to control that would be to have a complete interface to
manage the priority of interface renderers, or to have ST implement
something like
registerInterfaceAttributeRenderers(List<AttributeRenderer>
renderers); so the programmer can specify the order of the
renderers.
So the loop would change to iterating through the registered interface
renderers and checking if the value implements each one (and they
would be in priority order).
That makes things deterministic again, and would require the use of a
list of interface renders separate from the map of class renderers,
which means only people who use interface renderers would incur any
performance penalty.
I'm still trying to think of a case where this scheme would be better
than wrapping everything with an adapter and registering a renderer
for that, because automatically wrapping certain classes that
implement an interface automatically is so easy to do by subclassing
StringTemplate. I'm still thinking along the lines of
internationalization, units of measure, stuff like that. Vincent can
you provide a real world case?
On Oct 22, 2009, at 9:45 AM, Sam Harwell wrote:
</pre>
<blockquote type="cite">
<pre wrap="">Hi Vincent,
My first thought is this changes an O(1) algorithm that has to run for
every rendered item into an O(n) algorithm. I would have to run this
through the instrumenting profiler to make sure it isn't slowing down
the rendering process before I could include it. There are a few other
ways to approach the problem, but I'm not yet sure which one would
work
out best.
Sam
-----Original Message-----
From: <a moz-do-not-send="true" class="moz-txt-link-abbreviated"
href="mailto:stringtemplate-interest-bounces@antlr.org">stringtemplate-interest-bounces@antlr.org</a>
[<a moz-do-not-send="true" class="moz-txt-link-freetext"
href="mailto:stringtemplate-interest-bounces@antlr.org">mailto:stringtemplate-interest-bounces@antlr.org</a>] On Behalf Of
Vincent
DARON
Sent: Thursday, October 22, 2009 10:12 AM
To: <a moz-do-not-send="true" class="moz-txt-link-abbreviated"
href="mailto:stringtemplate-interest@antlr.org">stringtemplate-interest@antlr.org</a>
Subject: [stringtemplate-interest] IAttributeRenderer and Type
Inheritancein C#
Hi
I would like to be able to register an IAttributeRenderer for objects
implementing an Interface.
Part of current implementation of GetAttributeRenderer
public virtual IAttributeRenderer GetAttributeRenderer( Type
attributeClassType )
{
IAttributeRenderer renderer = null;
if ( _attributeRenderers != null )
{
if ( !_attributeRenderers.TryGetValue(
attributeClassType, out renderer ) )
renderer = null;
}
// ...snip ... //
}
My proposal (untested, but should be ok)
public virtual IAttributeRenderer GetAttributeRenderer( Type
attributeClassType )
{
IAttributeRenderer renderer = null;
if ( _attributeRenderers != null )
{
                foreach(Type key in _attributeRenderers.Keys)
                {
                        if(key.IsAssignableFrom(attributeClassType))
                        {
                                renderer = _attributeRenderers[key];
                                break;
                        }
                }
}
// ...snip ... //
}
It will allow to register Attribute Renderer for objects implementing
interfaces
RegisterAttributeRenderer(typeof(IFormatProvider), ...);
Goot idea ?
Second question, is it possible to have access to source using Source
Control (Subversion, Hg, Git, ...) ? It would be far easier to test
and
create patches.
Thanks for answer/comments
Vincent
_______________________________________________
stringtemplate-interest mailing list
<a moz-do-not-send="true" class="moz-txt-link-abbreviated"
href="mailto:stringtemplate-interest@antlr.org">stringtemplate-interest@antlr.org</a>
<a moz-do-not-send="true" class="moz-txt-link-freetext"
href="http://www.antlr.org/mailman/listinfo/stringtemplate-interest">http://www.antlr.org/mailman/listinfo/stringtemplate-interest</a>
_______________________________________________
stringtemplate-interest mailing list
<a moz-do-not-send="true" class="moz-txt-link-abbreviated"
href="mailto:stringtemplate-interest@antlr.org">stringtemplate-interest@antlr.org</a>
<a moz-do-not-send="true" class="moz-txt-link-freetext"
href="http://www.antlr.org/mailman/listinfo/stringtemplate-interest">http://www.antlr.org/mailman/listinfo/stringtemplate-interest</a>
</pre>
</blockquote>
<pre wrap=""><!---->
_______________________________________________
stringtemplate-interest mailing list
<a moz-do-not-send="true" class="moz-txt-link-abbreviated"
href="mailto:stringtemplate-interest@antlr.org">stringtemplate-interest@antlr.org</a>
<a moz-do-not-send="true" class="moz-txt-link-freetext"
href="http://www.antlr.org/mailman/listinfo/stringtemplate-interest">http://www.antlr.org/mailman/listinfo/stringtemplate-interest</a>
</pre>
</blockquote>
<br>
</div>
_______________________________________________<br>
stringtemplate-interest mailing list<br>
<a moz-do-not-send="true"
href="mailto:stringtemplate-interest@antlr.org">stringtemplate-interest@antlr.org</a><br>
<a class="moz-txt-link-freetext" href="http://www.antlr.org/mailman/listinfo/stringtemplate-interest">http://www.antlr.org/mailman/listinfo/stringtemplate-interest</a><br>
</blockquote>
</div>
<br>
<pre wrap="">
<hr size="4" width="90%">
_______________________________________________
stringtemplate-interest mailing list
<a class="moz-txt-link-abbreviated" href="mailto:stringtemplate-interest@antlr.org">stringtemplate-interest@antlr.org</a>
<a class="moz-txt-link-freetext" href="http://www.antlr.org/mailman/listinfo/stringtemplate-interest">http://www.antlr.org/mailman/listinfo/stringtemplate-interest</a>
</pre>
</blockquote>
<br>
</body>
</html>