All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.vaadin.flow.migration.AbstractCopyResourcesStep Maven / Gradle / Ivy

There is a newer version: 2.11.1
Show newest version
/*
 * Copyright 2000-2020 Vaadin Ltd.
 *
 * 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.vaadin.flow.migration;

import java.io.File;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Step which copies resources from provided collection of directories to the
 * target folder. It keeps the files hierarchical structure.
 * 

* Depending on provided parameter the content of copied file may be modified. * * @author Vaadin Ltd * @since 2.0 */ public abstract class AbstractCopyResourcesStep { protected static final String BOWER_COMPONENTS = "bower_components"; protected interface FileTreeHandler { /** * Handles a {@code source} file or folder. *

* Return value is used to indicate whether the file of folder has been * handled or not. * * @param source * the source file or directory * @param target * the target file or directory * @return {@code true} if the file should be handled, if the * {@code source} is directory then it will be skipped in case * {@code false} is returned * @throws IOException */ boolean handle(Path source, Path target) throws IOException; } private static class CopyFileVisitor extends SimpleFileVisitor { private final Path sourceRoot; private final Path targetRoot; private final FileTreeHandler writer; private List paths = new ArrayList<>(); private CopyFileVisitor(Path sourceRoot, Path targetRoot, FileTreeHandler fileProducer) { this.sourceRoot = sourceRoot; this.targetRoot = targetRoot; this.writer = fileProducer; } @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { Path target = getTarget(file); getLogger().debug("Writing content to '{}'", target.toString()); if (writer.handle(file, target)) { paths.add(getRelativePath(target, targetRoot)); } return super.visitFile(file, attrs); } @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { Path target = getTarget(dir); if (!writer.handle(dir, target)) { return FileVisitResult.SKIP_SUBTREE; } if (!target.toFile().exists()) { getLogger().debug("Creating a new {} directory", target.toString()); Files.createDirectory(getTarget(dir)); } else { getLogger().debug( "Directory/file {} already exists, skipping its creation", target.toString()); } return super.preVisitDirectory(dir, attrs); } List getVisitedPaths() { return paths; } private Path getTarget(Path source) { Path relativePath = sourceRoot.relativize(source); String topLevel = relativePath.getName(0).toString(); if ("frontend".equals(topLevel)) { if (relativePath.getNameCount() == 1) { return targetRoot; } relativePath = relativePath.subpath(1, relativePath.getNameCount()); } return targetRoot.resolve(relativePath); } } private final File target; private final List resources; private final FileTreeHandler handler; /** * Creates a new instance. * * @param target * the target directory * @param sourceFolders * an array of source folders * @param handler * a strategy which handles the files in the source directories */ public AbstractCopyResourcesStep(File target, File[] sourceFolders, FileTreeHandler handler) { this.target = target; resources = Arrays.asList(sourceFolders); this.handler = handler; } /** * Copies resources. *

* Collects imported bower components using provided {@code bowerComponents} * if it's not {@code null}. * * @return a map where the key is the resource folder and the value is the * list of paths inside the {@code target} directory which has been * copied * @throws IOException */ public Map> copyResources() throws IOException { if (target.exists() && !target.isDirectory()) { throw new IOException("Target path " + target.getPath() + " exists and is not a directory"); } if (!target.exists()) { FileUtils.forceMkdir(target); } getLogger().debug("Use {} as source folders to copy", resources); Map> allResources = new HashMap<>(); for (File resourceFolder : resources) { getLogger().debug("Copy resources from {} to {}", resourceFolder, target.getPath()); allResources.put(resourceFolder.getPath(), doCopyResources(resourceFolder)); } return allResources; } private List doCopyResources(File source) throws IOException { CopyFileVisitor visitor = new CopyFileVisitor(source.toPath(), target.toPath(), handler); Files.walkFileTree(source.toPath(), visitor); return visitor.getVisitedPaths(); } /** * Constructs a relative path between the {@code source} path and a * {@code against}. * * @param source * the path which needs to be relativize * @param against * the path to relativize against this path * @return */ protected static String getRelativePath(Path source, Path against) { Path relativize = against.relativize(source); return StreamSupport.stream(relativize.spliterator(), false) .map(Path::toString).collect(Collectors.joining("/")); } private static Logger getLogger() { return LoggerFactory.getLogger(AbstractCopyResourcesStep.class); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy