Jeremias Maerki wrote:

> > A PseudoLogger is required (but can be passed
> > null) in the FontServer constructor
> 
> That's an implementation detail and not a problem. It has 
> nothing to do with the API. FontServer is an interface in the 
> API and you are talking about the implementation of 
> FontServer here, I assume.

Well, it may have nothing to do with the aXSL API, but it certainly has
something to do with the FOray API. To implement FOray (which I understand
to be the discussion), you have to do both. If it is wrong to demand a
logging mechanism in aXSL's API, how can it then be right to do so in
FOray's API? It sounds like I could solve all of your concerns by creating a
FOray FontConsumer implementation that is an abstract class, making you pick
some class to extend it, and then simply demanding a logging mechanism in
the implementation's constructor.

Am I right? If so, doesn't it all seem silly? The client application now has
to have implementation-specific code embedded at FontConsumer (document)
construction. Poof. Pluggability just disappeared. For what benefit? None.
Your client application still supplies exactly the same thing it supplied
the other way.

Really, why does FOP care whether it needs to supply logging information
because aXSL requires it or because FOray requires it?

> > and is required in a method in
> > FontConsumer. But FontConsumer is implemented on the client 
> side, in 
> > which the client application tells FOray about itself.
> 
> This method getPseudoLogger() is what caught my purist's eye 
> in the first place. It breaks IoC.

I don't care. (I am sure that comes across more rudely than I intend). There
are more important things here.

> > Second, why should FOray limit its clients to only use 
> static logging? 
> > If the client has to expose a static logging mechanism to FOray in 
> > order to get static logging to work, what can possibly be 
> wrong with 
> > exposing a non-static logging mechanism to FOray? Right now, FOray 
> > doesn't care whether static or non-static logging is used. 
> Why should it?
> 
> Exactly. Why should it? If you remove all logging concerns 
> from the work interface you don't do any assumptions about 
> how logging is done. The presence of getPseudoLogger(), 
> though, produces a strong emphasis on non-static logging.

Not true. Your PseudoLogger implementation can use whatever logging it wants
to, or, as may please you better, send it to /dev/null.

Again, if you accept implementation constructors as part of the API that FOP
must deal with, then I think your whole line of reasoning disappears here.

> > Third, lets define the "concern". <important>My understanding of 
> > Separation of Concerns in this case is that FOrayFont owns 
> the concern 
> > that a message needs to be logged, and that the client application 
> > owns the concern of how that logging should be 
> > accomplished.</important>
> > 
> > In order to maintain that Separation of Concerns, one of two things 
> > must
> > happen:
> > 1. The client must tell the component how stuff should be logged.
> > 2. The server must tell the client what should be logged.
> > 
> > This means some logging-related stuff will appear in the interface 
> > between the two.
> 
> Not IMO. It can be an implementation detail. See more below.
> 
> > The design considerations are as follows:
> > 1. FOrayFont needs to be able to log messages.
> 
> For whom? For the developer or for the end-user? Because 

Ah, now this is what I consider to be an implementation detail!

> that's what I've learned during the past months: That it 
> should be well divided between the two audiences. The 
> speciality is that the developer doesn't need a logger per 
> processing run (i.e. non-static logging) and the end-user 
> often needs more than just pure Strings through a generic 
> logging interface. Note that this is not yet reality in FOP 
> but I believe it will be soon.

Well, I noticed that you chose to ignore the <important> tag, and it shows
up here. Why should the component concern itself with the differences
between the two audiences? If a user wants to log debug or trace messages
into a permanent file somewhere, what business is that of FOrayFont's????
All it should do is respond to the level of detail that is requested by the
client application, and to place it where the client application wants, both
of which, AFAICT, you won't allow me to find out.

> > 2. FOrayFont needs to be able to work with any client system, 
> > regardless of their preferences on logging.
> 
> Nobody challenges that. Due to input from Batik the question 
> is raised whether such a library should do any logging at 
> all. Don't get me wrong.

