package org.csstudio.sds.util; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; /** * Utility to deal with relative paths. * * @author Kai Meyer (C1 WPS) * */ public final class PathUtil { /** * Path to get one folder back. */ private static IPath _folderBackPath = new Path("../"); /** * Private constructor. */ private PathUtil() { // nothing to do } /** * Creates a new relativ {@link IPath} based on the given path, but relative * to the anchorPath. * * If the parameters are * "C:/Program/Development/SDS/Scripts/Script.css-sdss" as path and * "C:/Program/Development/SDS/Display.css-sds" as anchorPath the result * will be "/Scripts/Script.css-sdss". * * @param path * The path to convert * @param anchorPath * The The related path * @return A new {@link IPath} based on path and relative to the anchorPath */ public static IPath makePathRelativToAnchor(final IPath path, final IPath anchorPath) { IPath result = path; IPath referencePath = anchorPath; String lastSegment = referencePath.lastSegment(); if (lastSegment.contains(".")) { referencePath = referencePath.removeLastSegments(1); } if (referencePath.isPrefixOf(result)) { result = result.setDevice(null); int count = referencePath.segmentCount(); result = result.removeFirstSegments(count); } else { String device = getDevice(result); String anchorDevice = getDevice(referencePath); if ((device == null && anchorDevice == null) || (device != null && device.equals(anchorDevice))) { if (device != null) { result = removeDevice(result); referencePath = removeDevice(referencePath); } for (int i = 0; i < referencePath.segmentCount(); i++) { String resultSegment = result.segment(i); String anchorSegment = referencePath.segment(i); if (resultSegment.equals(anchorSegment)) { result = result.removeFirstSegments(1); } else { result = _folderBackPath.append(result); } } } } result = result.makeRelative(); return result; } /** * Returns the device of the given path. * * @param path * The {@link IPath} * @return The device (ending with ':') or <code>null</code> if no device * exists */ private static String getDevice(final IPath path) { String string = path.toString(); String device = null; if (string.charAt(1) == IPath.DEVICE_SEPARATOR) { device = string.substring(0, 2); } return device; } /** * Removes the device of the given path. * * @param path * The {@link IPath} * @return The path without the device */ private static IPath removeDevice(final IPath path) { IPath result = path; String string = path.toString(); if (string.charAt(1) == IPath.DEVICE_SEPARATOR) { result = new Path(string.substring(2)); } return result; } /** * Creates a new absolute {@link IPath} based on the relativePath and the * anchorPath. * * If the parameters are "/Scripts/Script.css-sdss" as path and * "C:/Program/Development/SDS/Display.css-sds" as anchorPath the result * will be "C:/Program/Development/SDS/Scripts/Script.css-sdss". * * @param relativePath * The path to convert * @param anchorPath * The The related path * @return A new {@link IPath} based on path and relative to the anchorPath */ public static IPath getFullPath(final IPath relativePath, final IPath anchorPath) { IPath result = relativePath; if (!result.isAbsolute()) { if (_folderBackPath.isPrefixOf(relativePath)) { int segmentsToRemove = 0; String folderBackSegment = _folderBackPath.toString(); String currentSegment = result.segment(0); while (currentSegment.equals(folderBackSegment)) { segmentsToRemove++; result = result.removeFirstSegments(1); currentSegment = result.segment(0); } IPath path = anchorPath.removeLastSegments(segmentsToRemove); result = path.append(result); } else { if (!anchorPath.isPrefixOf(result)) { result = anchorPath.append(result); } } } return result; } }