More redirection stubs for added packages.

Last change only handled added classes in existing packages; we now
emit stubs for added packages.

Change-Id: Ic148b5e555643e03ddd99a61fa3a73142bed6076
diff --git a/src/jdiff/APIDiff.java b/src/jdiff/APIDiff.java
index 4b4fd26..f590516 100755
--- a/src/jdiff/APIDiff.java
+++ b/src/jdiff/APIDiff.java
@@ -14,11 +14,11 @@
 public class APIDiff {
 
     /** Packages added in the new API. */
-    public List packagesAdded = null; // PackageAPI[]
+    public final List<PackageAPI> packagesAdded = new ArrayList<>();
     /** Packages removed in the new API. */
-    public List packagesRemoved = null; // PackageAPI[]
+    public final List<PackageAPI> packagesRemoved = new ArrayList<>();
     /** Packages changed in the new API. */
-    public List packagesChanged = null; // PackageDiff[]
+    public final List<PackageDiff> packagesChanged = new ArrayList<>();
 
     /** Name of the old API. */
     public static String oldAPIName_;
@@ -32,9 +32,5 @@
     public APIDiff() {
         oldAPIName_ = null;
         newAPIName_ = null;
-        packagesAdded = new ArrayList(); // PackageAPI[]
-        packagesRemoved = new ArrayList(); // PackageAPI[]
-        packagesChanged = new ArrayList(); // PackageDiff[]
     }   
 }
-
diff --git a/src/jdiff/ClassAPI.java b/src/jdiff/ClassAPI.java
index 9490cc7..f9fb737 100755
--- a/src/jdiff/ClassAPI.java
+++ b/src/jdiff/ClassAPI.java
@@ -13,7 +13,7 @@
  * See the file LICENSE.txt for copyright details.
  * @author Matthew Doar, mdoar@pobox.com
  */
-class ClassAPI implements Comparable {
+class ClassAPI implements Comparable<ClassAPI> {
 
     /** Name of the class, not fully qualified. */
     public String name_;
@@ -31,16 +31,16 @@
     public String extends_; // Can only extend zero or one class or interface
 
     /** Interfaces implemented by this class. */
-    public List implements_; // String[]
+    public final List<String> implements_ = new ArrayList<>();
 
     /** Constructors in this class. */
-    public List ctors_; // ConstructorAPI[]
+    public final List<ConstructorAPI> ctors_ = new ArrayList<>();
 
     /** Methods in this class. */
-    public List methods_; // MethodAPI[]
+    public final List<MethodAPI> methods_ = new ArrayList<>();
 
     /** Fields in this class. */
-    public List fields_; //FieldAPI[]
+    public final List<FieldAPI> fields_ = new ArrayList<>();
 
     /** The doc block, default is null. */
     public String doc_ = null;
@@ -53,15 +53,10 @@
         isInterface_ = isInterface;
         isAbstract_ = isAbstract;
         modifiers_ = modifiers;
-
-        implements_ = new ArrayList(); // String[]
-        ctors_ = new ArrayList(); // ConstructorAPI[]
-        methods_ = new ArrayList(); // MethodAPI[]
-        fields_ = new ArrayList(); // FieldAPI[]
     }
 
     /** Compare two ClassAPI objects by all the known information. */
-    public int compareTo(Object o) {
+    public int compareTo(ClassAPI o) {
         ClassAPI oClassAPI = (ClassAPI)o;
         int comp = name_.compareTo(oClassAPI.name_);
         if (comp != 0)
diff --git a/src/jdiff/ConstructorAPI.java b/src/jdiff/ConstructorAPI.java
index 65467ef..f2caeba 100755
--- a/src/jdiff/ConstructorAPI.java
+++ b/src/jdiff/ConstructorAPI.java
@@ -13,7 +13,7 @@
  * See the file LICENSE.txt for copyright details.
  * @author Matthew Doar, mdoar@pobox.com
  */
-class ConstructorAPI implements Comparable {
+class ConstructorAPI implements Comparable<ConstructorAPI> {
     /**
      * Name of the constructor.
      * Either this or type_ must be non-null
@@ -58,7 +58,7 @@
     }
 
     /** Compare two ConstructorAPI objects by type and modifiers. */
-    public int compareTo(Object o) {
+    public int compareTo(ConstructorAPI o) {
         ConstructorAPI constructorAPI = (ConstructorAPI)o;
         int comp = compareNullIsLeast(name_, constructorAPI.name_);
         if (comp != 0)
diff --git a/src/jdiff/FieldAPI.java b/src/jdiff/FieldAPI.java
index 151e729..e8e449b 100755
--- a/src/jdiff/FieldAPI.java
+++ b/src/jdiff/FieldAPI.java
@@ -13,7 +13,7 @@
  * See the file LICENSE.txt for copyright details.
  * @author Matthew Doar, mdoar@pobox.com
  */
-class FieldAPI implements Comparable {
+class FieldAPI implements Comparable<FieldAPI> {
     /** Name of the field. */
     public String name_;
 
@@ -67,7 +67,7 @@
     }
 
     /** Compare two FieldAPI objects, including name, type and modifiers. */
-    public int compareTo(Object o) {
+    public int compareTo(FieldAPI o) {
         FieldAPI oFieldAPI = (FieldAPI)o;
         int comp = name_.compareTo(oFieldAPI.name_);
         if (comp != 0)
diff --git a/src/jdiff/HTMLReportGenerator.java b/src/jdiff/HTMLReportGenerator.java
index c0ca4ff..b906959 100755
--- a/src/jdiff/HTMLReportGenerator.java
+++ b/src/jdiff/HTMLReportGenerator.java
@@ -184,11 +184,9 @@
     public void writeReport(APIDiff apiDiff) {
 
         // Report packages which were removed in the new API
-        if (apiDiff.packagesRemoved.size() != 0) {
+        if (!apiDiff.packagesRemoved.isEmpty()) {
             writeTableStart("Removed Packages", 2);
-            Iterator iter = apiDiff.packagesRemoved.iterator();
-            while (iter.hasNext()) {
-                PackageAPI pkgAPI = (PackageAPI)(iter.next());
+            for (PackageAPI pkgAPI : apiDiff.packagesRemoved) {
                 String pkgName = pkgAPI.name_;
                 if (trace) System.out.println("Package " + pkgName + " was removed.");
                 writePackageTableEntry(pkgName, 0, pkgAPI.doc_, false);
@@ -197,39 +195,36 @@
         }
         
         // Report packages which were added in the new API
-        if (apiDiff.packagesAdded.size() != 0) {
+        if (!apiDiff.packagesAdded.isEmpty()) {
             writeTableStart("Added Packages", 2);
-            Iterator iter = apiDiff.packagesAdded.iterator();
-            while (iter.hasNext()) {
-                PackageAPI pkgAPI = (PackageAPI)(iter.next());
+            for (PackageAPI pkgAPI : apiDiff.packagesAdded) {
                 String pkgName = pkgAPI.name_;
                 if (trace) System.out.println("Package " + pkgName + " was added.");
                 writePackageTableEntry(pkgName, 1, pkgAPI.doc_, false);
             }
             writeTableEnd();
+
+            // Now emit a separate file for each added package.
+            for (PackageAPI pkgAPI : apiDiff.packagesAdded) {
+                reportAddedPackage(pkgAPI);
+            }
         }
 
         // Report packages which were changed in the new API
-        if (apiDiff.packagesChanged.size() != 0) {
+        if (!apiDiff.packagesChanged.isEmpty()) {
             // Emit a table of changed packages, with links to the file
             // for each package.
             writeTableStart("Changed Packages", 3);
-            Iterator iter = apiDiff.packagesChanged.iterator();
-            while (iter.hasNext()) {
-                PackageDiff pkgDiff = (PackageDiff)(iter.next());
+            for (PackageDiff pkgDiff : apiDiff.packagesChanged) {
                 String pkgName = pkgDiff.name_;
                 if (trace) System.out.println("Package " + pkgName + " was changed.");
                 writePackageTableEntry(pkgName, 2, null, false);
             }
             writeTableEnd();
-            writeText("<!-- End of API section -->");
 
             // Now emit a separate file for each changed package.
-            writeText("<!-- Start of packages section -->");
-            PackageDiff[] pkgDiffs = new PackageDiff[apiDiff.packagesChanged.size()];
-            pkgDiffs = (PackageDiff[])apiDiff.packagesChanged.toArray(pkgDiffs);
-            for (int i = 0; i < pkgDiffs.length; i++) {
-                reportChangedPackage(pkgDiffs, i);
+            for (PackageDiff pkgDiff : apiDiff.packagesChanged) {
+                reportChangedPackage(pkgDiff);
             }
         }
             writeText("      </div>	");
@@ -251,13 +246,37 @@
             writeText("    </div> <!-- end body-content --> ");
     }
 
+    /**
+     * Write out a quick redirection file for added packages.
+     */
+    public void reportAddedPackage(PackageAPI pkgAPI) {
+        String pkgName = pkgAPI.name_;
 
+        String localReportFileName = reportFileName + JDiff.DIR_SEP + "pkg_" + pkgName
+                + reportFileExt;
+        if (outputDir != null)
+            localReportFileName = outputDir + JDiff.DIR_SEP + localReportFileName;
+
+        try (PrintWriter pw = new PrintWriter(new FileOutputStream(localReportFileName))) {
+            // Link to HTML file for the package
+            String pkgRef = newDocPrefix + pkgName.replace('.', '/');
+            pw.write("<html><head><meta http-equiv=\"refresh\" content=\"0;URL='" + pkgRef
+                    + "/package-summary.html'\" /></head></html>");
+        } catch(IOException e) {
+            System.out.println("IO Error while attempting to create " + localReportFileName);
+            System.out.println("Error: "+ e.getMessage());
+            System.exit(1);
+        }
+
+        for (ClassAPI classAPI : pkgAPI.classes_) {
+            reportAddedClass(pkgAPI.name_, classAPI);
+        }
+    }
 
     /**
      * Write out the details of a changed package in a separate file.
      */
-    public void reportChangedPackage(PackageDiff[] pkgDiffs, int pkgIndex) {
-        PackageDiff pkgDiff = pkgDiffs[pkgIndex];
+    public void reportChangedPackage(PackageDiff pkgDiff) {
         String pkgName = pkgDiff.name_;
 
         PrintWriter oldReportFile = null;
@@ -288,14 +307,7 @@
         // A link to the package in the new API
         String linkedPkgName = "<A HREF=\"" + pkgRef + ".html\" target=\"_top\"><font size=\"+1\"><code>" + pkgName + "</code></font></A>";
         String prevPkgRef = null;
-        if (pkgIndex != 0) {
-            prevPkgRef = "pkg_" + pkgDiffs[pkgIndex-1].name_ + reportFileExt;
-        }
-        // Create the HTML link to the next package
         String nextPkgRef = null;
-        if (pkgIndex < pkgDiffs.length - 1) {
-            nextPkgRef = "pkg_" + pkgDiffs[pkgIndex+1].name_ + reportFileExt;
-        }
 
         writeSectionHeader("Package " + linkedPkgName, pkgName, 
                            prevPkgRef, nextPkgRef,
diff --git a/src/jdiff/PackageAPI.java b/src/jdiff/PackageAPI.java
index 885752f..8a82bea 100755
--- a/src/jdiff/PackageAPI.java
+++ b/src/jdiff/PackageAPI.java
@@ -13,13 +13,13 @@
  * See the file LICENSE.txt for copyright details.
  * @author Matthew Doar, mdoar@pobox.com
  */
-class PackageAPI implements Comparable {
+class PackageAPI implements Comparable<PackageAPI> {
 
     /** Full qualified name of the package. */
     public String name_;
 
     /** Classes within this package. */
-    public List classes_;  // ClassAPI[]
+    public final List<ClassAPI> classes_ = new ArrayList<>();
 
     /** The doc block, default is null. */
     public String doc_ = null;
@@ -27,11 +27,10 @@
     /** Constructor. */
     public PackageAPI(String name) {
         name_ = name;
-        classes_ = new ArrayList(); // ClassAPI[]
     }
 
     /** Compare two PackageAPI objects by name. */
-    public int compareTo(Object o) {
+    public int compareTo(PackageAPI o) {
         PackageAPI oPackageAPI = (PackageAPI)o;
         if (APIComparator.docChanged(doc_, oPackageAPI.doc_))
             return -1;
diff --git a/src/jdiff/PackageDiff.java b/src/jdiff/PackageDiff.java
index 94606ac..495f6e6 100755
--- a/src/jdiff/PackageDiff.java
+++ b/src/jdiff/PackageDiff.java
@@ -14,11 +14,11 @@
     public String name_;
 
     /** Classes added in the new API. */
-    public List<ClassAPI> classesAdded = null;
+    public final List<ClassAPI> classesAdded = new ArrayList<>();
     /** Classes removed in the new API. */
-    public List<ClassAPI> classesRemoved = null;
+    public final List<ClassAPI> classesRemoved = new ArrayList<>();
     /** Classes changed in the new API. */
-    public List<ClassDiff> classesChanged = null;
+    public final List<ClassDiff> classesChanged = new ArrayList<>();
 
     /** 
      * A string describing the changes in documentation. 
@@ -31,8 +31,5 @@
     /** Default constructor. */
     public PackageDiff(String name) {
         name_ = name;
-        classesAdded = new ArrayList<>();
-        classesRemoved = new ArrayList<>();
-        classesChanged = new ArrayList<>();
     }   
 }