/** * (C) Copyright 2013 Jabylon (http://www.jabylon.org) and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package org.jabylon.rest.ui.model; import java.util.Collection; import org.apache.wicket.model.IModel; import org.eclipse.emf.cdo.CDOObject; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EClassifier; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.util.EcoreUtil; public class AttachableWritableModel<T extends CDOObject> implements IEObjectModel<T>, AttachableModel<T>{ private static final long serialVersionUID = 1L; private String eClass; private String namespace; private String containmentFeature; private IModel<? extends CDOObject> parent; private transient T model; public AttachableWritableModel(EClass eClass, IModel<? extends CDOObject> parent, EStructuralFeature containmentFeature) { super(); this.eClass = eClass.getName(); this.namespace = eClass.getEPackage().getNsURI(); this.parent = parent; this.containmentFeature = containmentFeature.getName(); } public AttachableWritableModel(EClass eClass, IModel<? extends CDOObject> parent) { this(eClass, parent, computeContainmentFeature(eClass,parent)); } private static EStructuralFeature computeContainmentFeature(EClass eClass, IModel<? extends CDOObject> parent) { EList<EReference> containments = parent.getObject().eClass().getEAllContainments(); for (EReference eReference : containments) { if(eReference.getEType().getInstanceClass().isAssignableFrom(eClass.getInstanceClass())) return eReference; } throw new IllegalArgumentException("Could not compute the correct containment feature for the given eclass"); } @Override public void detach() { parent.detach(); } @Override public T getObject() { if(model==null) model = createModel(); return model; } @SuppressWarnings("unchecked") private T createModel() { EClassifier classifier = EPackage.Registry.INSTANCE.getEPackage(namespace).getEClassifier(eClass); T object = (T) EcoreUtil.create((EClass) classifier); return object; } @Override public void setObject(T object) { model = object; } @Override public <X> IModel<X> forProperty(EStructuralFeature feature) { return new EObjectPropertyModel<X, T>(this, feature); } @SuppressWarnings({ "rawtypes", "unchecked" }) @Override public void attach() { CDOObject container = parent.getObject(); EStructuralFeature feature = container.eClass().getEStructuralFeature(containmentFeature); if(feature.isMany()) { Collection c = (Collection) container.eGet(feature); c.add(getObject()); } else container.eSet(feature, getObject()); } @Override public IModel<?> getParent() { return parent; } }