Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Dynamically creating EObjects in the linker
Dynamically creating EObjects in the linker [message #803468] Tue, 21 February 2012 11:42 Go to next message
John J. Camilleri is currently offline John J. CamilleriFriend
Messages: 33
Registered: November 2011
Location: Göteborg
Member
There a few posts on this board hinting about how to dynamically create/destroy EObjects in a resource to satisfy linking. In particular: Hook for creation and destruction of EObject, create object if no ref found, and Xtext/EMF cross-references to virtual/phantom resources.

However there is no actual code posted and I am getting problems trying to get this working. So far I have this:
public class GFLinkingService extends DefaultLinkingService {
  @Override
  public List<EObject> getLinkedObjects(EObject context, EReference ref, INode node) throws IllegalNodeException {
    List<EObject> list = super.getLinkedObjects(context, ref, node);
    if (list.isEmpty()) {
        Ident newIdent = GFFactoryImpl.eINSTANCE.createIdent();
        newIdent.setS(node.getText());
        context.eResource().getContents().add(newIdent);
        list = Collections.singletonList((EObject)newIdent);
    }
    return list;
  }
}

However when I edit the file I keep getting this exception about concurrent modification:
!ENTRY org.eclipse.core.jobs 4 2 2012-02-21 13:09:43.516
!MESSAGE An internal error occurred during: "Xtext validation".
!STACK 0
java.util.ConcurrentModificationException
	at org.eclipse.emf.common.util.AbstractEList$EIterator.checkModCount(AbstractEList.java:762)
	at org.eclipse.emf.common.util.AbstractEList$EIterator.doNext(AbstractEList.java:710)
	at org.eclipse.emf.common.util.AbstractEList$EIterator.next(AbstractEList.java:696)
	at org.eclipse.emf.common.util.AbstractTreeIterator.next(AbstractTreeIterator.java:139)
	at org.eclipse.xtext.linking.lazy.LazyLinkingResource.resolveLazyCrossReferences(LazyLinkingResource.java:97)
	at org.eclipse.xtext.EcoreUtil2.resolveLazyCrossReferences(EcoreUtil2.java:485)
	at org.eclipse.xtext.validation.ResourceValidatorImpl.resolveProxies(ResourceValidatorImpl.java:127)
	at org.eclipse.xtext.validation.ResourceValidatorImpl.validate(ResourceValidatorImpl.java:62)
	at org.grammaticalframework.eclipse.validation.GFResourceValidator.validate(GFResourceValidator.java:38)
	at org.eclipse.xtext.ui.editor.validation.ValidationJob$1.exec(ValidationJob.java:79)
	at org.eclipse.xtext.ui.editor.validation.ValidationJob$1.exec(ValidationJob.java:1)
	at org.eclipse.xtext.util.concurrent.AbstractReadWriteAcces.readOnly(AbstractReadWriteAcces.java:32)
	at org.eclipse.xtext.ui.editor.model.XtextDocument.readOnly(XtextDocument.java:78)
	at org.eclipse.xtext.ui.editor.validation.ValidationJob.createIssues(ValidationJob.java:75)
	at org.eclipse.xtext.ui.editor.validation.ValidationJob.run(ValidationJob.java:64)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)


How can I solve this?

Also, I have overridden beforeModelLinked() so that I can clear these dynamic EObjects, but what should the code inside actually look like?
public class GFLinker extends LazyLinker {
  @Override
  protected void beforeModelLinked(EObject model, IDiagnosticConsumer diagnosticsConsumer) {
    super.beforeModelLinked(model, diagnosticsConsumer);
    // what now?
  }
}


Any help in the right direction would really be appreiciated!

[Updated on: Tue, 21 February 2012 12:33]

Report message to a moderator

