Skip to content

Instantly share code, notes, and snippets.

@andreaskc
Forked from jkuehn/gist:786448
Created September 15, 2011 14:51
Show Gist options
  • Save andreaskc/1219451 to your computer and use it in GitHub Desktop.
Save andreaskc/1219451 to your computer and use it in GitHub Desktop.
Grails Service for GridFS access
package net.saberco
//Reworked by Andy Kallenbach, SaberCo.net, September 17, 2011
//Refactored saveFile
//Fixed saving extra data fields along with file
//Need to finish an updateFile to overwrite an existing file
import com.mongodb.gridfs.GridFS
import eu.medsea.mimeutil.detector.MagicMimeMimeDetector
import org.springframework.web.multipart.commons.CommonsMultipartFile
import com.mongodb.gridfs.GridFSInputFile
import com.mongodb.DBObject
import com.mongodb.gridfs.GridFSDBFile
import org.bson.types.ObjectId
import com.mongodb.WriteConcern
import javax.servlet.http.HttpServletResponse
import org.apache.commons.io.IOUtils
import org.codehaus.groovy.grails.commons.ApplicationHolder
import com.mongodb.DB
import com.mongodb.BasicDBObject
import com.mongodb.gridfs.GridFSFile
class FilestorageService {
static transactional = false
def mongo
def grailsApplication
private HashMap<String, GridFS> _gridfs = new HashMap<String, GridFS>()
public GridFSFile saveFile(String bucket, CommonsMultipartFile file, String filename = null, Map metaData = null) {
// get content type
byte[] b = new byte[4096]
BufferedInputStream s = new BufferedInputStream(file.getInputStream(), 6144)
s.mark(0)
s.read(b, 0, 4096)
s.reset()
def contentType = getMimeType(b)
saveFile(bucket, s, filename, Map);
}
public GridFSFile saveFile(String bucket, File file, String filename, Map metaData = null) {
saveFile(bucket, file.newInputStream(), getMimeType(file), filename, Map);
}
public GridFSFile saveFile(String bucket, byte[] fileContents, String filename, Map metaData = null) {
saveFile(bucket, new ByteArrayInputStream(fileContents), getMimeType(fileContents), filename, Map);
}
public GridFSFile saveFile(String bucket, InputStream fileStream, String ContentType, String filename, Map metaData = null)
{
GridFS gfs = getGridfs(bucket);
GridFSInputFile gInputFile = gfs.createFile(fileStream);
gInputFile.setFilename(filename);
gInputFile.setContentType(ContentType);
metaData.each {
gInputFile.put(it.key.toString(), it.value)
}
/*if (metaData) {
DBObject mD = gInputFile.getMetaData();
metaData.each {
println "key: " + it.key.toString() + " value: " + it.value;
mD.put(it.key.toString(), it.value)
}
}*/
_saveFile(gfs, bucket, gInputFile)
}
private GridFSFile _saveFile(GridFS gfs, String bucket, GridFSInputFile gInputFile) {
String errormsg;
try
{
gInputFile.save();
}
catch(Exception e)
{
log.error('could not save file ' + gInputFile + ': ' + e.message)
}
return gInputFile
}
def GridFSDBFile getFile(String bucket, String id, boolean asObjectId = true) {
GridFS gfs = getGridfs(bucket);
if (asObjectId) {
return gfs.findOne(new ObjectId(id))
} else {
return gfs.findOne(new BasicDBObject('_id', id))
}
}
def GridFSDBFile findFile(String bucket, Map query) {
GridFS gfs = getGridfs(bucket);
BasicDBObject mongoQuery = new BasicDBObject();
query.each {
mongoQuery.put(it.key.toString(), it.value)
}
GridFSDBFile aFile = gfs.findOne(mongoQuery);
return aFile
}
def List find(String bucket, Map query, Integer resultsToSkip, Integer pageSize) {
GridFS gfs = getGridfs(bucket);
BasicDBObject mongoQuery = new BasicDBObject();
query.each {
mongoQuery.put(it.key.toString(), it.value)
}
return gfs.find(mongoQuery);
}
def deleteFile(String bucket, Map query) {
GridFS gfs = getGridfs(bucket);
gfs.remove(query as BasicDBObject)
}
private GridFS getGridfs(String bucket) {
def gridfs = _gridfs[bucket]
if (!gridfs) {
def mongoConfig = grailsApplication.config?.grails?.mongo
def databaseName = mongoConfig?.remove("databaseName") ?: grailsApplication.metadata.getApplicationName()
databaseName = databaseName?databaseName+'files':'files'
DB db = mongo.mongo.getDB(databaseName)
db.setWriteConcern(WriteConcern.SAFE)
gridfs = new GridFS(db, bucket)
_gridfs[bucket] = gridfs
}
return gridfs
}
public String getMimeType(File file) {
// use mime magic
MagicMimeMimeDetector detector = new MagicMimeMimeDetector();
Collection mimeTypes = detector.getMimeTypesFile(file);
if (mimeTypes) return mimeTypes[0].toString()
return "application/octet-stream"
}
public String getMimeType(byte[] ba) {
// use mime magic
MagicMimeMimeDetector detector = new MagicMimeMimeDetector();
Collection mimeTypes = detector.getMimeTypesByteArray(ba);
if (mimeTypes) return mimeTypes.iterator().getAt(0).toString()
return "application/octet-stream"
}
public void deliverGridFSFile(HttpServletResponse response, GridFSDBFile file, String filename = null, boolean asAttachment = true) {
response.setContentType file.getContentType()
response.setContentLength ((int)file.getLength())
if (filename == null) filename = file.getFilename()
if (asAttachment) response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");
// response.setHeader("Cache-Control", "no-store");
// response.setHeader("Pragma", "no-cache");
// response.setDateHeader("Expires", 0);
try {
IOUtils.copy(file.getInputStream(), response.getOutputStream())
} catch (Exception e) {
try {
// todo log
response.sendError(HttpServletResponse.SC_NOT_FOUND);
} catch (IOException ignored) {}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment