|
|
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 2 of 3
ObjectFactory method implementation, with which the Startup class may instantiate a root object from any class. This is an important feature of the startup system. If your system structure
should be altered in the future, you need only implement a new root class and modify the configuration file to completely
revamp the system. This is an example of the usefulness of the Abstract Factory pattern (see Design Patterns, by Erich Gamma et al. in Resources). The only relevant method of the ObjectFactory, createObject performs five tasks (listed below) marked ### 1) - ### 5), as shown in the ObjectFactory.java code listing.
Class.forName() method.
createObject match those of the current constructor from (3), mark the constructor as an invocation candidate. If not, move to the next
declared constructor and try again.
// Copyright (c) 2000 jguru.com
// All rights reserved.
package com.jguru.initHandler;
import java.lang.reflect.Constructor;
/**
* Implementation of the ObjectFactory interface that
* creates instances of a given class using provided
* argument parameters.
*
* @author Lennart Jörelid, jGuru Europe
* @version $Id$
* @since January 2000
*/
public class SimpleObjectFactory implements ObjectFactory
{
/**
* Instantiates an object from the class given and with the
* provided arguments. Primitive arguments must be sent in
* their respective java.lang containers. (i.e., java.lang.Byte
* for a byte argument, java.lang.Integer for an int argument, etc.)
* <br>
* All exceptions thrown within the createObject method are
* type-shifted into a StartupException.
*
* @param className The fully qualified name of the class from which
* an object should be created.
* @param args The argument array to be fed to the constructor.
* @return The fully instantiated object.
* @exception com.jguru.initHandler.StartupException thrown if
* anything goes wrong in creating the object.
*/
public Object createObject(String className, Object args[])
throws StartupException
{
// The provided class and the constructor that should
// ultimately be invoked to create an object of the class.
Class theClass = null;
Constructor invocationCandidate = null;
Object toReturn = null;
// ### 1) Load the class and check sanity
try
{
theClass = Class.forName(className); catch(ClassNotFoundException ex)
{
throw new StartupException("[Startup createObject]: Could
not load class " + className);
}
// ### 2) Get the constructors of the declared class.
Constructor[] theConstructors = theClass.getConstructors();
// ### 3) Check number and type of arguments required for each
// found constructor in the loaded class.
outer: for(int i = 0; i < theConstructors.length; i++)
{
// Get the class of the arguments
Class[] constructorArgs = theConstructors[i].getParameterTypes
();
// If we have different argument lengths,
// the found constructor could not be called using the
// current parameter array. Skip to the next constructor.
if(args.length != constructorArgs.length)
continue outer;
// Is this a no-argument constructor?
if(args.length == 0)
{
invocationCandidate = theConstructors[i];break outer;
}
// ### 4) This constructor requires parameters.
// Loop through all provided parameters to verify
// that they match the required ones.
for(int j = 0; j < args.length; j++)
{
// Check if the constructor argument might be
// typecast into the proper class. This must be done for all
// primitive types, which must be encapsulated in their
java.lang.XXXX
// containers to be passed as part of an object[] array.
boolean matched = false;
if(constructorArgs[j].isPrimitive())
{
String primName = constructorArgs[j].getName();
String argName = args[j].getClass().getName();
if(primName.equals("byte") &&
argName.equals("java.lang.Byte")) matched = true;
if(primName.equals("short") &&
argName.equals("java.lang.Short")) matched = true;
if(primName.equals("int") &&
argName.equals("java.lang.Integer")) matched = true;
if(primName.equals("long") &&
argName.equals("java.lang.Long")) matched = true;
if(primName.equals("long") &&
argName.equals("java.lang.Integer")) matched = true;
if(primName.equals("float") &&
argName.equals("java.lang.Float")) matched = true;
if(primName.equals("double") &&
argName.equals("java.lang.Double")) matched = true;
if(primName.equals("char") &&
argName.equals("java.lang.Character")) matched = true;
if(primName.equals("boolean") &&
argName.equals("java.lang.Boolean")) matched = true;
if(!matched) continue outer;
}
if( !matched && (!args[j].getClass
().equals(constructorArgs[j]))) }
// We found the constructor to invoke.
// Check sanity, and assign the value to
// the invocationCandidate variable.
if(invocationCandidate != null)
{
// We should never wind up here....
throw new StartupException("[Startup createObject]:
Guru meditation; Found 2 " +
+ "constructors with same signature in class
" + theClass.getName());
}
// We found an invocation candidate, whose number and type of
arguments
// match the argument array provided to this method.
// Assign the constructor to the invocationCandidate variable.
invocationCandidate = theConstructors[i];
// Check sanity
if(invocationCandidate == null)
throw new StartupException("[Startup createObject]: Found no
constructor matching argument " +
+ " criteria in " + theClass.getName());
// ### 5) Sane. Invoke the constructor and return the object.
try
{
if(args.length == 0)
{
toReturn = theClass.newInstance();
}
else
{
toReturn = invocationCandidate.newInstance(args); }
catch(Exception ex)
{
// Despite all the testing, something was quite wrong here.
// Throw the proper exception from this method.
throw new StartupException("[Startup createObject]:
Invocation failed for object of type "
+ className + "(" + theClass.getName()
+ "), Exception: "
+ ex.getClass().getName() + " " +
ex.getMessage());
}
// All done. Return.
return toReturn;
}
public Object createObject(String className)
{
return createObject(className, new Object[]{});
}
}
Server-side Java: Read the whole series -archived on JavaWorld