java/de/jflex/ucd/UcdVersion.java (87 lines of code) (raw):

/* * Copyright (C) 2018-2020 Google, LLC. * SPDX-License-Identifier: BSD-3-Clause */ package de.jflex.ucd; import com.google.auto.value.AutoValue; import com.google.common.collect.ImmutableMap; import de.jflex.util.javac.JavaPackageUtils; import de.jflex.version.Version; import java.io.File; import java.io.FileNotFoundException; /** Describes a single Unicode version. */ @AutoValue public abstract class UcdVersion { private static final String BAZEL_PREFIX = JavaPackageUtils.getPathForClass(UcdVersion.class); public static final String EXTERNAL = "external"; public abstract Version version(); public abstract ImmutableMap<UcdFileType, File> files(); public File getFile(UcdFileType type) { return files().get(type); } public static Builder builder(String version) { return new AutoValue_UcdVersion.Builder().setVersion(version); } public static Builder builder(Version version) { return new AutoValue_UcdVersion.Builder().setVersion(version); } public static UcdVersion findUcdFiles(Version version, Iterable<String> argv) throws FileNotFoundException { Builder builder = builder(version); for (String arg : argv) { for (UcdFileType type : UcdFileType.values()) { // From Unicode 4.1, a zip contains all files, which can just be found by name if (arg.endsWith(type.name() + ".txt")) { builder.putFile(type, findFile(arg)); } else if (type == UcdFileType.Emoji && arg.contains("emoji_data_txt")) { // Emoji is a single URL, hence uses a different naming convention builder.putFile(UcdFileType.Emoji, findFile(arg)); } else if (arg.contains(type.toString())) { // similarly Unicode 1.0-4.0 is e.g. // external/ucd_4_0_1_Blocks_4_0_1_txt/file/downloaded builder.putFile(type, findFile(arg)); } } // Hack for the UNIDATA DerivedAge.txt if (arg.contains("ucd_derived_age")) { builder.putFile(UcdFileType.DerivedAge, findFile(arg)); } } return builder.build(); } private static File findFile(String arg) throws FileNotFoundException { File file = new File(arg); if (file.exists()) { return file; } // File downloaded by Bazel in the external dir File externalFile = new File(BAZEL_PREFIX, arg); if (file.exists()) { return externalFile; } throw new FileNotFoundException(arg); } public abstract Builder toBuilder(); @Override public final String toString() { return version().toString(); } @AutoValue.Builder public abstract static class Builder { public abstract Builder setVersion(Version version); public Builder setVersion(String version) { return setVersion(new Version(version)); } abstract ImmutableMap.Builder<UcdFileType, File> filesBuilder(); public Builder putFile(UcdFileType unicodeFileType, File file) { filesBuilder().put(unicodeFileType, findExternalPath(file)); return this; } public abstract Version version(); public abstract UcdVersion build(); } /** Given a path that contains "external", returns only the path after "external/". */ private static File findExternalPath(File file) { File externalDir = getExternalRootDirectory(file); if (externalDir != null) { return new File(file.getPath().substring(externalDir.getPath().length() - EXTERNAL.length())); } return file; } private static File getExternalRootDirectory(File file) { for (File parent = file.getParentFile(); parent != null; parent = parent.getParentFile()) { if (EXTERNAL.equals(parent.getName())) { return parent; } } return null; } }