If you don't want to do any logging, send the log messages to /dev/null. But
it is not reasonable to insist that other client applications must
effectively do the same thing by never getting the opportunity to log.

> I'm all for developer-oriented logging, even in basic 
> libraries. It's just that I somehow need to find out how to 
> accomodate everyone, like you intend, too. The complication 
> here is that I needed to bring a new consideration into play. 
> And we really need to pay attention what we are talking 
> about: the aXSL API or the FOray implementation. If you read 
> my message again I specifically talk about aXSL, not FOray.

OK. Again, I must ask for a proposal for a solution. Submit patches for aXSL
and FOray that allow FOray to log messages on a document-by-document basis
and retain pluggability, and we can talk about this again.

> > I can keep all logging internal to the FOrayFont subsystem, which 
> > would mean that the client application (FOP) has no control 
> over the 
> > logging whatsoever. Very bad. FOray has to guess what kind 
> of logger 
> > to use, and it will never be right.
> 
> It's not true that it doesn't have control. It's just that 
> (static) logging is controlled from elsewhere.
> 
> > I can expose a logging interface that allows the client 
> application to 
> > handle logging its own way. This has been the approach used so far.
> > 
> > The only other solution is a bit more complex, and IMO, quickly 
> > becomes ugly. FOrayFont currently asks some client object 
> to implement 
> > the FontConsumer interface. Instead of having FontConsumer 
> provide a 
> > PseudoLogger, it could have a method instead that logs messages:
> > 
> >     /**
> >      * @param level An integer describing the level at which this 
> > message should be logged,
> >      * that is, error, warning, debug, etc.
> >      */
> >     public void logMessage(String message, int level) ;
> 
> That would be worse, IMO.

I agree.

> > Further, does a logMessage() method still expose logging 
> functionality 
> > in a way that is objectionable to you and to Batik?
> 
> Yes. IMO the API should not expose any aspect of logging, 
> only pure work functionality. An implementation of the API, 
> on the other side, will then expose any technical means 
> (methods, config files...) to configure/control logging. Do 
> you find logging aspects in APIs like DOM, JAXP, JDBC, EJB 
> etc.? No, I don't think so. But any DOM implementation, or 
> JDBC driver or Enterprise Java Bean is allowed to do logging 
> of some sort and there are ways/approaches to configure it. 
> Or take my JAXG. It doesn't care about how and if 
> (developer-oriented) logging is done. Only the 
> implementations define ways to control that if they support 
> it. That is the key point!

OK. Point taken. The difference is that FontConsumer is pretty passive. An
implementation will never instantiate a FontConsumer implementation. The
*client* application implements it. I think of this as a feature not a flaw,
else I would change it.

> > > Now, I know this has the potential to spark a heated debate again 
> > > and it raises question marks about the FOrayFont integration, but 
> > > ATM I really don't know what to do about it right now. I just 
> > > realized we have a problem here. I/we made promises on 
> > > general@xmlgraphics.apache.org to try to remove logging and other 
> > > external dependencies (like Avalon) for the common components 
> > > because that's something which is very important to the 
> Batik side.
> > 
> > So, then, how are those components supposed to log anything? Or, if 
> > they are to log using their own static stuff, how can this be 
> > configured by the client?
> 
> Eventually such basic libraries shouldn't log anything 
> anymore. That's the big dilemma I'm sitting in, the one I 
> need to find a way out of.

Arggh. So, we disagree here. Is it so terrible to simply implement
PseudoLogger to ignore any input it gets?

> Anyway, ways to remove the necessity to log are: unit tests 
> and stabilization. The problem is getting rid of something so 
> extremely handy but actually completely unnecessary for 
> something basic like a PDF or font library. But I'd never 
> want to get rid of the ability to log in a complex system 
> like a layout engine.

Hmmm. I had forgotten that PDF and font libraries were non-complex. :-)

