API discussion (revived)

2005-08-20 Thread Jeremias Maerki
The "API discussion" thread around 2005-08-03 trailed off. I'd like to
revive it again because I feel that is something that needs to be done.

Anybody against moving the CLI to a org.apache.fop.cli package?

The only issue I see when doing this is that FOP's API then still
resides in the org.apache.fop.apps package which is sort of unintuitive
then. "apps" would suggest a command-line application IMO but we're then
only talking about an API. In the end it comes back to the discussion
about the API. Is the API ok like it is? Is it in the right package?

We've already broken API compatibility so changing packages (I'm
thinking think about org.apach.fop, removing "apps") shouldn't be a big
deal before the first release.

Anybody against my adding support for selecting the renderer by the use
of the MIME type (in addition to the current integer constants) and
adding a renderer discovery (similar to FOP extensions and what I
recently added for the XMLHandlerRegistry)?

On the other side, maybe we should really take the time to write up a
short specification for the API and to have that voted on. After all,
this is the main entry point into FOP. If anybody could take the lead on
this, I'd be very grateful as I have my hands full enough already. I can
still do it myself, if really nobody can be found to do it. But I'd
really not do all that stuff in a "lonely rider" fashion.

Jeremias Maerki



Re: API discussion (revived)

2005-08-21 Thread Manuel Mall
On Sun, 21 Aug 2005 02:29 pm, Jeremias Maerki wrote:
> The "API discussion" thread around 2005-08-03 trailed off. I'd like
> to revive it again because I feel that is something that needs to be
> done.
>
> Anybody against moving the CLI to a org.apache.fop.cli package?

For command line applications I like it short and sweet, e.g. 
org.apache.fop.Fop would be fine with me. The current 
CommandLineOptions could go into org.apache.fop.cli.

>
> The only issue I see when doing this is that FOP's API then still
> resides in the org.apache.fop.apps package which is sort of
> unintuitive then. "apps" would suggest a command-line application IMO
> but we're then only talking about an API. In the end it comes back to
> the discussion about the API. Is the API ok like it is? Is it in the
> right package?

I agree, it is an unintuitive package name. I am not philosophically 
against having the command line application and the exposed API in the 
same package. But certainly not in the same class. What about moving 
the API part from the current org.apache.fop.apps.Fop into 
org.apache.fop.FOProcessor?

> We've already broken API compatibility so changing packages (I'm
> thinking think about org.apach.fop, removing "apps") shouldn't be a
> big deal before the first release.

As long as we don't do anything that prevents from creating a wrapper 
org.apache.fop.apps.Driver class for those who like backwards 
compatibility -:).

> Anybody against my adding support for selecting the renderer by the
> use of the MIME type (in addition to the current integer constants)
> and adding a renderer discovery (similar to FOP extensions and what I
> recently added for the XMLHandlerRegistry)?
>
> On the other side, maybe we should really take the time to write up a
> short specification for the API and to have that voted on. After all,
> this is the main entry point into FOP. If anybody could take the lead
> on this, I'd be very grateful as I have my hands full enough already.
> I can still do it myself, if really nobody can be found to do it. But
> I'd really not do all that stuff in a "lonely rider" fashion.

Only looking a structural aspect and not the details of the API we have 
options like:

a) Don't do anything leave it as it is as it avoids quite a bit of 
refactoring work and redoing all the examples, etc..

b) Move all command line stuff into org.apache.fop.cli including the 
application and move all API stuff into org.apache.fop.api.

c) Move the command line application to org.apache.fop, move anything 
required just to support the command line app to org.apache.fop.cli. 
Also move all API classes, i.e. all classes exposed to users wanting to 
embed FOP up one level to org.apache.fop. Make sure that the command 
line application is in a different class than the main API class, i.e. 
don't overload Fop.java.

d) Do some mix of b) and c), e.g. move command line app to 
org.apache.fop and move the API to org.apache.fop.api.

In all cases but a)  the org.apache.fop.apps package will disappear.

> Jeremias Maerki
Manuel


Re: API discussion (revived)

2005-08-21 Thread Jeremias Maerki

On 21.08.2005 09:08:48 Manuel Mall wrote:
> On Sun, 21 Aug 2005 02:29 pm, Jeremias Maerki wrote:
> > The "API discussion" thread around 2005-08-03 trailed off. I'd like
> > to revive it again because I feel that is something that needs to be
> > done.
> >
> > Anybody against moving the CLI to a org.apache.fop.cli package?
> 
> For command line applications I like it short and sweet, e.g. 
> org.apache.fop.Fop would be fine with me. The current 
> CommandLineOptions could go into org.apache.fop.cli.

Do you mean splitting up the code for the CLI in two different packages?
Hmm. I'd prefer to have "org.apache.fop.cli.Main" as main class, just
like I did in Barcode4J.

> > The only issue I see when doing this is that FOP's API then still
> > resides in the org.apache.fop.apps package which is sort of
> > unintuitive then. "apps" would suggest a command-line application IMO
> > but we're then only talking about an API. In the end it comes back to
> > the discussion about the API. Is the API ok like it is? Is it in the
> > right package?
> 
> I agree, it is an unintuitive package name. I am not philosophically 
> against having the command line application and the exposed API in the 
> same package. But certainly not in the same class. What about moving 
> the API part from the current org.apache.fop.apps.Fop into 
> org.apache.fop.FOProcessor?

Would be ok for me.

> > We've already broken API compatibility so changing packages (I'm
> > thinking think about org.apach.fop, removing "apps") shouldn't be a
> > big deal before the first release.
> 
> As long as we don't do anything that prevents from creating a wrapper 
> org.apache.fop.apps.Driver class for those who like backwards 
> compatibility -:).

It might even be easier to provide the wrapper since the new API is not
in the same package anymore.

> > Anybody against my adding support for selecting the renderer by the
> > use of the MIME type (in addition to the current integer constants)
> > and adding a renderer discovery (similar to FOP extensions and what I
> > recently added for the XMLHandlerRegistry)?
> >
> > On the other side, maybe we should really take the time to write up a
> > short specification for the API and to have that voted on. After all,
> > this is the main entry point into FOP. If anybody could take the lead
> > on this, I'd be very grateful as I have my hands full enough already.
> > I can still do it myself, if really nobody can be found to do it. But
> > I'd really not do all that stuff in a "lonely rider" fashion.
> 
> Only looking a structural aspect and not the details of the API we have 
> options like:
> 
> a) Don't do anything leave it as it is as it avoids quite a bit of 
> refactoring work and redoing all the examples, etc..

Not an option IMO. This is too important. And the work necessary is
negligible.

> b) Move all command line stuff into org.apache.fop.cli including the 
> application and move all API stuff into org.apache.fop.api.

That's a possibility.

> c) Move the command line application to org.apache.fop, move anything 
> required just to support the command line app to org.apache.fop.cli. 
> Also move all API classes, i.e. all classes exposed to users wanting to 
> embed FOP up one level to org.apache.fop. Make sure that the command 
> line application is in a different class than the main API class, i.e. 
> don't overload Fop.java.

As I hinted above I wouldn't like the splitting up of code belonging
together.

> d) Do some mix of b) and c), e.g. move command line app to 
> org.apache.fop and move the API to org.apache.fop.api.
> 
> In all cases but a)  the org.apache.fop.apps package will disappear.

e) (my preference) Move the API to org.apache fop and the CLI to
org.apache.fop.cli (including the Main class).


Jeremias Maerki



Re: API discussion (revived)

2005-08-21 Thread Manuel Mall
On Sun, 21 Aug 2005 04:05 pm, Jeremias Maerki wrote:
> On 21.08.2005 09:08:48 Manuel Mall wrote:
> > On Sun, 21 Aug 2005 02:29 pm, Jeremias Maerki wrote:

> e) (my preference) Move the API to org.apache fop and the CLI to
> org.apache.fop.cli (including the Main class).

Fine with me. I still like org.apache.fop.Fop for command line 
invocation though but who really cares about 4 more characters on the 
command line :-).

Manuel

>
> Jeremias Maerki


Re: API discussion (revived)

2005-08-21 Thread Simon Pepping
On Sun, Aug 21, 2005 at 08:29:03AM +0200, Jeremias Maerki wrote:
> The "API discussion" thread around 2005-08-03 trailed off. I'd like to
> revive it again because I feel that is something that needs to be done.
> 
> Anybody against moving the CLI to a org.apache.fop.cli package?
> 
> The only issue I see when doing this is that FOP's API then still
> resides in the org.apache.fop.apps package which is sort of unintuitive
> then. "apps" would suggest a command-line application IMO but we're then
> only talking about an API. In the end it comes back to the discussion
> about the API. Is the API ok like it is? Is it in the right package?
> 
> We've already broken API compatibility so changing packages (I'm
> thinking think about org.apach.fop, removing "apps") shouldn't be a big
> deal before the first release.
> 
> Anybody against my adding support for selecting the renderer by the use
> of the MIME type (in addition to the current integer constants) and
> adding a renderer discovery (similar to FOP extensions and what I
> recently added for the XMLHandlerRegistry)?
> 
> On the other side, maybe we should really take the time to write up a
> short specification for the API and to have that voted on. After all,
> this is the main entry point into FOP. If anybody could take the lead on
> this, I'd be very grateful as I have my hands full enough already. I can
> still do it myself, if really nobody can be found to do it. But I'd
> really not do all that stuff in a "lonely rider" fashion.

I am afraid I have no strong feelings about this issue.  So I'll go
with your "lonely rider" stuff or what you and Manuel come up with.

Simon

-- 
Simon Pepping
home page: http://www.leverkruid.nl



Re: API discussion (revived)

2005-08-21 Thread J.Pietschmann

Jeremias Maerki wrote:

We've already broken API compatibility so changing packages (I'm
thinking think about org.apach.fop, removing "apps") shouldn't be a big
deal before the first release.


I guess people would be more upset about FOPException moving
to a new package than any other API change. It might be worth
a try though.


On the other side, maybe we should really take the time to write up a
short specification for the API and to have that voted on.


What's wrong with the spec in the Wiki?

J.Pietschmann


Re: API discussion (revived)

2005-08-21 Thread Jeremias Maerki

On 21.08.2005 22:45:12 J.Pietschmann wrote:
> Jeremias Maerki wrote:
> > We've already broken API compatibility so changing packages (I'm
> > thinking think about org.apach.fop, removing "apps") shouldn't be a big
> > deal before the first release.
> 
> I guess people would be more upset about FOPException moving
> to a new package than any other API change. It might be worth
> a try though.

Uh, yeah, that one. That's a design task by itself. Any takers for a
good exception strategy for FOP and XML Graphics Commons? I'm not
the brightest when it comes to exceptions.

> > On the other side, maybe we should really take the time to write up a
> > short specification for the API and to have that voted on.
> 
> What's wrong with the spec in the Wiki?

You mean specificationS (plural), right? Nothing really, except that
today's reality looks different and the API discussion from two years
ago is not finished. Anyway, my proposal from back then is now
implemented as my API abstraction with a few little changes. If I had
the naming problem behind me and the stuff published we could simply
take that and be done with it. Damn, I'll clean this up first thing
tomorrow morning. Should have done it today.


Jeremias Maerki



Re: API discussion (revived)

2005-08-21 Thread The Web Maestro

On Aug 21, 2005, at 11:39 AM, Simon Pepping wrote:

On Sun, Aug 21, 2005 at 08:29:03AM +0200, Jeremias Maerki wrote:

On the other side, maybe we should really take the time to write up a
short specification for the API and to have that voted on. After all,
this is the main entry point into FOP. If anybody could take the lead 
on
this, I'd be very grateful as I have my hands full enough already. I 
can

still do it myself, if really nobody can be found to do it. But I'd
really not do all that stuff in a "lonely rider" fashion.


I am afraid I have no strong feelings about this issue.  So I'll go
with your "lonely rider" stuff or what you and Manuel come up with.

Simon


I'll second that. I don't have much 'energy' on this. I will say that 
it's nice to see Manuel's enthusiasm. We should've hinted at an 
upcoming 1.0 release long ago! ;-)


Regards,

Web Maestro Clay
--
<[EMAIL PROTECTED]> - 
My religion is simple. My religion is kindness.
- HH The 14th Dalai Lama of Tibet



Re: API discussion (revived)

2005-08-22 Thread Chris Bowditch

The Web Maestro wrote:

On Aug 21, 2005, at 11:39 AM, Simon Pepping wrote:


On Sun, Aug 21, 2005 at 08:29:03AM +0200, Jeremias Maerki wrote:


On the other side, maybe we should really take the time to write up a
short specification for the API and to have that voted on. After all,
this is the main entry point into FOP. If anybody could take the lead on
this, I'd be very grateful as I have my hands full enough already. I can
still do it myself, if really nobody can be found to do it. But I'd
really not do all that stuff in a "lonely rider" fashion.



I am afraid I have no strong feelings about this issue.  So I'll go
with your "lonely rider" stuff or what you and Manuel come up with.

Simon


I too am not worried about the API/CLI. Mainly because I don't see a lot 
wrong with the current one! But if you guys think it need re-organising 
thats fine, so long as no functionality is lost, I'm happy.





I'll second that. I don't have much 'energy' on this. I will say that 
it's nice to see Manuel's enthusiasm. We should've hinted at an upcoming 
1.0 release long ago! ;-)


Jeremias' announcement about an upcoming release of HEAD was more than a 
 hint. It's real and coming in a few weeks time :-)


Chris



Re: API discussion (revived)

2005-08-28 Thread J.Pietschmann

Jeremias Maerki wrote:

Uh, yeah, that one. That's a design task by itself. Any takers for a
good exception strategy for FOP and XML Graphics Commons?


Back in the mists of time, men, computers and animals happily lived
together and everything run as expected. Then a moth got trapped
between the contacts of a relay and was squashed, and "unusual
operating conditions" were introduced. Ever since men struggled with
corrupt databases, printers which were out of paper, dropped network
connections and users insisting that their name contains a mongolian
hyphen.

Well. The first problem is defining "what's a problem?".
When designing an API, the parameters, return values and the behavior
description form a contract. The general rule is that everything is
a problem if
- it doesn't fit the commonly accepted semantics of the interface
- it's impossible to foresee by the API designer (e.g. because it's
 caused by a foreign sub-provider)
- it can't be handled locally (e.g. needs human intervention, like
 a printer being out of paper)

Let's take the usual file reading API an an example. The standard
behavior is "read as much bytes into the provided array as possible".
A subtle part of the contract is EOF handling: if the file pointer is
not yet at EOF, there is an successful read, possibly capped by the
number of bytes available to EOF. At EOF, there is a successful read
of zero bytes. the next read throws an exception.
What we learn: there may be conditions which occur reasonably often
and which are best handled by the immediate caller, and which therefore
aren't considered "problematic". Note further how "in band" information
was abused for this purpose. It's unreasonable to expect this pattern
to be applicable often.
OTOH, the Class.forName is so often used to check for the existence
of a specific class that the design of throwing a ClassNotFoundException
looks ugly.

