Jason van Zyl wrote:

> First, we want to simplify the Runtime. Geir and I have been discussing
> this, and I think it would be possible to get rid of the following
> methods:
> 
> Runtime.setProperties()
> Runtime.setDefaultsProperties()

Yep. +1

> Now, I posit that there are only two ways that an application using
> Velocity would want to initialize the Runtime:
> 
> 1) Using an external configuration file
> 2) Grab configuration information from any number of different
>      sources. Most likely and application configuration file, but it
>     could be from a database, LDAP server, or what have you.

I'll see your posit and raise you one :

 3) <guess>

As promised, I asked my client yesterday, first thing when I walked in
(or at least their director of software development : 

"How do you manage configuration information inside your application?"  

After looking at in a way I interpreted to be wondering why they pay me
money to tell them things, he said 

"Properties class"

I will surprise you all as noting this is irrelevant to the discussion :
)  But for anyone still reading these, I wanted to report back...

> To satisfy these two possibilities, I propose the two following methods:
> 
> 1)  This is the case where the client app simply wants to pull
>        in an external configuration file. I propose the following as
>        the standard way of pulling in an external configuration file.
> 
> Runtime.init(String configuration)
> [SNIP]

Ok.  I have always liked this.    However, looking ahead, I think we can
even eliminate this :) and I will tell you why later.

> And users currently using this method will have to make no changes
> to there code because a Configuration object is made from the
> file referred to by 'configuration'. This very simple abstraction
> makes things a lot simpler: no more concerns over using a
> particular class for runtime intializations.
> 
> If we change the internal representation again to another type of
> config file then again client code will not have to change. The format
> of the configuration may change (say we move to XML) but the code
> will not have to change.

Sure.
 
> I think this is the simplest method for initializing the runtime with
> an external configuration file and allows us flexibility in the
> future.
> 
> 2) This is the case where the client application grabs velocity
> configuration
>       from whatever source it chooses. I will use Turbine as an example:
> 
> Runtime.setSourceProperty(Runtime.FILE_RESOURCE_LOADER_PATH, path1);
> Runtime.setProperty(Runtime.RUNTIM_LOG, log);
> Runtime.init()

Tentatively, I agree.  I say tentatively, because I do think we need to
be precise about defining the API.

To that end, I propose that we modify the entire Runtime configuration
API to be :

/**
 *  sets the value of the property <prop> to the value <value>. 
 * Repeated call with the same <prop> simply replace the existing value
 */
boolean setProperty( String prop, String value )

/**
 *  adds a value to the multivalued property <prop>
 */ 
boolean addProperty( String prop, String value )

/**
 * takes the user properties as set via above if any,
 * lays them over the default prop set, and inits
 */
init()

This makes it lucidly clear what is going on - and you don't get stuck
with side effects of the internal configuration turning a scalar valued
property into a vector-valued one when you are simply trying to replace
a value.  Further, the Runtime core is agnostic wrt format or container
- be it file, Properties, Configuration, Hashtable.

The advantages :

Turbine can do :

 Runtime.addProperty(Runtime.FILE_RESOURCE_LOADER_PATH, path1);
 Runtime.setProperty(Runtime.RUNTIM_LOG, log);
 Runtime.init()

and any of us from the Cult of Properties or the Configuration Tribe, or
any upcoming method du jour :

 for( Enumeration e = p.propertyNames(); e.hasMoreElements(); )
 {
        String s = (String) e.nextElement();
        Runtime.setProperty(s,  p.getProperty(s));
 }
 Runtime.init();

Of course, note that it is critical that we fix our properties anyway -
right now, the *.resource.path properties are such that you *CANNOT* use
any Map-like container to hold them, so you can't mix them with your
application properties, and you can't use Properties.load() to load
them, and....  

For example, if you have a situation where your Velocity properties are
split between a static set, and something you figure out at runtime,
then you would have to manually parse the properties file and store in a
Vector of Hashes or something.  Ug.


> Now I agree with Geir that a more deterministic way to set a resource
> loader property would be good, but that is peripheral to this proposal.

Yep - and I think that your other good ideas on this issue re   

resource.loader = foo 
resource.loader.foo.<prop>

will help solve this completely.  But we can do that next.

> Any thoughts?

I'll summarize :

I am +1000 for simplifying Runtime.  I have wanted to for months. (That
was the motivation behind the o.a.v.a.Velocity class)

I believe we can achieve everything we need if Runtime supports the
following methods

setProperty( key, val ) : replaces the value of key with val
addProperty( key, val ) : adds to a multivalued property (not in love
with method name...)
Runtime.init() : takes the default properties, replaces any values with
any in the 'user properties' set via setProperty() and addProperty().

this means that you would have full control from the app layer to reset,
set scalar and make 'vector' properties.

However, this is contingent upon making our properties unique - any
vector property must have a 'uniqueifying' integer at the end of it, and
setProperty() will do the right thing.  That integer can be used for
ordering if relevant.

I volunteer to make this work, the trailing integer bit, if someone else
doesn't want to.

What this means is that we have now precisely defined a configuration
API : we don't care what form the application uses to hold it, we don't
care what  format on disk they are stored - we can support all currently
known management mechanisms.

Now, it is really easy to do an init( filename ), init( Properties ),
init( Configuration ), init( whatever), so I will add to the Velocity
application helper class the following :

init( String filename ) : as it won't be in Runtime anymore
init( Properties props )
init( Configuration config )
?

That way, application developers have the support for convenient use,
but we do the right thing and simplify Runtime.  Good stuff, Jason.

Apologies in advance : I am away again today fighting the good fight
getting Velocity integrated into another production system for a client,
so you won't hear a peep from me til this evening.

I also have a few things for TODO, so you will see them then.

Viva la Velocity!

geir

-- 
Geir Magnusson Jr.                               [EMAIL PROTECTED]
Developing for the web?  See http://jakarta.apache.org/velocity/

Reply via email to