Also, I wouldn't spend very much time trying to reconcile "extremely handy"
with "completely unnecessary". That one will keep you busy for awhile.
Better IMO would be to pick one and try to live with it. Or, better yet, to
*allow* both by picking the lowest common denominator, which in this case is
"extremely handy". If Batik thinks font subsystem is "completely
unnecessary" and FOP thinks it is "extremely handy", then Batis should send
logging output to /dev/null and FOP should do something more interesting
with it. Both can be made happy this way.

> > > Maybe we could have two different implementations of the 
> > > PDFTextElementBridge so Batik can do native text rendering in a 
> > > different way than FOP but there's still the PDF library that 
> > > depends largely on the font subsystem. But maybe this could be 
> > > handled in a similar way. I need to investigate that a 
> little more.
> > 
> > I'll be glad to help any way I can, and at this stage FOray 
> can be flexible.
> > But I must admit that I don't follow the logic. I need for 
> someone to 
> > do one of the following:
> > 1. explain which of the two design considerations listed above you 
> > would have your components abandon
> 
> From my POV as a developer in general: none of them.
> From my POV as the one who pushes for XML Graphics Commons: both.
> 
> See my problem?

Yes, you want A and not A at the same time. I am frankly unwilling to let
you delegate that problem to me :-) at least until I hear a better reason
than has been given so far.

> > 2. suggest a solution that allows *both* design 
> considerations to be 
> > retained, but does not have the client either doing the logging or 
> > telling the component how to do the logging.
> 
> Let logging be entirely an implementation detail, not a part 
> of the functional API.

Again, the implementation you have chosen needs it anyway. So, the effective
API that FOP is using is functionally the same either way.

> > I still find myself learning new tricks,
> 
> Me too! Me tooooo!
> 
> > so perhaps there is some other
> > elegant alternative that I am simply too blind to yet see.
> 
> We don't need a solution right now. I would just like you to 
> think about removing logging as an aspect of the aXSL APIs. 
> That would make things easier. But it's also just an aspect 
> of my general view of API design.

OK. I have thought about it. I don't see a way to do it without giving
something up that is more important.

> It actually doesn't have so much to do with Batik and XML 
> Graphics Commons.
> 
> I just needed to raise the overall concern about external 
> dependencies because of what Thomas said in our discussion 
> about XML Graphics Commons and because of the stuff we voted 
> on. We don't have to find a solution today. I don't even have 
> time for that right now. I can't continue with moving the 
> main components to Commons right now anyway because I need to 
> wait for what Vincent is doing. Furthermore, I want to get 
> that first preview release out of the door and that can't 
> happen with XML Graphics Commons. It's too late for that.

I think a reasonable approach would be to let Vincent implement it as it
stands, and see whether anybody complains. If so, I think it is entirely
reasonable to insist that they offer an alternative to consider.

> > The deeper question here is whether it is really wise to avoid all 
> > external dependencies. FOray is invested heavily in the idea that 
> > reusability is A Good Thing. My sense is that FOP still 
> struggles with this question.
> 
> I usually don't use external dependencies without considering 
> all the consequences. I'm all for reuse. The problem is that 

Using external dependencies judiciously is wise. Refusing to use them at all
seems very unwise IMO. You will get to rewrite Ant, Xalan, and Xerces for
starters.

> we found out that Batik and FOP have an extremely differing 
> views on these things and we decided to start sharing (PDF 
> lib etc.) and transferring (Transcoders) components inside 
> the XML Graphics project. This has some consequences.
> As I said, I just wanted everyone to know that there are 
> issues that will need to be dealt with someday but we don't 
> have to do it right now.
> If there's an obvious solution, good, but I don't see it right now.

OK. I don't either. I am trying to be responsive to your concerns, but admit
that I don't yet understand or appreciate them properly. I am ... still
trying to understand why this is important.

Victor Mote

Reply via email to