/* * Copyright (C) 2011 Everit Kft. (http://everit.org) * * 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 org.everit.osgi.dev.maven.util; import java.io.File; import java.io.FileFilter; import java.nio.file.Path; import java.util.List; import java.util.Set; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import org.apache.commons.io.filefilter.TrueFileFilter; import org.apache.commons.lang3.StringUtils; import org.apache.maven.plugin.MojoExecutionException; import org.everit.osgi.dev.dist.util.configuration.schema.EntryType; import org.everit.osgi.dev.dist.util.configuration.schema.EnvironmentType; import org.everit.osgi.dev.dist.util.configuration.schema.RuntimePathRegexesType; /** * Cleans the folder of an environment from unwanted files after an incremental upgrade. */ public final class EnvironmentCleaner { public static void cleanEnvironmentFolder(final EnvironmentType distributedEnvironment, final File environmentRootDir, final FileManager fileManager) throws MojoExecutionException { new EnvironmentCleaner(distributedEnvironment, environmentRootDir, fileManager).clean(); } private final String environmentId; private final Path environmentRootPath; private Pattern[] runtimePathPatterns; private final Set<File> touchedFiles; private EnvironmentCleaner(final EnvironmentType distributedEnvironment, final File environmentDir, final FileManager fileManager) throws MojoExecutionException { this.environmentRootPath = environmentDir.toPath(); this.environmentId = distributedEnvironment.getId(); this.touchedFiles = fileManager.getTouchedFiles(); RuntimePathRegexesType runtimePaths = distributedEnvironment.getRuntimePathRegexes(); if (runtimePaths == null) { this.runtimePathPatterns = new Pattern[0]; } else { List<EntryType> pathRegexEntries = distributedEnvironment.getRuntimePathRegexes().getEntry(); this.runtimePathPatterns = new Pattern[pathRegexEntries.size()]; int i = 0; for (EntryType pathRegex : pathRegexEntries) { try { runtimePathPatterns[i] = Pattern.compile(StringUtils.replace(pathRegex.getValue(), "\\\\", "/")); } catch (PatternSyntaxException e) { throw new MojoExecutionException( "Invalid regular expression for runtime path in environment '" + environmentId + "': " + pathRegex); } i++; } } } private void clean() { File environmentRootDir = environmentRootPath.toFile(); cleanDirRecurse(environmentRootDir); } /** * Cleans the folder or file with sub-folders. * * @return True if the directory was deleted. */ private boolean cleanDirRecurse(final File directory) { if (isPathRuntime(directory)) { return false; } File[] dirContents = directory.listFiles((FileFilter) TrueFileFilter.INSTANCE); boolean emptyAfterCleaning = true; for (File dirContent : dirContents) { if (dirContent.isDirectory()) { emptyAfterCleaning = cleanDirRecurse(dirContent) && emptyAfterCleaning; } else { emptyAfterCleaning = cleanFile(dirContent) && emptyAfterCleaning; } } if (emptyAfterCleaning && !touchedFiles.contains(directory)) { directory.delete(); return true; } else { return false; } } private boolean cleanFile(final File file) { if (touchedFiles.contains(file) || isPathRuntime(file)) { return false; } file.delete(); return true; } private boolean isPathRuntime(final File pathFile) { Path relativePath = environmentRootPath.relativize(pathFile.toPath()); String relativePathString = relativePath.normalize().toString(); if (pathFile.isDirectory()) { relativePathString += "/"; } for (Pattern runtimePathPatter : runtimePathPatterns) { if (runtimePathPatter.matcher(StringUtils.replace(relativePathString, "\\", "/")).matches()) { return true; } } return false; } }