Skip to content

Instantly share code, notes, and snippets.

@joshua-moore
Created October 27, 2014 21:12
Show Gist options
  • Save joshua-moore/57137d54d11d6b6ff211 to your computer and use it in GitHub Desktop.
Save joshua-moore/57137d54d11d6b6ff211 to your computer and use it in GitHub Desktop.
Example of Virtual File System as Grails Service
package com.example
import org.springframework.beans.factory.InitializingBean
import java.net.URLEncoder
import java.io.InputStream
import java.io.OutputStream
import java.io.ByteArrayOutputStream
import org.apache.commons.io.FileUtils
import org.apache.commons.vfs2.FileSystemManager
import org.apache.commons.vfs2.VFS
import org.apache.commons.vfs2.FileObject
import org.apache.commons.vfs2.FileSystemOptions
import org.apache.commons.vfs2.provider.ftp.FtpFileSystemConfigBuilder
import org.apache.commons.vfs2.Selectors
import org.apache.commons.vfs2.FileType
class VirtualFileSystemService implements InitializingBean {
static transactional = false
FileSystemManager vfs = VFS.getManager()
FileSystemOptions vfsFileSystemOptions = new FileSystemOptions()
void afterPropertiesSet() {
// setup FTP file system options
FtpFileSystemConfigBuilder.getInstance().setPassiveMode(vfsFileSystemOptions, true)
FtpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(vfsFileSystemOptions, true)
FtpFileSystemConfigBuilder.getInstance().setDataTimeout(vfsFileSystemOptions, 180000)
}
boolean exists(Map settings, String container, String fileName) {
FileObject fo = resolveFile(settings, container, fileName)
boolean file_exists = fo?.exists() ?: false
fo.close()
return file_exists
}
List listFiles(Map settings, String container, String fileName) {
List results = []
FileObject fo = resolveFile(settings, container, fileName)
if (!fo.exists()) return results
List files = fo.getChildren()
files.each {
results << [
type: (it.getType() == FileType.FOLDER) ? 'FOLDER' : 'FILE',
name: it.getName().getBaseName(),
size: (it.getType() == FileType.FILE) ? it.getContent().getSize() : 0
]
}
fo.close()
return results
}
void delete(Map settings, String container, String fileName) {
FileObject fo = resolveFile(settings, container, fileName)
if (fo.exists() == true) fo.delete(Selectors.SELECT_ALL)
fo.close()
}
void rename(Map settings, String container, String fileName, String newFileName) {
FileObject fo = resolveFile(settings, container, fileName)
if (fo.exists() == false) return
FileObject nfo = resolveFile(settings, container, newFileName)
fo.doRename(nfo)
fo.close()
nfo.close()
}
void createDirectory(Map settings, String container, String fileName) {
FileObject fo = resolveFile(settings, container, fileName)
if (fo.exists() == true) return
fo.createFolder()
fo.close()
}
void upload(Map settings, String container, String fileName, InputStream data) {
log.debug("Save file ${fileName} to ${container}")
FileObject pfo = resolveFile(settings, container, null)
log.debug("Parent exists?: " + pfo.exists())
FileObject fo = resolveFile(settings, container, fileName)
if (fo.exists() == false) {
try {
fo.createFile()
} catch (Exception e) {
log.error(e)
log.error(e.getMessage())
throw e
}
} else {
fo.delete()
fo.createFile()
}
long bytesCopied = org.apache.commons.io.IOUtils.copy(data, fo.content.outputStream)
log.debug("${bytesCopied} bytes uploaded.")
fo.close()
}
OutputStream download(Map settings, String container, String fileName) {
FileObject fo = resolveFile(settings, container, fileName)
if (fo.exists() == false) return null
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()
org.apache.commons.io.IOUtils.copy(fo.content.inputStream, outputStream)
fo.close()
return outputStream
}
FileObject resolveFile(Map settings, String container, String fileName) {
// add any leading forward slash to container if not present
if (!container.startsWith("/")) {
container = "/" + container
}
// remove any trailing slash from container if present
if (container.endsWith("/")) {
container = container.substring(0, container.length() -1)
}
String path = "${container}/${fileName}"
if (!fileName) path = "${container}"
log.debug("resolving path for ftp://${URLEncoder.encode(settings['username'])}:${URLEncoder.encode(settings['password'])}@${settings['host']}${path}")
return vfs.resolveFile("ftp://${URLEncoder.encode(settings['username'])}:${URLEncoder.encode(settings['password'])}@${settings['host']}${path}", vfsFileSystemOptions)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment