Skip to content

sebthom.de

Menu
  • Home
  • Über mich
  • Impressum
    • Datenschutzerklärung
  • Gästebuch
Menu

Using EMF ECore model objects with Wicket components

Posted on Mittwoch, der 8. September 2010Donnerstag, der 9. September 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 sagt:
    Freitag, der 17. Dezember 2010 um 11:17 Uhr

    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.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Kategorien

  • Blog (1)
  • IT (21)
    • Entwicklung (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)

Neueste Beiträge

  • 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

Neueste Kommentare

  • Annibale bei Visual Basic – Multiple Undos Class v2.04
  • Annibale bei Visual Basic – Multiple Undos Class v2.04
  • koliko2k3 bei Gästebuch
  • hdkid bei MyPad v1.1.6 – ein PHP Editor
  • Luis Diego Villarreal bei Excel – VBA Timer Example v1.0.1

Archive

  • Juni 2014
  • Mai 2012
  • Januar 2011
  • Oktober 2010
  • September 2010
  • März 2010
  • Februar 2010
  • September 2009
  • Juli 2009
  • März 2009
  • Februar 2009
  • November 2008
  • September 2008
  • Mai 2008
  • September 2007
  • Juli 2007
  • Juli 2004
  • März 2003
  • August 2002
  • April 2002
  • Januar 2002
  • Deutsch (de)Deutsch
  • English (en)English
© 2025 sebthom.de | Powered by Minimalist Blog WordPress Theme