EMF auf Modeländerung reagieren

greeni

Mitglied
Ich habe da mal eine Verständnisfrage zu EMF. Ich hab verstanden das mir EMF in mein Model ein Observerpattern intigriert. Aber ich verstehe nicht wie ich auf Änderungen des Datenmodels reagieren kann. Wie bekomme ich in meinem EMF Editor mit (oder auch auf einer anderen GUI) wenn sich in meinem Datenmodell irgendetwas geändert hat?
 
G

Gast2

Gast
Kannst auf dein Model ein Adapter adden

Java:
    eAdapters().add(new Adapter() {
        public Notifier getTarget() {
            return null;
        }

        public boolean isAdapterForType(Object type) {
            return false;
        }

        public void notifyChanged(Notification notification) {
        }

        public void setTarget(Notifier newTarget) {
        }

     });
 

Wildcard

Top Contributor
Tipp: Es gibt auch einen EContentAdapter. Damit kannst du auf alle Änderungen im gesamten Objektbaum (oder einem Teilbaum) hören. Soetwas ist zB praktisch um ein Dirty Flag oder ähnliches zu setzen.
Es gibt sogar einen Changerecorder der automatisch alle gemachten Änderungen mitschneidet. Diese kannst du dann zu jeder Zeit rückgängig machen, abspeichern, oder sonstwas damit anstellen.
 
G

Gast2

Gast
Tipp: Es gibt auch einen EContentAdapter. Damit kannst du auf alle Änderungen im gesamten Objektbaum (oder einem Teilbaum) hören. Soetwas ist zB praktisch um ein Dirty Flag oder ähnliches zu setzen.
Es gibt sogar einen Changerecorder der automatisch alle gemachten Änderungen mitschneidet. Diese kannst du dann zu jeder Zeit rückgängig machen, abspeichern, oder sonstwas damit anstellen.

Gibts dafür ein Beispiel?
 
G

Gast2

Gast
Für das rückgängig machen des changerecorders oder wie man den benutzt und das dirty flag zu setzten. Weil bei mir im Editor weiß ich nie richtig wie man ein Objekt dirty setzt und abpürft ob sich wirklich was geändert hat.
 
G

Gast2

Gast
wenn ich ein neues model anlege, woher bekomm ich dann die Ressource?
Gibt es irgendwo ein Beispiel dazu?
 
G

Gast2

Gast
Mhm check ich grad nicht von ws hängt es denn ab ?
Ich hab einfach einen Editor in dem alle Attribute eines Models eingeben kann also wenn ein Attribut eingegeben wird kann man abspeichern. Danach natrülich nur noch wenn sich etwas geändert hat.
 
G

Gast2