== Design choice: return codes vs. throwing ==
In ancient times, it was custom for subroutines to return an integer
enumerating possible outcomes. Of course, one outcome was usually a
catch all "unknown error" or such.
The obvious advantage of this approach is the simplicity. There are
a few drawbacks, of course:
- The immediate caller has to catch the value and act accordingly.
 If the immediate caller can't handle the problem, it has to pass
 it further up in a sensible way.
- The range of possible outcomes (error codes) can't be easily extended
 later. Possible extensions might clash with codes defined elsewhere.
 The only surefire solution for this is a central error code repository
 and recompiling *everything* after changes to the repository. This was
 already a pain 20 years ago, and it's going to hurt real bad today.
- A single integer can't pass all that much information up the chain.
The real death of the error return codes is of course the first
drawback: if even a single routine in the call stack is missing an error
code, upper layers are screwed. With ever more libraries stacked on
top of each other, error codes became too unwieldy.
A nice demonstration of the problem is the java.io.File.delete(), which
returns false if a directory wasn't deleted. The Tomcat webapp deployer
missed checking the return value, probably because the code deleted all
the files in the directory before. Unfortunately for me, I had the
directory tree on a NFS mounted drive, and some NFS lockfiles didn't get
removed in time, thereby thwarting the attempt to delete the directory.
Nevertheless, upper layers got an "ok", but later redeployment of the
webapp failed due to existing directories (which wasn't caught properly
either). It's definitely unexpected to get an "OK" for an actually
failed deployment.

== Design choice checked vs. unchecked exceptions ==
Java provides the usual exceptions, which have to be declared in the
API, as well as Errors and RuntimeExceptions, which don't have to be
declared.
The semantics of Error should be easy: An Error "indicates serious
problems that a reasonable application should not try to catch." I.e.
it should got to the very top and abort the application or at least the
operation in progress. Throwing an Error is not an easy decision, in
particular if the library can be expected to be used in an interactive
application where a higher level entity (the user) can be asked whether
to (a)bort, (i)gnore or (c)ontinue. Therefore, I consider the java.lang
Errors basically complete.
The discussion whether to use a checked exception or a subclass of
RuntimeException usually gets near a religious war. There is the "we
don't want method heads to be cluttered with *lots* of exception
declarations" vs. the "exceptions are part of the contract and have
to be declared" fractions.
There are reasons for RuntimeException to exist, in particular that
subclasses are thrown by language constructs which are not functions
(OutOfMemoryException, ArrayOutOfBoundsException). But then, did you
really expect String.substring to throw an ArrayOutOfBou

Re: API discussion (revived)

2005-08-29 Thread Jeremias Maerki
Very good post! This is a very complete overview over the whole problem
region. I don't think you missed anything important except maybe your
personal opinion how you'd propose to go on. :-) You've adressed a few
points but I get the impression that you left off the more fundamental
decisions, the ones I'm actually most interested in. We also have to
keep in mind that the migration of components into XML Graphics Commons
will have implications on the exception strategy.

A nit: It's OutOfMemoryError, not OutOfMemoryException.

Thank you for writing this up!!!

On 29.08.2005 00:16:53 J.Pietschmann wrote:
> Jeremias Maerki wrote:
> > Uh, yeah, that one. That's a design task by itself. Any takers for a
> > good exception strategy for FOP and XML Graphics Commons?
> 
> Back in the mists of time, men, computers and animals happily lived
> together and everything run as expected. Then a moth got trapped
> between the contacts of a relay and was squashed, and "unusual
> operating conditions" were introduced. Ever since men struggled with
> corrupt databases, printers which were out of paper, dropped network
> connections and users insisting that their name contains a mongolian
> hyphen.
> 
> Well. The first problem is defining "what's a problem?".
> When designing an API, the parameters, return values and the behavior
> description form a contract. The general rule is that everything is
> a problem if
> - it doesn't fit the commonly accepted semantics of the interface
> - it's impossible to foresee by the API designer (e.g. because it's
>   caused by a foreign sub-provider)
> - it can't be handled locally (e.g. needs human intervention, like
>   a printer being out of paper)
> 
> Let's take the usual file reading API an an example. The standard
> behavior is "read as much bytes into the provided array as possible".
> A subtle part of the contract is EOF handling: if the file pointer is
> not yet at EOF, there is an successful read, possibly capped by the
> number of bytes available to EOF. At EOF, there is a successful read
> of zero bytes. the next read throws an exception.
> What we learn: there may be conditions which occur reasonably often
> and which are best handled by the immediate caller, and which therefore
> aren't considered "problematic". Note further how "in band" information
> was abused for this purpose. It's unreasonable to expect this pattern
> to be applicable often.
> OTOH, the Class.forName is so often used to check for the existence
> of a specific class that the design of throwing a ClassNotFoundException
> looks ugly.
> 
> == Design choice: return codes vs. throwing ==
> In ancient times, it was custom for subroutines to return an integer
> enumerating possible outcomes. Of course, one outcome was usually a
> catch all "unknown error" or such.
> The obvious advantage of this approach is the simplicity. There are
> a few drawbacks, of course:
> - The immediate caller has to catch the value and act accordingly.
>   If the immediate caller can't handle the problem, it has to pass
>   it further up in a sensible way.
> - The range of possible outcomes (error codes) can't be easily extended
>   later. Possible extensions might clash with codes defined elsewhere.
>   The only surefire solution for this is a central error code repository
>   and recompiling *everything* after changes to the repository. This was
>   already a pain 20 years ago, and it's going to hurt real bad today.
> - A single integer can't pass all that much information up the chain.
> The real death of the error return codes is of course the first
> drawback: if even a single routine in the call stack is missing an error
> code, upper layers are screwed. With ever more libraries stacked on
> top of each other, error codes became too unwieldy.
> A nice demonstration of the problem is the java.io.File.delete(), which
> returns false if a directory wasn't deleted. The Tomcat webapp deployer
> missed checking the return value, probably because the code deleted all
> the files in the directory before. Unfortunately for me, I had the
> directory tree on a NFS mounted drive, and some NFS lockfiles didn't get
> removed in time, thereby thwarting the attempt to delete the directory.
> Nevertheless, upper layers got an "ok", but later redeployment of the
> webapp failed due to existing directories (which wasn't caught properly
> either). It's definitely unexpected to get an "OK" for an actually
> failed deployment.
> 
> == Design choice checked vs. unchecked exceptions ==
> Java provides the usual exceptions, which have to be declared in the
> API, as well as Errors and RuntimeExceptions, which don't have to be
> declared.
> The semantics of Error should be easy: An Error "indicates serious
> problems that a reasonable application should not try to catch." I.e.
> it should got to the very top and abort the application or at least the
> operation in progress. Throwing an Error is not an easy decision, in
> particular if the library ca

