/******************************************************************************* * Copyright (c) 2012 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.xpect.ui.util; import java.io.IOException; import org.eclipse.core.runtime.Platform; import org.eclipse.emf.common.notify.Adapter; import org.eclipse.emf.common.notify.impl.AdapterImpl; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.xtext.resource.ClassloaderClasspathUriResolver; import org.eclipse.xtext.resource.XtextResource; import org.eclipse.xtext.resource.XtextResourceFactory; import org.eclipse.xtext.resource.XtextResourceSet; import org.eclipse.xtext.util.StringInputStream; import org.osgi.framework.Bundle; import org.xpect.XpectConstants; import org.xpect.XpectFile; import org.xpect.registry.ILanguageInfo; import org.xpect.runner.XpectRunner; import com.google.common.base.Throwables; import com.google.inject.Injector; /** * @author Moritz Eysholdt - Initial contribution and API */ public class XpectFileAccess { private static class XpectResourceAdapter extends AdapterImpl { private final XtextResource resource; public XpectResourceAdapter(XtextResource resource) { super(); this.resource = resource; } } public static ClassLoader getXpectLibClassLoader() { Bundle lib = Platform.getBundle("org.xpect.xtext.lib"); if (lib != null) { try { Class<?> cls = lib.loadClass("org.xpect.xtext.lib.tests.XtextTests"); ClassLoader loader = cls.getClassLoader(); return loader; } catch (ClassNotFoundException e) { Throwables.propagate(e); } } return null; } protected static ResourceSet cloneResourceSet(ResourceSet rs) { XtextResourceSet result = new XtextResourceSet(); result.setPackageRegistry(rs.getPackageRegistry()); // need delegation or nothing because of "java" protocol // result.setResourceFactoryRegistry(rs.getResourceFactoryRegistry()); result.setURIConverter(rs.getURIConverter()); if (XpectRunner.testClassloader != null) { result.setClasspathURIContext(XpectRunner.testClassloader); result.setClasspathUriResolver(new ClassloaderClasspathUriResolver()); } else if (rs instanceof XtextResourceSet) { XtextResourceSet xrs = (XtextResourceSet) rs; Object context = xrs.getClasspathURIContext(); if (context != null) { result.setClasspathURIContext(context); result.setClasspathUriResolver(xrs.getClasspathUriResolver()); } else { result.setClasspathURIContext(getXpectLibClassLoader()); result.setClasspathUriResolver(new ClassloaderClasspathUriResolver()); } } return result; } private static XpectFile findXpectFile(Resource xpectResource) { for (EObject contents : xpectResource.getContents()) if (contents instanceof XpectFile) return (XpectFile) contents; return null; } public static XpectFile getXpectFile(Resource resource) { for (EObject contents : resource.getContents()) if (contents instanceof XpectFile) return (XpectFile) contents; return findXpectFile(getXpectResource(resource)); } public static XtextResource getXpectResource(Resource resource) { for (EObject contents : resource.getContents()) if (contents instanceof XpectFile) return (XtextResource) resource; String document = ((XtextResource) resource).getParseResult().getRootNode().getText(); for (Adapter a : resource.eAdapters()) if (a instanceof XpectResourceAdapter) { XtextResource xpectResource = ((XpectResourceAdapter) a).resource; if (!xpectResource.getParseResult().getRootNode().getText().equals(document)) load(xpectResource, document); return xpectResource; } ResourceSet rs = cloneResourceSet(resource.getResourceSet()); Injector injector = ILanguageInfo.Registry.INSTANCE.getLanguageByFileExtension(XpectConstants.XPECT_FILE_EXT).getInjector(); XtextResource xpectResource = (XtextResource) injector.getInstance(XtextResourceFactory.class).createResource(resource.getURI()); rs.getResources().add(xpectResource); load(xpectResource, document); resource.eAdapters().add(new XpectResourceAdapter(xpectResource)); return xpectResource; } private static void load(Resource xpectResource, String document) { try { xpectResource.unload(); xpectResource.load(new StringInputStream(document), null); } catch (IOException e) { e.printStackTrace(); } } }