| /* |
| * Copyright (c) 2007 Borland Software Corporation |
| * |
| * 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: |
| * bblajer - initial API and implementation |
| */ |
| package org.eclipse.gmf.internal.xpand; |
| |
| import java.io.BufferedReader; |
| import java.io.IOException; |
| import java.io.InputStreamReader; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.LinkedHashSet; |
| import java.util.List; |
| import java.util.Set; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.Path; |
| |
| /** |
| * Tracks template roots for a given project. |
| */ |
| public class RootManager { |
| static final IPath PROJECT_RELATIVE_PATH_TO_CONFIG_FILE = new Path(".xpand-root"); //$NON-NLS-1$ |
| private final IFile myConfig; |
| private List<RootDescription> myRoots; |
| private List<IRootChangeListener> myListeners = new ArrayList<IRootChangeListener>(2); |
| |
| public RootManager(IProject project) { |
| myConfig = project.getFile(PROJECT_RELATIVE_PATH_TO_CONFIG_FILE); |
| } |
| |
| public void addRootChangeListener(IRootChangeListener l) { |
| if (l != null && !myListeners.contains(l)) { |
| myListeners.add(l); |
| } |
| } |
| |
| public void removeRootChangeListener(IRootChangeListener l) { |
| myListeners.remove(l); |
| } |
| |
| void rootsChanged() { |
| myRoots = null; |
| for (IRootChangeListener next : myListeners) { |
| next.rootsChanged(this); |
| } |
| } |
| |
| protected IProject getProject() { |
| return myConfig.getProject(); |
| } |
| |
| public RootDescription getRootDescription(IFile file) { |
| for (RootDescription nextDescription : getRoots()) { |
| if (nextDescription.contains(file)) { |
| return nextDescription; |
| } |
| } |
| return null; |
| } |
| |
| public List<RootDescription> getRoots() { |
| if (myRoots == null) { |
| reloadRoots(); |
| } |
| return myRoots; |
| } |
| |
| private void reloadRoots() { |
| if (!myConfig.exists()) { |
| myRoots = Collections.singletonList(new RootDescription(DEFAULT_ROOTS)); |
| return; |
| } |
| final ArrayList<RootDescription> read = new ArrayList<RootDescription>(); |
| BufferedReader in = null; |
| try { |
| in = new BufferedReader(new InputStreamReader(myConfig.getContents(), myConfig.getCharset())); |
| String line; |
| while((line = in.readLine()) != null) { |
| line = line.trim(); |
| if (line.length() > 0 && line.charAt(0) != '#') { |
| String[] split = line.split(","); |
| ArrayList<IPath> nextPaths = new ArrayList<IPath>(split.length); |
| for (String nextPath : split) { |
| nextPath = nextPath.trim(); |
| if (nextPath.length() > 0) { |
| IPath toAdd = new Path(nextPath); |
| //Absolute paths specify resources relative to workbench and/or |
| if (toAdd.isAbsolute() && toAdd.segmentCount() < 2) { |
| continue; |
| } |
| nextPaths.add(toAdd); |
| } |
| } |
| read.add(new RootDescription(nextPaths)); |
| } |
| } |
| } catch (CoreException ex) { |
| // IGNORE |
| } catch (IOException ex) { |
| // IGNORE |
| } finally { |
| if (in != null) { |
| try { |
| in.close(); |
| } catch (IOException ex) { |
| /* IGNORE */ |
| } |
| } |
| } |
| myRoots = read; |
| } |
| |
| public Set<IProject> getReferencedProjects() { |
| Set<IProject> result = new LinkedHashSet<IProject>(); |
| for (RootDescription nextDescription : getRoots()) { |
| result.addAll(nextDescription.getReferencedProjects()); |
| } |
| return result; |
| } |
| |
| boolean containsProject(IPath projectPath) { |
| if (myRoots == null) { |
| return false; |
| } |
| for (RootDescription nextRoots : myRoots) { |
| for (IPath next : nextRoots.getRoots()) { |
| if (next.isAbsolute() && projectPath.isPrefixOf(next)) { |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| private static final List<IPath> DEFAULT_ROOTS = Collections.<IPath>singletonList(new Path("templates")); //$NON-NLS-1$ |
| |
| public interface IRootChangeListener { |
| public void rootsChanged(RootManager rootManager); |
| } |
| |
| // TODO: make this class static? |
| public class RootDescription { |
| private final List<IPath> myRoots; |
| private Set<IProject> myReferencedProjects; |
| |
| public RootDescription(List<IPath> roots) { |
| myRoots = roots; |
| } |
| |
| public Set<IProject> getReferencedProjects() { |
| if (myReferencedProjects == null) { |
| myReferencedProjects = new LinkedHashSet<IProject>(); |
| for (IPath next : getRoots()) { |
| if (next.isAbsolute() && next.segmentCount() > 1) { |
| IProject candidate = ResourcesPlugin.getWorkspace().getRoot().getProject(next.segment(0)); |
| if (candidate.isAccessible()) { |
| myReferencedProjects.add(candidate); |
| } |
| } |
| } |
| } |
| return myReferencedProjects; |
| } |
| |
| public List<IPath> getRoots() { |
| return myRoots; |
| } |
| |
| public boolean contains(IResource resource) { |
| if (resource == null) { |
| return false; |
| } |
| for (IPath nextRoot : myRoots) { |
| if (nextRoot.isAbsolute()) { |
| if (nextRoot.isPrefixOf(resource.getFullPath())) { |
| return true; |
| } |
| } else { |
| if (resource.getProject().equals(getProject()) && nextRoot.isPrefixOf(resource.getProjectRelativePath())) { |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| } |
| } |