package tutorial.jdo; import java.lang.reflect.*; import java.util.*; import javax.jdo.*; /** * Provides some maintenance methods for adding, removing, and analyzing * the animals in the data store. */ public class AnimalMaintenance { /** * Return a list of animals that match the specified query filter. * * @param filter the JDO filter to apply to the query * @param cls the class of animal to query on * @param pm the PersistenceManager to obtain the query from */ public static List getAnimals(String filter, Class cls, PersistenceManager pm) { // Execute a query for the specified class and filter. Query query = pm.newQuery(cls, filter); return (List) query.execute(); } /** * Performs the actual JDO work of putting object * into the data store. * * @param object the object to persist in the data store */ public static void persistObject(Object object) { // Get a PersistenceManagerFactory and PersistenceManager. PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory ("META-INF/jdo.properties"); PersistenceManager pm = pmf.getPersistenceManager(); // Obtain a transaction and mark the beginning // of the unit of work boundary. Transaction transaction = pm.currentTransaction(); transaction.begin(); pm.makePersistent(object); // Mark the end of the unit of work boundary, // and record all inserts in the database. transaction.commit(); System.out.println("Added " + object); // Close the PersistenceManager and PersistenceManagerFactory. pm.close(); pmf.close(); } /** * Performs the actual JDO work of removing objects * from the data store. * * @param objects the objects to persist in the data store * @param pm the PersistenceManager to delete with */ public static void deleteObjects(Collection objects, PersistenceManager pm) { // Obtain a transaction and mark the beginning of the // unit of work boundary. Transaction transaction = pm.currentTransaction(); transaction.begin(); for (Iterator iter = objects.iterator(); iter.hasNext(); ) System.out.println("Removed animal: " + iter.next()); // This method removes the objects in 'objects' from the data store. pm.deletePersistentAll(objects); // Mark the end of the unit of work boundary, and record all // deletes in the database. transaction.commit(); } /////////////////////////////////////////////////////////////// // Methods below here are provided by BEA, and do not // need to be altered. Feel free to examine the code below, // but for the purposes of this tutorial, there is no need to // read and understand everything that they do. /////////////////////////////////////////////////////////////// /** * Uses reflection to add the animal specified by cls, * name, and arg. Assumes that there is a * two-arg constructor whose first argument is a string name, and whose * second argument is some sort of primitive or string. * * @param cls the type of animal to add; one of Dog, Rabbit, or Snake * @param name the name of the animal to add * @param arg the numeric arg to be passed to the constructor. * this will be translated into the appropriate type * for the class specified, as determined by reflection * on the constructors */ public static void add(Class cls, String name, String arg) throws IllegalArgumentException { try { Constructor[] constructors = cls.getDeclaredConstructors(); for (int i = 0; i < constructors.length; i++) { // Find an appropriate constructor. Class[] paramTypes = constructors[i].getParameterTypes(); if (paramTypes.length == 2 && paramTypes[0] == String.class) { Object[] params = new Object[] { name, getPrimitiveWrapper(arg, paramTypes[1]), }; Object newObject = constructors[i].newInstance(params); persistObject(newObject); } } } catch (Exception e) { System.out.println("Exception creating " + cls + ": " + e); } } /** * Attempt to convert arg to a primite object wrapper * of class cls. */ private static Object getPrimitiveWrapper(String arg, Class cls) { if (cls.equals(Boolean.class) || cls.equals(Boolean.TYPE)) return Boolean.valueOf(arg); if (cls.equals(Byte.class) || cls.equals(Byte.TYPE)) return Byte.valueOf(arg); if (cls.equals(Character.class) || cls.equals(Character.TYPE)) return new Character(arg.charAt (0)); if (cls.equals(Short.class) || cls.equals(Short.TYPE)) return Short.valueOf(arg); if (cls.equals(Integer.class) || cls.equals(Integer.TYPE)) return Integer.valueOf(arg); if (cls.equals(Long.class) || cls.equals(Long.TYPE)) return Long.valueOf(arg); if (cls.equals(Float.class) || cls.equals(Float.TYPE)) return Float.valueOf(arg); if (cls.equals(Double.class) || cls.equals(Double.TYPE)) return Double.valueOf(arg); return null; } /** * Removes all animals that match query. * * @param query the filter to use when finding animals to remove * @param cls the class of animal to query on */ public static void remove(String query, Class cls) { // don't allow removing all animals if (query.trim().length() == 0) { System.out.println("Error: cannot remove all animals. Please " + "provide a query."); return; } PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory ("META-INF/jdo.properties"); PersistenceManager pm = pmf.getPersistenceManager(); List animals = getAnimals(query, cls, pm); if (animals.isEmpty()) { System.out.println("No animal matching '" + query + "' found in persistence manager."); } else deleteObjects(animals, pm); pm.close(); pmf.close(); } /** * Prints out a description of all the animals that match * query. * * @param query the filter to use when finding animals to list * @param cls the class of animal to query on * @param detailed if true, display details about * each animal identified by query; * else, print out terse info only */ public static void list(String query, Class cls, boolean detailed) { PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory ("META-INF/jdo.properties"); PersistenceManager pm = pmf.getPersistenceManager(); Collection animals = getAnimals(query, cls, pm); if (animals.size() == 0) { System.out.println("No animal matching '" + query + "' found in persistence manager."); } else { for (Iterator iter = animals.iterator(); iter.hasNext();) { Animal animal = (Animal) iter.next(); System.out.println(animal.toString(detailed)); } } pm.close(); pmf.close(); } public static void main(String[] args) throws Exception { try { if ((args.length == 2 || args.length == 3) && args[0].equals("list")) { String query = ""; if (args.length == 3) query = args[2]; list(query, getAnimalSubclass(args[1]), false); return; } if (args.length == 3 && args[0].equals("details")) { list(args[2], getAnimalSubclass(args[1]), true); return; } if (args.length == 3 && args[0].equals("remove")) { remove(args[2], getAnimalSubclass(args[1])); return; } if (args.length == 4 && args[0].equals("add")) { add(getAnimalSubclass(args[1]), args[2], args[3]); return; } } catch (ClassNotFoundException cnfe) { System.out.println("Error: tutorial.jdo." + args[1] + " does not" + " exist. Ensure that this class is compiled, and retry."); } // If we get here, something went wrong. System.out.println("Usage:"); System.out.println(" java tutorial.jdo.AnimalMaintenance list" + " 'class' ['query']"); System.out.println(" java tutorial.jdo.AnimalMaintenance details" + " 'class' 'query'"); System.out.println(" java tutorial.jdo.AnimalMaintenance remove" + " 'class' 'query'"); System.out.println(" java tutorial.jdo.AnimalMaintenance add Dog" + " 'name' 'price'"); System.out.println(" java tutorial.jdo.AnimalMaintenance add Snake" + " 'name' 'length'"); System.out.println(" java tutorial.jdo.AnimalMaintenance add Rabbit" + " 'name' 'isFemale'"); System.out.println(); System.out.println(" 'query' is a JDO query string identifying " + "the animals to act upon"); System.out.println(" 'class' is the Animal subclass to query on."); } /** * Looks up the class specified by clsName. This class must * be one of Dog, Rabbit, Snake, and Animal. */ private static Class getAnimalSubclass(String clsName) throws ClassNotFoundException { if (!clsName.startsWith("tutorial.jdo.")) clsName = "tutorial.jdo." + clsName; if (!clsName.equals("tutorial.jdo.Dog") && !clsName.equals("tutorial.jdo.Rabbit") && !clsName.equals("tutorial.jdo.Snake") && !clsName.equals("tutorial.jdo.Animal")) { throw new IllegalArgumentException ("Error: " + clsName + " is not a legal type of animal. " + "Animal types are limited to \"Dog\", \"Rabbit\", " + "\"Animal\", and \"Snake\"."); } return Class.forName(clsName); } }