Java tutorial
/* * Copyright 2012-present Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may obtain * a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package com.facebook.buck.java; import com.facebook.buck.rules.JavaPackageFinder; import com.facebook.buck.util.HumanReadableException; import com.google.common.base.Joiner; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSortedSet; import com.google.common.collect.Lists; import java.io.File; import java.util.Deque; public class DefaultJavaPackageFinder implements JavaPackageFinder { /** * Each element in this set is a path prefix from the root of the repository. * <p> * Elements in this set are ordered opposite to their natural order such that if one element is a * prefix of another element in the Set, the longer String will appear first. This makes it * possible to iterate over the elements in the set in order, comparing to a test element, such * that the longest matching prefix matches the test element. * <p> * Every element in this set ends with a slash. */ private final ImmutableSortedSet<String> pathsFromRoot; private final ImmutableSet<String> pathElements; public DefaultJavaPackageFinder(ImmutableSortedSet<String> pathsFromRoot, ImmutableSet<String> pathElements) { this.pathsFromRoot = pathsFromRoot; this.pathElements = pathElements; } @Override public String findJavaPackageFolderForPath(String pathRelativeToProjectRoot) { for (String pathFromRoot : pathsFromRoot) { if (pathRelativeToProjectRoot.startsWith(pathFromRoot)) { int lastSlashIndex = pathRelativeToProjectRoot.lastIndexOf('/'); Preconditions.checkState(lastSlashIndex >= 0, "Because pathFromRoot must end with a slash and is a prefix of " + "pathRelativeToProjectRoot, pathRelativeToProjectRoot must contain a slash."); return pathRelativeToProjectRoot.substring(pathFromRoot.length(), lastSlashIndex + 1); } } File directory; if (pathRelativeToProjectRoot.endsWith("/")) { directory = new File(pathRelativeToProjectRoot); } else { directory = new File(pathRelativeToProjectRoot).getParentFile(); } Deque<String> parts = Lists.newLinkedList(); while (directory != null && !pathElements.contains(directory.getName())) { parts.addFirst(directory.getName()); directory = directory.getParentFile(); } if (!parts.isEmpty()) { return Joiner.on('/').join(parts) + '/'; } else { return ""; } } public ImmutableSortedSet<String> getPathsFromRoot() { return pathsFromRoot; } public ImmutableSet<String> getPathElements() { return pathElements; } /** * @param pathPatterns elements that start with a slash must be prefix patterns; all other * elements indicate individual directory names (and therefore cannot contain slashes). */ public static DefaultJavaPackageFinder createDefaultJavaPackageFinder(Iterable<String> pathPatterns) { ImmutableSortedSet.Builder<String> pathsFromRoot = ImmutableSortedSet.reverseOrder(); ImmutableSet.Builder<String> pathElements = ImmutableSet.builder(); for (String pattern : pathPatterns) { if (pattern.charAt(0) == '/') { // Strip the leading slash. pattern = pattern.substring(1); // Ensure there is a trailing slash, unless it is an empty string. if (!pattern.isEmpty() && !pattern.endsWith("/")) { pattern = pattern + "/"; } pathsFromRoot.add(pattern); } else { if (pattern.contains("/")) { throw new HumanReadableException( "Path pattern that does not start with a slash cannot contain a slash: %s", pattern); } pathElements.add(pattern); } } return new DefaultJavaPackageFinder(pathsFromRoot.build(), pathElements.build()); } @Override public String findJavaPackageForPath(String pathRelativeToProjectRoot) { String folder = findJavaPackageFolderForPath(pathRelativeToProjectRoot); if (!folder.isEmpty()) { // Strip the trailing slash and replace the remaining slashes with dots. return folder.substring(0, folder.length() - 1).replace('/', '.'); } else { return ""; } } }