package tutorial.persistence; import java.lang.reflect.*; import java.util.*; import javax.persistence.*; /** * 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 em the EntityManager to obtain the query from * @param filter the JPQL filter to apply to the query */ public static List getAnimals(String filter, EntityManager em) { System.out.println ("*** getAnimals method will be implemented in Chapter III ***"); return Collections.EMPTY_LIST; } /** * Performs the actual JPA work of putting object * into the data store. * * @param object the object to persist in the data store */ public static void persistObject(EntityManager em, Object object) { System.out.println ("*** persistObject method will be implemented in Chapter III ***"); } /** * Performs the actual JPA work of removing objects * from the data store. * * @param em the EntityManager to delete with * @param objects the objects to persist in the data store */ public static void deleteObjects(Collection objects, EntityManager em) { System.out.println ("*** deleteObject method will be implemented in Chapter III ***"); } /////////////////////////////////////////////////////////////// // 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 em the EntityManager to use * @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(EntityManager em, 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(em, 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 em the EntityManager to use * @param query the filter to use when finding animals to remove */ public static void remove(EntityManager em, String query) { // don't allow removing all animals if (query.trim().length() == 0) { System.out.println("Error: cannot remove all animals. Please " + "provide a query."); return; } List animals = getAnimals(query, em); if (animals.isEmpty()) { System.out.println("No animal matching '" + query + "' found in entity manager."); } else deleteObjects(animals, em); } /** * Prints out a description of all the animals that match * query. * * @param em the EntityManager to use * @param query the filter to use when finding animals to list * @param detailed if true, display details about * each animal identified by query; * else, print out terse info only */ public static void list(EntityManager em, String query, boolean detailed) { List animals = getAnimals(query, em); if (animals.size() == 0) { System.out.println("No animal matching '" + query + "' found in entity manager."); } else { for (Animal animal : animals) System.out.println(animal.toString(detailed)); } } public static void main(String[] args) throws Exception { EntityManagerFactory emf = Persistence. createEntityManagerFactory(null); EntityManager em = emf.createEntityManager(); try { if (args.length == 2 && args[0].equals("list")) { String query; if (args[1].startsWith("select ") || args[1].startsWith("SELECT ")) query = args[1]; else query = "select a from " + args[1] + " a"; list(em, query, false); return; } if (args.length == 2 && args[0].equals("details")) { list(em, args[1], true); return; } if (args.length == 2 && args[0].equals("remove")) { remove(em, args[1]); return; } if (args.length == 4 && args[0].equals("add")) { add(em, getAnimalSubclass(args[1]), args[2], args[3]); return; } } catch (ClassNotFoundException cnfe) { System.out.println("Error: tutorial.persistence." + args[1] + " does not exist. Ensure that this class is compiled," + " and retry."); } finally { if (em.getTransaction().isActive()) em.getTransaction().rollback(); em.close(); emf.close(); } // If we get here, something went wrong. System.out.println("Usage:"); String cname = AnimalMaintenance.class.getName(); System.out.println(" java " + cname + " list <'class'|'query'>"); System.out.println(" java " + cname + " details 'query'"); System.out.println(" java " + cname + " remove 'query'"); System.out.println(" java " + cname + " add Dog" + " 'name' 'price'"); System.out.println(" java " + cname + " add Snake" + " 'name' 'length'"); System.out.println(" java " + cname + " add Rabbit" + " 'name' 'isFemale'"); System.out.println(); System.out.println(" 'query' is a JPQL 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.persistence.")) clsName = "tutorial.persistence." + clsName; if (!clsName.equals("tutorial.persistence.Dog") && !clsName.equals("tutorial.persistence.Rabbit") && !clsName.equals("tutorial.persistence.Snake") && !clsName.equals("tutorial.persistence.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); } }