Re: API discussion (revived)

2005-08-30 Thread J.Pietschmann

Jeremias Maerki wrote:

I don't think you missed anything important except maybe your
personal opinion how you'd propose to go on. :-)


Ok.
Step 0: Baseline rules.
- No new Errors except possibly some sort of a FOPConfigurationError
 (JAXP implementations tend to have an equivalent). Does anybody
 think we need more?
- No new RuntimeException descendants, checked exceptions only.
- Keep exception declarations lean.
- Don't wrap RuntimeExceptions thrown by lower layers unless
 the wrapper contains essential additional information
- Think before committing code (this is a test :-).

Step 1: Identify subpackages which potentially are of intertest
as libraries for others and therefore should get their own
exceptions. Candidates
- PDF lib
- RTF lib
- shall we have a SVG lib, PS lib, etc? (BTW had anyone a look at
 the Cairo API?)
- Font metrics, font management. Oops, already outsorced.
- Hyphenation
- Word parsing for hyphenation
- Data structure underlying the pattern hyphenator (may be reused
 for automatic ligatures)
- URL handling
- Unified Image handling API. I hope we aren't reinventing JAI.
- Image cache
- Colorspace handlung (not yet implemented)
- Various Unicode stuff, in particular TR14 and BIDI handling (still
  missing too)
- Character shaping (also no code yet)

Step 2: Decide how many independent exception trees per package as
identified in step 1. Proposal
- Hyphenation gets two Exceptions, one for compiling the patterns,
 one for the actual hyphenation (if necessary)
- The renderer libraries should probably get one exception tree
- The smaller utility libs should be ok with existing java.lang
 exceptions and perhaps IOException
- A FOPException, of course.
Necessary decisions:
- Should the Renderer and perhaps the specific renderers (not the
 reusable renderer libs) get their own exceptions? I tend to say
 no, but I'm still sorting arguments.
- Do we need a FOPConfigurationException?
- Do we need a FOPConfigurationError?
- How many exceptions shoudl the font subsystem get (if there's
 something to decide).

Step 3: How to use exceptions from the JRE
- Renderer libs which actually do stream IO should declare IOException
 instead of wrapping it.
- Something similar for the image handling API
- Reusable utility methods taking URLs (as java.net.URL/URI, perhaps
 also as String?) should declare URL related exceptions rather than
 wrap them.
- Everything else is probably forced to wrap, i.e. no declaration of
 exceptions other than the package specific ones. I don't want to have
 IOExcpetion et al declared in Java interfaces unless the majority
 of the conceivable implementations will throw them.

Step 4: additional exceptions.
- FOPIOException, and possibly descendants, for wrapping IOException
- FOPPrintException, for wrapping PrintException thrown by the
 print renderer. Print renderer users are likely to want to catch it.
- Does anybody ever catch a PropertyException? It may still
 be useful due to the code. I also think at least some instances
 of PropertyException are thrown because of validation problems.
 We might want to split it into a subclass of ValidationException, a
 PropertyExpressionParseException and a
 PropertyExpressionEvaluationException.
- We might want to have other subclasses of FOPException indicating
 specific problems with user supplied data, similar to
 ValidationException.
- If there is some code repeatedly used in setting up a FOPException,
 this may point to another FOPException subclass.
- It may be an idea to have a subclass of FOException which has a
 Locator (or another location indication) and others which havn't
 (i.e. exceptions thrown by renderers). Is it always possible to
 pinpoint the FO which is related to a particular exception? There
 are certainly problems where this is difficult due to asynchronity
 or buffering, like "sample.foo:13: no space left on device".
