/* * 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; } } }