diff options
author | Ed Merks | 2018-11-02 07:21:05 +0000 |
---|---|---|
committer | Ed Merks | 2018-11-02 07:21:05 +0000 |
commit | b3565513635ad76057d1bb78be19f4bd1cb003d6 (patch) | |
tree | ff0382335407800d83db15e4851ad37752062654 /plugins/org.eclipse.emf.ecore/src/org/eclipse/emf | |
parent | 1a8a6fb7e84c76107b0d7b186ec357e0e857e249 (diff) | |
download | org.eclipse.emf-b3565513635ad76057d1bb78be19f4bd1cb003d6.tar.gz org.eclipse.emf-b3565513635ad76057d1bb78be19f4bd1cb003d6.tar.xz org.eclipse.emf-b3565513635ad76057d1bb78be19f4bd1cb003d6.zip |
[540041] StackOverflow with circular contained EClass proxy
Diffstat (limited to 'plugins/org.eclipse.emf.ecore/src/org/eclipse/emf')
-rw-r--r-- | plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/impl/EModelElementImpl.java | 38 | ||||
-rw-r--r-- | plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/impl/EPackageImpl.java | 116 |
2 files changed, 132 insertions, 22 deletions
diff --git a/plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/impl/EModelElementImpl.java b/plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/impl/EModelElementImpl.java index 1f28e66e6..cf891c792 100644 --- a/plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/impl/EModelElementImpl.java +++ b/plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/impl/EModelElementImpl.java @@ -469,27 +469,31 @@ public abstract class EModelElementImpl extends MinimalEObjectImpl.Container imp } name = "%".equals(name) ? null : URI.decode(name); - - // Look for a matching named element. - // - for (Object object : eContents()) - { - if (object instanceof ENamedElement) - { - ENamedElement eNamedElement = (ENamedElement)object; - String otherName = eNamedElement.getName(); - if ((name == null ? otherName == null : name.equals(otherName)) && count-- == 0) - { - return eNamedElement; - } - } - } - - return null; + + return eObjectForURIFragmentNameSegment(name, count); } } return super.eObjectForURIFragmentSegment(uriFragmentSegment); } + EObject eObjectForURIFragmentNameSegment(String name, int count) + { + // Look for a matching named element. + // + for (Object object : eContents()) + { + if (object instanceof ENamedElement) + { + ENamedElement eNamedElement = (ENamedElement)object; + String otherName = eNamedElement.getName(); + if ((name == null ? otherName == null : name.equals(otherName)) && count-- == 0) + { + return eNamedElement; + } + } + } + + return null; + } } diff --git a/plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/impl/EPackageImpl.java b/plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/impl/EPackageImpl.java index 0fa07dff0..da96eb7e6 100644 --- a/plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/impl/EPackageImpl.java +++ b/plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/impl/EPackageImpl.java @@ -14,6 +14,7 @@ package org.eclipse.emf.ecore.impl; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; @@ -423,6 +424,7 @@ public class EPackageImpl extends ENamedElementImpl implements EPackage, BasicEx protected void didChange() { eNameToEClassifierMap = null; + eNameToENamedElementMaps = null; } }; } @@ -530,13 +532,23 @@ public class EPackageImpl extends ENamedElementImpl implements EPackage, BasicEx /** * <!-- begin-user-doc --> * <!-- end-user-doc --> - * @generated + * @generated NOT */ public EList<EPackage> getESubpackages() { if (eSubpackages == null) { - eSubpackages = new EObjectContainmentWithInverseEList.Resolving<EPackage>(EPackage.class, this, EcorePackage.EPACKAGE__ESUBPACKAGES, EcorePackage.EPACKAGE__ESUPER_PACKAGE); + eSubpackages = + new EObjectContainmentWithInverseEList.Resolving<EPackage>(EPackage.class, this, EcorePackage.EPACKAGE__ESUBPACKAGES, EcorePackage.EPACKAGE__ESUPER_PACKAGE) + { + private static final long serialVersionUID = 1L; + + @Override + protected void didChange() + { + eNameToENamedElementMaps = null; + } + }; } return eSubpackages; } @@ -1867,11 +1879,105 @@ public class EPackageImpl extends ENamedElementImpl implements EPackage, BasicEx this.ePackageExtendedMetaData = ePackageExtendedMetaData; } + private static final class Computation + { + private static final ThreadLocal<Map<EPackage, Computation>> COMPUTATION_IN_PROGRESS = + new ThreadLocal<Map<EPackage, Computation>>() + { + @Override + protected Map<EPackage, Computation> initialValue() + { + return new HashMap<EPackage, Computation>(); + } + }; + + public static final Computation get(EPackage ePackage) + { + Map<EPackage, Computation> computationInProgress = COMPUTATION_IN_PROGRESS.get(); + Computation computation = computationInProgress.get(ePackage); + if (computation == null) + { + computation = new Computation(ePackage, computationInProgress); + computationInProgress.put(ePackage, computation); + } + return computation; + } + + private final EPackage ePackage; + + private final Map<EPackage, Computation> computationInProgress; + + private final Iterator<EObject> iterator; + + private final List<Map<String, ENamedElement>> result = new ArrayList<Map<String,ENamedElement>>(); + + public Computation(EPackage ePackage, Map<EPackage, Computation> computationInProgress) + { + this.ePackage = ePackage; + this.computationInProgress = computationInProgress; + iterator = ePackage.eContents().iterator(); + result.add(new HashMap<String, ENamedElement>()); + } + + public List<Map<String, ENamedElement>> compute() + { + try + { + while (iterator.hasNext()) + { + EObject eObject = iterator.next(); + if (eObject instanceof ENamedElement) + { + ENamedElement eNamedElement = (ENamedElement)eObject; + Map<String, ENamedElement> target = result.get(0); + int count = 0; + String name = eNamedElement.getName(); + while (target.containsKey(name)) + { + if (result.size() >= ++count) + { + target = new HashMap<String, ENamedElement>(); + result.add(target); + } + else + { + target = result.get(count); + } + } + target.put(name, eNamedElement); + } + } + + return result; + } + finally + { + computationInProgress.remove(ePackage); + } + } + } + + private List<Map<String, ENamedElement>> eNameToENamedElementMaps; + + @Override + EObject eObjectForURIFragmentNameSegment(String name, int count) + { + if (eNameToENamedElementMaps == null) + { + Computation computation = Computation.get(this); + eNameToENamedElementMaps = computation.compute(); + } + return count >= 0 || count < eNameToENamedElementMaps.size() ? eNameToENamedElementMaps.get(count).get(name) : null; + } + @Override - public EObject eObjectForURIFragmentSegment(String uriFragmentSegment) + public void setName(String newName) { - EObject result = getEClassifierGen(uriFragmentSegment); - return result != null ? result : super.eObjectForURIFragmentSegment(uriFragmentSegment); + if (eContainer instanceof EPackageImpl) + { + ((EPackageImpl)eContainer).eNameToENamedElementMaps = null; + } + super.setName(newName); } /** |