/**
* <copyright>
*
* Copyright (c) 2002, 2011 Sebastian Benz 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:
* Sebastian Benz - Initial API and implementation
*
* </copyright>
*
*
*/
package org.xrepl.xscript.scoping;
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Lists.newArrayList;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.xtext.EcoreUtil2;
import org.eclipse.xtext.util.Pair;
import org.eclipse.xtext.util.SimpleCache;
import org.eclipse.xtext.util.Tuples;
import org.xrepl.xscript.xscript.XEPackageImport;
import org.xrepl.xscript.xscript.XScript;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
public final class EPackageResolver {
public Iterable<EPackage> getEPackages(XScript root) {
List<XEPackageImport> ePackageUris = getEPackageUris(root);
List<EPackage> result = new ArrayList<EPackage>(ePackageUris.size());
for (XEPackageImport XPackageUse : ePackageUris) {
try {
EPackage ePackage = resolve(root.eResource(),
XPackageUse.getNsUri());
result.add(ePackage);
} catch (EPackageNotFoundException e) {
// user will be informed during validation
}
}
return result;
}
private List<XEPackageImport> getEPackageUris(XScript root) {
return newArrayList(filter(root.getExpressions(), XEPackageImport.class));
}
private SimpleCache<Pair<Resource, String>, EPackage> cache = new SimpleCache<Pair<Resource, String>, EPackage>(
new Function<Pair<Resource, String>, EPackage>() {
public EPackage apply(Pair<Resource, String> tuple) {
String packageUri = tuple.getSecond();
EPackage ePackage = getPackageFromRegistry(packageUri);
if (ePackage == null) {
ePackage = loadPackageAsResource(tuple.getFirst(),
packageUri);
}
checkPackage(packageUri, ePackage);
return ePackage;
}
});
public EPackage resolve(Resource resource, String packageUri) {
Pair<Resource, String> pair = Tuples.create(resource, packageUri);
return cache.get(pair);
}
private EPackage loadPackageAsResource(Resource context, String packageUri) {
return getEPackage(EcoreUtil2.getResource(context, packageUri));
}
private EPackage getPackageFromRegistry(String packageUri) {
EPackage ePackage = EPackage.Registry.INSTANCE.getEPackage(packageUri);
return ePackage;
}
private void checkPackage(String packageUri, EPackage ePackage)
throws EPackageNotFoundException {
if (ePackage == null) {
throw new EPackageNotFoundException("Could not resolve package "
+ packageUri);
}
}
private EPackage getEPackage(Resource resource) {
EList<EObject> contents = resource.getContents();
if (!contents.isEmpty() && contents.get(0) instanceof EPackage) {
return (EPackage) contents.get(0);
}
throw new NoSuchElementException("Resource " + resource.getURI()
+ " is empty");
}
public Iterable<EPackage> getAllRegisteredEPackages() {
// copy due to potential CME while resolving EPackages
List<String> packageUris = Lists
.newArrayList(EPackage.Registry.INSTANCE.keySet());
return Iterables.transform(packageUris,
new Function<String, EPackage>() {
public EPackage apply(String uri) {
return EPackage.Registry.INSTANCE.getEPackage(uri);
}
});
}
}