- We might want to have separate exceptions indicating real bugs rather
 than problems with user supplied data or ressources:
 * FOPNotImplementedException indicating known deficiencies
 * FOPInternalException thrown in "can't happen" branches


Some additional thoughts: There are basically two reasons for building
an exception tree:
1. Code reuse, standard OO staple.
2. Catching specific exceptions.
An example for the second: Imagine
 catch( FOOException e) {
  Throwable cause = e.getCause();
  if (cause instanceOf IOException) {
notifyUser(cause);
  } else if (cause instanceOf BarException)
   ...
 }
vs.
 catch(FOOIOEXception e) {
  notifyUser((IOException)e.getCause());
 }
 catch(FOOBarException e) {
  ...
 }


Step 5: Miscellaneous
- The RTF lib exception should derive from Excetion rather than
 IOException. Add IOException as necessary. Yes, this hurts.
- Do something about PDFFilterException.
- Should we use IllegalArgumentException for sanity checkings
 in the public API classes (not FOTree, layout or anything deeper
 down), e.g. for enumerations for renderers which aren't known?
 I'm u

Re: API discussion (revived)

2005-08-31 Thread Jeremias Maerki

On 31.08.2005 00:16:05 J.Pietschmann wrote:
> Jeremias Maerki wrote:
> > I don't think you missed anything important except maybe your
> > personal opinion how you'd propose to go on. :-)
> 
> Ok.
> Step 0: Baseline rules.
> - No new Errors except possibly some sort of a FOPConfigurationError
>   (JAXP implementations tend to have an equivalent). Does anybody
>   think we need more?

Nope. If this config error is at all necessary.

> - No new RuntimeException descendants, checked exceptions only.
> - Keep exception declarations lean.
> - Don't wrap RuntimeExceptions thrown by lower layers unless
>   the wrapper contains essential additional information
> - Think before committing code (this is a test :-).

Uh, yeah. I think I should remember that last one.

> Step 1: Identify subpackages which potentially are of intertest
> as libraries for others and therefore should get their own
> exceptions. Candidates

(everything that goes into Commons) :-)

> - PDF lib
> - RTF lib
> - shall we have a SVG lib, PS lib, etc? 

Yes, we shall. See XML Graphics Commons Plan.

> (BTW had anyone a look at the Cairo API?)

Cairo? no. It's not Java, is it?

> - Font metrics, font management. Oops, already outsorced.
> - Hyphenation
> - Word parsing for hyphenation
> - Data structure underlying the pattern hyphenator (may be reused
>   for automatic ligatures)
> - URL handling
> - Unified Image handling API. I hope we aren't reinventing JAI.
> - Image cache
> - Colorspace handlung (not yet implemented)
> - Various Unicode stuff, in particular TR14 and BIDI handling (still
>missing too)
> - Character shaping (also no code yet)
> 
> Step 2: Decide how many independent exception trees per package as
> identified in step 1. Proposal
> - Hyphenation gets two Exceptions, one for compiling the patterns,
>   one for the actual hyphenation (if necessary)
> - The renderer libraries should probably get one exception tree
> - The smaller utility libs should be ok with existing java.lang
>   exceptions and perhaps IOException
> - A FOPException, of course.
> Necessary decisions:
> - Should the Renderer and perhaps the specific renderers (not the
>   reusable renderer libs) get their own exceptions? I tend to say
>   no, but I'm still sorting arguments.

I don't think, either. Some renderers do a lot of IOExceptions, see my
ugly handleIOTrouble() in PSRenderer.

> - Do we need a FOPConfigurationException?
> - Do we need a FOPConfigurationError?

Depends. I guess ATM we'll need a FOPConfigurationException. I don't buy
the Error, yet.

> - How many exceptions shoudl the font subsystem get (if there's
>   something to decide).

As few as possible. Can't tell, yet.

> Step 3: How to use exceptions from the JRE
> - Renderer libs which actually do stream IO should declare IOException
>   instead of wrapping it.

Right. But does that mean we add IOException to the throws list of all
the render*() methods (Renderer interface and AbstractRenderer base
class)? Probably the cleanest approach. Since I'm working on the
renderers right now I can immediately start with that if noone thinks
this is bad.

> - Something similar for the image handling API
> - Reusable utility methods taking URLs (as java.net.URL/URI, perhaps
>   also as String?) should declare URL related exceptions rather than
>   wrap them.
> - Everything else is probably forced to wrap, i.e. no declaration of
>   exceptions other than the package specific ones. I don't want to have
>   IOExcpetion et al declared in Java interfaces unless the majority
>   of the conceivable implementations will throw them.

Ah, more or less answers my question above. :-)

> Step 4: additional exceptions.
> - FOPIOException, and possibly descendants, for wrapping IOException

Really???

> - FOPPrintException, for wrapping PrintException thrown by the
>   print renderer. Print renderer users are likely to want to catch it.

More likely for that to happen than for IOException.

> - Does anybody ever catch a PropertyException? It may still
>   be useful due to the code. I also think at least some instances
>   of PropertyException are thrown because of validation problems.
>   We might want to split it into a subclass of ValidationException, a
>   PropertyExpressionParseException and a
>   PropertyExpressionEvaluationException.

