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);
}
}