On 25.01.2008 17:50:44 Vincent Hennebert wrote:
> Jeremias Maerki wrote:
> > On 25.01.2008 12:35:50 Vincent Hennebert wrote:
> >> Hi Jeremias,
> >>
> >> Jeremias Maerki wrote:
> >>> That's actually one of the requirements, I just haven't discussed this
> >>> explicitely on the Wiki page. I assumed everyone can throw any unchecked
> >>> exception in the listener. Introducing a checked exception for this
> >>> purpose would be horrible as it would go through all of FOP which I
> >>> don't think would be useful. Does anyone see that differently?
> >> No it’s ok to me if particular implementations of FopEventListener throw 
> >> unchecked exceptions.
> >>
> >> But that mentioning of exceptions just makes me wondering of the 
> >> following: what if an unrecoverable error occurs (say, too many cells on 
> >> a table row)? I guess I’ll trigger an event of severity 
> >> EventSeverity.ERROR and I absolutely expect that /every/ listener will 
> >> throw an exception in such a case? Otherwise the processing will become 
> >> hazardous.
> > 
> > You can always throw an exception right after the line where you
> > broadbast the event. That makes sure that the exception is thrown.
> > There's no need to rely on external behaviour.
> 
> Hmmm, not very beautiful IMHO. You’ll have to do basically the same 
> thing twice every time. And, suppose the listener doesn’t do anything 
> particular, the exception that would be thrown afterwards would result 
> into the same ugly stacktrace as we have currently, which would kill 
> a bit the benefit of the new feedback mechanism, wouldn’t it?
> Is there anything wrong with expecting the error level (or fatal, or 
> whatever) to somehow stop the process?
>

> Now that I’ve written that, re-read myself and was about to hit the 
> “send message” button, I realise that processing feedback is a slightly 
> different notion from exception handling.
> Still, my question above holds.

Please note that there is no stacktrace information with the event, only
with the exception. The event mechanism is for clients with advanced
requirements about getting, for example, the may want to create a list
of all the problems which they present to the client in a special GUI
that may even allow them to jump to the right place in the original
document. An exception may not have this kind of information.

> It’s not the listener that would have to throw the exception 

but it is allowed to do so (an overflow may be a reason to stop for some).

> (IIUC the whole thing is meant to allow third-party listeners to be 
> implemented in the future, like graphical progress bars?), but the 
> broadcaster (like you say below actually).
> If for some reason this is not implemented that way, then I’d expect 
> something like the following: I would throw a FOPException, without any 
> explicit error message —this was already done via the feedback 
> mechanism— and some higher-level object would catch it, send a message 
> like “a fatal error occurred, processing stopped.” and actually stop. 
> I’m not very familiar with the API, but I guess this would be the 
> Renderer.startRenderer method, which would simply terminate normally.

No, the exception should always contain the cause.

> 
> > We could even add a convention that for an event with
> > EventSeverity.FATAL the first/second/last parameter must be an Exception
> > class. The Exception class would have to have a constructor that takes
> > an EventObject as parameter for initializing the exception. The dynamic
> > proxy would then throw the exception right after broadcasting the
> > exception. Or we could change the EventProducer convention so that every
> > method returns the generated EventObject that you can then use to
> > initialize an exception. Probably easier and more flexible.
> > 
> >> As to the best approach, the extended one looks good to me. May I ask 
> >> you to keep Java 1.5 in mind when designing your classes? It’s not far 
> >> away now and there are things which are likely to become much more 
> >> elegant with genericity. Just to take your example on the wiki page:
> >>     in EventBroadcaster:
> >>     public <T extends EventProducer> T getEventProducerFor(Class<T> class)
> >>
> >>     then I can make
> >>     BasicFOValidationEventProducer producer =
> >>       getUserAgent().getEventBroadcaster().getEventProducerFor(
> >>          BasicFOValidationEventProducer.class);
> >> Exit the hazardous cast and potential run-time exception :-)
> > 
> > Please tell me how I should "keep Java 1.5 in mind"? I cannot use
> 
> Well, nothing more than avoid designing classes to circumvent Java 1.4’s 
> lack of genericity (or typesafe enums). The following method:
>     public EventProducer getEventProducerFor(Class class)
> isn’t safe and bad design in Java 1.4. 

How is this bad design? It's just generic. Your solution below is just
the typesafe wrapper around the above. Otherwise you have to duplicate
the code for each method which is worse.

> To keep on the safe way you would 
> probably have to do something like
>     public BasicFOValidationEventProducer getBasicFOValidationEventProducer()
> and add as many methods as there are EventProducer implementations. Just 
> forget that and go with the simple version.

-1 to that because I will import interfaces from all sorts of packages
in FOP, at least if these methods are added to DefaultEventBroadcaster.
Better would be something like:

public class BasicFOValidationEventProducerFactory {
  public static BasicFOValidationEventProducer 
getBasicFOValidationEventProducer(EventBroadcaster broadcaster) {
    return 
(BasicFOValidationEventProducer)broadcaster.getEventProducerFor(BasicFOValidationEventProducer.class);
  }
}

(but that adds another minimal class)

> In fact I’m asking you for keeping your life simple :-)

A complicated life is sometimes more fun, not that the above is
complicated. :-)


Jeremias Maerki

Reply via email to