package org.yaac.server.service;
import static com.google.common.collect.Lists.newLinkedList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.logging.Logger;
import javax.inject.Inject;
import org.yaac.client.service.BlobService;
import org.yaac.shared.ErrorCode;
import org.yaac.shared.SharedConstants.Blobstore;
import org.yaac.shared.YaacException;
import org.yaac.shared.blob.BlobInfoDTO;
import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.blobstore.BlobstoreService;
import com.google.appengine.api.blobstore.BlobstoreServiceFactory;
import com.google.appengine.api.datastore.AsyncDatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.FilterPredicate;
import com.google.appengine.api.datastore.Query.SortPredicate;
import com.googlecode.gql4j.GqlQuery;
/**
* @author Max Zhu (thebbsky@gmail.com)
*
*/
public class BlobServiceImpl implements BlobService {
private final Logger logger;
@Inject
BlobServiceImpl(Logger logger) {
super();
this.logger = logger;
}
@Override
public List<BlobInfoDTO> load(String filterStr) throws YaacException {
// step 1 : parse query
String strQuery = "select * from " + Blobstore.BLOB_INFO_KIND + " " + filterStr;
GqlQuery gql = new GqlQuery(strQuery);
Query query = gql.query();
logger.info("loading blobs, filter = " + filterStr);
logger.info("parsed query = " + strQuery);
// step 2 : validate query
for (FilterPredicate filter : query.getFilterPredicates()) {
if (! Blobstore.BLOB_INFO_ALL_PROPERTIES.contains(filter.getPropertyName())) {
throw new YaacException(ErrorCode.E201, null);
}
}
for (SortPredicate sort : query.getSortPredicates()) {
if (! Blobstore.BLOB_INFO_ALL_PROPERTIES.contains(sort.getPropertyName())) {
throw new YaacException(ErrorCode.E201, null);
}
}
// step3 : execute query
AsyncDatastoreService datastore = DatastoreServiceFactory.getAsyncDatastoreService();
Iterable<Entity> entities = datastore.prepare(gql.query()).asIterable(gql.fetchOptions());
List<BlobInfoDTO> result = newLinkedList();
for (Entity e : entities) {
result.add(new BlobInfoDTO(e.getKey().getName(),
(Date) e.getProperty(Blobstore.BLOB_INFO_CREATION),
(String) e.getProperty(Blobstore.BLOB_INFO_CONTENT_TYPE),
(String) e.getProperty(Blobstore.BLOB_INFO_FILENAME),
(Long) e.getProperty(Blobstore.BLOB_INFO_SIZE),
(String) e.getProperty(Blobstore.BLOB_INFO_MD5_HASH)));
}
return result;
}
@Override
public void delete(Collection<String> blobKeyStrs) throws YaacException {
BlobstoreService blobstore = BlobstoreServiceFactory.getBlobstoreService();
BlobKey [] keys = new BlobKey[blobKeyStrs.size()];
int i = 0;
for (String blobKeyStr : blobKeyStrs) {
keys[i++] = new BlobKey(blobKeyStr);
}
blobstore.delete(keys);
}
}