Dynamically creating EObjects in the linker [message #803468] |
Tue, 21 February 2012 11:42 |
John J. Camilleri 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 #803501 is a reply to message #803468] |
Tue, 21 February 2012 12:28 |
Sebastian Zarnekow Messages: 3118 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 |
John J. Camilleri 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
|
|
|
Powered by
FUDForum. Page generated in 0.04115 seconds