/** * Copyright (c) 2017 committers of YAKINDU 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 * Contributors: * committers of YAKINDU - initial API and implementation * */ package org.yakindu.base.expressions.scoping; import java.util.Collections; import java.util.List; import java.util.Set; import java.util.concurrent.ExecutionException; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.URIConverter; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.eclipse.xtext.resource.IEObjectDescription; import org.eclipse.xtext.resource.IResourceDescription; import org.eclipse.xtext.resource.IResourceServiceProvider; import org.eclipse.xtext.resource.impl.EObjectDescriptionLookUp; import org.eclipse.xtext.scoping.IGlobalScopeProvider; import org.eclipse.xtext.scoping.IScope; import org.eclipse.xtext.scoping.Scopes; import org.eclipse.xtext.scoping.impl.AbstractGlobalScopeProvider; import org.eclipse.xtext.scoping.impl.SelectableBasedScope; import com.google.common.base.Predicate; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.inject.Inject; /** * * @author andreas muelder - Initial contribution and API * */ public abstract class AbstractLibraryGlobalScopeProvider extends AbstractGlobalScopeProvider implements IGlobalScopeProvider { @Inject private IResourceServiceProvider.Registry serviceProviderRegistry; protected abstract Set<URI> getLibraries(Resource context); protected Iterable<URI> getValidLibraries(Resource context) { return Iterables.filter(getLibraries(context), new Predicate<URI>() { @Override public boolean apply(URI input) { return URIConverter.INSTANCE.exists(input, Collections.EMPTY_MAP); } }); } private LoadingCache<URI, Iterable<IEObjectDescription>> libraryCache; public AbstractLibraryGlobalScopeProvider() { libraryCache = CacheBuilder.newBuilder().build(new CacheLoader<URI, Iterable<IEObjectDescription>>() { @Override public Iterable<IEObjectDescription> load(URI key) throws Exception { return getDescriptions(key); } }); } @Override public IScope getScope(Resource context, EReference reference, Predicate<IEObjectDescription> filter) { List<IEObjectDescription> descriptions = Lists.newArrayList(); for (URI uri : getValidLibraries(context)) { try { Iterables.addAll(descriptions, libraryCache.get(uri)); } catch (ExecutionException e) { e.printStackTrace(); } } return SelectableBasedScope.createScope(IScope.NULLSCOPE, new EObjectDescriptionLookUp(descriptions), reference.getEReferenceType(), isIgnoreCase(reference)); } protected Iterable<IEObjectDescription> getDescriptions(URI uri) { List<IEObjectDescription> result = Lists.newArrayList(); ResourceSet set = new ResourceSetImpl(); Resource resource = set.getResource(uri, true); IResourceServiceProvider resourceServiceProvider = serviceProviderRegistry.getResourceServiceProvider(uri); if (resourceServiceProvider == null) { Iterables.addAll(result, Scopes.scopedElementsFor(Lists.newArrayList(resource.getAllContents()))); } else { IResourceDescription resourceDescription = resourceServiceProvider.getResourceDescriptionManager() .getResourceDescription(resource); Iterables.addAll(result, resourceDescription.getExportedObjects()); } resource.unload(); return result; } }