+1

> - We might want to have other subclasses of FOPException indicating
>   specific problems with user supplied data, similar to
>   ValidationException.

Yes, LayoutException.

> - If there is some code repeatedly used in setting up a FOPException,
>   this may point to another FOPException subclass.
> - It may be an idea to have a subclass of FOException which has a
>   Locator (or another location indication) and others which havn't
>   (i.e. exceptions thrown by renderers). Is it always possible to
>   pinpoint the FO which is related to a particular exception? There
>   are certainly problems where this is difficult due to asynchronity
>   or buffering, like "sample.foo:13:

Re: API discussion (revived)

2005-08-31 Thread J.Pietschmann

Jeremias Maerki wrote:

Cairo? no. It's not Java, is it?

It's C. Nevertheless, it might provide ideas. They can render
2D graphics to PDF.


Depends. I guess ATM we'll need a FOPConfigurationException. I don't buy
the Error, yet.


Ok.


- How many exceptions shoudl the font subsystem get (if there's
 something to decide).

As few as possible. Can't tell, yet.


Hehe!


- Renderer libs which actually do stream IO should declare IOException
 instead of wrapping it.


Right. But does that mean we add IOException to the throws list of all
the render*() methods (Renderer interface and AbstractRenderer base
class)?


The renderer implementation classes (and other FOP specific classes,
if any), should wrap the IOException.



- FOPIOException, and possibly descendants, for wrapping IOException

Really???


Dunno. Nevertheless many IOExceptions indicate classic ressource
problems (disk full, connection reset by peer). Note that I/O related
java.net exceptions derive from IOException too.



- We might want to have other subclasses of FOPException indicating
 specific problems with user supplied data, similar to
 ValidationException.


Yes, LayoutException.


I'll check this.


Did I mention I18N? :-)


Horror! =:-0

:-)


- We might want to have separate exceptions indicating real bugs rather
 than problems with user supplied data or ressources:
 * FOPNotImplementedException indicating known deficiencies
 * FOPInternalException thrown in "can't happen" branches


But aren't those subclasses of RuntimeException which you ruled out
above


I had thought of deriving them from the checked FOPException, but of
course this may cause exception declarations on methods which don't
need them for other purposes. Possibly lots of them.

Ok, let's search for reusable Exceptions. Well, not all of the
exceptions provided by the RTL are apparently supposed to be reused.
Some clearly are (IllegalStateException, Illegal ArgumentException),
because other Java packages do so.
There we find java.lang.UnsupportedOperationException. On of the JDK
docs I read suggested it was part of the container framework, which
might hint on not reusing it. But then, Java 1.4 derives a
java.awt.HeadlessException (funny name: imagine beheaded exception!),
so we might use it as well. There are also java.lang.InternalError
(might be applicable to "can't happen" tests) and
java.lang.UnknownError. Well, they are errors and using them might
cause even more programmers to catch Throwable instead of Exception
(with possibly bad consequences).

The more I think of it, the more I'm inclined to derive
FOPNotImplementedException and and FOPInternalException from 
RuntimeException, or possibly using a FOPRuntimeException for

both purposes.


Side note: From the 1.4.1 Java docs
  MissingRessourceException: Signals that a resource is missing.
Wow, talk about a comprehensive documentation.

I also noticed that designing the exception system naturally leads
to thoughts about logging. Logging is used for different purposes:
- Indicate progress
- Log warnings, which indicate the output may differ from the output
 of other FO processors. This may be caused for example by
 implementation choices because of the spec is ambiguous or left
 it explicitely to the implementation.
- Log errors which have been ignored or warnings which are actually
 errors (bad input, ressource problems, ...) which have been recovered
 from. The output may to be different from what the user expected,
 or not (an example being the infamous page-number-format="1", which
 formally *is* a syntax error).
- Log information or warnings that something happened which the user
 likely didn't expect, or tells him he is about to shoot himself into
 the foot (for example using a proprietary extension, a legal but
 commonly misunderstood construct, or a deprecated feature).
- Debugging, mainly for developers.

I'd like to throw some ideas onto the list:
- Have some sort of progress() method on the user agent for indicating
 layout/rendering progress.
- Have a warning() , error() and fatalError() method on the user agent.
 Provide a mechanism so that the user can turn recoverable errors and
 warnings into fatal errors, preferably individually.

J.Pietschmann



JAXG snapshot available (was: Re: API discussion (revived))

2005-08-22 Thread Jeremias Maerki
I've cleaned up JAXG and published it on my website:

http://www.jeremias-maerki.ch/dev/jaxg/

Comments are welcome.

Jeremias Maerki



Re: JAXG snapshot available (was: Re: API discussion (revived))

2005-08-25 Thread Simon Pepping
Jeremias,

It is a good package. I have a few remarks.

1. At some point I wanted it to be possible to set input and output
   types on the Factory. In that way it would be possible to write a
   factory implementation which knows about several of the processing
   engines, and depending on the input and output types (and some user
   configuration, at the discretion of the factory implementation)
   could choose the best engine, e.g. JFOR for fo to rtf, FOP head for
   fo to all other, Batik for SVG to other.

   But that would introduce input type dependence into the
   code. Currently the following code:

   XGProcessorFactory factory = XGProcessorFactory.newInstance();
   XGProcessor processor = factory.newXGProcessor();
   Source src = new StreamSource(new File(args[0]));
   XGResult res = new StreamXGResult("application/pdf", new File(args[1]));
   processor.process(src, res);

   together with the appropriate value of the system property can be
   used to process both FO and SVG, with the engine of choice by the
   invoker.

2. I am a bit suprised that you use a specific factory implementation
   in your examples, and not the engine agnostic newInstance
   method. This is counter to the goal of engine agnostic code.

   This made me think that perhaps another goal is more important:
   This is a framework that allows one to access each engine through
   the same interface. It does so by writing adapters between the
   defined interface and the engines.

   Viewed this way, the reference implementation is not just that. It
   is the essential part of your package, viz. the set of adapters.

3. The interface is not limited to XML Graphics applications. It is
   suitable for any engine that exposes a SAXResult interface, or can
   be made to expose such an interface by an adapter.

I hope these thoughts make sense.

Regards, Simon

On Mon, Aug 22, 2005 at 12:23:45PM +0200, Jeremias Maerki wrote:
> I've cleaned up JAXG and published it on my website:
> 
> http://www.jeremias-maerki.ch/dev/jaxg/
> 
> Comments are welcome.
> 
> Jeremias Maerki
> 

-- 
Simon Pepping
home page: http://www.leverkruid.nl



Re: JAXG snapshot available (was: Re: API discussion (revived))

2005-08-26 Thread Jeremias Maerki

On 25.08.2005 22:17:33 Simon Pepping wrote:
> Jeremias,
> 
> It is a good package. I have a few remarks.

Thanks a lot for taking time to review!

> 1. At some point I wanted it to be possible to set input and output
>types on the Factory. In that way it would be possible to write a
>factory implementation which knows about several of the processing
>engines, and depending on the input and output types (and some user
>configuration, at the discretion of the factory implementation)
>could choose the best engine, e.g. JFOR for fo to rtf, FOP head for
>fo to all other, Batik for SVG to other.

Almost sounds like Nicola Ken Barozzi's Morphos idea [1]. :-) It didn't
work out back then. But the idea was good.

[1] 
http://svn.apache.org/viewcvs.cgi/jakarta/commons/sandbox/morphos/trunk/?rev=146738

>But that would introduce input type dependence into the
>code.

Hmm, I think it is possible (though probably not worth the effort) to
write a special factory builder/provider that analyzes the input file
and choosing the effective XGProcessorFactory much like we do that with
our image analyzers in FOP. This wouldn't even have to be part of the
API. This could simply be an external component.

> Currently the following code:
> 
>XGProcessorFactory factory = XGProcessorFactory.newInstance();
>XGProcessor processor = factory.newXGProcessor();
>Source src = new StreamSource(new File(args[0]));
>XGResult res = new StreamXGResult("application/pdf", new File(args[1]));
>processor.process(src, res);
> 
>together with the appropriate value of the system property can be
>used to process both FO and SVG, with the engine of choice by the
>invoker.
>
> 2. I am a bit suprised that you use a specific factory implementation
>in your examples, and not the engine agnostic newInstance
>method. This is counter to the goal of engine agnostic code.
> 
>This made me think that perhaps another goal is more important:
>This is a framework that allows one to access each engine through
>the same interface. It does so by writing adapters between the
>defined interface and the engines.

Exactly. There are different ways that you can obtain a factory instance.
Unlike with JAXP I don't want to tell you how exactly to do this
although you CAN do it the JAXP way. This comes out from the necessity
for supporting multiple FO processors in the same VM (also the reason
for the XGProcessorFactoryProxy and the DeploymentPackage class). With
JAXP you will generally be happy with exactly one implementation for the
whole VM.

>Viewed this way, the reference implementation is not just that. It
>is the essential part of your package, viz. the set of adapters.
> 
> 3. The interface is not limited to XML Graphics applications. It is
>suitable for any engine that exposes a SAXResult interface, or can
>be made to expose such an interface by an adapter.

It doesn't necessarily have to expose SAX functionality to feed in the
XML but it's probably to most flexible (and for some packages like FOP
the fastest) way. It's perfectly feasible to write an implementation of
the API the passes the input XML to the engine as a DOM or as a stream.
The only problem is the need for buffering in the case of the
XGProcessorHandler. It would be no big deal to write an implementation
of the API that calls an external C-written program using System.exec().

> I hope these thoughts make sense.

Absolutely. Thanks for them.

> Regards, Simon
> 
> On Mon, Aug 22, 2005 at 12:23:45PM +0200, Jeremias Maerki wrote:
> > I've cleaned up JAXG and published it on my website:
> > 
> > http://www.jeremias-maerki.ch/dev/jaxg/
> > 
> > Comments are welcome.
> > 
> > Jeremias Maerki
> > 
> 
> -- 
> Simon Pepping
> home page: http://www.leverkruid.nl



Jeremias Maerki