-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 
Author Message
 Post subject: XMLDatabinder class not in hibernate 3
PostPosted: Thu Apr 06, 2006 8:30 pm 
Newbie

Joined: Tue Apr 13, 2004 12:02 am
Posts: 12
hi, guys,

I am a hibernate lover from vesion 2.

per the hibernate 3 has been realesed, I found net.sf.hibernate.xml
pacakage and XMLDatabinder class disappeared.

I think it should be useful sometimes and it is better to keep this
functionality.

moreover, attached my own ReverseXMLDatabinder.java, it convert xml to
hibernate java object.

it is working for 2.14

hope a little help.

glen

package export.util;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.MappingException;
import net.sf.hibernate.collection.CollectionPersister;
import net.sf.hibernate.engine.SessionFactoryImplementor;
import net.sf.hibernate.engine.SessionImplementor;
import net.sf.hibernate.metadata.ClassMetadata;
import net.sf.hibernate.persister.ClassPersister;
import net.sf.hibernate.type.ComponentType;
import net.sf.hibernate.type.DateType;
import net.sf.hibernate.type.PersistentCollectionType;
import net.sf.hibernate.type.TimestampType;
import net.sf.hibernate.type.Type;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.DocumentHelper;
import export.entity.log.ActionLog;
import java.io.Serializable;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
*
* <ul>
* <li>Convert hibernate generic xml to object with bi-direction link as
* hibernate format.
* </ul>
*
* @author glen.xin.guo@gmail.com
* @version 0.1
*/
public class ReverseXMLDatabinder {
private List objects = new ArrayList();
public Map objectsMap = new HashMap();
private SessionFactoryImplementor factory;
private SessionImplementor session;
private String fullyQualifiedClassName;
private final static Logger log = Logger
.getLogger(ReverseXMLDatabinder.class);
/**
* Public construct.
*
* @param factory
* @param session
*/
public ReverseXMLDatabinder(SessionFactoryImplementor factory,
SessionImplementor session) {
this.factory = factory;
this.session = session;
}
/**
* Return a List container holds object
*
* @return java.util.List
*/
public List getObjects() {
return objects;
}
/*
* get PK of object
*/
private Object getId(Element element, Object parentObj)
throws ClassNotFoundException, HibernateException,
InstantiationException, IllegalAccessException, DBUtilException {
Object id = null;
Class clazz = getClassForElement(element, "class", "package");
ClassPersister persister = getPersister(clazz);
Object obj = null;
//ID (composite ids not supported atm)
Type idType = persister.getIdentifierType();
String idStrValue = element.elementText("id");
//no id property, try composite id
if (idStrValue == null) {
Element compositeIdElement = element.element("composite-id");
if (compositeIdElement != null) {
List propertiesOfCompositeIdElement = compositeIdElement
.elements("property");
int compositeId_size = propertiesOfCompositeIdElement.size();
String[] compositeIdValueStr = new String[compositeId_size];
String[] compositeIdPropertyName = new String[compositeId_size];
for (int i = 0; i < compositeId_size; i++) {
Element propertyOfCompositeIdElement = (Element) propertiesOfCompositeIdElement
.get(i);
compositeIdValueStr[i] = propertyOfCompositeIdElement
.getText();
compositeIdPropertyName[i] = propertyOfCompositeIdElement
.attributeValue("name");
}
Object[] propertyValuesOfCompositeId = new Object[propertiesOfCompositeIdElement
.size()];
Type[] subtypes = ((ComponentType) idType).getSubtypes();
for (int i = 0; i < subtypes.length; i++) {
Type subtype = subtypes[i];
if (!subtype.isEntityType()) {
String valueStr = GetValueStrInCompositeId(
compositeIdValueStr, compositeIdPropertyName,
compositeIdPropertyName[i]);
propertyValuesOfCompositeId[i] = fromXml(subtype,
valueStr);
} else {
//recursion getId
if (parentObj == null) {
Element temp_element = (Element) (propertiesOfCompositeIdElement
.get(i));
Object temp_id = getId(temp_element, null);
Class temp_clazz = getClassForElement(temp_element,
"class", "package");
ClassPersister temp_persister = getPersister(temp_clazz);
//ID (composite ids not supported atm)
Type temp_idType = persister.getIdentifierType();
parentObj = addObjectOrGetExisting(temp_persister,
temp_id, temp_idType, temp_clazz);
}
propertyValuesOfCompositeId[i] = parentObj;
}
}
Class id_clazz = getClassForElement(compositeIdElement,
"class", "");
Object composite_id = id_clazz.newInstance();
((ComponentType) idType).setPropertyValues(composite_id,
propertyValuesOfCompositeId);
id = composite_id;
}
} else {
id = idStrValue;
}
return id;
}
/**
* Main function method to process data xml and convert it to object within
* hibernate session!
*
* @param xmlData
* @throws ClassNotFoundException
* @throws HibernateException
* @throws InstantiationException
* @throws IllegalAccessException
* @throws DocumentException
* @throws DBUtilException
*/
public void fromXML(String xmlData) throws ClassNotFoundException,
HibernateException, InstantiationException, IllegalAccessException,
DocumentException, DBUtilException {
List xmlValidationErrorsList = new ArrayList();
SAXReader reader = new SAXReader();
Document doc = DocumentHelper.parseText(xmlData);
Element root = doc.getRootElement();
Iterator iter = root.elementIterator();
while (iter.hasNext()) {
Element element = (Element) iter.next();
Object id = getId(element, null);
Class clazz = getClassForElement(element, "class", "package");
ClassPersister persister = getPersister(clazz);
Object obj = null;
//ID (composite ids not supported atm)
Type idType = persister.getIdentifierType();
obj = addObjectOrGetExisting(persister, id, idType, clazz);
//PROPERTIES
List properties = element.elements("property");
if (properties.size() > 0)
log.debug("processing properties for "
+ fullyQualifiedClassName);
for (int i = 0; i < properties.size(); i++) {
Element propertyElement = (Element) properties.get(i);
//log.debug("###############################");
//log.debug("time is "+propertyElement.attributeValue("time"));
setProperty(obj, persister, propertyElement);
}
//COLLECTIONS
List collections = element.elements("collection");
if (collections.size() > 0)
log.debug("processing collections for "
+ fullyQualifiedClassName);
for (int i = 0; i < collections.size(); i++) {
Element collectionElement = (Element) collections.get(i);
setProperty(obj, persister, collectionElement);
}
}
}
private String GetValueStrInCompositeId(String[] compositeIdValueStr,
String[] compositeIdPropertyName, String propertyName) {
String value = "";
for (int i = 0; i < compositeIdPropertyName.length; i++) {
if (propertyName != null
&& propertyName.equals(compositeIdPropertyName[i])) {
value = value.concat(compositeIdValueStr[i]);
break;
}
}
return value;
}
private Class getClassForElement(Element element,
String classAttributeName, String packageAttributeName)
throws ClassNotFoundException, DBUtilException {
String className = element.attributeValue(classAttributeName);
/*
* if(className == null){ log.fatal("className is null. check
* Bi-direction!!!"); throw new DBUtilException("className is null.
* check Bi-direction!!!"); }
*/
fullyQualifiedClassName = "";
if (packageAttributeName != null && packageAttributeName.length() > 0) {
String packageName = element.attributeValue(packageAttributeName);
fullyQualifiedClassName += packageName + ".";
}
fullyQualifiedClassName += className;
Class clazz = Class.forName(fullyQualifiedClassName);
return clazz;
}
/*
* add Object Or Get Existing from object map
*/
private Object addObjectOrGetExisting(ClassPersister persister,
Object rawIdValue, Type idType, Class clazz)
throws HibernateException, IllegalAccessException,
InstantiationException, DBUtilException {
if (rawIdValue == null) {
return clazz.newInstance();
}
Object obj = null;
if (persister.hasIdentifierPropertyOrEmbeddedCompositeIdentifier()) {
Object idValue = null;
ClassAndIdPair classAndIdPair = null;
if (persister.hasIdentifierProperty()) {
if (persister.getIdentifierType() instanceof ComponentType) {
idValue = rawIdValue;
} else {
idValue = fromXml(idType, (String) rawIdValue);
}
}
//???????????????????/
//else if (persister.getIdentifierType() instanceof ComponentType)
//{
// idValue = rawIdValue;
//}
classAndIdPair = new ClassAndIdPair(clazz, idValue);
obj = objectsMap.get(classAndIdPair);
if (obj == null) {
if (persister.hasIdentifierProperty()) {
log.debug("Load class " + fullyQualifiedClassName);
try {
obj = session.get(clazz, (Serializable) idValue);
//not in DB, so create new obj
if (obj == null) {
obj = session.instantiate(clazz,
(Serializable) idValue);
log.debug("class " + fullyQualifiedClassName
+ " not found! create new!");
}
} catch (net.sf.hibernate.TransientObjectException e) {
log.debug("NO WORRIES??? net.sf.hibernate.TransientObjectException: "
+ e.getMessage());
// not in DB, so create new obj
if (obj == null) {
obj = session.instantiate(clazz,
(Serializable) idValue);
log.debug("class " + fullyQualifiedClassName
+ " not found! create new!");
}
}
if (session.contains(obj))
log.debug("fullyQualifiedClassName: "
+ fullyQualifiedClassName + " in DB!");
} else {
log.debug("it is woking? for NO PK class");
obj = clazz.newInstance();
}
/*
* ? should move to line 271? what is useful? if
* (persister.hasIdentifierProperty()) { log.info("it is
* woking?"); persister.setIdentifier(obj,
* (Serializable)idValue); }
*/
objects.add(obj);
objectsMap.put(classAndIdPair, obj);
}
} else {
//? just to be on the safe side
obj = clazz.newInstance();
}
return obj;
}
private void setProperty(Object obj, ClassPersister persister,
Element propertyElement) throws HibernateException,
ClassNotFoundException, IllegalAccessException,
InstantiationException, DBUtilException {
String propertyName = propertyElement.attributeValue("name");
String propertyValueStr = propertyElement.getText();
Type type = persister.getPropertyType(propertyName);
if (type.isPersistentCollectionType()) {
log.debug("Load collection " + propertyName);
Collection collection = (Collection) ((ClassMetadata) persister)
.getPropertyValue(obj, propertyName);
if (collection != null)
log.debug(propertyName + " collection size load from DB: "
+ collection.size());
if (collection == null) {
log.debug("colletion is null");
CollectionPersister collectionPersister = session.getFactory()
.getCollectionPersister(
((PersistentCollectionType) type).getRole());
collection = (Collection) ((PersistentCollectionType) type)
.instantiate(session, collectionPersister);
//collection =
// (Collection)((PersistentCollectionType)type).getCollection(persister.getIdentifier(obj),
// obj, session);
//latest Hibernate code seems to be broken, a hack:
if (collection instanceof java.util.Set) {
collection = new java.util.HashSet();
} else if (collection instanceof java.util.List) {
collection = new java.util.ArrayList();
}
((ClassMetadata) persister).setPropertyValue(obj, propertyName,
collection);
}
List elements = propertyElement.elements("element");
log.debug(propertyName + " element size from xml is: "
+ elements.size());
boolean deleteFlag = true;
/*
* for the collection of actionlogs and sadreasons, deleteFlag will
* be always false forever!
*/
if (propertyName.equalsIgnoreCase("actionlogs"))
deleteFlag = false;
if (deleteFlag && propertyName.equalsIgnoreCase("actionlogs")) {
throw new DBUtilException("delete flag is wrong !");
}
//if no child in collection, so clear all
if (elements.size() == 0 && deleteFlag)
collection.clear();
String elemXml[] = new String[elements.size()];
for (int i = 0; i < elements.size(); i++) {
Element elementElement = (Element) elements.get(i);
Object elementId = getId(elementElement, obj);
Class elementClazz = getClassForElement(elementElement,
"class", "package");
ClassPersister elementPersister = getPersister(elementClazz);
Type elementIdType = elementPersister.getIdentifierType();
Object element = addObjectOrGetExisting(elementPersister,
elementId, elementIdType, elementClazz);
if (deleteFlag && !propertyName.equalsIgnoreCase("actionlogs"))
elemXml[i] = parseStr(element.toString());
/*if (propertyName.equalsIgnoreCase("actionlogs")
&& element instanceof ActionLog) {
ActionLog al = (ActionLog) element;
if (al.getComp_id().getTime() == null) {
log.info("ActionLogtime is null!!!!!!!!!!!!");
al.getComp_id().setTime(
Calendar.getInstance().getTime());
}
}*/
if (collection.add(element))
log.debug("add new element done: " + element.toString());
}
/*
* for delete orphan child in collection except SadReason,Actionlog!
*/
if (elements.size() < collection.size() && elements.size() != 0
&& deleteFlag) {
log.debug("############################################");
log.debug("###Load collection: " + propertyName);
log.debug("for delete orphan child in collection!");
log
.debug("In xml, "
+ elements.size()
+ " child in should be left in collection after remove!");
Object[] o = collection.toArray();
log.debug("collection size before delete is " + o.length);
long collSizeAfterAdd = collection.size();
for (int j = 0; j < collSizeAfterAdd; j++) {
log.debug("processing NO." + j + " obj in collection!");
boolean found = false;
for (int k = 0; k < elements.size(); k++) {
String str = parseStr(o[j].toString());
log.debug("str length: " + str.length());
log.debug("Xml length: " + elemXml[k].length());
//if found in elements,, then keep in collection,
//otherwise, remove from collection
if (str.equalsIgnoreCase(elemXml[k])) {
log.debug("found collection " + j + " in element!");
log.debug("elemStr: " + elemXml[k]);
log.debug("collstr: " + str);
found = true;
break;
}
}
if (!found) {
log.debug("remove " + j + " child!");
log.debug("delete obj in DB: "
+ parseStr(o[j].toString()));
collection.remove(o[j]);
}
}
log.debug("after delete child, collection size: "
+ collection.size());
if (collection.size() != elements.size()) {
log.fatal("###############delete orphan children is wrong !");
throw new DBUtilException(
"delete orphan children is wrong !");
}
}
if (collection.size() != elements.size() && deleteFlag) {
log
.fatal("###############processing collection wrong!");
throw new DBUtilException("processing collection wrong!");
}
} else if (type.isEntityType()) {
//To be ensure!!!!
String entityIdStr = propertyElement.elementText("id");
//String entityIdStr = propertyElement.attributeValue("id");
if (entityIdStr != null) {
Class entityClazz = getClassForElement(propertyElement, "type",
null);
ClassPersister entityPersister = getPersister(entityClazz);
Type entityIdType = entityPersister.getIdentifierType();
Object propertyValue = addObjectOrGetExisting(persister,
entityIdStr, entityIdType, entityClazz);
((ClassMetadata) persister).setPropertyValue(obj, propertyName,
propertyValue);
}
} else {
Object propertyValue = fromXml(type, propertyValueStr);
((ClassMetadata) persister).setPropertyValue(obj, propertyName,
propertyValue);
}
}
/**
* @todo: correct TimestampType and DateType's fromString() to use the same format of the corresponding toString()
*/
private Object fromXml(Type idType, String str) throws HibernateException,
DBUtilException {
if (idType instanceof TimestampType) {
if (str.length() == 0)
throw new DBUtilException("Timestamp is null! ");
try {
if (str != null && str.trim().length() > 0) {
//1989-06-04 11:11:11.0
log.debug("TimestampType ActionLog time: " + new SimpleDateFormat("dd MMMM yyyy HH:mm:ss")
.parse(str));
return new SimpleDateFormat("dd MMMM yyyy HH:mm:ss")
.parse(str);
} else {
return null;
}
} catch (ParseException e) {
return null;
}
} else if (idType instanceof DateType) {
try {
if (str != null && str.trim().length() > 0) {
log.debug("Date ActionLog Time: "
+ new SimpleDateFormat("dd MMMM yyyy").parse(str));
return new SimpleDateFormat("dd MMMM yyyy").parse(str);
} else {
return null;
}
} catch (ParseException e) {
return null;
}
} else {
return idType.fromString(str);
}
}
private ClassPersister getPersister(Class clazz) throws MappingException {
return factory.getPersister(clazz);
}
//for get value part from class.toString
private String parseStr(String str) {
str = str.trim();
int index = str.indexOf("[");
str = str.substring(index);
index = str.indexOf("[");
str = str.substring(index + 1);
index = str.indexOf("[");
return str.substring(index);
}
private static final class ClassAndIdPair {
public Class clazz;
public Object id;
public ClassAndIdPair(Class clazz, Object id) {
this.clazz = clazz;
this.id = id;
}
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(this, obj);
}
public int hashCode() {
return clazz.getName().hashCode()
+ (id != null ? id.hashCode() : 0);
}
}
}


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.