package examples;

import static org.junit.Assert.fail;

import java.io.File;
import java.io.IOException;
import java.security.CodeSource;
import java.util.Enumeration;
import java.util.Properties;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.junit.Test;

public class MainTest {

    @Test
    public void checkExamplesPropertiesIsComplete() throws Exception {
        Properties cp = scanClasses();
        Properties fp = new Properties();
        fp.load(this.getClass().getResourceAsStream("examples.properties"));
        for(String c : cp.stringPropertyNames()) {
            String fv = fp.getProperty(c); 
            final String cv = cp.getProperty(c);
            if (fv == null) {
                System.out.printf("%-25s %s - missing from examples.properties%n",c,cv);
            } else if (!fv.equals(cv)) {
                System.out.printf("%-25s %s - expected value %s %n",c,fv,cv);
            }
        }
    }

    private Properties scanClasses() throws IOException {
        CodeSource codeSource = Main.class.getProtectionDomain().getCodeSource();
        final String sourceFile = codeSource.getLocation().getFile();
        Properties p = new Properties();
        if (sourceFile.endsWith(".jar")) {
            JarFile jf = new JarFile(sourceFile);
            Enumeration<JarEntry> e = jf.entries();
            while (e.hasMoreElements()) {
              JarEntry je = e.nextElement();
              String name = je.getName();
              processFileName(name, p);
            }
            jf.close();
        } else {
            File examples = new File(sourceFile, "examples"); // must match top level examples package name
            if (examples.exists()) {
                scanForClasses(sourceFile.length(), examples, p);
            } else {
                fail("Could not find examples classes");
            }
        }
        return p;
    }

    private static void scanForClasses(int rootLength, File current, Properties p) {
        for(File file : current.listFiles()) {
            if (file.isDirectory()) {
                scanForClasses(rootLength, file, p);
            } else {                
                processFileName(file.getPath().substring(rootLength), p);
            }
        }        
    }

    private static void processFileName(String name, Properties p) {
        if (!name.endsWith(".class")
                || name.contains("$") // subclasses
                || name.equals("examples/Main.class")  // the initial class, don't want to add that
                || !hasMainMethod(name)
                ) {
            return;
        }
        name = name.replace(".class", "");
        final int lastSep = name.lastIndexOf('/');
        final String alias = name.substring(lastSep+1);
        if (p.containsKey(alias)) {
            System.out.printf("Duplicate alias: %-25s %s %s %n",alias,name,p.getProperty(alias));            
        } else {
            p.setProperty(alias, name);
        }
    }

    private static boolean hasMainMethod(String name) {
        name = name.replace(".class", "");
        name = name.replace("/", ".");
        try {
            Class<?> clazz = Class.forName(name, false, MainTest.class.getClassLoader());
            clazz.getMethod("main", new Class[]{String[].class});
            return true;
        } catch (ClassNotFoundException e) {
            System.out.println("Cannot find " + name);
            return false;
        } catch (NoSuchMethodException e) {
            return false;
        } catch (SecurityException e) {
            e.printStackTrace();
        }
        return true;
    }
}

@@ -553,50 +553,236 @@
     
-for(String c : cp.stringPropertyNames()) %7B
+@SuppressWarnings(%22unchecked%22) // OK%0A        final Enumeration%3CString%3E propertyNames = (Enumeration%3CString%3E) cp.propertyNames();%0A        while(propertyNames.hasMoreElements())%7B%0A            String c = propertyNames.nextElement();
 %0A   

Replace Java 6+ method call