001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package org.apache.commons.io.file; 019 020import java.io.IOException; 021import java.nio.file.CopyOption; 022import java.nio.file.FileVisitResult; 023import java.nio.file.Files; 024import java.nio.file.Path; 025import java.nio.file.attribute.BasicFileAttributes; 026 027import org.apache.commons.io.file.Counters.PathCounters; 028 029/** 030 * Copies a source directory to a target directory. 031 * 032 * @since 2.7 033 */ 034public class CopyDirectoryVisitor extends CountingPathVisitor { 035 036 private static final CopyOption[] EMPTY_COPY_OPTIONS = new CopyOption[0]; 037 038 private final CopyOption[] copyOptions; 039 private final Path sourceDirectory; 040 private final Path targetDirectory; 041 042 /** 043 * Constructs a new visitor that deletes files except for the files and directories explicitly given. 044 * 045 * @param pathCounter How to count visits. 046 * @param sourceDirectory The source directory 047 * @param targetDirectory The target directory 048 * @param copyOptions Specifies how the copying should be done. 049 */ 050 public CopyDirectoryVisitor(final PathCounters pathCounter, final Path sourceDirectory, final Path targetDirectory, 051 final CopyOption... copyOptions) { 052 super(pathCounter); 053 this.sourceDirectory = sourceDirectory; 054 this.targetDirectory = targetDirectory; 055 this.copyOptions = copyOptions == null ? EMPTY_COPY_OPTIONS : copyOptions.clone(); 056 } 057 058 @Override 059 public FileVisitResult preVisitDirectory(final Path directory, final BasicFileAttributes attributes) 060 throws IOException { 061 final Path newTargetDir = targetDirectory.resolve(sourceDirectory.relativize(directory)); 062 if (Files.notExists(newTargetDir)) { 063 Files.createDirectory(newTargetDir); 064 } 065 return super.preVisitDirectory(directory, attributes); 066 } 067 068 @Override 069 public FileVisitResult visitFile(final Path sourceFile, final BasicFileAttributes attributes) throws IOException { 070 final Path targetFile = targetDirectory.resolve(sourceDirectory.relativize(sourceFile)); 071 Files.copy(sourceFile, targetFile, copyOptions); 072 return super.visitFile(targetFile, attributes); 073 } 074 075}