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]