Skip to content

Commit

Permalink
DATAMONGO-6 - Initial support for GridFS.
Browse files Browse the repository at this point in the history
We now provide a GridFsTemplate for storing, retrieving and deleting documents from GridFS. Introduced GridFsResource implementation to integrate with Spring's Resource abstraction. Beyond that GridFsOperations extends ResourcePatternResolver and thus allows to retrieve GridFsResources via Ant-style filename patterns.
  • Loading branch information
odrotbohm committed Feb 1, 2012
1 parent 9caa8b1 commit 572c4bb
Show file tree
Hide file tree
Showing 8 changed files with 751 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* Copyright 2011 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.data.mongodb.gridfs;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.util.Assert;

/**
* Value object to abstract Ant paths.
*
* @author Oliver Gierke
*/
class AntPath {

private static final String PREFIX_DELIMITER = ":";
private static final Pattern WILDCARD_PATTERN = Pattern.compile("\\?|\\*\\*|\\*");

private final String path;

/**
* Creates a new {@link AntPath} from the given path.
*
* @param path must not be {@literal null}.
*/
public AntPath(String path) {
Assert.notNull(path);
this.path = path;
}

/**
* Returns whether the path is a pattern.
*
* @return
*/
public boolean isPattern() {
String path = stripPrefix(this.path);
return (path.indexOf('*') != -1 || path.indexOf('?') != -1);
}

private static String stripPrefix(String path) {
int index = path.indexOf(PREFIX_DELIMITER);
return (index > -1 ? path.substring(index + 1) : path);
}

/**
* Returns the regular expression equivalent of this Ant path.
*
* @return
*/
public String toRegex() {

StringBuilder patternBuilder = new StringBuilder();
Matcher m = WILDCARD_PATTERN.matcher(path);
int end = 0;

while (m.find()) {

patternBuilder.append(quote(path, end, m.start()));
String match = m.group();

if ("?".equals(match)) {
patternBuilder.append('.');
} else if ("**".equals(match)) {
patternBuilder.append(".*");
} else if ("*".equals(match)) {
patternBuilder.append("[^/]*");
}

end = m.end();
}

patternBuilder.append(quote(path, end, path.length()));
return patternBuilder.toString();
}

private static String quote(String s, int start, int end) {
if (start == end) {
return "";
}
return Pattern.quote(s.substring(start, end));
}

/*
* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return path;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright 2011 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.data.mongodb.gridfs;

import org.springframework.data.mongodb.core.query.Criteria;

/**
* GridFs-specific helper class to define {@link Criteria}s.
*
* @author Oliver Gierke
*/
public class GridFsCriteria extends Criteria {

/**
* Creates a new {@link GridFsCriteria} for the given key.
*
* @param key
*/
public GridFsCriteria(String key) {
super(key);
}

/**
* Creates a {@link GridFsCriteria} for restrictions on the file's metadata.
*
* @return
*/
public static GridFsCriteria whereMetaData() {
return new GridFsCriteria("metadata");
}

/**
* Creates a {@link GridFsCriteria} for restrictions on a single file's metadata item.
*
* @param metadataKey
* @return
*/
public static GridFsCriteria whereMetaData(String metadataKey) {
String extension = metadataKey == null ? "" : "." + metadataKey;
return new GridFsCriteria(String.format("metadata%s", extension));
}

/**
* Creates a {@link GridFsCriteria} for restrictions on the file's name.
*
* @return
*/
public static GridFsCriteria whereFilename() {
return new GridFsCriteria("filename");
}

/**
* Creates a {@link GridFsCriteria} for restrictions on the file's content type.
*
* @return
*/
public static GridFsCriteria whereContentType() {
return new GridFsCriteria("contentType");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* Copyright 2011 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.data.mongodb.gridfs;

import java.io.InputStream;
import java.util.List;

import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.data.mongodb.core.query.Query;

import com.mongodb.DBObject;
import com.mongodb.gridfs.GridFSDBFile;
import com.mongodb.gridfs.GridFSFile;

/**
* Collection of operations to store and read files from MongoDB GridFS.
*
* @author Oliver Gierke
*/
public interface GridFsOperations extends ResourcePatternResolver {

/**
* Stores the given content into a file with the given name.
*
* @param content must not be {@literal null}.
* @param filename must not be {@literal null} or empty.
* @return the {@link GridFSFile} just created
*/
GridFSFile store(InputStream content, String filename);

/**
* Stores the given content into a file with the given name using the given metadata. The metadata object will be
* marshalled before writing.
*
* @param content must not be {@literal null}.
* @param filename must not be {@literal null} or empty.
* @param metadata
* @return the {@link GridFSFile} just created
*/
GridFSFile store(InputStream content, String filename, Object metadata);

/**
* Stores the given content into a file with the given name using the given metadata.
*
* @param content must not be {@literal null}.
* @param filename must not be {@literal null} or empty.
* @param metadata must not be {@literal null}.
* @return the {@link GridFSFile} just created
*/
GridFSFile store(InputStream content, String filename, DBObject metadata);

/**
* Returns all files matching the given query.
*
* @param query
* @return
*/
List<GridFSDBFile> find(Query query);

/**
* Returns a single file matching the given query or {@literal null} in case no file matches.
*
* @param query
* @return
*/
GridFSDBFile findOne(Query query);

/**
* Deletes all files matching the given {@link Query}.
*
* @param query
*/
void delete(Query query);

/**
* Returns all {@link GridFsResource} with the given file name.
*
* @param filename
* @return
* @see ResourcePatternResolver#getResource(String)
*/
GridFsResource getResource(String filename);

/**
* Returns all {@link GridFsResource}s matching the given file name pattern.
*
* @param filenamePattern
* @return
* @see ResourcePatternResolver#getResources(String)
*/
GridFsResource[] getResources(String filenamePattern);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Copyright 2011 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.data.mongodb.gridfs;

import java.io.IOException;

import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;

import com.mongodb.gridfs.GridFSDBFile;

/**
* {@link GridFSDBFile} based {@link Resource} implementation.
*
* @author Oliver Gierke
*/
public class GridFsResource extends InputStreamResource {

private final GridFSDBFile file;

/**
* Creates a new {@link GridFsResource} from the given {@link GridFSDBFile}.
*
* @param file must not be {@literal null}.
*/
public GridFsResource(GridFSDBFile file) {
super(file.getInputStream());
this.file = file;
}

/*
* (non-Javadoc)
* @see org.springframework.core.io.AbstractResource#contentLength()
*/
@Override
public long contentLength() throws IOException {
return file.getLength();
}

/*
* (non-Javadoc)
* @see org.springframework.core.io.AbstractResource#getFilename()
*/
@Override
public String getFilename() throws IllegalStateException {
return file.getFilename();
}

/*
* (non-Javadoc)
* @see org.springframework.core.io.AbstractResource#lastModified()
*/
@Override
public long lastModified() throws IOException {
return file.getUploadDate().getTime();
}

/**
* Returns the {@link Resource}'s id.
*
* @return
*/
public Object getId() {
return file.getId();
}

/**
* Returns the {@link Resource}'s content type.
*
* @return
*/
public String getContentType() {
return file.getContentType();
}
}

0 comments on commit 572c4bb

Please sign in to comment.