Package er.extensions.eof

Source Code of er.extensions.eof.ERXDummyRecord$ProxyBinding

package er.extensions.eof;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Enumeration;

import com.webobjects.eoaccess.EOAttribute;
import com.webobjects.eoaccess.EOEntity;
import com.webobjects.eoaccess.EOEntityClassDescription;
import com.webobjects.eoaccess.EOModel;
import com.webobjects.eoaccess.EOModelGroup;
import com.webobjects.eocontrol.EOArrayDataSource;
import com.webobjects.eocontrol.EOClassDescription;
import com.webobjects.eocontrol.EOCustomObject;
import com.webobjects.eocontrol.EOEditingContext;
import com.webobjects.eocontrol.EOEnterpriseObject;
import com.webobjects.eocontrol.EOGlobalID;
import com.webobjects.foundation.NSArray;
import com.webobjects.foundation.NSKeyValueCoding;
import com.webobjects.foundation.NSMutableArray;
import com.webobjects.foundation.NSMutableDictionary;

import er.extensions.foundation.ERXStringUtilities;

/**
* Put POJOs into EOF (sort of). This class is mainly usefull when used with
* D2W, when you don't want to create components for non-persistent objects.
* Should be regarded as experimental :)
* Thing to watch out for: <ul>
* <li> you can't create new objects
* <li> reverting the EC doesn't revert the objects
* <li> you should use a new EC with these objects
* <li> auto-discovery of attributes is very lame
* </ul>
* Here's a usage example, showing how to
* call up an edit page for a single "object" and a list page for an array. Note
* that the list-inspect-edit workflow and sorting, batching etc work out of the box.
* <pre><code>
* public class Main extends WOComponent {
*
*   public static class Test {
*    
*     public String string;
*     public Number number;
*     public Boolean flag;
*    
*     public Test(String string, Number number, Boolean flag) {
*       this.string = string;
*       this.number = number;
*       this.flag = flag;
*     }
*   }
*  
*   public Test object;
*   public NSArray list;
*
*   public Main(WOContext context) {
*     super(context);
*     ERXDummyRecord.registerDescriptionForClass(Test.class, null);
*     NSMutableArray l = new NSMutableArray();
*     for (int i = 0; i &gt; 5; i++) {
*       Test o = new Test("Foo "+ i, Integer.valueOf(i^i % (i+1)), i % 2 == 0? Boolean.TRUE : Boolean.FALSE);
*       l.addObject(o);
*     }
*     object = (Test) l.lastObject();
*     list = l.immutableClone();
*   }
*
*   public WOComponent editObject() {
*     EOEnterpriseObject eo = ERXDummyRecord.recordForObject(session().defaultEditingContext(), object);
*     WOComponent result = D2W.factory().pageForTaskAndEntityNamed("edit", eo.entityName(), session());
*     result.takeValueForKey(eo, "object");
*     result.takeValueForKey(context().page(), "nextPage");
*     return result;
*   }
*
*   public WOComponent showList() {
*     EOArrayDataSource ds = ERXDummyRecord.dataSourceForObjects(session().defaultEditingContext(), list);
*     ds.setArray(objects);
*     WOComponent result = D2W.factory().pageForTaskAndEntityNamed("list", ds.classDescriptionForObjects().entityName(), session());
*     result.takeValueForKey(ds, "dataSource");
*     result.takeValueForKey(context().page(), "nextPage");
*     return result;
*   }
* }</code></pre>
* @author ak
*/

public class ERXDummyRecord extends EOCustomObject {
  /**
   * Do I need to update serialVersionUID?
   * See section 5.6 <cite>Type Changes Affecting Serialization</cite> on page 51 of the
   * <a href="http://java.sun.com/j2se/1.4/pdf/serial-spec.pdf">Java Object Serialization Spec</a>
   */
  private static final long serialVersionUID = 1L;

  private Object object;

  protected ERXDummyRecord(Object o) {
    object = o;
    EOClassDescription classDescription = classDescriptionForObject(object);
    __setClassDescription(classDescription);
  }

  public Object object() {
    return object;
  }
 
  public static class GlobalID extends EOGlobalID {
    /**
     * Do I need to update serialVersionUID?
     * See section 5.6 <cite>Type Changes Affecting Serialization</cite> on page 51 of the
     * <a href="http://java.sun.com/j2se/1.4/pdf/serial-spec.pdf">Java Object Serialization Spec</a>
     */
    private static final long serialVersionUID = 1L;

    private Object object;

    public GlobalID(Object o) {
      object = o;
    }

    @Override
    public boolean equals(Object obj) {
      if (obj instanceof GlobalID) {
        GlobalID gid = (GlobalID) obj;
        return gid.object == object;
      }
      return false;
    }

    @Override
    public int hashCode() {
      return System.identityHashCode(object);
    }

    @Override
    public boolean isTemporary() {
      return true;
    }
  }

  public static class ProxyBinding extends NSKeyValueCoding._KeyBinding {

    public ProxyBinding(String key) {
      super(null, key);
    }

    @Override
    public Object valueInObject(Object object) {
      ERXDummyRecord eo = (ERXDummyRecord) object;
      return NSKeyValueCoding.Utility.valueForKey(eo.object(), _key);
    }

