You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by rd...@apache.org on 2003/09/08 15:58:53 UTC
cvs commit: jakarta-commons/betwixt/xdocs/guide binding.xml writing.xml
rdonkin 2003/09/08 06:58:53
Modified: betwixt/xdocs/guide binding.xml writing.xml
Log:
Documentation for ClassNormalizer
Revision Changes Path
1.3 +30 -0 jakarta-commons/betwixt/xdocs/guide/binding.xml
Index: binding.xml
===================================================================
RCS file: /home/cvs/jakarta-commons/betwixt/xdocs/guide/binding.xml,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- binding.xml 16 Aug 2003 06:30:24 -0000 1.2
+++ binding.xml 8 Sep 2003 13:58:53 -0000 1.3
@@ -339,6 +339,36 @@
property is specified then the bean can be written and then read back.
</p>
</subsection>
+ <subsection name='Introspection And Normalization'>
+ <p>
+When an Object is introspected by the <code>XMLIntrospector</code>, the class is examined and
+an <code>XMLBeanInfo</code> created based upon it. But there are occasions when some variation
+is needed - for example when reading or writing Entity Beans or Proxy implementations.
+ </p>
+ <p>
+Betwixt provides the <code>ClassNormalizer</code> strategy class as a way to allow users to customise
+the process by which Betwixt works out which Class should be introspected for a given Object.
+The default implementation simply supplies the Class of the Object.
+But by setting the <code>classNormalizer</code> property of <code>XMLIntrospector</code>,
+a custom implementation can be used instead.
+ </p>
+ <p>
+Betwixt supplies a second implementation called <code>ListedClassNormalizer</code>.
+This contains a list of classes to match together with the Class which should be returned
+when the Class is matched.
+ </p>
+ <p>
+For example, take a class <code>FaceImpl</code> that implements an interface <code>IFace</code>.
+Betwixt will introspect every instance of <code>FaceImpl</code> as if it just implemented
+<code>IFace</code> by use of the following code:
+ </p>
+<code><pre>
+ XMLIntrospector introspector = ...;
+ ListedClassNormalizer classNormalizer = new ListedClassNormalizer();
+ classNormalizer.addSubstitution( IFace.class );
+ introspector.setClassNormalizer( classNormalizer );
+</pre></code>
+ </subsection>
</section>
<section name='Converting Objects And Primitives To Strings (And Back Again)'>
1.2 +50 -0 jakarta-commons/betwixt/xdocs/guide/writing.xml
Index: writing.xml
===================================================================
RCS file: /home/cvs/jakarta-commons/betwixt/xdocs/guide/writing.xml,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- writing.xml 14 Aug 2003 21:26:31 -0000 1.1
+++ writing.xml 8 Sep 2003 13:58:53 -0000 1.2
@@ -22,6 +22,56 @@
.betwixt file.
</p>
</subsection>
+ <subsection name='Writing Entity Beans'>
+ <p>
+Entity beans are a kind of Enterprise Java Bean. For more details see the
+<a href='http://java.sun.com/j2ee/'>J2EE</a> specification. They are a common way to persist data.
+When dealing with an entity bean, you usually deal with the remote interface rather than the
+concrete implementation. There is no gaurantee that the class presented by the container will be
+the class your created to provide the bean's functionality.
+Indeed, <code>Proxy</code> implementations are
+one common way in which the remote interfaces are implemented.
+ </p>
+ <p>
+This causes some difficulties for Betwixt. Betwixt (by default) will introspect the actual implementation
+presented by the container.
+Fortunately, the normalization mechanism described <a href='binding#Introspection%20And%20Normalization'>here</a>
+can be used to allow betwixt to introspect the actual interface (rather than the implementation).
+ </p>
+ <p>
+There are two different strategies that can be used. The first is to create a special
+<code>ClassNormalizer</code> which extracts an interface from a <code>Proxy</code>.
+(Thanks to Christoph Gaffga for suggesting this.)
+For example:
+ </p>
+<code><pre>
+ XMLIntrospector introspector = ...;
+ introspector.setClassNormalizer( new ClassNormalizer() {
+ public Class normalize( Class clazz ) {
+ if ( Proxy.isProxyClass(clazz) && clazz.getInterfaces().length >0 ) {
+ return clazz.getInterfaces()[0];
+ }
+ return clazz;
+ }
+ });
+</pre></code>
+ <p>
+Of course, this will only work if your J2EE implementation uses <code>Proxy</code> classes to implement
+it's Entity Beans.
+ </p>
+ <p>
+The alternative is to use a <code>ListedClassNormalizer</code> and register all remote interfaces.
+For example:
+ </p>
+<code><pre>
+ XMLIntrospector introspector = ...;
+ ListedClassNormalizer classNormalizer = new ListedClassNormalizer();
+ classNormalizer.addSubstitution( MyRemoteInterfaceOne.class );
+ classNormalizer.addSubstitution( MyRemoteInterfaceTwo.class );
+ ...
+ introspector.setClassNormalizer( classNormalizer );
+</pre></code>
+ </subsection>
</section>
</body>
</document>