Re: Dynamically creating EObjects in the linker [message #803499 is a reply to message #803468] Tue, 21 February 2012 12:30 Go to previous messageGo to next message
John J. Camilleri is currently offline John J. CamilleriFriend
Messages: 33
Registered: November 2011
Location: Göteborg
Member
Ok, so the name "ConcurrentModificationException" was a bit of a giveaway. Instead of trying to create the new EObjects in the same resource, I am creating a new dummy resource for this purpose:
//context.eResource().getContents().add(newIdent);
URI uri = URI.createURI("dummy.projectionsatisfier");
Resource r = context.eResource().getResourceSet().createResource(uri);
r.getContents().add(newIdent);
This more or less works, so my question is: how good/bad is the code above? Is it missing anything?

Also, what should I put in the beforeModelLinked() method? Shall I just completely delete the resource with URI "dummy.projectionsatisfier"?
Re: Dynamically creating EObjects in the linker [message #803501 is a reply to message #803468] Tue, 21 February 2012 12:28 Go to previous messageGo to next message
Sebastian Zarnekow is currently offline Sebastian ZarnekowFriend
Messages: 3107
Registered: July 2009
Senior Member
Hi John

don't add the newly created objects to the list that was obtained from
super.getLinkedObjects but create a new list with one item, e.g.
Collections.singletonList(newInstance).

You'll have to remove those potentially demand-created objects from the
resource in #beforeModelLinked.

Regards,
Sebastian
--
Need professional support for Eclipse Modeling?
Go visit: http://xtext.itemis.com

Am 21.02.12 12:42, schrieb John J. Camilleri:
> There a few posts on this board hinting about how to dynamically
> create/destroy EObjects in a resource to satisfy linking. In particular
> this post: http://www.eclipse.org/forums/index.php/m/658115/.
>
> However there is no actual code posted and I am getting problems trying
> to get this working. So far I have this:
> public class GFLinkingService extends DefaultLinkingService {
> @Override
> public List<EObject> getLinkedObjects(EObject context, EReference ref,
> INode node) throws IllegalNodeException {
> List<EObject> list = super.getLinkedObjects(context, ref, node);
> if (list.isEmpty()) {
> Ident newIdent = GFFactoryImpl.eINSTANCE.createIdent();
> newIdent.setS(node.getText());
> context.eResource().getContents().add(newIdent);
> list.add(newIdent);
> }
> return list;
> }
> }
> public class GFLinker extends LazyLinker {
> @Override
> protected void beforeModelLinked(EObject model, IDiagnosticConsumer
> diagnosticsConsumer) {
> super.beforeModelLinked(model, diagnosticsConsumer);
> // what now?
> }
> }
> However I keep getting this exception:
> [main] ERROR org.eclipse.xtext.linking.lazy.LazyLinkingResource -
> resolution of uriFragment
> 'xtextLink_::0.2.4.0.2.1.1.1.6.0.0.2.3.7.22.0::0::/0' failed.
> java.lang.UnsupportedOperationException
> at java.util.AbstractList.add(AbstractList.java:148)
> at java.util.AbstractList.add(AbstractList.java:108)
> at
> org.grammaticalframework.eclipse.linking.GFLinkingService.getLinkedObjects(GFLinkingService.java:47)
>
> at
> org.eclipse.xtext.linking.lazy.LazyLinkingResource.getEObject(LazyLinkingResource.java:175)
>
> at
> org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.getEObject(ResourceSetImpl.java:219)
>
> at org.eclipse.emf.ecore.util.EcoreUtil.resolve(EcoreUtil.java:203)
> at org.eclipse.emf.ecore.util.EcoreUtil.resolve(EcoreUtil.java:263)
> at
> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eResolveProxy(BasicEObjectImpl.java:1483)
>
> at
> org.grammaticalframework.eclipse.gF.impl.LabelImpl.getName(LabelImpl.java:97)
>
> at
> org.grammaticalframework.eclipse.gF.impl.LabelImpl.eGet(LabelImpl.java:164)
> at
> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjectImpl.java:1021)
>
> at
> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjectImpl.java:1013)
>
> at
> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjectImpl.java:1008)
>
> at
> org.eclipse.xtext.resource.EObjectAtOffsetHelper.resolveCrossReferencedElement(EObjectAtOffsetHelper.java:127)
>
> at
> org.eclipse.xtext.resource.EObjectAtOffsetHelper.getCrossReferencedElement(EObjectAtOffsetHelper.java:72)
>
> at
> org.eclipse.xtext.resource.EObjectAtOffsetHelper.resolveCrossReferencedElementAt(EObjectAtOffsetHelper.java:41)
>
> at
> org.eclipse.xtext.ui.editor.hover.AbstractEObjectHover.getXtextElementAt(AbstractEObjectHover.java:95)
>
> at
> org.eclipse.xtext.ui.editor.hover.AbstractEObjectHover$1.exec(AbstractEObjectHover.java:53)
>
> at
> org.eclipse.xtext.ui.editor.hover.AbstractEObjectHover$1.exec(AbstractEObjectHover.java:1)
>
> at
> org.eclipse.xtext.util.concurrent.AbstractReadWriteAcces.readOnly(AbstractReadWriteAcces.java:32)
>
> at
> org.eclipse.xtext.ui.editor.model.XtextDocument.readOnly(XtextDocument.java:78)
>
> at
> org.eclipse.xtext.ui.editor.hover.AbstractEObjectHover.getHoverRegion(AbstractEObjectHover.java:51)
>
> at
> org.eclipse.xtext.ui.editor.hover.AbstractCompositeHover.getHoverRegion(AbstractCompositeHover.java:62)
>
> at
> org.eclipse.jface.text.TextViewerHoverManager.computeInformation(TextViewerHoverManager.java:140)
>
> at
> org.eclipse.jface.text.AbstractInformationControlManager.doShowInformation(AbstractInformationControlManager.java:1131)
>
> at
> org.eclipse.jface.text.AbstractHoverInformationControlManager$MouseTracker.mouseHover(AbstractHoverInformationControlManager.java:519)
>
> at
> org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:207)
> at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
> at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1258)
> at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3588)
> at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3209)
> at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2696)
> at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2660)
> at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2494)
> at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:674)
> at
> org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
>
> at
> org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:667)
> at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
> at
> org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:123)
>
> at
> org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
>
> at
> org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
>
> at
> org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
>
> at
> org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
>
> at
> org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
>
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
>
> at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>
> at java.lang.reflect.Method.invoke(Method.java:616)
> at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
> at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
> at org.eclipse.equinox.launcher.Main.run(Main.java:1410)
> at org.eclipse.equinox.launcher.Main.main(Main.java:1386)
> Would someone be kind enough as to point me in the right direction? Thanks!
Re: Dynamically creating EObjects in the linker [message #803578 is a reply to message #803499] Tue, 21 February 2012 14:29 Go to previous message
John J. Camilleri is currently offline John J. CamilleriFriend
Messages: 33
Registered: November 2011
Location: Göteborg
Member
Hi Sebastian, yes I finally realised that that was the problem.. duh!

My beforeModelLinked method now looks like the following, as far as I can tell it seems to be doing the job:
@Override
protected void beforeModelLinked(EObject model, IDiagnosticConsumer diagnosticsConsumer) {
  super.beforeModelLinked(model, diagnosticsConsumer);
  Resource res = model.eResource().getResourceSet().getResource(URI.createURI("dummy.projectionsatisfier"), false);
  if (res != null) {
    try {
      res.delete(null);
    } catch (IOException e) {

    }
  }
}


Hope this helps anyone else who is trying to get their heads round this.

[Updated on: Tue, 21 February 2012 14:30]

Report message to a moderator

Previous Topic:support for Eclipse 3.7?
Next Topic:Referencing EClasses from my dsl
Goto Forum:
  


Current Time: Tue Mar 31 03:03:28 GMT 2020

Powered by FUDForum. Page generated in 0.01661 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top