Gast
Also ich habs mal hinbekommen mit EcliseLink testweise ein Model zu speichern
Java:
	@Override
	public Kunde createKunde(Kunde kunde) {
		String query = EclipseLinkURIUtil.createContentsEqualQuery(kunde.eClass(), VerwaltungPackage.eINSTANCE.getPerson_Name(), kunde.getName());
		URI libraryURI = EclipseLinkURIUtil.createEclipseLinkURI("verwaltung",query);
		ResourceSet resourceSet1 = new ResourceSetImpl();
		resourceSet1.getLoadOptions().put(
				PersistenceUnitProperties.CLASSLOADER,
				this.getClass().getClassLoader());
		Resource kundeResource1 = resourceSet1.createResource(libraryURI);
		
		
		kundeResource1.getContents().add(kunde);
		try {
			kundeResource1.save(Collections.EMPTY_MAP);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		System.out.println(kunde.eResource());
		System.out.println(kunde.getId());
		return kunde;
	}
1. wie läuft das jetzt mit Transaktionen ab?
2.
Java:
	private boolean isKundeChange() {
		bindingContext.updateModels();
		return kunde.eResource() == null ? true : kunde.eResource().isModified();
	}
ist immer false, muss ich das isModified selber auf true setzen???


EDIT: mit kunde.eResource().setTrackingModification(true); hab ich es auch schon probiert wird immer wieder auf false gesetzt...
 
Zuletzt bearbeitet von einem Moderator:
G

Gast2

Gast
Also die Funktionen werden wohl nicht unterstützt...
Java:
public class EclipseLinkResourceImpl extends ResourceImpl implements EclipseLinkResource {
	@Override
	public final boolean isTrackingModification() {
		return false;
	}

	@Override
	public final void setTrackingModification(boolean isTrackingModification) {
		// do nothing
	}

	@Override
	public boolean isModified() {
		return false;
	}

	@Override
	public void setModified(boolean isModified) {
		// do nothing
	}

Gibt es sonst noch Vorteile Resource zum Laden und Speichern zu benutzen? Weil die Änderungen wären für mich das einzigst interessante gewesen...

Weil für eigene Abfragen muss man von der Klasse erben und ein paar Methoden überschreiben.
 

Wildcard

Top Contributor
EclipseLink ist ein Spezialfall, im Normalfall kannst du nur über eine Resource laden und speichern.
Die Änderungen mitzubekommen ist auch ohne Resource kein Problem, dafür kannst du den ContentAdapter verwenden.
 
G

Gast2

Gast
Ja ich hätte Resourcen gerne genutzt, damit ich beim Standard bleibe, aber ich hab mir wie gesagt mal den src angeschaut und es ist brutal umständlich gescheite Abfragen zu generieren oder am besten selbst eine Klasse für die Abfragen zu machen die von der EclipseLinkResourceImpl erbt.

Okay wie kann kann ich die Änderungen mitbekommen un abfragen? Weil ich möchte ein Objekt natürlich nur speichern können, wenn es dirty ist, sowie im Eclipse Text Editor.
 

Wildcard

Top Contributor
Editierst du innerhalb eines Editors? Wenn ja, häng dich doch an den Undo Stack.
Etwas vereinfacht: Wenn keine Undos mehr auf dem Stack liegen ist deine Resource unverändert.
 
G

Gast2

Gast
Ja ich hab einen Editor mit einem EMF Objekt welches ich über JFace-Databinding angebunden habe und nun weiß ich nicht wie ich die isDirty Methode gescheit implementiere:
Hab mir überlegt extra ein dirtyObjekt anzulegen und dass immer mit dem orginal zu verlgeichen und bei änderungen dann zu speichern. hat geklappt fand ich unsauber.
Hier vielleicht mal ein Bsp:
Java:
@Autowired
	private BaseService service;
	private Verwaltung verwaltung = VerwaltungFactory.eINSTANCE.createVerwaltung();
	private Text lastName;
	private EMFDataBindingContext m_bindingContext;


	public void createPartControl(Composite parent) {
		verwaltung = VerwaltungFactory.eINSTANCE.createVerwaltung();
		parent.setLayout(new GridLayout());
		lastName = new Text(parent, SWT.BORDER);
		lastName.setMessage("Name eingeben");
		bindValue();
	}

	private void bindValue() {
		m_bindingContext = new EMFDataBindingContext();
		lastName.addModifyListener(new ModifyListener() {
			
			@Override
			public void modifyText(ModifyEvent e) {
				firePropertyChange(PROP_DIRTY);
				
			}
		});
		m_bindingContext.bindValue(SWTObservables.observeText(lastName,SWT.Modify), EMFObservables.observeValue(verwaltung,
				VerwaltungPackage.Literals.VERWALTUNG__NAME), null, null);
	}

	/**
	 * Passing the focus request to the viewer's control.
	 */
	public void setFocus() {
		lastName.setFocus();
	}
	
	

	@Override
	public void doSave(IProgressMonitor monitor) {
		service.saveOrUpdate(verwaltung);
		firePropertyChange(PROP_DIRTY);
		
	}

	@Override
	public void doSaveAs() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public boolean isDirty() {
		// 1. Versuch war verwaltung.eResource().isModified();
		// 2ter Versuch war !EcoreUtil.equals(verwaltung, dirtyObjekt);
		
		return true;
	}

	@Override
	public boolean isSaveAsAllowed() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean isSaveOnCloseNeeded() {
		// TODO Auto-generated method stub
		return true;
	}
 

Wildcard

Top Contributor
(Content)Adapter oder UndoStack, ich weiß nicht was ich sonst noch dazu sagen soll. EMF gibt dir die Werkzeuge an die Hand, du musst sie nur noch verwenden.
 
G

Gast2

Gast
Hab ich den UndoStack und ContentAdapter nur wenn ich Resourcen verwende oder kann die auch ohne Resourcen verwenden.

Ich hab noch nie was mit EMF gemacht, deshalb hab ich auch grad kein plan wie man einen ContentAdapter benutzt.
 

Wildcard

Top Contributor
Hat nichts mit Resourcen zu tun. Mit Undo Stack meine ich die Undo Redo History deines Editors.
Ein ContentAdapter wird einfach als Adapter auf ein EObject gesetzt und über alle Changes in diesem Objekt und den Kindern des Objekts informiert.
 
G

Gast2

Gast
Damit wir nicht aneinander vorbei reden. Du meinst schon diesen Adapter?
Java:
eObject.eAdapters().add(new EContentAdapter());
 
G

Gast2

Gast
Ja okay soweit war es mir klar.
Aber z.B. ich hab ein Textfeld in dem man den Namen eingeben kann. Ich lad das Objekt steht als Anfangwert: "Test" drin. So jetzt tipp ich was neues ein. Im notifyChange merk ich mir für das Objekt das es dirty ist. Jetzt macht der Benutzer die Eingabe rückgängig oder schreibt das gleiche rein. Dann wird das ja trotzdem als Änderung durchgehen.

Das mit dem UndoStack muss ich mir nochmal anschaun, hab mir aus dem CVS die Beispiele geholt aber sieht auf den ersten blick komplex aus.
 

Ähnliche Java Themen

Neue Themen


Oben