| /******************************************************************************* |
| * Copyright (c) 2004, 2011 Richard Hoefter 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: |
| * Richard Hoefter (richard.hoefter@web.de) - initial API and implementation, bug 95300, bug 95297, bug 128104, bug 201180, bug 288830 |
| * IBM Corporation - NLS'ing and incorporating into Eclipse. |
| * - Bug 177833 Class created from combination of all utility classes of contribution |
| * - Bug 267459 Java project with an external jar file from C:\ on the build path throws a NPE during the Ant Buildfile generation. |
| * - bug fixing |
| *******************************************************************************/ |
| |
| package org.eclipse.ant.internal.ui.datatransfer; |
| |
| import java.io.BufferedReader; |
| import java.io.ByteArrayInputStream; |
| import java.io.File; |
| import java.io.FileNotFoundException; |
| import java.io.FileReader; |
| import java.io.IOException; |
| import java.io.StringWriter; |
| import java.net.URI; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Comparator; |
| import java.util.Iterator; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.TreeSet; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| |
| import javax.xml.parsers.DocumentBuilderFactory; |
| import javax.xml.parsers.ParserConfigurationException; |
| import javax.xml.transform.OutputKeys; |
| import javax.xml.transform.Result; |
| import javax.xml.transform.Source; |
| import javax.xml.transform.Transformer; |
| import javax.xml.transform.TransformerConfigurationException; |
| import javax.xml.transform.TransformerException; |
| import javax.xml.transform.TransformerFactory; |
| import javax.xml.transform.TransformerFactoryConfigurationError; |
| import javax.xml.transform.dom.DOMSource; |
| import javax.xml.transform.stream.StreamResult; |
| |
| import org.eclipse.ant.internal.core.IAntCoreConstants; |
| import org.eclipse.ant.internal.ui.AntUIPlugin; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IMarker; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IWorkspace; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IAdaptable; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.core.runtime.OperationCanceledException; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.variables.VariablesPlugin; |
| import org.eclipse.jdt.core.IClasspathEntry; |
| import org.eclipse.jdt.core.IJavaElement; |
| import org.eclipse.jdt.core.IJavaModelMarker; |
| import org.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jdt.core.IPackageFragmentRoot; |
| import org.eclipse.jdt.core.IType; |
| import org.eclipse.jdt.core.JavaCore; |
| import org.eclipse.jdt.core.JavaModelException; |
| import org.eclipse.jdt.junit.JUnitCore; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.swt.widgets.Shell; |
| import org.w3c.dom.Document; |
| import org.xml.sax.SAXException; |
| |
| /** |
| * Collection of utility methods to help when exporting to an Ant build file. |
| */ |
| public class ExportUtil { |
| private ExportUtil() { |
| } |
| |
| /** |
| * Get resource from selection. |
| */ |
| public static IResource getResource(ISelection selection) { |
| if (selection instanceof IStructuredSelection) { |
| for (Iterator iter = ((IStructuredSelection) selection).iterator(); iter |
| .hasNext();) { |
| IAdaptable adaptable = (IAdaptable) iter.next(); |
| return (IResource) adaptable.getAdapter(IResource.class); |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Get Java project from resource. |
| */ |
| public static IJavaProject getJavaProjectByName(String name) { |
| try { |
| IProject project = ResourcesPlugin.getWorkspace().getRoot() |
| .getProject(name); |
| if (project.exists()) { |
| return JavaCore.create(project); |
| } |
| } catch (IllegalArgumentException iae) { |
| } |
| return null; |
| } |
| |
| /** |
| * Get project root for given project. |
| */ |
| public static String getProjectRoot(IJavaProject project) { |
| if (project == null) { |
| return null; |
| } |
| IResource resource = project.getResource(); |
| if (resource == null) { |
| return null; |
| } |
| IPath location = resource.getLocation(); |
| if (location == null) { |
| return null; |
| } |
| return location.toString(); |
| } |
| |
| /** |
| * Convert Eclipse path to absolute filename. |
| * |
| * @param file |
| * Project root optionally followed by resource name. An absolute |
| * path is simply converted to a string. |
| * @return full qualified path |
| */ |
| public static String resolve(IPath file) { |
| if (file == null) { |
| return null; |
| } |
| try { |
| IFile f = ResourcesPlugin.getWorkspace().getRoot().getFile(file); |
| URI uri = f.getLocationURI(); |
| return (uri != null) ? uri.toString() : f.toString(); |
| } catch (IllegalArgumentException e) { |
| // resource is missing |
| String projectName = removePrefix(file.toString(), "/"); //$NON-NLS-1$ |
| IJavaProject project = getJavaProjectByName(projectName); |
| if (project != null) { |
| return getProjectRoot(project); |
| } |
| // project is null because file is not enclosed in a project i.e. |
| // external jar |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=267459 |
| return file.toOSString(); |
| } |
| } |
| |
| /** |
| * Get Java project for given root. |
| */ |
| public static IJavaProject getJavaProject(String root) { |
| IPath path = new Path(root); |
| if (path.segmentCount() == 1) { |
| return getJavaProjectByName(root); |
| } |
| IResource resource = ResourcesPlugin.getWorkspace().getRoot() |
| .findMember(path); |
| if (resource != null && resource.getType() == IResource.PROJECT) { |
| if (resource.exists()) { |
| return (IJavaProject) JavaCore.create(resource); |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Remove project root from given project file. |
| */ |
| public static String removeProjectRoot(String file, IProject project) { |
| String res = removePrefix(file, '/' + project.getName() + '/'); |
| if (res.equals('/' + project.getName())) { |
| return "."; //$NON-NLS-1$ |
| } |
| return res; |
| } |
| |
| /** |
| * Remove project root from given project file. |
| * |
| * @param newProjectRoot |
| * replace project root, e.g. with a variable ${project.location} |
| */ |
| public static String replaceProjectRoot(String file, IProject project, |
| String newProjectRoot) { |
| String res = removeProjectRoot(file, project); |
| if (res.equals(".")) //$NON-NLS-1$ |
| { |
| return newProjectRoot; |
| } |
| if (newProjectRoot == null) { |
| return res; |
| } |
| if (!res.equals(file)) { |
| return newProjectRoot + '/' + res; |
| } |
| return res; |
| } |
| |
| /** |
| * Get for given project all directly dependent projects. |
| * |
| * @return set of IJavaProject objects |
| */ |
| public static List getClasspathProjects(IJavaProject project) |
| throws JavaModelException { |
| List projects = new ArrayList(); |
| IClasspathEntry entries[] = project.getRawClasspath(); |
| addClasspathProjects(projects, entries); |
| return sortProjectsUsingBuildOrder(projects); |
| } |
| |
| private static void addClasspathProjects(List projects, |
| IClasspathEntry[] entries) { |
| for (int i = 0; i < entries.length; i++) { |
| IClasspathEntry classpathEntry = entries[i]; |
| if (classpathEntry.getContentKind() == IPackageFragmentRoot.K_SOURCE |
| && classpathEntry.getEntryKind() == IClasspathEntry.CPE_PROJECT) { |
| // found required project on build path |
| String subProjectRoot = classpathEntry.getPath().toString(); |
| IJavaProject subProject = getJavaProject(subProjectRoot); |
| // is project available in workspace |
| if (subProject != null) { |
| projects.add(subProject); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Get for given project all directly and indirectly dependent projects. |
| * |
| * @return set of IJavaProject objects |
| */ |
| public static List getClasspathProjectsRecursive(IJavaProject project) |
| throws JavaModelException { |
| LinkedList result = new LinkedList(); |
| getClasspathProjectsRecursive(project, result); |
| return sortProjectsUsingBuildOrder(result); |
| } |
| |
| private static void getClasspathProjectsRecursive(IJavaProject project, |
| LinkedList result) throws JavaModelException { |
| List projects = getClasspathProjects(project); |
| for (Iterator iter = projects.iterator(); iter.hasNext();) { |
| IJavaProject javaProject = (IJavaProject) iter.next(); |
| if (!result.contains(javaProject)) { |
| result.addFirst(javaProject); |
| getClasspathProjectsRecursive(javaProject, result); // recursion |
| } |
| } |
| } |
| |
| /** |
| * Sort projects according to General -> Workspace -> Build Order. |
| * |
| * @param projects |
| * list of IJavaProject objects |
| * @return list of IJavaProject objects with new order |
| */ |
| private static List sortProjectsUsingBuildOrder(List javaProjects) { |
| if (javaProjects.isEmpty()) { |
| return javaProjects; |
| } |
| List result = new ArrayList(javaProjects.size()); |
| IWorkspace workspace = ResourcesPlugin.getWorkspace(); |
| String[] buildOrder = workspace.getDescription().getBuildOrder(); |
| if (buildOrder == null) {// default build order |
| IProject[] projects = new IProject[javaProjects.size()]; |
| int i = 0; |
| for (Iterator iter = javaProjects.iterator(); iter.hasNext(); i++) { |
| IJavaProject javaProject = (IJavaProject) iter.next(); |
| projects[i] = javaProject.getProject(); |
| } |
| IWorkspace.ProjectOrder po = ResourcesPlugin.getWorkspace() |
| .computeProjectOrder(projects); |
| projects = po.projects; |
| buildOrder = new String[projects.length]; |
| for (i = 0; i < projects.length; i++) { |
| buildOrder[i] = projects[i].getName(); |
| } |
| } |
| |
| for (int i = 0; i < buildOrder.length && !javaProjects.isEmpty(); i++) { |
| String projectName = buildOrder[i]; |
| for (Iterator iter = javaProjects.iterator(); iter.hasNext();) { |
| IJavaProject javaProject = (IJavaProject) iter.next(); |
| if (javaProject.getProject().getName().equals(projectName)) { |
| result.add(javaProject); |
| iter.remove(); |
| } |
| } |
| } |
| // add any remaining projects not specified in the build order |
| result.addAll(javaProjects); |
| return result; |
| } |
| |
| /** |
| * Check if given project has a cyclic dependency. |
| * |
| * <p> |
| * See org.eclipse.jdt.core.tests.model.ClasspathTests.numberOfCycleMarkers. |
| */ |
| public static boolean hasCyclicDependency(IJavaProject javaProject) |
| throws CoreException { |
| IMarker[] markers = javaProject.getProject().findMarkers( |
| IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, |
| IResource.DEPTH_ONE); |
| for (int i = 0; i < markers.length; i++) { |
| IMarker marker = markers[i]; |
| String cycleAttr = (String) marker |
| .getAttribute(IJavaModelMarker.CYCLE_DETECTED); |
| if (cycleAttr != null && cycleAttr.equals("true")) //$NON-NLS-1$ |
| { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Find JUnit tests. Same tests are also returned by Eclipse run |
| * configuration wizard. |
| * |
| * @param containerHandle |
| * project, package or source folder |
| */ |
| public static IType[] findTestsInContainer(String containerHandle) { |
| IJavaElement container = JavaCore.create(containerHandle); |
| if (container == null) { |
| return new IType[0]; |
| } |
| try { |
| return JUnitCore |
| .findTestTypes(container, new NullProgressMonitor()); |
| } catch (OperationCanceledException e) { |
| AntUIPlugin.log(e); |
| } catch (CoreException e) { |
| AntUIPlugin.log(e); |
| } |
| return new IType[0]; |
| } |
| |
| /** |
| * Compares projects by project name. |
| */ |
| public static synchronized Comparator getJavaProjectComparator() { |
| if (javaProjectComparator == null) { |
| javaProjectComparator = new JavaProjectComparator(); |
| } |
| return javaProjectComparator; |
| } |
| |
| private static Comparator javaProjectComparator; |
| |
| private static class JavaProjectComparator implements Comparator { |
| public int compare(Object o1, Object o2) { |
| IJavaProject j1 = (IJavaProject) o1; |
| IJavaProject j2 = (IJavaProject) o2; |
| return j1.getProject().getName().compareTo( |
| j2.getProject().getName()); |
| } |
| } |
| |
| /** |
| * Compares objects by class name. |
| */ |
| public static synchronized Comparator getClassnameComparator() { |
| if (classnameComparator == null) { |
| classnameComparator = new ClassnameComparator(); |
| } |
| return classnameComparator; |
| } |
| |
| private static Comparator classnameComparator; |
| |
| private static class ClassnameComparator implements Comparator { |
| public int compare(Object o1, Object o2) { |
| return o1.getClass().getName().compareTo(o2.getClass().getName()); |
| } |
| } |
| |
| /** |
| * Compares IFile objects. |
| */ |
| public static synchronized Comparator getIFileComparator() { |
| if (fileComparator == null) { |
| fileComparator = new IFileComparator(); |
| } |
| return fileComparator; |
| } |
| |
| private static Comparator fileComparator; |
| |
| private static class IFileComparator implements Comparator { |
| public int compare(Object o1, Object o2) { |
| IFile f1 = (IFile) o1; |
| IFile f2 = (IFile) o2; |
| return f1.toString().compareTo(f2.toString()); |
| } |
| } |
| |
| /** |
| * Compares IType objects. |
| */ |
| public static synchronized Comparator getITypeComparator() { |
| if (typeComparator == null) { |
| typeComparator = new TypeComparator(); |
| } |
| return typeComparator; |
| } |
| |
| private static Comparator typeComparator; |
| |
| private static class TypeComparator implements Comparator { |
| public int compare(Object o1, Object o2) { |
| IType t1 = (IType) o1; |
| IType t2 = (IType) o2; |
| return t1.getFullyQualifiedName().compareTo( |
| t2.getFullyQualifiedName()); |
| } |
| } |
| |
| /** |
| * Platform specific newline character(s). |
| */ |
| public static final String NEWLINE = System.getProperty("line.separator"); //$NON-NLS-1$ |
| |
| public static String removePrefix(String s, String prefix) { |
| if (s == null) { |
| return null; |
| } |
| if (s.startsWith(prefix)) { |
| return s.substring(prefix.length()); |
| } |
| return s; |
| } |
| |
| /** |
| * Remove suffix from given string. |
| */ |
| public static String removeSuffix(String s, String suffix) { |
| if (s == null) { |
| return null; |
| } |
| if (s.endsWith(suffix)) { |
| return s.substring(0, s.length() - suffix.length()); |
| } |
| return s; |
| } |
| |
| /** |
| * Remove prefix and suffix from given string. |
| */ |
| public static String removePrefixAndSuffix(String s, String prefix, |
| String suffix) { |
| return removePrefix(removeSuffix(s, suffix), prefix); |
| } |
| |
| /** |
| * Convert document to formatted XML string. |
| */ |
| public static String toString(Document doc) |
| throws TransformerConfigurationException, |
| TransformerFactoryConfigurationError, TransformerException { |
| // NOTE: There are different transformer implementations in the wild, |
| // which are configured differently |
| // regarding the indent size: |
| // Java 1.4: org.apache.xalan.transformer.TransformerIdentityImpl |
| // Java 1.5: |
| // com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl |
| |
| StringWriter writer = new StringWriter(); |
| Source source = new DOMSource(doc); |
| Result result = new StreamResult(writer); |
| TransformerFactory factory = TransformerFactory.newInstance(); |
| boolean indentFallback = false; |
| try { |
| // indent using TransformerImpl |
| factory.setAttribute("indent-number", "4"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } catch (IllegalArgumentException e) { |
| // option not supported, set indent size below |
| indentFallback = true; |
| } |
| Transformer transformer = factory.newTransformer(); |
| transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$ |
| if (indentFallback) { |
| // indent using TransformerIdentityImpl |
| transformer.setOutputProperty( |
| "{http://xml.apache.org/xslt}indent-amount", "4"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| transformer.transform(source, result); |
| return writer.toString(); |
| } |
| |
| /** |
| * Read XML file. |
| */ |
| public static Document parseXmlFile(File file) throws SAXException, |
| IOException, ParserConfigurationException { |
| DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); |
| factory.setValidating(false); |
| Document doc = factory.newDocumentBuilder().parse(file); |
| return doc; |
| } |
| |
| /** |
| * Read XML string. |
| */ |
| public static Document parseXmlString(String s) throws SAXException, |
| IOException, ParserConfigurationException { |
| DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); |
| factory.setValidating(false); |
| Document doc = factory.newDocumentBuilder().parse( |
| new ByteArrayInputStream(s.getBytes())); |
| return doc; |
| } |
| |
| /** |
| * Converts collection to a separated string. |
| * |
| * @param c |
| * collection |
| * @param separator |
| * string to separate items |
| * @return collection items separated with given separator |
| */ |
| public static String toString(Collection c, String separator) { |
| StringBuffer b = new StringBuffer(); |
| for (Iterator iter = c.iterator(); iter.hasNext();) { |
| b.append((String) iter.next()); |
| b.append(separator); |
| } |
| if (c.size() > 0) { |
| b.delete(b.length() - separator.length(), b.length()); |
| } |
| return b.toString(); |
| } |
| |
| /** |
| * Remove duplicates preserving original order. |
| * |
| * @param l |
| * list to remove duplicates from |
| * @return new list without duplicates |
| */ |
| public static List removeDuplicates(List l) { |
| List res = new ArrayList(); |
| for (Iterator iter = l.iterator(); iter.hasNext();) { |
| Object element = iter.next(); |
| if (!res.contains(element)) { |
| res.add(element); |
| } |
| } |
| return res; |
| } |
| |
| /** |
| * Check if given file exists that was not written by this export. |
| */ |
| public static boolean existsUserFile(String filename) { |
| File buildFile = new File(filename); |
| if (buildFile.exists()) { |
| BufferedReader in = null; |
| try { |
| in = new BufferedReader(new FileReader(buildFile)); |
| int i = BuildFileCreator.WARNING.indexOf(NEWLINE); |
| String warning = BuildFileCreator.WARNING.substring(0, i); |
| String line; |
| while ((line = in.readLine()) != null) { |
| if (line.indexOf(warning) != -1) { |
| return false; |
| } |
| } |
| return true; |
| } catch (FileNotFoundException e) { |
| return false; |
| } catch (IOException e) { |
| return false; |
| } finally { |
| try { |
| if (in != null) { |
| in.close(); |
| } |
| } catch (IOException e) { |
| // ignore |
| } |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Request write access to given file. Depending on the version control |
| * plug-in opens a confirm checkout dialog. |
| * |
| * @param shell |
| * parent instance for dialogs |
| * @param file |
| * file to request write access for |
| * @return <code>true</code> if user confirmed checkout |
| */ |
| public static boolean validateEdit(Shell shell, IFile file) { |
| return file.getWorkspace().validateEdit(new IFile[] { file }, shell) |
| .isOK(); |
| } |
| |
| /** |
| * Request write access to given files. Depending on the version control |
| * plug-in opens a confirm checkout dialog. |
| * |
| * @param shell |
| * parent instance for dialogs |
| * @return <code>IFile</code> objects for which user confirmed checkout |
| * @throws CoreException |
| * thrown if project is under version control, but not connected |
| */ |
| public static Set validateEdit(Shell shell, List files) |
| throws CoreException { |
| Set confirmedFiles = new TreeSet(getIFileComparator()); |
| if (files.size() == 0) { |
| return confirmedFiles; |
| } |
| IStatus status = ((IFile) files.get(0)).getWorkspace().validateEdit( |
| (IFile[]) files.toArray(new IFile[files.size()]), shell); |
| if (status.isMultiStatus() && status.getChildren().length > 0) { |
| for (int i = 0; i < status.getChildren().length; i++) { |
| IStatus statusChild = status.getChildren()[i]; |
| if (statusChild.isOK()) { |
| confirmedFiles.add(files.get(i)); |
| } |
| } |
| } else if (status.isOK()) { |
| for (Iterator iterator = files.iterator(); iterator.hasNext();) { |
| IFile file = (IFile) iterator.next(); |
| confirmedFiles.add(file); |
| } |
| } |
| if (status.getSeverity() == IStatus.ERROR) { |
| // not possible to checkout files: not connected to version |
| // control plugin or hijacked files and made read-only, so |
| // collect error messages provided by validator and re-throw |
| StringBuffer message = new StringBuffer(status.getPlugin() + ": " //$NON-NLS-1$ |
| + status.getMessage() + NEWLINE); |
| if (status.isMultiStatus()) { |
| for (int i = 0; i < status.getChildren().length; i++) { |
| IStatus statusChild = status.getChildren()[i]; |
| message.append(statusChild.getMessage() + NEWLINE); |
| } |
| } |
| throw new CoreException(new Status(IStatus.ERROR, |
| AntUIPlugin.PI_ANTUI, 0, message.toString(), null)); |
| } |
| |
| return confirmedFiles; |
| } |
| |
| /** |
| * Check if given classpath is a reference to the default classpath of the |
| * project. Ideal for testing if runtime classpath was customized. |
| */ |
| public static boolean isDefaultClasspath(IJavaProject project, |
| EclipseClasspath classpath) { |
| // default classpath contains exactly the JRE and the project reference |
| List list = removeDuplicates(classpath.rawClassPathEntries); |
| if (list.size() != 2) { |
| return false; |
| } |
| String entry1 = (String) list.get(0); |
| String entry2 = (String) list.get(1); |
| if (!EclipseClasspath.isJreReference(entry1)) { |
| return false; |
| } |
| if (EclipseClasspath.isProjectReference(entry2)) { |
| IJavaProject referencedProject = EclipseClasspath |
| .resolveProjectReference(entry2); |
| if (referencedProject == null) { |
| // project was not loaded in workspace |
| return false; |
| } else if (referencedProject.getProject().getName().equals( |
| project.getProject().getName())) { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| /** |
| * Add variable/value for Eclipse variable. If given string is no variable, |
| * nothing is added. |
| * |
| * @param variable2valueMap |
| * property map to add variable/value |
| * @param s |
| * String which may contain Eclipse variables, e.g. |
| * ${project_name} |
| */ |
| public static void addVariable(Map variable2valueMap, String s, |
| String projectRoot) { |
| if (s == null || s.equals(IAntCoreConstants.EMPTY_STRING)) |
| { |
| return; |
| } |
| Pattern pattern = Pattern.compile("\\$\\{.*?\\}"); // ${var} //$NON-NLS-1$ |
| Matcher matcher = pattern.matcher(s); |
| while (matcher.find()) { |
| String variable = matcher.group(); |
| String value; |
| try { |
| value = VariablesPlugin.getDefault().getStringVariableManager() |
| .performStringSubstitution(variable); |
| } catch (CoreException e) { |
| // cannot resolve variable |
| value = variable; |
| } |
| variable = removePrefixAndSuffix(variable, "${", "}"); //$NON-NLS-1$ //$NON-NLS-2$ |
| // if it is an environment variable, convert to Ant environment |
| // syntax |
| if (variable.startsWith("env_var:")) //$NON-NLS-1$ |
| { |
| value = "env." + variable.substring("env_var:".length()); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| File file = new File(value); |
| if (file.exists()) { |
| value = getRelativePath(file.getAbsolutePath(), projectRoot); |
| } |
| variable2valueMap.put(variable, value); |
| } |
| } |
| |
| /** |
| * Returns a path which is equivalent to the given location relative to the |
| * specified base path. |
| */ |
| public static String getRelativePath(String otherLocation, String basePath) { |
| |
| IPath location = new Path(otherLocation); |
| IPath base = new Path(basePath); |
| if ((location.getDevice() != null && !location.getDevice() |
| .equalsIgnoreCase(base.getDevice())) |
| || !location.isAbsolute()) { |
| return otherLocation; |
| } |
| int baseCount = base.segmentCount(); |
| int count = base.matchingFirstSegments(location); |
| String temp = IAntCoreConstants.EMPTY_STRING; |
| for (int j = 0; j < baseCount - count; j++) { |
| temp += "../"; //$NON-NLS-1$ |
| } |
| String relative = new Path(temp).append( |
| location.removeFirstSegments(count)).toString(); |
| if (relative.length() == 0) { |
| relative = "."; //$NON-NLS-1$ |
| } |
| |
| return relative; |
| } |
| } |