Links

Lists

Latest Updates

Ruby On Rails List
Python list
Advanced Java
The JavaScript List
Apache Users
Full Disclosure
Linux Security

Search the archives!


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

design question: deriving ouputs walking a tree


  • From: boazbk@xxxxxxxxxxxxxx (Boaz Barak)
  • Subject: design question: deriving ouputs walking a tree
  • Date: Sun, 27 Sep 1998 13:44:49 +0200

Here is a suggestion for another approach (of course , since I don't really
know all the details it may not be the right one for you):

have the renderer provide methods such as
void render(A a);
void render(B b);
void render(C c);
...

for all the classes it supports , have a dispatch method which will find out
using reflection which is the most appropriate method to call.
I have used this technique in places where I wished for "runtime
overloading" - like message handling where you wish you can add a derived
class which handles a particular message ( I think a place where we all miss
runtime overloading is the equals() method where we are forced to define it
as equals(Object o) ).

I've used the following code, but you can probably write more optimized code
, I think also that JDK 1.3 might have something
like as part of their proxy creation mechanism. I also don't handle here
problems that might appear if the class declaring the method is public, but
the derived class is not.

Boaz Barak

code from
http://www.math.tau.ac.il/~boazbk/pos
 /**
  * returns true iff types1 is more specific than types2
  * @exception POSException is thrown if they are incomparable.
  */
 public static boolean isMoreSpecific(Class[] types1,Class[] types2) throws
IL.ac.tau.pos.POSException {
  if (types1 == null) return false;
  if ((types1 != null) && (types2 == null)) return true;
  if (types1.length != types2.length) throw new
IL.ac.tau.pos.POSException("Args not of the same length - " + types1.length
+" != " + types2.length);
  for (int i = 0 ; i < types1.length ; i++)
   if (!types2[i].isAssignableFrom(types1[i])) return false;
  return true;
 }


 /**
  * try to get most appropriate method ,return null if fails.
  */
 public static java.lang.reflect.Method getMethod(Class cls,String
name,Object[] args)
  throws IL.ac.tau.pos.POSException {
  Log.debug("ProxyFactory.getMethod called withh Class "+ cls + " MethodName
= " + name + " args="+args);
  try {
   Method[] methods = cls.getMethods();
   Class[] paramTypes = new Class[args.length];
   for (int i = 0 ; i < args.length ; i++)
    paramTypes[i] = (args[i]==null ? null : args[i].getClass());
   for (int i = 0 ; i <methods.length ; i++)
    if (!methods[i].getName().equals(name) ||
(!isApplicable(paramTypes,methods[i].getParameterTypes()))) methods[i] =
null;
   Method method = null;
   for (int i = 0 ; i < methods.length ; i++) {
    if (methods[i]==null)
     continue;
    if (method==null ||
(isMoreSpecific(methods[i].getParameterTypes(),method.getParameterTypes())))
     method = methods[i];
   }
   return method;
  } catch (IL.ac.tau.pos.POSException e)  {
   throw e;
  } catch (Exception e) {
     Log.error(e);
     throw new IL.ac.tau.pos.POSException("Exception " + e + " getting
method");
  }


 }


----- Original Message -----
From: James Tauber <jtauber@xxxxxxxxxxx>
To: <advanced-java@xxxxxxxxxxxxxxxx>
Sent: ùáú 25 ñôèîáø 1999 10:48
Subject: design question: deriving ouputs walking a tree


> As I've mentioned before, I'm working on an XSL formatter called FOP (see
> http://www.jtauber.com/fop/). I'm rethinking a lot of the overall design
and
> the following question has come up:
>
> XSL formatting really has two stages, formatting and rendering. The result
> of formatting is a tree where each node is a particular type of layout
area.
> I don't need to be any more specific than this for my question.
>
> The rendering step (which my design question relates to) involves walking
> the layout area tree and producing output in a particular format. The way
I
> implement it, FOP can use different renderers (implementations of a
Renderer
> inteface) to produce different output formats, although the principal one
at
> the moment is a render for PDF (PDFRenderer).
>
> My question relates to the relationship between the classes representing
> different area types in the layout area tree and the renderer class.
>
> They way I do it at the moment (which I don't really like) is PDFRenderer
> has a method for handling each area type and as well as outputing the PDF
> for the particular area type, the method iterates over the child nodes of
> the layout area tree and calls other methods in the class on those child
> nodes, using a series of "if A instanceof B" (which is the part I *really*
> don't like).
>
> Here is what I am thinking of changing it to:
>
> * The classes representing the different layout area types have a static
> "registerRenderer" method that takes the renderer as a parameter and puts
it
> in a static variable.
> * The classes representing the different layout area types have a instance
> method "render" that causes the appropriate method (for the particular
> layout area type) of the registered render class to be called with "this"
as
> a parameter.
> * After the layout area tree has been built, the first thing the renderer
> does is call the registerRenderer method of each class representing a
layout
> area type, thus registering itself.
> * The individual methods don't have a series of "if A instanceof B", any
> more. They simply call the "render" method of whatever node in the layout
> area tree is currently being traversed.
>
> Do people agree that this is a better approach? It seems to me to be a
good
> use of polymorphism.
>
> I look forward to your learned opinions
>
> Thanks
>
> James
> --
> James Tauber / jtauber@xxxxxxxxxxx / www.jtauber.com
> Maintainer of : www.xmlinfo.com,  www.xmlsoftware.com and www.schema.net
> <pipe>Ceci n'est pas une pipe</pipe>
>
>
>
>
>
>
>
>
>
>
> ---
> To unsubscribe, mail advanced-java-unsubscribe@xxxxxxxxxxxxxxxx
> To get help, mail advanced-java-help@xxxxxxxxxxxxxxxx
>


---
To unsubscribe, mail advanced-java-unsubscribe@xxxxxxxxxxxxxxxx
To get help, mail advanced-java-help@xxxxxxxxxxxxxxxx