/** * <copyright> * </copyright> * * */ package org.feature.multi.perspective.mapping.viewmapping.resource.mtext.mopp; /** * Standard implementation of <code>IContextDependentURIFragment</code>. * * @param <ContainerType> the type of the object that contains the reference which * shall be resolved by this fragment. * @param <ReferenceType> the type of the reference which shall be resolved by * this fragment. */ public abstract class MtextContextDependentURIFragment<ContainerType extends org.eclipse.emf.ecore.EObject, ReferenceType extends org.eclipse.emf.ecore.EObject> implements org.feature.multi.perspective.mapping.viewmapping.resource.mtext.IMtextContextDependentURIFragment<ReferenceType> { protected String identifier; protected ContainerType container; protected org.eclipse.emf.ecore.EReference reference; protected int positionInReference; protected org.eclipse.emf.ecore.EObject proxy; protected org.feature.multi.perspective.mapping.viewmapping.resource.mtext.IMtextReferenceResolveResult<ReferenceType> result; private boolean resolving; public MtextContextDependentURIFragment(String identifier, ContainerType container, org.eclipse.emf.ecore.EReference reference, int positionInReference, org.eclipse.emf.ecore.EObject proxy) { this.identifier = identifier; this.container = container; this.reference = reference; this.positionInReference = positionInReference; this.proxy = proxy; } public boolean isResolved() { return result != null; } public org.feature.multi.perspective.mapping.viewmapping.resource.mtext.IMtextReferenceResolveResult<ReferenceType> resolve() { if (resolving) { return null; } resolving = true; if (result == null || !result.wasResolved()) { result = new org.feature.multi.perspective.mapping.viewmapping.resource.mtext.mopp.MtextReferenceResolveResult<ReferenceType>(false); // set an initial default error message result.setErrorMessage(getStdErrorMessage()); org.feature.multi.perspective.mapping.viewmapping.resource.mtext.IMtextReferenceResolver<ContainerType, ReferenceType> resolver = getResolver(); // do the actual resolving resolver.resolve(getIdentifier(), getContainer(), getReference(), getPositionInReference(), false, result); // EMFText allows proxies to resolve to multiple objects. The first one is // returned, the others are added here to the reference. if (result.wasResolvedMultiple()) { handleMultipleResults(); } } resolving = false; return result; } public abstract org.feature.multi.perspective.mapping.viewmapping.resource.mtext.IMtextReferenceResolver<ContainerType, ReferenceType> getResolver(); private void handleMultipleResults() { org.eclipse.emf.common.util.EList<org.eclipse.emf.ecore.EObject> list = null; Object temp = container.eGet(reference); if (temp instanceof org.eclipse.emf.common.util.EList<?>) { list = org.feature.multi.perspective.mapping.viewmapping.resource.mtext.util.MtextCastUtil.cast(temp); } boolean first = true; for (org.feature.multi.perspective.mapping.viewmapping.resource.mtext.IMtextReferenceMapping<ReferenceType> mapping : result.getMappings()) { if (first) { first = false; } else if (list != null) { addResultToList(mapping, proxy, list); } else { new org.feature.multi.perspective.mapping.viewmapping.resource.mtext.util.MtextRuntimeUtil().logError(container.eClass().getName() + "." + reference.getName() + " has multiplicity 1 but was resolved to multiple elements", null); } } } private void addResultToList(org.feature.multi.perspective.mapping.viewmapping.resource.mtext.IMtextReferenceMapping<ReferenceType> mapping, org.eclipse.emf.ecore.EObject proxy, org.eclipse.emf.common.util.EList<org.eclipse.emf.ecore.EObject> list) { org.eclipse.emf.ecore.EObject target = null; int proxyPosition = list.indexOf(proxy); if (mapping instanceof org.feature.multi.perspective.mapping.viewmapping.resource.mtext.IMtextElementMapping<?>) { target = ((org.feature.multi.perspective.mapping.viewmapping.resource.mtext.IMtextElementMapping<ReferenceType>) mapping).getTargetElement(); } else if (mapping instanceof org.feature.multi.perspective.mapping.viewmapping.resource.mtext.IMtextURIMapping<?>) { target = org.eclipse.emf.ecore.util.EcoreUtil.copy(proxy); org.eclipse.emf.common.util.URI uri = ((org.feature.multi.perspective.mapping.viewmapping.resource.mtext.IMtextURIMapping<ReferenceType>) mapping).getTargetIdentifier(); ((org.eclipse.emf.ecore.InternalEObject) target).eSetProxyURI(uri); } else { assert false; } try { // if target is an another proxy and list is "unique" add() will try to resolve // the new proxy to check for uniqueness. There seems to be no way to avoid that. // Until now this does not cause any problems. if (proxyPosition + 1 == list.size()) { list.add(target); } else { list.add(proxyPosition + 1, target); } } catch (Exception e1) { e1.printStackTrace(); } } private String getStdErrorMessage() { String typeName = this.getReference().getEType().getName(); String msg = typeName + " '" + identifier + "' not declared"; return msg; } public String getIdentifier() { return identifier; } public ContainerType getContainer() { return container; } public org.eclipse.emf.ecore.EReference getReference() { return reference; } public int getPositionInReference() { return positionInReference; } public org.eclipse.emf.ecore.EObject getProxy() { return proxy; } }