001    package net.databinder.models.ao;
002    
003    import java.io.Serializable;
004    import java.lang.reflect.Method;
005    import java.util.HashMap;
006    import java.util.Map;
007    import java.util.Map.Entry;
008    
009    import org.apache.wicket.util.string.Strings;
010    
011    import net.databinder.ao.Databinder;
012    import net.databinder.models.BindingModel;
013    import net.databinder.models.LoadableWritableModel;
014    import net.java.ao.Common;
015    import net.java.ao.RawEntity;
016    import net.java.ao.schema.FieldNameConverter;
017    
018    @SuppressWarnings("unchecked")
019    public class EntityModel extends LoadableWritableModel implements BindingModel {
020            private Serializable id;
021            private Class entityType;
022            private Map<String, Object> propertyStore;
023            private Object managerKey;
024            
025            public EntityModel(Class entityType, Serializable id) {
026                    this(entityType);
027                    this.id = id;
028            }
029            
030            public EntityModel(Class entityType) {
031                    this.entityType = entityType;
032            }
033            
034            public EntityModel(RawEntity<?> entity) {
035                    setObject(entity);
036            }
037            
038            public boolean isBound() {
039                    return id != null;
040            }
041            
042            @Override
043            protected Object load() {
044                    if (isBound())
045                            return Databinder.getEntityManager(managerKey).get(entityType, id);
046                    return getPropertyStore();
047            }
048            
049            public void setObject(Object object) {
050                    unbind();
051                    RawEntity entity = (RawEntity) object;
052                    entityType = entity.getEntityType();
053                    id = (Serializable) Common.getPrimaryKeyValue(entity);
054                    setTempModelObject(entity);
055            }
056            
057            protected void putDefaultProperties(Map<String, Object> propertyStore) { }
058            
059            public void unbind() {
060                    id = null;
061                    propertyStore = null; 
062                    detach();
063            }
064    
065            /**
066             * @return map of  properties to values for Wicket property models
067             */
068            public Map<String, Object> getPropertyStore() {
069                    if (propertyStore == null) {
070                            propertyStore = new HashMap<String, Object>();
071                            putDefaultProperties(propertyStore);
072                    }
073                    return propertyStore;
074            }
075    
076            /**
077             * @return map of database fields to their values for creating new entities
078             */
079            public Map<String, Object> getFieldMap() {
080                    Map<String, Object> properties = getPropertyStore(), fields = new HashMap<String, Object>();
081                    FieldNameConverter conv = Databinder.getEntityManager(managerKey).getFieldNameConverter();
082                    for (Entry<String, Object> e : properties.entrySet()) {
083                            String field = e.getKey(), prop = Strings.capitalize(field);
084                            for (Method m : entityType.getMethods()) {
085                                    // match getter or setter
086                                    if (m.getName().substring(3).equals(prop)) {
087                                            field = conv.getName(m);
088                                            break;
089                                    }
090                            }
091                            if (e.getValue() != null)
092                                    fields.put(field, e.getValue());
093                    }
094                    return fields;
095            }
096    
097            public Class getEntityType() {
098                    return entityType;
099            }
100    
101            public Object getManagerKey() {
102                    return managerKey;
103            }
104    
105            public void setManagerKey(Object managerKey) {
106                    this.managerKey = managerKey;
107            }
108            
109    }