/** * Copyright (c) 2012 Cloudsmith Inc. and other contributors, as listed below. * 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: * Cloudsmith * */ package org.cloudsmith.xtext.ui.resource; import org.cloudsmith.xtext.resource.ResourceAccess; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IStorage; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.emf.common.util.URI; import org.eclipse.xtext.ui.resource.IStorage2UriMapper; import org.eclipse.xtext.util.Pair; import com.google.inject.Inject; import com.google.inject.Provider; /** * An Eclipse Platform based {@link Provider} implementation making use of the {@link ResourceContext} to provide * a {@link Resource} specific instance of {@code T} (or "global" if the context is not resource specific). * */ public abstract class PlatformResourceSpecificProvider<T> implements Provider<T> { @Inject protected Provider<ResourceAccess> resourceAccessProvider; @Inject private IWorkspace workspace; @Inject private IStorage2UriMapper storage2UriMapper; /** * A concrete implementation should lookup specific data of type {@code T} for the given IResource. If the given {@code resource} is null, the * implementation should return a "global"/default {@code T}. * * @param resource * the Eclipse platform resource, or null if {@link #getResourceURI()} is not a platform URI * @return data of type T */ abstract protected T dataForResource(IResource resource); /** * Finds the closest Platform {@link IResource} given an URI that is a platform {@link URI}, or an URI that * an {@link IStorage2UriMapper} can map to an {@link IProject}. * * @param uri * @return IResource, or null, if the given uri can not be mapped to IResource. */ protected IResource findPlatformResource(URI uri) { if(uri != null) { if(uri.isPlatformResource()) { String pathString = uri.toPlatformString(true); IWorkspaceRoot root = workspace.getRoot(); IResource r = root.findMember(pathString); // uri is on the form: platform:/resource/project-name/path // search up to project (inclusive) for an existing resource while(r == null && uri.segmentCount() > 1) { uri = uri.trimSegments(1); pathString = uri.toPlatformString(true); r = root.findMember(pathString); } return r; } for(Pair<IStorage, IProject> storage : storage2UriMapper.getStorages(uri)) { return storage.getSecond(); } } // Not a resource URL, a derived implementation may do better return null; } @Override public T get() { // get the ResourceContext in effect (either a global context where the returned URI is // null or the URI of one resource. URI uri = resourceAccessProvider.get().getResourceURI(); return dataForResource(findPlatformResource(uri)); } }