<?xml version="1.0" encoding="UTF-8"?>
<!--

 Copyright 2004 The Apache Software Foundation.
 
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at
 
      http://www.apache.org/licenses/LICENSE-2.0
 
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.

-->
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.2//EN" "document-v12.dtd">
<document>
  <header><title>Java Source Reflection</title></header>
  <body>
      <section><title>Why Source Reflection?</title>
        <p>Java Source Generation is frequently based on reflection. For example,
          the <link href="patterns/proxy.html">Proxy Generator</link> works
          roughly like this: Class A is inspected using Java Reflection.
          A new class B is created. For any public method in A, a method
          in B is created, that invokes A.</p>
        <p>This approach has a subtle inconvenience: To use Java reflection,
          the class A must have already been compiled. As a consequence, the
          use of generated sources typically happens in three stages:</p>
        <ol>
          <li>Compiling a part of the sources</li>
          <li>Invoking the source generator</li>
          <li>Compiling the remaining sources</li>
        </ol>
        <p>This can become rather nasty. In particular, you cannot reference
          the second part of the sources from the first part. The build
          scripts tend to be overly complex and difficult to maintain.</p>
        <p>Java Source Reflection is a true simplification of the above
          process: Required informations are gathered from the Java
          source files, and not from the compiled classes.</p>
        </section>

      <section><title>How it works</title>
        <p>Java Source Reflection is implemented by the class
          <link href="../apidocs/org/apache/ws/jaxme/js/util/JavaParser.html">
          JavaParser</link>. This class takes as input a Java source file and
          converts it into an instance of
          <link href="../apidocs/org/apache/ws/jaxme/js/JavaSource.html">
          JavaSource</link>. The Java parser is internally based on an
          <link href="ext:antlr">AntLR parser</link>. (AntLR is a public
          domain parser generator.)</p>
        <p>The created
          <link href="../apidocs/org/apache/ws/jaxme/js/JavaSource.html">
          JavaSource</link> instance contains instances of
          <link href="../apidocs/org/apache/ws/jaxme/js/JavaMethod.html">
          JavaMethod</link>,
          <link href="../apidocs/org/apache/ws/jaxme/js/JavaField.html">
          JavaField</link>,
          <link href="../apidocs/org/apache/ws/jaxme/js/JavaInnerClass.html">
          JavaInnerClass</link>, and so on. Obviously, these can be used to
          replace classical Java reflection.</p>
        </section>

	  <section><title>Using the JavaParser</title>
	    <p>To use the Java parser, your classpath must obviously contain
	      the file jaxmejs.jar. However, because the actual parser is
	      generated by <link href="ext:antlr">AntLR</link>, you need the
	      file antlr.jar as well. Both files come to you as part of the
	      JaxMe distribution. Besides, a current version of antlr.jar
	      (2.7.4, as of this writing) can always be obtained from
	      <link href="ext:antlr">www.antlr.org</link>. However, if you
	      replace the AntLR parser, then you should probably use the
	      JaxMe source distribution, and rebuild the binaries, thus
	      creating a new parser.</p>
	    <p>The following sample uses Java source reflection to print
	      all public non-static methods of a certain Java class:</p>
	    <source>
   import org.apache.ws.jaxme.js.*;

   public void printPublicInstanceMethods(File pFile) {
     JavaSourceFactory jsf = new JavaSourceFactory();
     JavaParser jp = new JavaParser(jsf);
     jp.parse(pFile);
     for (Iterator iter = jsf.getJavaSources();  iter.hasNext();  ) {
       JavaSource js = (JavaSource) iter.next();
       System.out.println("Public instance methods of class: " + js.getQName());
       JavaMethod[] methods = js.getMethods();
       for (int i = 0;  i &lt; methods.length;  i++) {
         if (methods[i].getProtection().equals(JavaSource.PUBLIC)  &amp;&amp;
             !methods[i].isPublic()) {
           System.out.println("  " + methods[i].getName());
         }
       }
       System.out.println(js.getQName());
     }
   }
	      </source>
	    </section>
  </body>
</document>
