Inspired by http://wicketinaction.com/2008/09/building-a-smart-entitymodel/
I created an EntityModel based on JPA annotations. Maybe this is helpful for 
somebody with the same question. 

Any suggestions to improve the code?


EntityModel.java
---------------------------------------------------------------------------
import com.helmbold.util.AnnotationReader;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.EntityNotFoundException;
import org.apache.wicket.model.IModel;


public abstract class EntityModel<T> implements IModel
{
    private transient T entity;
    private Class entityClass;
    private Serializable entityId;

    
    public EntityModel(T entity)
    {
        this.entity = entity;
        entityClass = entity.getClass();
        
    }

    public EntityModel(Class<? extends T> entityClass, Serializable entityId)
    {
        this.entityClass = entityClass;
        this.entityId = entityId;
    }


    @Override
    public T getObject()
    {
        if (entity == null)
        {
            if (entityId != null)
                load();
        }
        return entity;
    }


    @Override
    public void detach()
    {
        if (entity != null)
        {
            // prevent null out before entity is persisted
            if (getEntityId() != null)
            {
                entityId = getEntityId();
                entity = null;
            }
        }
    }


    private void load()
    {
        entity = load(entityClass, this.entityId);
        if (entity == null)
            throw new EntityNotFoundException("Entity " + entityId + " of type"+
                entityClass + " not found.");
    }


    protected abstract T load(Class entityClass, Serializable entityId);


    public void setObject(T object)
    {
            throw new UnsupportedOperationException(getClass() +
                            "setObject(T entity) is not supported.");
    }


    private Serializable getEntityId()
    {
        Object id = null;
        try
        {
            id = AnnotationReader.getAnnotatedValue(entity, entityClass);
        } catch (IllegalArgumentException ex)
        {
            Logger.getLogger(EntityModel.class.getName()).log(Level.SEVERE, 
null, ex);
        } catch (IllegalAccessException ex)
        {
            Logger.getLogger(EntityModel.class.getName()).log(Level.SEVERE, 
null, ex);
        } catch (InvocationTargetException ex)
        {
            Logger.getLogger(EntityModel.class.getName()).log(Level.SEVERE, 
null, ex);
        }
        return (Serializable) id;
    }

}
---------------------------------------------------------------------------

AnnotationReader.java
---------------------------------------------------------------------------
package com.helmbold.util;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class AnnotationReader {


    /**
     * Inspects the given object and looks first for a field with the given
     * annotation and, if no such field was found, for a method with the given
     * annotation. This is a convinience method that invokes
     * getAnnotatedFieldValue and invokeAnnotatedMethod.
     *
     * @param inspectedObject The object to inspect.
     * @param annotationType Searched annotation.
     * @return Value of the annotated field or return value of the annotated
     * method or null, if no such field or method were found.
     * @throws java.lang.IllegalArgumentException
     * @throws java.lang.IllegalAccessException
     * @throws java.lang.reflect.InvocationTargetException
     */
    public static Object getAnnotatedValue(
                    Object inspectedObject,
                    Class annotationType)
    throws IllegalArgumentException, IllegalAccessException,
    InvocationTargetException
    {
        Object value = getAnnotatedFieldValue(inspectedObject, annotationType);
        if (value != null)
            return value;
        return invokeAnnotatedMethod(inspectedObject, annotationType);
    }


    /**
     * Inspects the given object and looks for a field with the given 
annotation.
     * If such a field is not found in the class of the current object, the 
search
     * will be continued recursivly in the super classes. The
     * search will be stopped when the first match was found.
     *
     * @param inspectedObject The object to inspect.
     * @param annotationType Searched annotation.
     * @return Value of the annotated field or null, if no such field was found.
     * @throws java.lang.IllegalArgumentException
     * @throws java.lang.IllegalAccessException
     */
    public static Object getAnnotatedFieldValue(
                    Object inspectedObject,
                    Class annotationType)
    throws IllegalArgumentException, IllegalAccessException
    {
        if(inspectedObject == null)
            throw new NullPointerException("inspectedObject must not be null.");
        if(annotationType == null)
            throw new NullPointerException("annotationType must not be null.");

        return getAnnotatedFieldValue(
                        inspectedObject.getClass(),
                        inspectedObject,
                        annotationType);
    }


    private static Object getAnnotatedFieldValue(
                    Class inspectedClass,
                    Object inspectedObject,
                    Class annotationType)
    throws IllegalArgumentException, IllegalAccessException
    {
        Field[] fields = inspectedClass.getDeclaredFields();
        if(fields != null){
            Field.setAccessible(fields, true);
            for(Field f : fields)
            {
                if(f.isAnnotationPresent(annotationType))
                    return f.get(inspectedObject);
            }
        }
        Class superClass = inspectedClass.getSuperclass();
        if (superClass != null)
            getAnnotatedFieldValue(superClass, inspectedObject,    
annotationType);
        return null;
    }


    /**
     * <p>Inspects the given object and looks for a method with the given
     * annotation. If such a method is not found in the class of the current
     * object, the search will be continued recursivly in the super classes. The
     * search will be stopped when the first match was found.</p>
     *
     * <p>Only public, parameterless methods will be invoked.</p>
     *
     * @param inspectedObject The object to inspect.
     * @param annotationType Searched annotation.
     * @return Return value of the annotated method or null, if no such method
     * was found.
     * @throws java.lang.IllegalArgumentException
     * @throws java.lang.IllegalAccessException
     * @throws java.lang.reflect.InvocationTargetException
     */
    public static Object invokeAnnotatedMethod(
                    Object inspectedObject,
                    Class annotationType)
    throws IllegalArgumentException, IllegalAccessException,
    InvocationTargetException
    {
        return invokeAnnotatedMethod(
                        inspectedObject.getClass(),
                        inspectedObject,
                        annotationType);
    }


    private static Object invokeAnnotatedMethod(
                    Class inspectedClass,
                    Object inspectedObject,
                    Class annotationType)
    throws IllegalArgumentException, IllegalAccessException,
    InvocationTargetException
    {
        Method[] methods = inspectedClass.getDeclaredMethods();
        for(Method method : methods)
        {
            if(method.isAnnotationPresent(annotationType))
                return method.invoke(inspectedObject);
        }
        Class superClass = inspectedClass.getSuperclass();
        if (superClass != null)
            invokeAnnotatedMethod(superClass,    inspectedObject, 
annotationType);
        return null;
    }

}

---------------------------------------------------------------------------




---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
For additional commands, e-mail: users-h...@wicket.apache.org

Reply via email to