CS639 Programming Assignment 1

Turning non-XML Data into XML

First Delivery: DumpClass for Monday Feb. 11, by midnight, in cs639/pa1a  (sources under cs639/pa1a/src, etc.)
Second Delivery: JavaToXML, DTD, Schema due Wed, Feb. 20, midnight, in your cs639/pa1b  (sources under cs639/pa1b/src, etc.)
For help, post messages in the Google group.

Suppose you are adding a feature to eclipse to allow it to support efficient remote access to Java sources via Web Services.  To support the Package Explorer, a Web Service is set up to supply just the needed data for one class's display, that is, the fields and methods of each class, and nested within that display, the fields and methods of a nested class (and so on.)  The first step is getting the needed data into XML, the task of this project. This XML will be eventually carried as the payload of the Web Services. For simplicity, let's concentrate on the Java classes and their methods, including the inner classes, but excluding local and anonymous classes, so methods can't have enclosed classes.

 

Of course we are not yet doing Web Services for this project. For this project, we will express the structure of Java programs (as summarized in eclipse) in XML.  Here's what we want to record

Here's an example of the desired XML,

<?xml version="1.0" encoding="UTF-8"?>
<source>
   <sourceName>Hello.java</sourceName>
   <jclass>
       <className>Hello</className>

       <visibility>public</visibility> 
       <innerclasses>                             
       <!--inner classes here before methods (see eclipse display) -->
       </innerclasses>

       <methods>  

          <static> <!-- static methods before non-static ones -->

            <method>
              <name>main</name>

              <visibility>public</visibility>

              <params>   <!--params but not return types -->
                <param>
                 <paramType>String[]</paramType>      
                </param>
              </params>
           </method>

                         <nonstatic>

           <!--use same <method> elements here, as needed -->

          </nonstaticMethods>

                </methods>
    </jclass>
</source>


 
  Note: We're using "jclass" instead of "class" to avoid using Java reserved words. We're ignoring constructors and fields for simplicity. Note that paramType may have parametrized type such as Set<Something>.

  1. Your program is going to read a Java source file and pick out from it just the needed information to compose such an XML document. Come up with an algorithm to determine, from a given Java source file, the class names and method names based on the syntax rules of Java.  This is not easy to do directly, but luckily we can piggyback on the parsing that the Java compiler does, by using reflection. This will get us everything we need, except for information on non-public inner classes (we'll ignore this drawback.)
  2. Write a DTD in JavaSource.dtd and an XML Schema for this in javaSource.xsd. Treat the Java type names (int, String[], ArrayList, etc.) as just text.  Your .dtd and .xsd files do not need to be any fancier than the ones provided for the book example.
  3. Turn Counter.java into callable code with the minimal edits to it, and add validation of the result of your transformation after it's created, in the case the user uses the "-v" or "-v -s" flags with JavaToXML.  Counter.java is in the sax subdirectory in XML Schema validation examples.  This is also linked from the Resources section of the class web page.


Implementation Notes

Inner Classes to Support. Note that inner classes can declared in many different places in a class.  But for simplicity, let's only handle public inner classes defined at the level of a class's methods, not ones local to a method.  In other words, ignore any classes defined locally within a method. Regardless of the inner class location between the methods in the .java file, the XML should show them before the methods.
Packages. Use the supplied skeleton of packages, in particular, cs639.presentation for the top-level program, cs639.jsource for the java source related code and cs639.validation for the validator code.  

Steps for JavaToXML:

  1. The basic package structure is provided in pa1a (pa1a.zip) along with DumpMethods.java, a simplification of MethodSpy.java in the Java tutorial on reflection. Build DumpMethods and make sure you understand its output on various (compiled) classes. Using the supplied Grid.java, Try DumpMethods on Grid$Spot to see into an inner class (you need to escape the $ on UNIX/Linux, i.e. use Grid\$Spot if you use the command line). Then write a little program DumpInnerClasses to look at the inner classes.  Also look at methods and inner classes in eclipse Package Explorer to see the display we are trying to support. Try out the standard Java tool javap and compare the results.
  2. Put DumpInnerClasses and DumpMethods together into a recursive program DumpClass that prints out to toString representations of the top-level class and all (public) inner classes and all methods of all these classes in the order we want the XML to follow, except for now you can list the static methods among the non-static methods. Use indentation to indication depth of recursion. For Grid, we want the follow output: for "java DumpClass Grid":

    class Grid, Modifiers: public
      class Grid$Spot, Modifiers: public static
      public int Grid$Spot.hashCode()
      public boolean Grid$Spot.equals(java.lang.Object)
    private void Grid.growGroup(int,int,java.util.Set<Grid$Spot>)
    public int Grid.sizeOfGroup(int,int)
    public static void Grid.main(java.lang.String[]
  3. First Delivery (pa1a): Put your files for DumpInnerClasses and DumpClass in the cs639.presentation package of your pa1a directory. They should have the supplied build.xml in the pa1a directory, working with your sources, and use the suggested packages under the src directory.  Add a target "test1" to build.xml to execute DumpInnerClasses on Grid, and "test2" to execute DumpClass on SortEx.
  4. Study the supplied example of recursive XML in $cs639/validate, and write the DTD and schema for this one.
  5. Refactor to use packages as follows. Leave the top-level UI code in JavaToXML in presentation. Set up a JavaSource class in jsource for all non-UI processing of the source (except for method-level processing). Set up a JavaMethod class to handle one method for one class, also in the jsource package.  
  6. Now add functionality for writing XML. JavaMethod writes XML for a method. JavaSource writes the header and class elements. If you wish, you can have a JavaClass  class for handling classes.Now a single call from JavaToXML.to JavaSource should do everything.
  7. Add the validation feature.


Second delivery (pa1b)
main program:
java cs639.jsource.JavaToXML <classname>
Base directory (pa1b):  output files Grid.xml, etc. (or write XML to standard output, or both), JavaSource.dtd, javaSource.xsd
build.xml: with test3 to output Grid's XML, test4 to output SortEx's XML, test3v to output Grid's XML with linkage to DTD, and validate it, and test3sv to output Grid's XML with linkage to the XML Schema and validate it.
src/cs639/presentation: JavaToXML.java, a small top-level program.
src/cs639/jsource: JavaMethod.java, JavaSource.java: the main XML processing code
src/cs639/validation: Counter.java, and your own RunCounter.java or whatever you want to call it.  Hopefully you can leave Counter.java unchanged.