package class9_2_CurrencyFactory_inClass.app; import class9_2_CurrencyFactory_inClass.currency.CurrencyMaker; import class9_2_CurrencyFactory_inClass.currency.DollarBillMaker; import class9_2_CurrencyFactory_inClass.currency.DollarCoinMaker; import java.io.IOException; import java.net.URL; import java.net.URLClassLoader; import java.util.Enumeration; import java.util.Scanner; import java.util.jar.JarEntry; import java.util.jar.JarFile; // MoneyMakerApp (the client) creates concrete XXXMaker instances ("Products") public class MoneyMakerApp { private URLClassLoader cl; public static void main(String[] args) throws IOException, ClassNotFoundException { System.out.println("This is the REAL in class-version."); MoneyMakerApp app = new MoneyMakerApp(); app.loadJar(args[0]); System.out.println("What type of currency do you want to make?"); Scanner in = new Scanner(System.in); app.mintMoney(in.next()); // app.mintMoney("DollarCoinMaker"); // let's do something illegal... // app.mintMoney("DollarBillMaker"); } public void loadJar(String pathToJar) throws IOException, ClassNotFoundException { System.out.println("Loading JAR file"); JarFile jarFile = new JarFile(pathToJar); Enumeration e = jarFile.entries(); URL[] urls = { new URL("jar:file:" + pathToJar+"!/") }; cl = URLClassLoader.newInstance(urls); System.out.println("e = " + e); while (e.hasMoreElements()) { JarEntry je = e.nextElement(); System.out.println("je = " + je); if(je.isDirectory() || !je.getName().endsWith(".class")){ System.out.println("skipping directory/non-class: je = " + je); continue; } // -6 because of .class String className = je.getName().substring(0,je.getName().length()-6); className = className.replace('/', '.'); Class c = cl.loadClass(className); System.out.println("className = " + className); System.out.println("c = " + c); try { if(c.newInstance() instanceof class9_2_CurrencyFactory_prep.currency.CurrencyMaker) { class9_2_CurrencyFactory_prep.currency.CurrencyMaker cm = (class9_2_CurrencyFactory_prep.currency.CurrencyMaker) c.newInstance(); cm.makeCurrency(); } } catch (InstantiationException | IllegalAccessException e1) { System.out.println("Could not instantiate class."); e1.printStackTrace(); } } } public void mintMoney(String type) throws IllegalArgumentException { CurrencyMaker cm; // abstract class try { Class myClass = Class.forName("class9_2_CurrencyFactory_inClass.currency."+type); cm = (CurrencyMaker) myClass.newInstance(); } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { System.out.println("Fallback: Try jar file"); try { Class myClass = cl.loadClass("class9_2_CurrencyFactory_inClass.currency."+type); cm = (CurrencyMaker) myClass.newInstance(); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e1) { System.out.println("Error: Could not create class: "+type); e.printStackTrace(); throw new IllegalArgumentException("Error: Could not create class: "+type); } } // direct the concrete CurrencyMakers cm.getSupplies(); cm.makeCurrency(); cm.ship(); // custom factory: (Never wrote) // CurrencyMakerMaker makerMaker; // cm = makerMaker.createMaker(); // ugly switch statement: // switch( type ) { // case "DOLLAR_COIN": // cm = new DollarCoinMaker(); // create a concrete CurrencyMaker // break; // // case "DOLLAR_BILL": // cm = new DollarBillMaker(); // create a concrete CurrencyMaker // break; // // default: // System.out.println("Can't create that denomination."); // throw new IllegalArgumentException("Can't create denomination: "+type); // } } }