/** * Copyright 2012 Red Hat, Inc. and/or its affiliates. * * 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.kie.workbench.common.services.datamodeller.util; import org.uberfire.io.IOService; import org.uberfire.java.nio.IOException; import org.uberfire.java.nio.file.DirectoryStream; import org.uberfire.java.nio.file.Files; import org.uberfire.java.nio.file.Path; import java.util.*; public class FileUtils { protected FileUtils() {}; public static FileUtils getInstance() { return new FileUtils(); } public Collection<ScanResult> scan(IOService ioService, Collection<Path> rootPaths, String fileType, boolean recursiveScan) throws IOException { ArrayList<String> fileTypes = new ArrayList<String>(); fileTypes.add(fileType); return scan(ioService, rootPaths, fileTypes, recursiveScan); } public Collection<ScanResult> scan(IOService ioService, Collection<Path> rootPaths, Collection<String> fileTypes, boolean recursiveScan) throws IOException { List<ScanResult> results = new ArrayList<ScanResult>(); final Map<Path, Path> scannedCache = new HashMap<Path, Path>(); if (rootPaths != null) { for (Path root : rootPaths) { if (Files.isDirectory(root) && !scannedCache.containsKey(root)) { results.addAll(scan(ioService, root, fileTypes, recursiveScan, scannedCache)); } else if ( (fileTypes == null || isFromType( root, fileTypes )) && !scannedCache.containsKey( root ) ) { results.add( new ScanResult( root ) ); scannedCache.put( root, root ); } } } return results; } public Collection<ScanResult> scan(IOService ioService, Path root, Collection<String> fileTypes, boolean recursiveScan) throws IOException { Collection<Path> roots = new ArrayList<Path>(); roots.add(root); return scan(ioService, roots, fileTypes, recursiveScan); } private Collection<ScanResult> scan(IOService ioService, Path rootPath, final Collection<String> fileTypes, final boolean recursiveScan, final Map<Path, Path> scannedCache) throws IOException { final Collection<ScanResult> results = new ArrayList<ScanResult>(); final List<Path> childDirectories = new ArrayList<Path>(); if (rootPath != null) { if (Files.isDirectory(rootPath) && !scannedCache.containsKey(rootPath)) { scannedCache.put(rootPath, rootPath); final DirectoryStream<Path> foundFiles = ioService.newDirectoryStream( rootPath , new DirectoryStream.Filter<Path>() { @Override public boolean accept( final Path entry ) throws IOException { boolean include = false; if ( Files.isDirectory( entry ) && recursiveScan) { //use this check iteration to additionally remember child directories childDirectories.add(entry); } else { if (fileTypes == null) { include = true; } else { include = isFromType( entry, fileTypes ); } } return include; } } ); if (foundFiles != null) { for (Path acceptedFile : foundFiles) { results.add(new ScanResult(acceptedFile)); } } //finally if (recursiveScan) { for (Path child : childDirectories) { results.addAll( scan(ioService, child, fileTypes, recursiveScan, scannedCache) ); } } } } return results; } private boolean isFromType(Path file, Collection<String> fileTypes) { if (Files.isDirectory( file )) return false; for (String type : fileTypes) { if (file.getFileName().toString().endsWith( type ) && !file.getFileName().toString().startsWith( "." )) return true; } return false; } public Collection<ScanResult> scanDirectories(IOService ioService, Path rootPath, final boolean includeRoot, final boolean recursiveScan/*, final Map<Path, Path> scannedCache*/) throws IOException { final Collection<ScanResult> results = new ArrayList<ScanResult>(); final List<Path> childDirectories = new ArrayList<Path>(); if (rootPath != null) { if (Files.isDirectory(rootPath) /* && !scannedCache.containsKey(rootPath)*/) { //scannedCache.put(rootPath, rootPath); if (includeRoot) results.add(new ScanResult(rootPath)); final DirectoryStream<Path> children = ioService.newDirectoryStream(rootPath); //finally if (recursiveScan) { for (Path child : children) { results.addAll( scanDirectories(ioService, child, true, recursiveScan/*, scannedCache*/) ); } } } } return results; } public boolean cleanEmptyDirectories(final IOService ioService, Path rootPath, boolean deleteRoot, List<String> deleteableFiles) throws IOException { DirDescriptor dirDescriptor; if (rootPath != null && Files.exists(rootPath) && Files.isDirectory(rootPath)) { final DirectoryStream<Path> children = ioService.newDirectoryStream(rootPath); if (children != null) { for (Path child : children) { if (Files.isDirectory(child)) { cleanEmptyDirectories(ioService, child, true, deleteableFiles); } } } dirDescriptor = isDeleteableDir(ioService, rootPath, deleteableFiles); if (dirDescriptor.isDeleteable()) { for (Path child : dirDescriptor.getChildren()) { ioService.delete(child); } if (deleteRoot) { //Invoke deleteIfExists because when the the last child is removede and JGit filesystem //is installed the directory is removed automatically ioService.deleteIfExists(rootPath); return true; } } } return false; } public DirDescriptor isDeleteableDir(final IOService ioService, Path dirPath, List<String> deleteableFiles) throws IOException { DirDescriptor dirDescriptor = new DirDescriptor(dirPath); boolean deleteable = false; final DirectoryStream<Path> children = ioService.newDirectoryStream(dirPath); if (children == null) { deleteable = true; } else { Iterator<Path> iterator = children.iterator(); if (iterator == null) { deleteable = true; } else { deleteable = true; for (Path child : children) { if (Files.isDirectory(child)) { dirDescriptor.setDeleteable(false); return dirDescriptor; } for (String deleteableFile : deleteableFiles) { if (!child.getFileName().endsWith(deleteableFile)) { dirDescriptor.setDeleteable(false); return dirDescriptor; } else { dirDescriptor.addChild(child); } } } } } dirDescriptor.setDeleteable(deleteable); return dirDescriptor; } class DirDescriptor { private boolean deleteable = false; private List<Path> children = new ArrayList<Path>(); private Path path; DirDescriptor(Path path) { this.path = path; } public boolean isDeleteable() { return deleteable; } public void setDeleteable(boolean deleteable) { this.deleteable = deleteable; } public List<Path> getChildren() { return children; } public void addChild(Path child) { children.add(child); } } public boolean isEmpty(final IOService ioService, Path dirPath) throws IOException { if (dirPath == null) return true; final DirectoryStream<Path> children = ioService.newDirectoryStream(dirPath); if (children == null) return true; Iterator<Path> iterator = children.iterator(); return iterator == null || !iterator.hasNext(); } public class ScanResult { private Path file; public ScanResult(Path file) { this.file = file; } public Path getFile() { return file; } public void setFile(Path file) { this.file = file; } } }