Miscellaneous.java
- /*
- * *********************************************************************************************************************
- *
- * blueMarine II: Semantic Media Centre
- * http://tidalwave.it/projects/bluemarine2
- *
- * Copyright (C) 2015 - 2021 by Tidalwave s.a.s. (http://tidalwave.it)
- *
- * *********************************************************************************************************************
- *
- * 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.
- *
- * *********************************************************************************************************************
- *
- * git clone https://bitbucket.org/tidalwave/bluemarine2-src
- * git clone https://github.com/tidalwave-it/bluemarine2-src
- *
- * *********************************************************************************************************************
- */
- package it.tidalwave.bluemarine2.util;
- import javax.annotation.Nonnull;
- import javax.annotation.Nullable;
- import java.text.Normalizer;
- //import java.util.regex.Pattern;
- import java.util.Objects;
- import java.util.stream.Stream;
- import java.io.File;
- import java.io.IOException;
- import java.nio.file.Files;
- import java.nio.file.Path;
- import java.nio.file.Paths;
- import java.nio.file.StandardCopyOption;
- import lombok.NoArgsConstructor;
- import lombok.extern.slf4j.Slf4j;
- import static java.util.stream.Collectors.toList;
- import static java.text.Normalizer.Form.*;
- //import java.util.regex.Matcher;
- import static lombok.AccessLevel.PRIVATE;
- /***********************************************************************************************************************
- *
- * @author Fabrizio Giudici
- *
- **********************************************************************************************************************/
- @NoArgsConstructor(access = PRIVATE) @Slf4j
- public final class Miscellaneous
- {
- private static final Normalizer.Form NATIVE_FORM;
- // private static final Pattern PATTERN_EXTENSION = Pattern.compile("(\\.[^.]+)$");
- static
- {
- final String osName = System.getProperty("os.name").toLowerCase();
- switch (osName)
- {
- case "linux":
- NATIVE_FORM = NFC;
- break;
- case "mac os x":
- NATIVE_FORM = NFD;
- break;
- case "windows":
- NATIVE_FORM = NFD; // FIXME: just guessing
- break;
- default:
- throw new ExceptionInInitializerError("Unknown o.s.: " + osName);
- }
- log.info(">>>> Charset normalizer form: {}", NATIVE_FORM);
- }
- /*******************************************************************************************************************
- *
- *
- *
- ******************************************************************************************************************/
- @Nullable
- public static String normalizedToNativeForm (@Nullable final String string)
- {
- return (string == null) ? null : Normalizer.normalize(string, NATIVE_FORM);
- }
- /*******************************************************************************************************************
- *
- * Takes a path, and in case it can't be resolved, it tries to replace with an equivalent representation of an
- * existing path, with the native form of character encoding (i.e. the one used by the file system).
- * If there is no normalized path to replace with, the original path is returned.
- * Note that this method is I/O heavy, as it must access the file system.
- * FIXME: what about using a cache?
- *
- * See http://askubuntu.com/questions/533690/rsync-with-special-character-files-not-working-between-mac-and-linux
- *
- * @param path the path
- * @return the normalized path
- *
- ******************************************************************************************************************/
- @Nonnull
- public static Path normalizedPath (@Nonnull final Path path)
- throws IOException
- {
- // log.trace("normalizedPath({}", path);
- if (Files.exists(path))
- {
- return path;
- }
- Path pathSoFar = Paths.get("/");
- for (final Path element : path)
- {
- // log.trace(">>>> pathSoFar: {} element: {}", pathSoFar, element);
- final Path resolved = pathSoFar.resolve(element);
- if (Files.exists(resolved))
- {
- pathSoFar = resolved;
- }
- else
- {
- // FIXME: refactor with lambdas
- try (final Stream<Path> stream = Files.list(pathSoFar))
- {
- boolean found = false;
- for (final Path child : stream.collect(toList()))
- {
- final Path childName = child.getFileName();
- found = Objects.equals(normalizedToNativeForm(element.toString()),
- normalizedToNativeForm(childName.toString()));
- // log.trace(">>>> original: {} found: {} same: {}", element, childName, found);
- if (found)
- {
- pathSoFar = pathSoFar.resolve(childName);
- break;
- }
- }
- if (!found)
- {
- return path; // fail
- }
- }
- }
- }
- return pathSoFar;
- }
- /*******************************************************************************************************************
- *
- *
- *
- ******************************************************************************************************************/
- @Nonnull
- public static File toFileBMT46 (@Nonnull final Path path)
- throws IOException
- {
- File file = path.toFile();
- if (probeBMT46(path))
- {
- file = File.createTempFile("bmt46-", "." + extensionOf(path));
- file.deleteOnExit();
- log.warn("Workaround for BMT-46: copying {} to temporary file: {}", path, file);
- Files.copy(path, file.toPath(), StandardCopyOption.REPLACE_EXISTING);
- }
- return file;
- }
- /*******************************************************************************************************************
- *
- *
- *
- ******************************************************************************************************************/
- @Nonnull
- private static String extensionOf (@Nonnull final Path path)
- {
- final int i = path.toString().lastIndexOf('.');
- return (i < 0) ? "" : path.toString().substring(i + 1);
- // final Matcher matcher = PATTERN_EXTENSION.matcher(path.toString()); TODO
- // return matcher.matches() ? matcher.group(0) : "";
- }
- /*******************************************************************************************************************
- *
- *
- *
- ******************************************************************************************************************/
- private static boolean probeBMT46 (@Nonnull final Path path)
- {
- return Files.exists(path) && !path.toFile().exists();
- }
- }