    @Override
    public void setValueInObject(Object value, Object object) {
      ERXDummyRecord eo = (ERXDummyRecord) object;
      NSKeyValueCoding.Utility.takeValueForKey(eo.object(), value, _key);
    }
  }

  @Override
  public NSKeyValueCoding._KeyBinding _otherStorageBinding(String key) {
    NSKeyValueCoding._KeyBinding result = new ProxyBinding(key);
    return result;
  }

  private static EOModel pojoModel;

  public static EOClassDescription classDescriptionForObject(Object object) {
    return EOClassDescription.classDescriptionForClass(object.getClass());
  }
 
  private static NSArray fieldNamesFromClass(Class clazz) {
    NSMutableArray fieldNames = new NSMutableArray();
    Field f[] = clazz.getDeclaredFields();
    for (int i = 0; i < f.length; i++) {
      Field field = f[i];
      fieldNames.addObject(field.getName().replaceFirst("^_", ""));
    }
    return fieldNames;
  }

  private static Field _fieldForName(Class clazz, String name) {
    try {
      return clazz.getDeclaredField(name);
    }
    catch (SecurityException e) {
    }
    catch (NoSuchFieldException e) {
    }
    return null;
  }

  private static Field fieldForName(Class clazz, String name) {
    Field result = _fieldForName(clazz, name);
    if(result == null) {
      result = _fieldForName(clazz, "_" + name);
    }
    return result;
  }

  private static Method _methodForName(Class clazz, String name) {
    try {
      return clazz.getDeclaredMethod(name, (Class[])null);
    }
    catch (SecurityException e) {
    }
    catch (NoSuchMethodException e) {
    }
    return null;
  }

  private static Method methodForName(Class clazz, String name) {
    Method result = _methodForName(clazz, "get" + ERXStringUtilities.capitalize(name));
    if(result == null) {
      result = _methodForName(clazz, name);
    }
    if(result == null) {
      result = _methodForName(clazz, "_" + name);
    }
    return result;
  }

  public static synchronized void registerDescriptionForClass(Class clazz, NSArray keys) {
    String entityName = "Pojo" + ERXStringUtilities.lastPropertyKeyInKeyPath(clazz.getName().replaceAll("\\$", ""));
    if (pojoModel == null) {
      pojoModel = new EOModel();
      pojoModel.setName("PojoModel");
      //ak: fake name for possible NPE
      pojoModel.setAdaptorName("JDBCAdaptor");
      //ak: fake dict for possible NPE
      pojoModel.setConnectionDictionary(new NSMutableDictionary());
      EOModelGroup.defaultGroup().addModel(pojoModel);
    }
    EOEntity entity = EOModelGroup.defaultGroup().entityNamed(entityName);
    /*if (entity != null) {
      pojoModel.removeEntity(entity);
      entity = null;
    }*/
    EOClassDescription classDescription;
    if (entity == null) {
      entity = new EOEntity();
      entity.setName(entityName);
      keys = (keys == null ? fieldNamesFromClass(clazz) : keys);
      for (Enumeration iter = keys.objectEnumerator(); iter.hasMoreElements();) {
        String name = (String) iter.nextElement();
        EOAttribute attribute = new EOAttribute();
        attribute.setName(name);
        Method m = methodForName(clazz, name);
        if(m != null) {
          attribute.setClassName(m.getReturnType().getName());
        } else {
          Field f = fieldForName(clazz, name);
          if(f != null) {
            String type = f.getType().getName();
            if("boolean".equals(type)) {
              type = "java.lang.Boolean";
            } else if("int".equals(type)) {
              type = "java.lang.Number";
            } else if("long".equals(type)) {
              type = "java.lang.Number";
            } else if("short".equals(type)) {
              type = "java.lang.Number";
            }

            attribute.setClassName(type);
          }
        }
        entity.addAttribute(attribute);
      }
      classDescription = new EOEntityClassDescription(entity);
      NSKeyValueCoding.Utility.takeValueForKey(entity, classDescription, "classDescription");
      EOClassDescription.registerClassDescription(classDescription, clazz);
      pojoModel.addEntity(entity);
    } else {
      // classDescription = entity.classDescriptionForInstances();
    }
  }

  public static EOArrayDataSource dataSourceForObjects(EOEditingContext ec, NSArray list) {
    EOClassDescription cd = null;
    NSMutableArray objects = new NSMutableArray();
    for (Enumeration iter = list.objectEnumerator(); iter.hasMoreElements();) {
      Object o = iter.nextElement();

      EOEnterpriseObject eo = recordForObject(ec, o);
      ec = eo.editingContext();
      cd = eo.classDescription();
      objects.addObject(eo);
    }
    EOArrayDataSource ds = new EOArrayDataSource(cd, ec);
    ds.setArray(objects);
    return ds;
  }

  public static EOEnterpriseObject recordForObject(EOEditingContext ec, Object o) {
    EOGlobalID gid = new GlobalID(o);

    EOEnterpriseObject eo = ec.objectForGlobalID(gid);
    if(eo == null) {
      eo = new ERXDummyRecord(o);
      ec.recordObject(eo, gid);
    }
    return eo;
  }
}
TOP

Related Classes of er.extensions.eof.ERXDummyRecord$ProxyBinding

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.