package org.nuxeo.mule.blob;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.util.Map;
import java.util.Set;
import org.apache.log4j.Logger;
import org.nuxeo.ecm.automation.client.Session;
import org.nuxeo.ecm.automation.client.jaxrs.impl.HttpAutomationClient;
import org.nuxeo.ecm.automation.client.model.Blob;
import org.nuxeo.ecm.automation.client.model.FileBlob;
import org.nuxeo.ecm.automation.client.model.HasFile;
import org.nuxeo.ecm.automation.client.model.PropertyMap;
import org.nuxeo.ecm.automation.client.model.StreamBlob;
public class BlobConverters {
private static final Logger logger = Logger.getLogger(BlobConverters.class);
protected static File workDir;
protected static File buildFileFromStream(InputStream stream)
throws IOException {
File wdir = getWorkDir();
File tmp = File.createTempFile("nuxeo", ".mule", wdir);
Files.copy(stream, tmp.toPath());
tmp.deleteOnExit();
return tmp;
}
public static NuxeoBlob fileToBlob(Object input) {
logger.info("Converting " + input.getClass().getName()
+ " to Nuxeo Blob");
if (input instanceof File) {
logger.info("Creating FileBlob");
return new NuxeoFileBlob(new FileBlob((File) input));
} else if (input instanceof FileInputStream) {
logger.info("Creating StreamBlob");
FileInputStream stream = (FileInputStream) input;
if (input.getClass().getSimpleName().contains(
"ReceiverFileInputStream")) {
// hack because this f**cking class is private !
try {
Method hiddentGetter = input.getClass().getDeclaredMethod(
"getCurrentFile", null);
hiddentGetter.setAccessible(true);
File targetFile = (File) hiddentGetter.invoke(input);
if (targetFile == null) {
logger.info("target File is null");
return new NuxeoFileBlob(new FileBlob(
buildFileFromStream(stream)));
} else {
logger.info("found target File via reflection ");
return new NuxeoFileBlob(new FileBlob(targetFile));
}
} catch (NoSuchMethodException e) {
logger.error("Can not find getCurrentFile method", e);
} catch (SecurityException e) {
logger.error("Can not access getCurrentFile method", e);
} catch (Exception e) {
logger.error("Can not execute getCurrentFile method", e);
}
}
return new NuxeoBlob(new StreamBlob(stream, "mule.blob",
"application/octet-stream"));
} else if (input instanceof byte[]) {
logger.info("Creating ByteArray Blob");
ByteArrayInputStream stream = new ByteArrayInputStream(
(byte[]) input);
return new NuxeoBlob(new StreamBlob(stream, "mule.blob",
"application/octet-stream"));
}
return null;
}
protected static String buildDownloadUrl(Map<String, Object> map)
throws UnsupportedEncodingException {
Set<String> keys = map.keySet();
if (keys.contains("name") && keys.contains("data")
&& keys.contains("mime-type")) {
return (String) map.get("data");
} else {
return null;
}
}
public static InputStream blobToStream(Session session, Object input)
throws UnsupportedEncodingException {
// simple case : this is a Nuxeo Blob
if (input instanceof Blob) {
try {
return ((Blob) input).getStream();
} catch (IOException e) {
logger.error("Unable to get Stream from Nuxeo Blob", e);
return null;
}
}
String downloadUrl = null;
// Blob property in a Document
if (input instanceof PropertyMap) {
PropertyMap pmap = (PropertyMap) input;
Map<String, Object> map = pmap.map();
downloadUrl = buildDownloadUrl(map);
} else if (input instanceof Map<?, ?>) {
Map<String, Object> map = (Map<String, Object>) input;
downloadUrl = buildDownloadUrl(map);
}
if (downloadUrl != null) {
DownloadClient dc = new DownloadClient(
(HttpAutomationClient) session.getClient());
return dc.download(downloadUrl);
}
return null;
}
public static Blob mapToBlob(Session session, Object input)
throws UnsupportedEncodingException {
String downloadUrl = null;
Map<String, Object> map = null;
// Blob property in a Document
if (input instanceof PropertyMap) {
PropertyMap pmap = (PropertyMap) input;
map = pmap.map();
downloadUrl = buildDownloadUrl(map);
} else if (input instanceof Map<?, ?>) {
map = (Map<String, Object>) input;
downloadUrl = buildDownloadUrl(map);
}
if (downloadUrl != null) {
DownloadClient dc = new DownloadClient(
(HttpAutomationClient) session.getClient());
return new StreamBlob(dc.download(downloadUrl),
(String) map.get("name"), (String) map.get("mime-type"));
}
return null;
}
public static File getWorkDir() {
if (workDir == null) {
workDir = new File(System.getProperty("java.io.tmpdir"),
"NuxeoMuleConnectorWorkDir");
if (workDir.exists() && !workDir.canWrite()) {
logger.debug("change directory to avoid FileNotFoundException (permission denied)");
try {
workDir = File.createTempFile("NuxeoMuleConnectorWorkDir",
null, workDir.getParentFile());
workDir.delete();
} catch (IOException e) {
logger.error("Could not create caching directory", e);
}
workDir.mkdirs();
}
}
return workDir;
}
public static void cleanup() throws IOException {
if (workDir != null) {
delete(workDir);
}
}
private static void delete(File f) throws IOException {
if (f.isDirectory()) {
for (File c : f.listFiles())
delete(c);
}
if (!f.delete())
throw new FileNotFoundException("Failed to delete file: " + f);
}
protected static File getTmpDir() {
File tmpSubDir = new File(getWorkDir(), "tmp-"
+ System.currentTimeMillis());
tmpSubDir.mkdirs();
return tmpSubDir;
}
public static File blobToFile(Blob blob) throws Exception {
String name = blob.getFileName();
if (blob instanceof HasFile) {
File file = ((HasFile) blob).getFile();
if (name != null && !name.isEmpty() && !file.getName().equals(name)) {
// rename the file !
File dest = new File(getTmpDir(), name);
file.renameTo(dest);
return dest;
}
return file;
}
if (name == null || name.isEmpty()) {
name = "blob.bin";
}
File tmpSubDir = getTmpDir();
File tmp = new File(tmpSubDir, name);
Files.copy(blob.getStream(), tmp.toPath());
tmp.deleteOnExit();
return tmp;
}
}