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) {
System.out.println
("*** getAnimals method will be implemented in Chapter III ***");
return Collections.EMPTY_LIST;
}
/**
* 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) {
System.out.println
("*** persistObject method will be implemented in Chapter III ***");
}
/**
* 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) {
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 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();
Collection animals = getAnimals(query, cls, pm);
if (animals.size() == 0) {
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();
List animals = getAnimals(query, cls, pm);
if (animals.isEmpty()) {
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." + 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);
}
}