package com.yael.utils;
import java.io.DataInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.util.logging.Logger;
import com.google.appengine.api.files.AppEngineFile;
import com.google.appengine.api.files.FileReadChannel;
import com.google.appengine.api.files.FileService;
import com.google.appengine.api.files.FileServiceFactory;
import com.google.appengine.api.files.FileWriteChannel;
import com.google.appengine.api.files.GSFileOptions.GSFileOptionsBuilder;
import com.google.appengine.api.files.LockException;
public class GSManager {
private static final Logger logger = Logger.getLogger(GSManager.class.getName());
private static final String DEFAULT_ACL = "public_read"; //Default permissions for uploaded file
private static final String DEFAULT_CACHE = "public, max-age=60"; //Default cacheControl: 1 min
private static final String DEFAULT_ENCODING = "UTF8";
private FileService fileService = null;
public GSManager(){
this.fileService = FileServiceFactory.getFileService();
}
public FileWriteChannel createWritableFile(String bucketName, String fileName) throws IOException {
return createWritableFile( bucketName, fileName, getMimeType(fileName), DEFAULT_ACL, DEFAULT_CACHE);
}
public FileWriteChannel createWritableFile(String bucketName, String fileName, String mimeType, String permission, String cacheControl) throws IOException {
GSFileOptionsBuilder optionsBuilder = null;
AppEngineFile writableFile = null;
String path = null;
if(Utils.isEmpty(bucketName)||Utils.isEmpty(fileName)){
logger.warning("bucketName : " + bucketName + " fileName : " + fileName);
throw new IOException("Invalid Bucket or File name!");
}
optionsBuilder = new GSFileOptionsBuilder();
optionsBuilder.setBucket(bucketName);
optionsBuilder.setKey(fileName);
optionsBuilder.setMimeType(mimeType);
optionsBuilder.setAcl(permission);
optionsBuilder.setCacheControl(cacheControl);
writableFile = this.fileService.createNewGSFile(optionsBuilder.build());
path = writableFile.getFullPath();
writableFile = new AppEngineFile(path);
//logger.info(path+" isWritable:"+writableFile.isWritable());
return fileService.openWriteChannel(writableFile, true);
}
public void closeWritableFile(FileWriteChannel file){
try {
if(file != null && file.isOpen()) file.closeFinally();
} catch (IllegalStateException e) {
logger.warning("IllegalStateException" + e);
e.printStackTrace();
} catch (IOException e) {
logger.warning("IOException" + e);
e.printStackTrace();
}
}
public void setObject(String bucketName, String fileName, byte[] data) throws IOException {
setObject(bucketName, fileName, getMimeType(fileName), DEFAULT_ACL, DEFAULT_CACHE, data, DEFAULT_ENCODING);
}
public void setObject(String bucketName, String fileName, String mimeType, String permission, String cacheControl, byte[] data, String encoding) throws IOException {
FileWriteChannel writeChannel = null;
try{
writeChannel = createWritableFile(bucketName,fileName,mimeType,permission,cacheControl);
writeChannel.write(ByteBuffer.wrap(data), encoding);
} catch (IOException e) {
logger.warning("IOException: " + e);
e.printStackTrace();
throw e;
} finally {
try {
if(writeChannel != null && writeChannel.isOpen()) writeChannel.closeFinally();
} catch (IllegalStateException e) {
logger.warning("IllegalStateException: " + e);
} catch (IOException e) {
logger.warning("IOException: " + e);
}
}
}
public byte[] getObject(String bucketName, String filename)
{
byte[] data = new byte [16384]; //switch to dynamic array
boolean lockForRead = false;
AppEngineFile readableFile = new AppEngineFile("/gs/"+bucketName+filename);
FileReadChannel readChannel;
try {
readChannel = fileService.openReadChannel(readableFile, lockForRead);
DataInputStream reader = new DataInputStream(Channels.newInputStream(readChannel));
reader.readFully(data);
readChannel.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (LockException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return data;
}
// public Map<String, String> getObjectList(String bucketName)
// {
// Document doc = XmlUtil.parse("http://storage.googleapis.com/"+bucketName);
// NodeList nodes = doc.getElementsByTagName("Key");
// //NodeList nodes = XmlUtil.selectNodes(doc, "//http://doc.s3.amazonaws.com/2006-03-01:Contents/http://doc.s3.amazonaws.com/2006-03-01:Key/text()");
//
// Map<String, String> images = new HashMap<String, String>(nodes.getLength());
// for(int i=0; i<nodes.getLength();i++){
// images.put(nodes.item(i).getTextContent(), "");
// }
// return images;
// }
public static String getMimeType(String fileName){
String type = findMimeType(fileName);
return (type==null)? "text/html": type;
}
public static boolean hasMimeType(String fileName){
String type = findMimeType(fileName);
return (type==null)? false: true;
}
private static String findMimeType(String fileName){
String type = fileName.substring(fileName.lastIndexOf(".") + 1);
if(type.equalsIgnoreCase("xml")) return "text/xml";
if(type.equalsIgnoreCase("jpg")) return "image/jpeg";
if(type.equalsIgnoreCase("jpeg")) return "image/jpeg";
if(type.equalsIgnoreCase("jpe")) return "image/jpeg";
if(type.equalsIgnoreCase("gif")) return "image/gif";
if(type.equalsIgnoreCase("png")) return "image/png";
if(type.equalsIgnoreCase("htm")) return "text/html";
if(type.equalsIgnoreCase("html")) return "text/html";
if(type.equalsIgnoreCase("htm")) return "text/html";
if(type.equalsIgnoreCase("txt")) return "text/plain";
else return null;
}
}