package org.drools.shapes.xsd;
import com.sun.org.apache.xpath.internal.operations.Mod;
import org.drools.runtime.StatefulKnowledgeSession;
import org.drools.runtime.rule.FactHandle;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlElements;
import javax.xml.bind.annotation.XmlType;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
public class Jaxplorer {
private static Map<Class, Collection<String>> declaredCache = new HashMap<Class, Collection<String>>();
private Object root;
private Collection<FactHandle> handles = new LinkedList<FactHandle>();
public Jaxplorer( Object root ) {
this.root = root;
}
public void deepInsert( StatefulKnowledgeSession kSession ) {
deepInsert( root, kSession );
}
protected void deepInsert( Object o, StatefulKnowledgeSession kSession ) {
if ( o instanceof JAXBElement ) {
kSession.insert( o );
deepInsert( ((JAXBElement) o).getValue(), kSession );
}
XmlType xmlType = o.getClass().getAnnotation( XmlType.class );
if ( xmlType != null ) {
handles.add( kSession.insert( o ) );
for ( String fname : getAllXmlFields(o) ) {
try {
if ( fname.startsWith( "_" ) ) {
fname = fname.substring( 1 );
}
String getterName = "get" + fname.substring( 0, 1 ).toUpperCase() + fname.substring( 1 );
Method getter = o.getClass().getMethod( getterName );
Object fieldVal = getter.invoke( o );
if ( fieldVal instanceof Collection ) {
for ( Object x : (Collection) fieldVal ) {
deepInsert( x, kSession );
}
} else {
if ( fieldVal != null ) {
deepInsert( fieldVal, kSession );
}
}
} catch ( IllegalAccessException e ) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
public void deepRetract( StatefulKnowledgeSession kSession ) {
for ( FactHandle h : handles ) {
kSession.retract( h );
}
}
private Collection<String> getAllXmlFields( Object o ) {
if ( declaredCache.containsKey( o.getClass() ) ) {
return declaredCache.get( o.getClass() );
}
List<String> fieldNames = new LinkedList<String>();
Class x = o.getClass();
while ( ! x.equals( Object.class ) ) {
XmlType xmlType = (XmlType) x.getAnnotation( XmlType.class );
if ( xmlType != null && xmlType.propOrder().length > 0 && ! xmlType.propOrder()[0].isEmpty() ) {
fieldNames.addAll( Arrays.asList( xmlType.propOrder() ) );
}
x = x.getSuperclass();
}
// System.out.println( "Class " + o.getClass() );
// for ( String s : fieldNames ) {
// System.out.println( "\t >> " + s );
// }
declaredCache.put( o.getClass(), fieldNames );
return fieldNames;
}
}