|
11 | 11 | package com.avaloq.tools.ddk.xtext.resource.persistence; |
12 | 12 |
|
13 | 13 | import java.io.IOException; |
| 14 | +import java.util.ArrayDeque; |
14 | 15 | import java.util.ArrayList; |
| 16 | +import java.util.Deque; |
15 | 17 | import java.util.List; |
16 | 18 |
|
17 | 19 | import org.eclipse.emf.common.notify.Adapter; |
|
21 | 23 | import org.eclipse.emf.common.util.TreeIterator; |
22 | 24 | import org.eclipse.emf.common.util.WrappedException; |
23 | 25 | import org.eclipse.emf.ecore.EObject; |
| 26 | +import org.eclipse.emf.ecore.EStructuralFeature; |
| 27 | +import org.eclipse.emf.ecore.impl.EClassImpl; |
24 | 28 | import org.eclipse.emf.ecore.resource.Resource; |
25 | | -import org.eclipse.emf.ecore.util.EContentsEList.FeatureIterator; |
26 | 29 | import org.eclipse.xtext.nodemodel.BidiIterable; |
27 | 30 | import org.eclipse.xtext.nodemodel.BidiTreeIterable; |
28 | 31 | import org.eclipse.xtext.nodemodel.BidiTreeIterator; |
@@ -80,24 +83,45 @@ static void installProxyNodeModel(final Resource resource) { |
80 | 83 | ProxyCompositeNode rootNode = installProxyNodeModel(root, idToEObjectMap); |
81 | 84 | idToEObjectMap.trimToSize(); |
82 | 85 | rootNode.idToEObjectMap = idToEObjectMap; |
83 | | - |
84 | 86 | if (resource instanceof XtextResource) { |
85 | 87 | ((XtextResource) resource).setParseResult(new ParseResult(root, rootNode, false)); |
86 | 88 | } |
87 | 89 | } |
88 | 90 |
|
89 | 91 | private static ProxyCompositeNode installProxyNodeModel(final EObject eObject, final List<EObject> map) { |
90 | | - ProxyCompositeNode result = new ProxyCompositeNode(); |
91 | | - eObject.eAdapters().add(result); |
| 92 | + Deque<EObject> deque = new ArrayDeque<>(); |
| 93 | + deque.push(eObject); |
| 94 | + ProxyCompositeNode rootComposite = new ProxyCompositeNode(); |
| 95 | + eObject.eAdapters().add(rootComposite); |
92 | 96 | map.add(eObject); |
93 | 97 |
|
94 | | - for (FeatureIterator<EObject> it = (FeatureIterator<EObject>) eObject.eContents().iterator(); it.hasNext();) { |
95 | | - EObject child = it.next(); |
96 | | - if (!it.feature().isTransient()) { |
97 | | - installProxyNodeModel(child, map); |
| 98 | + while (!deque.isEmpty()) { |
| 99 | + EObject nextEObject = deque.pop(); |
| 100 | + EStructuralFeature[] structuralFeatures = ((EClassImpl.FeatureSubsetSupplier) nextEObject.eClass().getEAllStructuralFeatures()).containments(); |
| 101 | + if (structuralFeatures != null) { |
| 102 | + for (int i = structuralFeatures.length - 1; i >= 0; i--) { |
| 103 | + EStructuralFeature eStructuralFeature = structuralFeatures[i]; |
| 104 | + if (!eStructuralFeature.isTransient()) { |
| 105 | + Object child = nextEObject.eGet(eStructuralFeature, false); |
| 106 | + if (child instanceof EObject singleChild) { |
| 107 | + singleChild.eAdapters().add(new ProxyCompositeNode()); |
| 108 | + map.add(singleChild); |
| 109 | + deque.push(singleChild); |
| 110 | + } else if (child instanceof EList listChild) { |
| 111 | + for (int j = listChild.size() - 1; j >= 0; j--) { |
| 112 | + EObject singleChild = (EObject) listChild.get(j); |
| 113 | + singleChild.eAdapters().add(new ProxyCompositeNode()); |
| 114 | + map.add(singleChild); |
| 115 | + deque.push(singleChild); |
| 116 | + } |
| 117 | + } else if (child != null) { |
| 118 | + throw new IllegalStateException("Unexpected class " + child.getClass()); //$NON-NLS-1$ |
| 119 | + } |
| 120 | + } |
| 121 | + } |
98 | 122 | } |
99 | 123 | } |
100 | | - return result; |
| 124 | + return rootComposite; |
101 | 125 | } |
102 | 126 |
|
103 | 127 | /** |
|
0 commit comments