package jeffaschenk.commons.parsers;
import jeffaschenk.commons.parsers.objects.ClassAnnotationData;
import jeffaschenk.commons.parsers.objects.mapping.MappingClass;
import jeffaschenk.commons.parsers.objects.mapping.MappingClasses;
import org.apache.commons.digester.Digester;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
/**
* ORM Parser to obtain the HIBERNATE ORM Mapping configuration and
* place into an accessible Object form.
* <p/>
* Used in Various Tools
*
* @author jeffaschenk@gmail.com
* @version $Id: $
*/
public class ORMParser {
// ***************************************
// Logging
/**
* Constant <code>log</code>
*/
protected static Log log = LogFactory.getLog(ORMParser.class);
// ****************************************
// System Property Defaults
public static final String defaultORMConfiguration = "hibernate-mapping.cfg.xml";
/**
* Default Protected and Secure Constructor.
*/
private ORMParser() {
}
/**
* This is a helper to the helper to use the Default
* ORM Configuration Mapping Resource.
*
* @return n array of {@link java.lang.Class} objects.
*/
public static final Class<?>[] getORMResourceBundle() {
return getORMResourceBundle(defaultORMConfiguration);
}
/**
* This helper method will read in the contents of the HIBERNATE Mapping
* Resource and parse all of the Mapped Class Names and in turn create an
* instantiated list of Classes for the Upstream Caller to perform
* annotation Parsing on those defined Mapped Classes.
*
* @param ormResourceName a {@link java.lang.String} object.
* @return an array of {@link java.lang.Class} objects.
*/
public static final Class<?>[] getORMResourceBundle(String ormResourceName) {
BufferedReader bisr = null;
Digester digester = null;
try {
// ******************************************
// Ensure we get our Thread ClassLoader.
// If we get the System ClassLoader and
// we are in a container, such as TOMCAT,
// we will not find our specific application
// Resource.
bisr = new BufferedReader(new InputStreamReader(Thread.currentThread().getContextClassLoader().getResourceAsStream(ormResourceName)));
digester = new Digester();
if (log.isTraceEnabled()) {
digester.setLogger(log);
}
digester.setValidating(false);
// *****************************
// Obtain Mapping Class Objects
digester.addObjectCreate("hibernate-configuration/session-factory",
MappingClasses.class);
digester.addObjectCreate(
"hibernate-configuration/session-factory/mapping",
MappingClass.class);
digester.addSetProperties(
"hibernate-configuration/session-factory/mapping", "class",
"name");
digester.addSetNext(
"hibernate-configuration/session-factory/mapping",
"addMappingClass",
"jeffaschenk.commons.parsers.objects.mapping.MappingClass");
// **********************************
// Parse the Resource Bundle.
MappingClasses mappingClasses = (MappingClasses) digester
.parse(bisr);
Class<?>[] objectModelClasses = new Class<?>[mappingClasses.getMappingClasses().size()];
// **********************************
// Show Mapping Classes.
int c = 0;
for (MappingClass mappingClass : mappingClasses.getMappingClasses()) {
try {
objectModelClasses[c] = Class.forName(mappingClass.getName());
} catch (ClassNotFoundException cnfe) {
log.warn("Unable to instantiate ClassName:[" + mappingClass.getName() + "], due to Class Not Found, will Ignore.");
}
c++;
} // End of For Each Loop.
// ***********************************************
// return our Class Array.
return objectModelClasses;
} catch (Exception e) {
log.error("Error Parsing ORM Configuration: " + e.getMessage(), e);
return null;
} finally {
digester = null;
if (bisr != null) {
try {
bisr.close();
} catch (IOException ioe) {
log.error(
"IO Exception Encountered while Closing ORM Resource Bundle: "
+ ioe.getMessage(), ioe);
}
}
}
}
/**
* Produces the Mapping by parsing the Class File Annotations.
*
* @param objectModelClasses an array of {@link java.lang.Class} objects.
* @return {@link java.util.Map} object.
*/
public static final Map<String, ClassAnnotationData> generateMapping(
Class<?>[] objectModelClasses) {
Map<String, ClassAnnotationData> mapping = new HashMap<String, ClassAnnotationData>();
if (objectModelClasses == null) {
return mapping;
}
// *****************************************
// Establish our Annotation Parser.
AnnotationParser ap = new AnnotationParser();
// *****************************************
// Iterate over all of the Class and
// use reflection to obtain Class and
// field Annotations.
for (Class<?> clazz : objectModelClasses) {
if (clazz == null) {
continue;
}
// ***********************************
// Obtain all Class annotations
ClassAnnotationData annotationData = ap.parse(clazz);
if (annotationData == null) {
continue;
}
// ***********************************
// Save Mapping Data For Lookup.
mapping.put(annotationData.getClassName(), annotationData);
} // End of ObjectClass For Each Loop.
// *****************************************
// Return the Mapping Object
return mapping;
}
}