Frank Schönheit wrote:
[...]
Yes, XInitialization behind the scenes of service constructors is a bad hack (that will hopefully go away). However, it should not be too hard to write a service implementation for a service like

   service ConsoleHandler: XLogHandler {
specific([in] string encoding, [in] XLogFormatter formatter, [in] long level, [in] long threshold); generic([in] sequence<PropertyValue> arguments) raises (IllegalArgumentException);
   };

which could then nicely be called through a generic createInstanceWithArguments (and should define a reasonable policy how to handle missing and excess arguments).

Uh - createInstanceWithArguments currently also uses XInitialization,
but this is an implementation detail of the respective factories only.
(I remember that long ago, we implemented factories for the
configuration provider which in fact did something different.)

So no, createInstanceWithArguments is not an option here, since it would
assume that constructors are implemented using XInitialization, and thus
cement this hack for all time.

Why? Today, service ctors are internally calling createInstanceWithArguments, and createInstanceWithArguments internally calls XInitialization.

createInstanceWithArguments to create a service can probably never go away, for backwards compatibility reasons.

So, whatever service ctors are going to do internally in the future, we should better define how service ctors and createInstanceWithArguments are conceptually intended to play together. That is, how createInstanceWithArguments can be interpreted in terms of service ctors. There are three cases to consider:

1 New-style services with a default ctor. The default ctor has signature ([in] any... arguments), which matches nicely with the createInstanceWithArguments([in] sequence<any> arguments) signature.

2 New-style services with no ctor, and old-style services. These anyway rely on being created with createInstanceWithArguments.

3 New-style services with one or more explicit ctors. (The current limitation for those ctors is that their signatures are sufficiently different, so that a service implementation can distinguish ctor calls based on the arguments passed in via createInstanceWithArguments. This limitation should fall in the future.) I would suggest the following: If among the ctors there is exactly one with signature ([in] any...), calling createInstanceWithArguments calls that ctor; otherwise, calling createInstanceWithArguments has unspecified results.

That would mean that we would have to revert to weaker typing for the ConsoleHandler service above:

   service ConsoleHandler: XLogHandler {
specific([in] string encoding, [in] XLogFormatter formatter, [in] long level, [in] long threshold); generic([in] any... arguments) raises (IllegalArgumentException); // arguments must be of type NamedValue
   };

You implement a ConsoleHandler with XInitialize (having to check whether the argument sequence is either <string, XLogFormatter, long, long> or <NamedValue...>). You generically instantiate handler services with createInstanceWithArguments, and we are guaranteed that this will continue to work, even with future handler services, as long as all handler services are defined to have one ctor with ([in] any...) signature. No need for XServiceDescription2 reflection.

However, looking at XServiceDescription2 ... I did not try it, but this
looks indeed as if a generic handler instantiation code could check
whether the to-be-instantiated service supports a ctor taking a
sequence<PropertyValue> (btw. I definatily prefer NamedValue here and it
all similar cases, using PropertyValue is an unnecessary hack since we
have NamedValues.).

NamedValue vs. PropertyValue: Yes, NamedValue was what I had in mind (just could not remember its name).

Assuming that the initialization happens using name-value pairs, it is
even possible to look for a ctor taking arguments with the proper
names/types in any order ...

Hmm, sounds tempting from an architectural point of view, but not really
like fun implementing it :-\

Assuming a proper ctor is found, how can I generically invoke it
(*without* using XInitialization directly)?

(Not true for Java 1.4; java.lang.Thread.getId was introduced in Java 1.5.)
Lemme be nitpicking, please ;)
The LogRecord - part of the Java logging API since 1.4 - has a member
ThreadID. So, the *concept* of a thread ID existed before there was a
possibility to obtain it from a Thread object ...
And how would that help us to implement a LogRecord filler that is compatible with Java 1.3.1 (or current base line)?

Hmm, yes, it wouldn't. But before somebody implements a logger in Java
1.3.1 (instead of using the existing implementation which doesn't have
this problem), Java 1.4 is the base line :).

The more since a Java logger implementation doesn't make any sense,
since here the ThreadID becomes meaningless, anyway - the Java UNO
bridge doesn't "preserve" the thread of the caller, as far as I know, so
every Java implementation obtaining the ThreadID would fill in nonsense.

But client code calling the logger should/could not be aware whether access to the logger is bridged, and any language-binding--specific thread IDs filled in by the logger would thus be meaningful from the client's point of view. That's why I argue for using language-binding--independent UNO thread IDs (which are strings) instead of langugage-binding--specific thread IDs (which are typically some integers).

Functionality that allows client code to obtain the ID of the UNO thread it is executing in would have to be offered in the interface of each UNO language binding. (The functionality should generally be already there, just not officially offered to client code.)

Okay, so I'll make the ID a string, and for the moment fill it by
converting the numerical ID to a string myself. I'll then file an issue
(to you?) requesting the functionality you describe.

For the C++ UNO language binding, the functionality is already available, albeit in a crude way: uno_getIdOfCurrentThread (uno/threadpool.h, from cppu) gives the thread ID in the form of a byte sequence (thread IDs are really byte sequences, not strings, see section "Threads" of <http://udk.openoffice.org/common/man/spec/urp.html>; I had forgotten about that detail). For an "official" way to produce UNO string representations of thread IDs, I would suggest to interpret each individual byte 0xXX as an individual Unicode scalar value U+00XX (i.e., interpret the byte sequence as an ISO-8859-1 string and translate it into a UNO string). Independent of that, please file an issue for an appropriate API.

Overall, this leaves us with the following items
- make ThreadID a string
- document the configuration-based initialization pattern
- initialize via ctor using reflection, not context values
  (assuming that a ctor can generically be called)

Did I forget something?

Thanks & Ciao
Frank

-Stephan

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to