001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 package org.apache.hadoop.fs; 019 020 import java.io.IOException; 021 022 import org.apache.hadoop.classification.InterfaceAudience; 023 import org.apache.hadoop.classification.InterfaceStability; 024 import org.apache.hadoop.conf.Configuration; 025 import org.apache.hadoop.conf.Configured; 026 027 /** 028 * Provides a trash facility which supports pluggable Trash policies. 029 * 030 * See the implementation of the configured TrashPolicy for more 031 * details. 032 */ 033 @InterfaceAudience.Public 034 @InterfaceStability.Stable 035 public class Trash extends Configured { 036 private TrashPolicy trashPolicy; // configured trash policy instance 037 038 /** 039 * Construct a trash can accessor. 040 * @param conf a Configuration 041 */ 042 public Trash(Configuration conf) throws IOException { 043 this(FileSystem.get(conf), conf); 044 } 045 046 /** 047 * Construct a trash can accessor for the FileSystem provided. 048 * @param fs the FileSystem 049 * @param conf a Configuration 050 */ 051 public Trash(FileSystem fs, Configuration conf) throws IOException { 052 super(conf); 053 trashPolicy = TrashPolicy.getInstance(conf, fs, fs.getHomeDirectory()); 054 } 055 056 /** 057 * In case of the symlinks or mount points, one has to move the appropriate 058 * trashbin in the actual volume of the path p being deleted. 059 * 060 * Hence we get the file system of the fully-qualified resolved-path and 061 * then move the path p to the trashbin in that volume, 062 * @param fs - the filesystem of path p 063 * @param p - the path being deleted - to be moved to trasg 064 * @param conf - configuration 065 * @return false if the item is already in the trash or trash is disabled 066 * @throws IOException on error 067 */ 068 public static boolean moveToAppropriateTrash(FileSystem fs, Path p, 069 Configuration conf) throws IOException { 070 Path fullyResolvedPath = fs.resolvePath(p); 071 FileSystem fullyResolvedFs = 072 FileSystem.get(fullyResolvedPath.toUri(), conf); 073 // If the trash interval is configured server side then clobber this 074 // configuration so that we always respect the server configuration. 075 try { 076 long trashInterval = fullyResolvedFs.getServerDefaults( 077 fullyResolvedPath).getTrashInterval(); 078 if (0 != trashInterval) { 079 Configuration confCopy = new Configuration(conf); 080 confCopy.setLong(CommonConfigurationKeysPublic.FS_TRASH_INTERVAL_KEY, 081 trashInterval); 082 conf = confCopy; 083 } 084 } catch (Exception e) { 085 // If we can not determine that trash is enabled server side then 086 // bail rather than potentially deleting a file when trash is enabled. 087 throw new IOException("Failed to get server trash configuration", e); 088 } 089 Trash trash = new Trash(fullyResolvedFs, conf); 090 boolean success = trash.moveToTrash(fullyResolvedPath); 091 if (success) { 092 System.out.println("Moved: '" + p + "' to trash at: " + 093 trash.getCurrentTrashDir() ); 094 } 095 return success; 096 } 097 098 /** 099 * Returns whether the trash is enabled for this filesystem 100 */ 101 public boolean isEnabled() { 102 return trashPolicy.isEnabled(); 103 } 104 105 /** Move a file or directory to the current trash directory. 106 * @return false if the item is already in the trash or trash is disabled 107 */ 108 public boolean moveToTrash(Path path) throws IOException { 109 return trashPolicy.moveToTrash(path); 110 } 111 112 /** Create a trash checkpoint. */ 113 public void checkpoint() throws IOException { 114 trashPolicy.createCheckpoint(); 115 } 116 117 /** Delete old checkpoint(s). */ 118 public void expunge() throws IOException { 119 trashPolicy.deleteCheckpoint(); 120 } 121 122 /** get the current working directory */ 123 Path getCurrentTrashDir() { 124 return trashPolicy.getCurrentTrashDir(); 125 } 126 127 /** get the configured trash policy */ 128 TrashPolicy getTrashPolicy() { 129 return trashPolicy; 130 } 131 132 /** Return a {@link Runnable} that periodically empties the trash of all 133 * users, intended to be run by the superuser. 134 */ 135 public Runnable getEmptier() throws IOException { 136 return trashPolicy.getEmptier(); 137 } 138 }