// ===================================================================== // // Copyright (C) 2012 - 2016, Philip Graf // // 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 // // ===================================================================== package ch.acanda.eclipse.pmd.builder; import java.io.File; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.InvalidPathException; import java.nio.file.Path; import java.nio.file.Paths; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IWorkspaceRoot; import ch.acanda.eclipse.pmd.domain.Location; import com.google.common.base.Optional; /** * Utility class to resolve a {@link Location}. * * @author Philip Graf */ public final class LocationResolver { private LocationResolver() { // hide constructor of utility class } /** * Resolves the location and checks if it exist. * * @return The absolute location if it exist or {@code Optional#absent()} if it doesn't. */ public static Optional<String> resolveIfExists(final Location location, final IProject project) { final Optional<String> path; switch (location.getContext()) { case WORKSPACE: path = resolveWorkspaceLocationIfExists(location, project); break; case PROJECT: path = resolveProjectLocationIfExists(location, project); break; case FILE_SYSTEM: path = resolveFileSystemLocationIfExists(location); break; case REMOTE: path = resolveRemoteLocationIfExists(location); break; default: throw new IllegalStateException("Unknown location context: " + location.getContext()); } return path; } /** * Resolves a location. Unlike {@link #resolveIfExists(Location, IProject)} this also resolves if the location does * not exist. * * @return The absolute location or {@code null} if it cannot be resolved. */ public static String resolve(final Location location, final IProject project) { final String resolvedLocation; switch (location.getContext()) { case WORKSPACE: final Path workspacePath = resolveWorkspaceLocation(location, project); resolvedLocation = workspacePath == null ? null : workspacePath.toString(); break; case PROJECT: final Path path = Paths.get(project.getLocationURI()).resolve(toOSPath(location.getPath())); resolvedLocation = path.normalize().toString(); break; case FILE_SYSTEM: case REMOTE: resolvedLocation = location.getPath(); break; default: throw new IllegalStateException("Unknown location context: " + location.getContext()); } return resolvedLocation; } private static Optional<String> resolveWorkspaceLocationIfExists(final Location location, final IProject project) { try { final Path path = resolveWorkspaceLocation(location, project); if (path != null && Files.exists(path)) { return Optional.of(path.toString()); } return Optional.absent(); } catch (final InvalidPathException e) { return Optional.absent(); } } private static Path resolveWorkspaceLocation(final Location location, final IProject project) { // format of the location's path: <project-name>/<project-relative-path> if (location.getPath().trim().length() > 0) { final Path locationPath = Paths.get(toOSPath(location.getPath())); if (locationPath.getNameCount() >= 2) { final String projectName = locationPath.getName(0).toString(); final IWorkspaceRoot root = project.getWorkspace().getRoot(); final URI locationURI = root.getProject(projectName).getLocationURI(); if (locationURI != null) { final Path projectRelativePath = locationPath.subpath(1, locationPath.getNameCount()); return Paths.get(locationURI).resolve(projectRelativePath); } } } return null; } private static Optional<String> resolveProjectLocationIfExists(final Location location, final IProject project) { try { final Path path = Paths.get(project.getLocationURI()).resolve(toOSPath(location.getPath())); return Files.exists(path) ? Optional.of(path.toString()) : Optional.<String>absent(); } catch (final InvalidPathException e) { return Optional.absent(); } } private static Optional<String> resolveFileSystemLocationIfExists(final Location location) { try { final Path path = Paths.get(location.getPath()); return Files.exists(path) ? Optional.of(path.toString()) : Optional.<String>absent(); } catch (final InvalidPathException e) { return Optional.absent(); } } private static Optional<String> resolveRemoteLocationIfExists(final Location location) { try { final URI uri = new URI(location.getPath()); uri.toURL().openStream().close(); return Optional.of(uri.toString()); } catch (final URISyntaxException | IOException e) { return Optional.absent(); } } private static String toOSPath(final String path) { return path.replace('\\', File.separatorChar).replace('/', File.separatorChar); } }