/** * Copyright (c) 2011 - 2015, Lunifera GmbH (Gross Enzersdorf), Loetz KG (Heidelberg) * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Florian Pirchner - Initial implementation */ package org.lunifera.dsl.xtext.lazyresolver.linker; import java.util.Collections; import java.util.List; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.xtext.linking.impl.DefaultLinkingService; import org.eclipse.xtext.linking.impl.IllegalNodeException; import org.eclipse.xtext.naming.IQualifiedNameConverter; import org.eclipse.xtext.naming.QualifiedName; import org.eclipse.xtext.nodemodel.INode; import org.eclipse.xtext.resource.IEObjectDescription; import org.eclipse.xtext.scoping.IScope; import org.eclipse.xtext.scoping.IScopeProvider; import org.lunifera.dsl.xtext.lazyresolver.LazyJvmTypeLinkingHelper; import org.lunifera.dsl.xtext.lazyresolver.LazyJvmTypeLinkingHelper.IJvmLinkCrossRefStringEnhancer; import org.lunifera.dsl.xtext.lazyresolver.api.logger.TimeLogger; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.inject.Inject; public class FastLinkingService extends DefaultLinkingService { private static final Logger LOGGER = LoggerFactory .getLogger(FastLinkingService.class); @Inject private IQualifiedNameConverter qualifiedNameConverter; @Inject private LazyJvmTypeLinkingHelper jvmTypeLinkingHelper; /** * @return the first element returned from the injected * {@link IScopeProvider} which matches the text of the passed * {@link INode node} */ public List<EObject> getLinkedObjects(EObject context, EReference ref, INode node) throws IllegalNodeException { final EClass requiredType = ref.getEReferenceType(); if (requiredType == null) return Collections.<EObject> emptyList(); String crossRefString = getCrossRefNodeAsString(node); if (crossRefString != null && !crossRefString.equals("")) { // enhance the cross reference string before scoping try { EStructuralFeature containingFeature = context .eContainingFeature(); if (jvmTypeLinkingHelper.isJvmLink(containingFeature)) { IJvmLinkCrossRefStringEnhancer enhancer = jvmTypeLinkingHelper .getEnhancer(containingFeature); if (enhancer != null) { crossRefString = enhancer.enhance(context, containingFeature, crossRefString); } } } catch (Exception e) { LOGGER.error("{}", e); } if (LOGGER.isDebugEnabled()) { LOGGER.debug("before getLinkedObjects: node: '" + crossRefString + "'"); } TimeLogger createLog = TimeLogger.start(getClass()); final IScope scope = getScope(context, ref); createLog.stop(LOGGER, "Creating scope for " + crossRefString + " " + toRefName(ref) + " and context " + context + " took"); QualifiedName qualifiedLinkName = qualifiedNameConverter .toQualifiedName(crossRefString); TimeLogger doScopeLog = TimeLogger.start(getClass()); IEObjectDescription eObjectDescription = scope .getSingleElement(qualifiedLinkName); doScopeLog.stop(LOGGER, "Executing scope for " + crossRefString + " " + toRefName(ref) + " and context " + context + " with result " + eObjectDescription + " took"); if (LOGGER.isDebugEnabled()) { LOGGER.debug("after getLinkedObjects: node: '" + crossRefString + "' result: " + eObjectDescription); } if (eObjectDescription != null) return Collections.singletonList(eObjectDescription .getEObjectOrProxy()); } return Collections.emptyList(); } private String toRefName(EReference ref) { EClass type = ref.getEReferenceType(); return type.getName() + "#" + ref.getName(); } }