Skip to content

sebthom.de

Menu
  • Home
  • About me
  • Imprint
    • Datenschutzerklärung
  • Guestbook
Menu

Using EMF ECore model objects with Wicket components

Posted on Wednesday September 8th, 2010Thursday September 9th, 2010 by sebthom

Apache Wicket uses so called model objects to bind data objects to Wicket components. The framework provides a number of model implementations to access data objects and their properties in various ways. The PropertyModel implementation for example is used to access and set the value of a Java object using reflection.

EPropertyModel

If you are working with EMF (Eclipse Modeling Framework) generated model classes you can also use PropertyModels to bind structural features (properties in EMF terminology) of an EObject to a Wicket component. E.g. if your EObject has an attribute called “comment” you could instantiate a model like this

IModel model = new PropertyModel(myEObject, "comment");

This approach has several disadvantages. First, the name of the attribute is declared as a String and not as a compile-time reference to the actual attribute. This means the application could break during runtime if you have renamed the attribute at one point and forgot to also change the String value. Second, this property model uses runtime reflection which is a slow alternative to compile time based access.
Java classes generated from EMF Models by default extend the EObject class which provides a compile-time reflection API. Using the generic eGet and eSet methods any public property of the EObject can be accessed. The EMF Generator also generates a Package class for each EMF package that holds a Literals interface listing all available attributes and references of all generated EClasses of the given package. If you lets say have an EClass “Ticket” with the attribute “comment” in the package “com.acme.service” you could utilize the compile time reflection API as follows:

EAttribute commentAttribute = com.acme.service.ServicePackage.Literals.TICKET__COMMENT;
Ticket newTicket = com.acme.service.ServiceFactory.eINSTANCE.create(Ticket.class);
newTicket.eSet(commentAttribute, "my comment");

Using the EMF compile-time reflection API I created a generic EMF ECore Feature Model implementation that leverages the compile-time references to structural features. Most of the code is actually related to working around the fact that EAttributes and EReferences are not serializable but which they should to be part safely referenced in a model that potentially is serialized by Wicket between requests.

import org.apache.wicket.model.IDetachable;
import org.apache.wicket.model.IObjectClassAwareModel;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;

/**
 * A property model to bind an attribute of an EMF ECore object
 * 
 * @author Sebastian Thomschke
 */
@SuppressWarnings("unchecked")
public class EFeatureModel<T> implements IObjectClassAwareModel<T>
{
	private static final long serialVersionUID = 1L;

	private transient EStructuralFeature feat;
	private String featContainerClassName;
	private String featName;
	private String featPackageNsURI;

	private EObject target;

	public EFeatureModel(EObject target, EStructuralFeature efeature)
	{
		this.target = target;
		this.feat = efeature;
		this.featName = efeature.getName();
		this.featContainerClassName = efeature.getContainerClass().getName();
		this.featPackageNsURI = ((EPackage) efeature.eContainer().eContainer()).getNsURI();
	}

	public void detach()
	{
		if (target instanceof IDetachable) ((IDetachable) target).detach();
	}

	public EStructuralFeature getFeature()
	{
		if (feat == null)
		{
			EPackage ePackage = EPackage.Registry.INSTANCE.getEPackage(featPackageNsURI);
			for (Object eClassifierItem : ePackage.getEClassifiers())
			{
				EClassifier eClassifier = (EClassifier) eClassifierItem;
				if (eClassifier.getInstanceClass().getName().equals(featContainerClassName))
					feat = ((EClass) eClassifier).getEStructuralFeature(featName);
			}
		}
		return feat;
	}

	public T getObject()
	{
		return (T) target.eGet(getFeature());
	}

	public Class<T> getObjectClass()
	{
		return getFeature().getEType().getInstanceClass();
	}

	public void setObject(T object)
	{
		// do nothing if the object is the same instance that is returned by the getter
		// this is esp. important for collection properties
		if (target.eGet(getFeature()) == object) return;

		target.eSet(getFeature(), object);
	}

	@Override
	public String toString()
	{
		return new StringBuilder("Model:classname=[").append(getClass().getName()).append("]").append(":target=[")
				.append(target).append("]").toString();
	}
}

Using this new model implementation is as simple as using the PropertyModel provided by Wicket:

IModel model = new EFeatureModel(myTicket, com.acme.service.ServicePackage.Literals.TICKET__COMMENT);

You can now fully enjoy the compile-time safeness of your EMF model.

Making EObjects serializable

Wicket usually serializes components and their associated models between HTTP requests. If you are using the provided EPropertyModel your EObject classes must implement the Serializable interface. To achieve this, simply extend the EObject interface with the Serializables interface and set “Root Extends Interface” property in your genmodel configuration to this interface.

/**
 * @author Sebastian Thomschke
 */
public interface SerializableEObject extends EObject, Serializable {
}

When you now regenerate the model classes they will extend the SerializableEObject interface and Wicket will stop complaining about objects in the model being not serializable.

1 thought on “Using EMF ECore model objects with Wicket components”

  1. Antonio Rodriguez says:
    Friday December 17th, 2010 at 11:17 AM

    Interesting the EMF capabilities for generating compile time reflection, this is one argument more to consider Eclipse Modeling as a suitable development platform. I’ve been reading about it as DSL workbench lately and I think it is worth it.

    Cheers,
    Tony.

Leave a Reply

Your email address will not be published. Required fields are marked *

Categories

  • Blog (1)
  • IT (21)
    • Development (16)
      • Java (7)
      • Jython (4)
      • Visual Basic (5)
    • Linux (3)
    • WebSphere Application Server (1)
    • WebSphere Portal (2)
    • Windows (1)
  • My Freeware (2)
  • My Music (3)

Recent Posts

  • Logging WebSphere API calls in wsadmin scripts
  • [Solved] Windows 7 “Safely Remove Hardware” pop-up menu horrendously slow
  • Bash: Capturing stderr in a variable while still printing to the console.
  • Configuring EMF Teneo with Hibernate, Commons DBCP, Spring Hibernate Transaction Manager, and the OpenSessionInViewFilter
  • Using EMF ECore model objects with Wicket components
  • Installing Tomcat 6 on Debian Squeeze
  • Leveraging PyDev’s auto-completion for indirectly created objects
  • OVal 1.40 released
  • Installing WebSphere Portal in a local network
  • Comparing version numbers in Jython / Python

Blogroll

  • E L S U A
  • elektrofever.de
  • OVal
  • Sweettt.com
  • Twins’ Running Blog

Recent Comments

  • Annibale on Visual Basic – Multiple Undos Class v2.04
  • Annibale on Visual Basic – Multiple Undos Class v2.04
  • koliko2k3 on Guestbook
  • hdkid on MyPad v1.1.6 – a PHP Editor
  • Luis Diego Villarreal on Excel – VBA Timer Example v1.0.1

Archives

  • June 2014
  • May 2012
  • January 2011
  • October 2010
  • September 2010
  • March 2010
  • February 2010
  • September 2009
  • July 2009
  • March 2009
  • February 2009
  • November 2008
  • September 2008
  • May 2008
  • September 2007
  • July 2007
  • July 2004
  • March 2003
  • August 2002
  • April 2002
  • January 2002
  • Deutsch (de)Deutsch
  • English (en)English
© 2025 sebthom.de | Powered by Minimalist Blog WordPress Theme