/*
* Copyright 2015 the original author or authors.
*
* 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.springframework.xd.dirt.module;
import java.io.IOException;
import java.lang.reflect.Field;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.util.FileSystemUtils;
import org.springframework.util.ReflectionUtils;
/**
* A wrapper around a Resource that adds capabilities lacking in the original interface.
*
* @since 1.2
* @author Eric Bottard
* @author David Turanski
*/
public abstract class ExtendedResource {
private static final Logger log = LoggerFactory.getLogger(ExtendedResource.class);
private static Class<?> HDFS_RESOURCE;
static {
try {
HDFS_RESOURCE = Class.forName("org.springframework.data.hadoop.fs.HdfsResource");
}
catch (ClassNotFoundException e) {
log.warn("Spring Data Hadoop is required on the classpath to register modules to HDFS. This feature is disabled.");
}
}
/**
* Delete the resource and all of its children, if any.
* @return whether deletion was successful or not
*/
public abstract boolean delete() throws IOException;
/**
* Makes sure that the resource and all its parent "directories" exist, creating them if necessary.
*/
public abstract boolean mkdirs() throws IOException;
public static ExtendedResource wrap(Resource original) {
if (original instanceof FileSystemResource) {
return new FileSystemExtendedResource((FileSystemResource) original);
}
else if (original.getClass().equals(HDFS_RESOURCE)) {
return new HdfsExtendedResource(original);
}
else {
throw new IllegalArgumentException("Unsupported resource " + original);
}
}
public static class FileSystemExtendedResource extends ExtendedResource {
private FileSystemResource fsResource;
FileSystemExtendedResource(FileSystemResource fsResource) {
this.fsResource = fsResource;
}
@Override
public boolean delete() throws IOException {
return FileSystemUtils.deleteRecursively(fsResource.getFile());
}
@Override
public boolean mkdirs() throws IOException {
return fsResource.getFile().mkdirs();
}
}
public static class HdfsExtendedResource extends ExtendedResource {
private static final Field PATH_FIELD;
private static final Field FS_FIELD;
static {
PATH_FIELD = ReflectionUtils.findField(HDFS_RESOURCE, "path");
ReflectionUtils.makeAccessible(PATH_FIELD);
FS_FIELD = ReflectionUtils.findField(HDFS_RESOURCE, "fs");
ReflectionUtils.makeAccessible(FS_FIELD);
}
private Path path;
private FileSystem fs;
HdfsExtendedResource(Resource hdfsResource) {
path = (Path) ReflectionUtils.getField(PATH_FIELD, hdfsResource);
fs = (FileSystem) ReflectionUtils.getField(FS_FIELD, hdfsResource);
}
@Override
public boolean delete() throws IOException {
return fs.delete(path, true);
}
@Override
public boolean mkdirs() throws IOException {
return fs.mkdirs(path);
}
}
}