package fgis.server.support.jpa;

import java.lang.reflect.Field;
import java.util.Map;
import java.util.Vector;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.DirectToFieldMapping;
import org.eclipse.persistence.mappings.converters.Converter;
import org.eclipse.persistence.mappings.converters.SerializedObjectConverter;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.sessions.SessionEvent;
import org.eclipse.persistence.sessions.SessionEventAdapter;
import org.geolatte.geom.Geometry;
import org.geolatte.geom.LineString;
import org.geolatte.geom.LinearRing;
import org.geolatte.geom.MultiLineString;
import org.geolatte.geom.MultiPoint;
import org.geolatte.geom.MultiPolygon;
import org.geolatte.geom.Point;
import org.geolatte.geom.Polygon;

public class ConverterInitializer
  extends SessionEventAdapter
{
  @Override
  public void preLogin( final SessionEvent event )
  {
    final Session session = event.getSession();
    final Map<Class, ClassDescriptor> descriptorMap = session.getDescriptors();

    // Walk through all descriptors...
    for ( final Map.Entry<Class, ClassDescriptor> entry : descriptorMap.entrySet() )
    {
      final ClassDescriptor desc = entry.getValue();
      final Vector<DatabaseMapping> mappings = desc.getMappings();
      // walk through all mappings for some class...
      for ( final DatabaseMapping mapping : mappings )
      {
        if ( mapping instanceof DirectToFieldMapping )
        {
          final DirectToFieldMapping dfm = (DirectToFieldMapping) mapping;
          if ( isCandidateConverter( dfm ) )
          {
            final Class type = entry.getKey();
            final String attributeName = dfm.getAttributeName();
            final Field field = getField( type, attributeName );
            final Class<?> fieldType = field.getType();
            if ( Point.class == fieldType ||
                 Polygon.class == fieldType ||
                 LineString.class == fieldType ||
                 MultiPoint.class == fieldType ||
                 MultiPolygon.class == fieldType ||
                 MultiLineString.class == fieldType ||
                 Geometry.class == fieldType ||
                 LinearRing.class == fieldType )
            {
              final Converter converter = new PostgisConverter();
              converter.initialize( mapping, session );
              dfm.setConverter( converter );
            }
          }
        }
      }
    }
  }

  private Field getField( final Class type, final String attributeName )
  {
    final Field field;
    try
    {
      field = type.getDeclaredField( attributeName );
    }
    catch ( final NoSuchFieldException nsfe )
    {
      throw new IllegalStateException( "Unable to find field: " + attributeName, nsfe );
    }
    return field;
  }

  // only consider mappings that are deemed to produce
  // byte[] database fields from objects...
  private boolean isCandidateConverter( final DirectToFieldMapping mapping )
  {
    final Converter converter = mapping.getConverter();
    return null != converter && converter instanceof SerializedObjectConverter;
  }
}
@@ -2658,27 +2658,64 @@
     
-final Field field;%0A
+Class t = type;%0A    while ( t != Object.class )%0A    %7B%0A  
     
@@ -2722,24 +2722,26 @@
 try%0A    
+ 
+ 
 %7B%0A      
 field = 
@@ -2736,20 +2736,18 @@
     
-field = type
+  return t
 .get
@@ -2778,26 +2778,30 @@
 Name );%0A    
-%7D%0A
+  %7D%0A  
     catch ( 
@@ -2834,28 +2834,88 @@
  nsfe )%0A    
+  
 %7B%0A  
+      //Ignore%0A      %7D%0A      t = t.getSuperclass();%0A    %7D%0A
     throw ne
@@ -2983,40 +2983,10 @@
 Name
-, nsfe );%0A    %7D%0A    return field
+ )
 ;%0A  

Support inheritance chains