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; 026import java.util.Arrays; 027import java.util.Objects; 028 029import org.apache.commons.io.file.Counters.PathCounters; 030 031/** 032 * Copies a source directory to a target directory. 033 * 034 * @since 2.7 035 */ 036public class CopyDirectoryVisitor extends CountingPathVisitor { 037 038 private static final CopyOption[] EMPTY_COPY_OPTIONS = new CopyOption[0]; 039 040 private final CopyOption[] copyOptions; 041 private final Path sourceDirectory; 042 private final Path targetDirectory; 043 044 /** 045 * Constructs a new visitor that deletes files except for the files and directories explicitly given. 046 * 047 * @param pathCounter How to count visits. 048 * @param sourceDirectory The source directory 049 * @param targetDirectory The target directory 050 * @param copyOptions Specifies how the copying should be done. 051 */ 052 public CopyDirectoryVisitor(final PathCounters pathCounter, final Path sourceDirectory, final Path targetDirectory, 053 final CopyOption... copyOptions) { 054 super(pathCounter); 055 this.sourceDirectory = sourceDirectory; 056 this.targetDirectory = targetDirectory; 057 this.copyOptions = copyOptions == null ? EMPTY_COPY_OPTIONS : copyOptions.clone(); 058 } 059 060 /** 061 * Copies the sourceFile to the targetFile. 062 * 063 * @param sourceFile the source file. 064 * @param targetFile the target file. 065 * @throws IOException if an I/O error occurs. 066 * @since 2.8.0 067 */ 068 protected void copy(final Path sourceFile, final Path targetFile) throws IOException { 069 Files.copy(sourceFile, targetFile, copyOptions); 070 } 071 072 @Override 073 public boolean equals(final Object obj) { 074 if (this == obj) { 075 return true; 076 } 077 if (!super.equals(obj)) { 078 return false; 079 } 080 if (getClass() != obj.getClass()) { 081 return false; 082 } 083 final CopyDirectoryVisitor other = (CopyDirectoryVisitor) obj; 084 return Arrays.equals(copyOptions, other.copyOptions) && Objects.equals(sourceDirectory, other.sourceDirectory) 085 && Objects.equals(targetDirectory, other.targetDirectory); 086 } 087 088 /** 089 * Gets the copy options. 090 * 091 * @return the copy options. 092 * @since 2.8.0 093 */ 094 public CopyOption[] getCopyOptions() { 095 return copyOptions.clone(); 096 } 097 098 /** 099 * Gets the source directory. 100 * 101 * @return the source directory. 102 * @since 2.8.0 103 */ 104 public Path getSourceDirectory() { 105 return sourceDirectory; 106 } 107 108 /** 109 * Gets the target directory. 110 * 111 * @return the target directory. 112 * @since 2.8.0 113 */ 114 public Path getTargetDirectory() { 115 return targetDirectory; 116 } 117 118 @Override 119 public int hashCode() { 120 final int prime = 31; 121 int result = super.hashCode(); 122 result = prime * result + Arrays.hashCode(copyOptions); 123 result = prime * result + Objects.hash(sourceDirectory, targetDirectory); 124 return result; 125 } 126 127 @Override 128 public FileVisitResult preVisitDirectory(final Path directory, final BasicFileAttributes attributes) 129 throws IOException { 130 final Path newTargetDir = targetDirectory.resolve(sourceDirectory.relativize(directory)); 131 if (Files.notExists(newTargetDir)) { 132 Files.createDirectory(newTargetDir); 133 } 134 return super.preVisitDirectory(directory, attributes); 135 } 136 137 @Override 138 public FileVisitResult visitFile(final Path sourceFile, final BasicFileAttributes attributes) throws IOException { 139 final Path targetFile = targetDirectory.resolve(sourceDirectory.relativize(sourceFile)); 140 copy(sourceFile, targetFile); 141 return super.visitFile(targetFile, attributes); 142 } 143 144}