org.eclipse.xtext.linking.impl.DefaultLinkingService Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2008 itemis AG (http://www.itemis.eu) and others.
* 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
*******************************************************************************/
package org.eclipse.xtext.linking.impl;
import java.util.Collections;
import java.util.List;
import org.apache.log4j.Logger;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.xtext.linking.LinkingScopeProviderBinding;
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.eclipse.xtext.scoping.impl.AbstractGlobalScopeDelegatingScopeProvider;
import org.eclipse.xtext.scoping.impl.IDelegatingScopeProvider;
import org.eclipse.xtext.util.internal.Stopwatches;
import org.eclipse.xtext.util.internal.Stopwatches.StoppedTask;
import com.google.inject.Inject;
import com.google.inject.Provider;
/**
* @author Heiko Behrens - Initial contribution and API
* @author Michael Clay
* @author Sebastian Zarnekow
* @author Sven Efftinge
* @author Moritz Eysholdt
*/
public class DefaultLinkingService extends AbstractLinkingService {
private static final Logger logger = Logger.getLogger(DefaultLinkingService.class);
@Inject
@LinkingScopeProviderBinding
private IScopeProvider scopeProvider;
@Inject
private Provider importedNamesAdapterProvider;
@Inject
private LinkingHelper linkingHelper;
@Inject
private IQualifiedNameConverter qualifiedNameConverter;
protected IScope getScope(EObject context, EReference reference) {
if (getScopeProvider() == null)
throw new IllegalStateException("scopeProvider must not be null.");
try {
registerImportedNamesAdapter(context);
return getScopeProvider().getScope(context, reference);
} finally {
unRegisterImportedNamesAdapter();
}
}
protected void unRegisterImportedNamesAdapter() {
unRegisterImportedNamesAdapter(getScopeProvider());
}
protected void unRegisterImportedNamesAdapter(IScopeProvider scopeProvider) {
if (scopeProvider instanceof AbstractGlobalScopeDelegatingScopeProvider) {
AbstractGlobalScopeDelegatingScopeProvider provider = (AbstractGlobalScopeDelegatingScopeProvider) scopeProvider;
provider.setWrapper(null);
} else if (scopeProvider instanceof IDelegatingScopeProvider) {
IDelegatingScopeProvider delegatingScopeProvider = (IDelegatingScopeProvider) scopeProvider;
unRegisterImportedNamesAdapter(delegatingScopeProvider.getDelegate());
}
}
protected void registerImportedNamesAdapter(EObject context) {
registerImportedNamesAdapter(getScopeProvider(), context);
}
protected void registerImportedNamesAdapter(IScopeProvider scopeProvider, EObject context) {
if (scopeProvider instanceof AbstractGlobalScopeDelegatingScopeProvider) {
AbstractGlobalScopeDelegatingScopeProvider provider = (AbstractGlobalScopeDelegatingScopeProvider) scopeProvider;
ImportedNamesAdapter adapter = getImportedNamesAdapter(context);
provider.setWrapper(adapter);
} else if (scopeProvider instanceof IDelegatingScopeProvider) {
IDelegatingScopeProvider delegatingScopeProvider = (IDelegatingScopeProvider) scopeProvider;
registerImportedNamesAdapter(delegatingScopeProvider.getDelegate(), context);
}
}
protected ImportedNamesAdapter getImportedNamesAdapter(EObject context) {
ImportedNamesAdapter adapter = ImportedNamesAdapter.find(context.eResource());
if (adapter!=null)
return adapter;
ImportedNamesAdapter importedNamesAdapter = importedNamesAdapterProvider.get();
context.eResource().eAdapters().add(importedNamesAdapter);
return importedNamesAdapter;
}
/**
* @return the first element returned from the injected {@link IScopeProvider} which matches the text of the passed
* {@link INode node}
*/
public List getLinkedObjects(EObject context, EReference ref, INode node)
throws IllegalNodeException {
final EClass requiredType = ref.getEReferenceType();
if (requiredType == null)
return Collections. emptyList();
final String crossRefString = getCrossRefNodeAsString(node);
if (crossRefString != null && !crossRefString.equals("")) {
if (logger.isDebugEnabled()) {
logger.debug("before getLinkedObjects: node: '" + crossRefString + "'");
}
StoppedTask task = Stopwatches.forTask("Crosslink resolution (DefaultLinkingService.getLinkedObjects)");
try {
task.start();
final IScope scope = getScope(context, ref);
QualifiedName qualifiedLinkName = qualifiedNameConverter.toQualifiedName(crossRefString);
IEObjectDescription eObjectDescription = scope.getSingleElement(qualifiedLinkName);
if (logger.isDebugEnabled()) {
logger.debug("after getLinkedObjects: node: '" + crossRefString + "' result: " + eObjectDescription);
}
if (eObjectDescription != null)
return Collections.singletonList(eObjectDescription.getEObjectOrProxy());
} finally {
task.stop();
}
}
return Collections.emptyList();
}
public String getCrossRefNodeAsString(INode node) throws IllegalNodeException {
return linkingHelper.getCrossRefNodeAsString(node, true);
}
public void setScopeProvider(IScopeProvider scopeProvider) {
this.scopeProvider = scopeProvider;
}
public IScopeProvider getScopeProvider() {
return scopeProvider;
}
protected LinkingHelper getLinkingHelper() {
return linkingHelper;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy