Jeremias Maerki wrote: > I got a little shock when I realized a problem I didn't think > of when we discussed moving FOP components over to XML > Graphics Commons. We said we would try to remove logging code > from these basic components entirely. > > Now, I forgot to consider the decision to use FOrayFont made earlier. > The external dependency on FOrayFont also would be a problem > in itself because the Batik side has strong feelings against > external dependencies. > We need to think about what to do about this WRT the PDF and > PS transcoders. Optimized text painting in these two > transcoders depends a lot on the font subsystem.
Well, the little change I just made removes entirely any dependency on Avalon in any FOray code, except for the fact that Ant seems to need it for logging (needed for creating hyphenation patterns and such). There is no longer any Avalon code in FOrayFont. In fact, that was the primary motivation for making the change. The Avalon Logger interface would have been quite a sufficient solution for anything that FOray needs, and, since it is an interface, adapters could be written from it to anything else, just as Vincent and I have been discussing for the PseudoLogger interface. > Aside from that, a thought about the aXSL APIs: Being an > ex-Avaloner SoC (separation of concerns) is a big concern to > me. The functional API of a package should IMO actually not > deal with (or rather expose) logging at all. It's a separate > concern. I'm ever growing more cofident that > developer-oriented logging should be done through a static > logging facility (like Commons Logging) and that > end-user-oriented logging needs to operate per processing run > (like Avalon Logger) but not necessarily through a standard > logging abstraction interface, but rather an > application-specific one that provides exactly what the > application needs to send feedback to the end-users. In that > light, a PDF or font library shouldn't expose any logging > facilities at all or at least to static logging that is > externally configured. First, do you understand that the FOrayFont library does not "expose any logging facilities" to the client, but instead asks the client to expose the logging facilities to it? A PseudoLogger is required (but can be passed null) in the FontServer constructor 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. 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? 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. The design considerations are as follows: 1. FOrayFont needs to be able to log messages. 2. FOrayFont needs to be able to work with any client system, regardless of their preferences on logging. 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. 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) ; The problem here is that I need to then create another interface that has something similar that can pass itself to FontServer so that general (not document-specific) logging messages can be handled. I also need to create one for Graphics, Text, FOTree, etc. I will have 10 or 12 methods in various interfaces that all do the same thing. This seems silly to me. This begs for a type to do this, which the Avalon Logger interface provided and which PseudoLogger provides as well. Further, does a logMessage() method still expose logging functionality in a way that is objectionable to you and to Batik? > 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 email@example.com 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? > 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 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. I still find myself learning new tricks, so perhaps there is some other elegant alternative that I am simply too blind to yet see. 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. Victor Mote