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 }