Vaadin Upload component - directly upload to mongo repository - java

I want to use a vaadin upload component in my webapplication and directly upload files to mongo db in gridfs format.
My current implementation use a temporary storage location to first upload file and then store in mongo converting to gridfs.
here is my upload component code: I have implement Receiver interface method recieveUpload
private File file;
private String tempFilePath;
public class HandleUploadImpl extends CustomComponent
implements Upload.SucceededListener,
Upload.FailedListener,
Upload.ProgressListener,
Upload.Receiver { ........
public OutputStream receiveUpload(String filename, String MIMEType) {
logger.debug("File information {} {}", filename, MIMEType);
this.filename = filename;
FileOutputStream fos;
file = new File(tempFilePath + filename);
try {
fos = new FileOutputStream(file);
} catch (final java.io.FileNotFoundException e) {
logger.error("Error occurred while opening the file {}", e);
return null;
}
return fos;
}
Here is my code to store in mongo repository
private void saveBuildFile(Map<String, Object> buildFileInfo, String key) {
if (buildFileInfo.containsKey(key)) {
GridFS gridFS = new GridFS(mongoTemplate.getDb(), COLLECTION_NAME);
File file = (File) buildFileInfo.get(key);
buildFileInfo.remove(key);
try {
GridFSInputFile savedFile = gridFS.createFile(file);
savedFile.put(idK, buildFileInfo.get(key + "-id"));
savedFile.save();
} catch (Exception e) {
logger.error("Something went wrong when saving the file in the db {}", e);
}
}
}
Is there a way I can omit the use of temporary storage and set the output stream of upload component to mongo repository gridfs file.

This works for me:
package ch.domain.vaadin;
import ch.domain.vaadin.mongo.MongoItem;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.gridfs.GridFS;
import com.mongodb.gridfs.GridFSInputFile;
import com.vaadin.data.fieldgroup.FieldGroup;
import com.vaadin.ui.Upload.Receiver;
import com.vaadin.ui.Upload.SucceededEvent;
import com.vaadin.ui.Upload.SucceededListener;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
/**
*
* #author eric
*/
class ImageUploader implements Receiver, SucceededListener {
private String filename;
private DB db;
private ByteArrayOutputStream fos;
private FieldGroup fieldGroup;
public void setFieldGroup(FieldGroup fieldGroup) {
this.fieldGroup = fieldGroup;
}
public ImageUploader(DB db)
{
this.db = db;
}
public OutputStream receiveUpload(String filename,
String mimeType) {
// Create upload stream
this.fos = new ByteArrayOutputStream();
this.filename = filename;
return this.fos; // Return the output stream to write to
}
public void uploadSucceeded(SucceededEvent event) {
GridFS gfsPhoto = new GridFS(db, "photo");
GridFSInputFile gfsFile = gfsPhoto.createFile(this.fos.toByteArray());
MongoItem parentId = (MongoItem) fieldGroup.getItemDataSource();
gfsFile.setMetaData(new BasicDBObject().append("parentId", parentId.getItemProperty("_id").getValue().toString()));
gfsFile.setFilename(this.filename);
gfsFile.save();
this.fos = null;
gfsFile = null;
// Show the uploaded file in the image viewer
// image.setVisible(true);
// image.setSource(new FileResource(file));
}
}

Related

Some Zip files are not extracting properly in alfresco through java code

I wrote java code to extract zip file in alfresco.
But through that code some zip files are not getting extracted properly.
And i have one more observation, that if i manually unzip that file and again manually create zip file then its working fine and its successfully getting extracted in alfresco site.
So i am not getting whats the problem exactly.
Is it problem with file or problem with my code or problem with zip file
Can anyone help me with this scenario...
Please refer below Logs for refrence...
2017-01-25 12:10:12,069 ERROR [tandf.ingestion.TransformExceptionService] [org.springframework.jms.listener.DefaultMessageListenerContainer#22-1] Unhandled Exception occured in ingestion pipeline: org.alfresco.error.AlfrescoRuntimeException: 00250134 Exception in Transaction.
at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:542)
at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:326)
at com.ixxus.tandf.service.XmlZipExtractService.lambda$extract$4(XmlZipExtractService.java:235)
at org.alfresco.repo.security.authentication.AuthenticationUtil.runAs(AuthenticationUtil.java:548)
at
I am Using below code for extracting zip file..
private void unzipToNode(final String zipFilePath, final NodeRef destinationFolder, final String isbn, final String zipFileNoderef, final String assetType, final NodeRef ingestedNodeRef) throws IOException {
LOG.debug("Inside : Start :-> unzipToNode, zipFileNoderef : {}", zipFileNoderef);
String rootDisplayPath = nodeUtils.getDisplayPath(destinationFolder);
List<NodeRef> folderNodes = new ArrayList<>();
try (ZipFile zipFile = new ZipFile(zipFilePath); FileInputStream fis = new FileInputStream(zipFilePath); ZipInputStream zipInput = new ZipInputStream(fis);) {
ZipEntry entry = zipInput.getNextEntry();
int zipFileSize = zipFile.size();
LOG.info("{} : zipFileSize from zip api for zipFileNoderef : {}", zipFileSize, zipFileNoderef);
int zipManualFileCount = 0;
while (entry != null) {
zipManualFileCount++;
LOG.debug("Processing the zip entry : {}, zipFileNoderef : {}", entry.getName(), zipFileNoderef);
InputStream inputStream = zipFile.getInputStream(entry);
/** create or get final folder path for current entry */
NodeRef nodeRef = createOrGetFolderStructure(destinationFolder, entry);
folderNodes.add(nodeRef);
String name;
if (!entry.isDirectory()) {
name = getFileNameFromEntry(entry);
/** if zip entry is file, then create and write the new node in validation site */
createNodeOnValidationSite(nodeRef, name, inputStream, assetType, ingestedNodeRef, rootDisplayPath);
}
/** close current entry and fetch next one */
zipInput.closeEntry();
entry = zipInput.getNextEntry();
}
LOG.info("{} : zipManualFileCount from zip api for zipFileNoderef : {}", zipManualFileCount, zipFileNoderef);
/** Close the last entry */
zipInput.closeEntry();
}
for(NodeRef folderNode : folderNodes){
if(nodeUtils.isNodeEmpty(folderNode)){
LOG.debug("Found empty folder [{}] within .zip [{}]", folderNode, ingestedNodeRef);
/** if the folder is empty we need to copy all properties to it as well to archive it */
copyAllProperties(ingestedNodeRef, folderNode, rootDisplayPath, assetType);
}
}
LOG.debug("Inside : End :-> unzipToNode : zipFileNoderef : {}", zipFileNoderef);
}
For extract a zip file can you please try this code.
package org.alfresco.repo.action.executer;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipException;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.action.ParameterDefinitionImpl;
import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.InvalidAspectException;
import org.alfresco.service.cmr.dictionary.InvalidTypeException;
import org.alfresco.service.cmr.model.FileExistsException;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentIOException;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.MimetypeService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.InvalidQNameException;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.TempFileProvider;
import org.alfresco.web.bean.repository.Repository;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
/**
* Zip action executor
*
* #author Davide Taibi
*/
public class ZipActionExecuter extends ActionExecuterAbstractBase
{
public static final String NAME = "importzip";
public static final String PARAM_ENCODING = "encoding";
public static final String PARAM_DESTINATION_FOLDER = "destination";
private static final String TEMP_FILE_PREFIX = "alf";
private static final String TEMP_FILE_SUFFIX = ".zip";
/**
* The node service
*/
private NodeService nodeService;
/**
* The content service
*/
private ContentService contentService;
private MimetypeService mimetypeService;
private FileFolderService fileFolderService;
/**
* Sets the NodeService to use
*
* #param nodeService The NodeService
*/
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
/**
* Sets the ContentService to use
*
* #param contentService The ContentService
*/
public void setContentService(ContentService contentService)
{
this.contentService = contentService;
}
public void setFileFolderService(FileFolderService fileFolderService) {
this.fileFolderService = fileFolderService;
}
public void setMimetypeService(MimetypeService mimetypeService) {
this.mimetypeService = mimetypeService;
}
private void extractFile(ZipFile archive,String mExtractToDir){
String fileName;
String destFileName;
byte[] buffer = new byte[16384];
mExtractToDir=mExtractToDir+File.separator;
try {
for ( Enumeration e = archive.getEntries(); e.hasMoreElements(); )
{
ZipEntry entry = (ZipEntry)e.nextElement();
if ( ! entry.isDirectory() )
{
fileName = entry.getName();
fileName = fileName.replace('/', File.separatorChar);
destFileName = mExtractToDir + fileName;
File destFile = new File(destFileName);
String parent = destFile.getParent();
if ( parent != null )
{
File parentFile = new File(parent);
if ( ! parentFile.exists() )
parentFile.mkdirs();
}
InputStream in = archive.getInputStream(entry);
OutputStream out = new FileOutputStream(destFileName);
int count;
while ( (count = in.read(buffer)) != -1 )
out.write(buffer, 0, count );
in.close();
out.close();
}else{
File newdir = new File( mExtractToDir + entry.getName() );
newdir.mkdir();
}
}
} catch (ZipException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void deleteDir(File dir){
File elenco=new File(dir.getPath());
for (File file:elenco.listFiles()){
if (file.isFile())
file.delete();
else
deleteDir(file);
}
dir.delete();
}
public void executeImpl(Action ruleAction, NodeRef actionedUponNodeRef) {
String spaceType;
NodeRef parentNodeRef;
FileInfo fileInfo;
NodeRef nodeRef;
if (this.nodeService.exists(actionedUponNodeRef) == true) {
ContentReader reader = this.contentService.getReader(
actionedUponNodeRef, ContentModel.PROP_CONTENT);
if (reader != null) {
if (MimetypeMap.MIMETYPE_ZIP.equals(reader.getMimetype())) {
File zFile = null;
ZipFile zipFile = null;
try {
spaceType = ContentModel.TYPE_FOLDER.toString();
String dirName = ""+this.nodeService.getProperty(actionedUponNodeRef, ContentModel.PROP_NAME);
dirName=dirName.substring(0,dirName.indexOf(".zip"));
parentNodeRef = (NodeRef)ruleAction.getParameterValue(PARAM_DESTINATION_FOLDER);// this.nodeService.getRootNode(Repository.getStoreRef());
fileInfo = fileFolderService.create(
parentNodeRef,
dirName,
Repository.resolveToQName(spaceType));
nodeRef = fileInfo.getNodeRef();
zFile = TempFileProvider.createTempFile(
TEMP_FILE_PREFIX, TEMP_FILE_SUFFIX);
reader.getContent(zFile);
zipFile = new ZipFile(zFile, "Cp437");
File tempDir=new File(TempFileProvider.getTempDir().getPath()+File.separator+dirName);
if (tempDir.exists()) deleteDir(tempDir);
extractFile(zipFile,tempDir.getPath());
importFile(tempDir.getPath(),nodeRef);
deleteDir(tempDir);
} catch (ContentIOException e) {
e.printStackTrace();
} catch (InvalidNodeRefException e) {
e.printStackTrace();
} catch (FileExistsException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
private void importFile(String dir,NodeRef root){
File elenco=new File(dir);
for (File file:elenco.listFiles()){
try {
if (file.isFile()){
InputStream contentStream = new FileInputStream(file);
// assign name
String fileName=file.getName();
Map<QName, Serializable> contentProps = new HashMap<QName, Serializable>();
contentProps.put(ContentModel.PROP_NAME, fileName);
// create content node
ChildAssociationRef association = nodeService
.createNode(
root,
ContentModel.ASSOC_CONTAINS,
QName.createQName(
NamespaceService.CONTENT_MODEL_PREFIX,
fileName),
ContentModel.TYPE_CONTENT,
contentProps);
NodeRef content = association.getChildRef();
// add titled aspect (for Web Client display)
Map<QName, Serializable> titledProps = new HashMap<QName, Serializable>();
titledProps.put(ContentModel.PROP_TITLE, fileName);
titledProps.put(ContentModel.PROP_DESCRIPTION,fileName);
nodeService.addAspect(content,
ContentModel.ASPECT_TITLED,
titledProps);
ContentWriter writer = contentService.getWriter(content,
ContentModel.PROP_CONTENT, true);
writer.setMimetype(mimetypeService.guessMimetype(file.getAbsolutePath()));
writer.setEncoding("Cp437");
writer.putContent(contentStream);
}else{
String spaceType = ContentModel.TYPE_FOLDER.toString();
FileInfo fileInfo = fileFolderService.create(
root,
file.getName(),
Repository.resolveToQName(spaceType));
importFile(file.getPath(),fileInfo.getNodeRef());
}
} catch (InvalidTypeException e) {
e.printStackTrace();
} catch (InvalidAspectException e) {
e.printStackTrace();
} catch (InvalidQNameException e) {
e.printStackTrace();
} catch (ContentIOException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (InvalidNodeRefException e) {
e.printStackTrace();
} catch (FileExistsException e) {
e.printStackTrace();
}
}
}
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
paramList.add(new ParameterDefinitionImpl(PARAM_DESTINATION_FOLDER, DataTypeDefinition.NODE_REF,
true, getParamDisplayLabel(PARAM_DESTINATION_FOLDER)));
paramList.add(new ParameterDefinitionImpl(PARAM_ENCODING, DataTypeDefinition.TEXT,
true, getParamDisplayLabel(PARAM_ENCODING)));
}
}
Moreover the file importzip-action-messages.properties :
importzip.title=Import Zip File
importzip.description=This Action import zip file into alfresco
importzip.aspect-name.display-label=The name of the aspect to apply to the node.
and add the following line to …-context.xml, (you can use action-services-context.xml)
<bean id="importzip" class="org.alfresco.repo.action.executer.ZipActionExecuter" parent="action-executer">
<property name="nodeService">
<ref bean="NodeService"></ref>
</property>
<property name="contentService">
<ref bean="ContentService" />
</property>
<property name="mimetypeService">
<ref bean="MimetypeService"></ref>
</property>
<property name="fileFolderService">
<ref bean="FileFolderService"></ref>
</property>
</bean>
<bean id="importzip-messages" class="org.alfresco.i18n.ResourceBundleBootstrapComponent">
<property name="resourceBundles">
<list>
<value>org.alfresco.repo.action.importzip-action-messages</value>
</list>
</property>
</bean>
and finally add this line to my web-client-config-custom.xml
<config evaluator="string-compare" condition="Action Wizards">
<action-handlers>
<handler name="importzip" class="org.alfresco.web.bean.actions.handlers.ImportHandler" />
</action-handlers>
</config>

Java : InputStream to Multi-part file conversion, result file is empty

I am working on a Java application in which I am trying to create a Multipart file out of downloaded InputStream. Unfortunately, it is not working and the Multipart file is empty. I checked the size of savedFile on disk before copying it to Multipart, and it has correct size, attributes, content.
What am I doing wrong in the conversion, there is no stacktrace, as I am catching it.
Code :
// InputStream contains file data.
byte[] bytes = IOUtils.toByteArray(inputStream);
File file = new File(msg + "temp");
if (file.exists() && file.isDirectory()) {
OutputStream outputStream = new FileOutputStream(new File(msg + "temp" + "/" +
groupAttachments.getFileName()));
outputStream.write(bytes);
outputStream.close();
}
java.io.File savedFile = new java.io.File(msg + "temp" + "/" +
groupAttachments.getFileName());
DiskFileItem fileItem = new DiskFileItem("file", "text/plain", false,
savedFile.getName(), (int) savedFile.length(), savedFile.getParentFile());
fileItem.getOutputStream();
MultipartFile multipartFile = new CommonsMultipartFile(fileItem);
System.out.println("Saved file size is "+savedFile.length());
if (multipartFile.isEmpty()) {
System.out.println("Dropbox uploaded multipart file is empty");
} else {
System.out.println("Multipart file is not empty.");
}
this.dropboxTask.insertFile(multipartFile, "",
savedPersonalNoteObject.getNoteid(), (long) 0, true);
Path path = Paths.get(msg + "temp" + "/" + groupAttachments.getFileName());
Console output :
Multipart file is not empty
Bytes are not null
File path is /My Group
Input stream is not null
Saved file size is 4765
Dropbox uploaded multipart file is empty
Multipart file is empty
Bytes are not null
What am I doing wrong in the conversion? Any help would be nice. Thanks a lot.
The DiskFileItem uses a DeferredFileOutputStream which uses an in-memory byte-array that is only filled when bytes are actually transferred.
Since files are used directly and no bytes are actually copied,
the byte-array is never filled. See for yourself in the source code:
Source code CommonsMultipartFile
Source code DiskFileItem
Source code DeferredFileOutputStream
So, instead of just calling fileItem.getOutputStream();, transfer the bytes to fill the in-memory byte-array:
try (OutputStream out = fileItem.getOutputStream();
InputStream in = Files.newInputStream(file.toPath())) {
IOUtils.copy(in, dfos);
}
and then the tranferTo call will work.
This appears to be a bit cumbersome for just moving a file: CommonsMultipartFile only calls fileItem.write((File)dest) in the transferTo method.
Below are two test cases, one using the DiskFileItem and one using the LocalFileItem. The code for LocalFileItem is shown further below.
I used dependencies org.springframework:spring-web:4.2.2.RELEASE, commons-fileupload:commons-fileupload:1.3.1 and junit:junit:4.12
Test class CommonMp:
import static org.junit.Assert.*;
import java.io.*;
import java.nio.charset.*;
import java.nio.file.*;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.io.IOUtils;
import org.junit.Test;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
public class CommonMp {
private final Charset CS = StandardCharsets.UTF_8;
#Test
public void testLocalMp() {
Path testInputFile = null, testOutputFile = null;
try {
testInputFile = prepareInputFile();
LocalFileItem lfi = new LocalFileItem(testInputFile);
CommonsMultipartFile cmf = new CommonsMultipartFile(lfi);
System.out.println("Empty: " + cmf.isEmpty());
testOutputFile = testInputFile.getParent().resolve("testMpOutput.txt");
cmf.transferTo(testOutputFile.toFile());
System.out.println("Size: " + cmf.getSize());
printOutput(testOutputFile);
} catch (Exception e) {
e.printStackTrace();
fail();
} finally {
deleteSilent(testInputFile, testOutputFile);
}
}
#Test
public void testMp() {
Path testInputFile = null, testOutputFile = null;
try {
testInputFile = prepareInputFile();
DiskFileItem di = new DiskFileItem("file", "text/plain", false, testInputFile.getFileName().toString(),
(int) Files.size(testInputFile), testInputFile.getParent().toFile());
try (OutputStream out = di.getOutputStream();
InputStream in = Files.newInputStream(testInputFile)) {
IOUtils.copy(in, out);
}
CommonsMultipartFile cmf = new CommonsMultipartFile(di);
System.out.println("Size: " + cmf.getSize());
testOutputFile = testInputFile.getParent().resolve("testMpOutput.txt");
cmf.transferTo(testOutputFile.toFile());
printOutput(testOutputFile);
} catch (Exception e) {
e.printStackTrace();
fail();
} finally {
deleteSilent(testInputFile, testOutputFile);
}
}
private Path prepareInputFile() throws IOException {
Path tmpDir = Paths.get(System.getProperty("java.io.tmpdir"));
Path testInputFile = tmpDir.resolve("testMpinput.txt");
try (OutputStream out = Files.newOutputStream(testInputFile)){
out.write("Just a test.".getBytes(CS));
}
return testInputFile;
}
private void printOutput(Path p) throws IOException {
byte[] outBytes = Files.readAllBytes(p);
System.out.println("Output: " + new String(outBytes, CS));
}
private void deleteSilent(Path... paths) {
for (Path p : paths) {
try { if (p != null) p.toFile().delete(); } catch (Exception ignored) {}
}
}
}
The custom LocalFileItem class, YMMV!
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemHeaders;
public class LocalFileItem implements FileItem {
private static final long serialVersionUID = 2467880290855097332L;
private final Path localFile;
public LocalFileItem(Path localFile) {
this.localFile = localFile;
}
#Override
public void write(File file) throws Exception {
Files.move(localFile, file.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
#Override
public long getSize() {
// Spring's CommonsMultipartFile caches the file size and uses it to determine availability.
long size = -1L;
try {
size = Files.size(localFile);
} catch (IOException ignored) {}
return size;
}
#Override
public void delete() {
localFile.toFile().delete();
}
/* *** properties and unsupported methods *** */
private FileItemHeaders headers;
private String contentType;
private String fieldName;
private boolean formField;
#Override
public FileItemHeaders getHeaders() {
return headers;
}
#Override
public void setHeaders(FileItemHeaders headers) {
this.headers = headers;
}
#Override
public InputStream getInputStream() throws IOException {
throw new IOException("Only method write(File) is supported.");
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
#Override
public String getContentType() {
return contentType;
}
#Override
public String getName() {
return localFile.getFileName().toString();
}
#Override
public boolean isInMemory() {
return false;
}
#Override
public byte[] get() {
throw new RuntimeException("Only method write(File) is supported.");
}
#Override
public String getString(String encoding)
throws UnsupportedEncodingException {
throw new RuntimeException("Only method write(File) is supported.");
}
#Override
public String getString() {
throw new RuntimeException("Only method write(File) is supported.");
}
#Override
public String getFieldName() {
return fieldName;
}
#Override
public void setFieldName(String name) {
this.fieldName = name;
}
#Override
public boolean isFormField() {
return formField;
}
#Override
public void setFormField(boolean state) {
this.formField = state;
}
#Override
public OutputStream getOutputStream() throws IOException {
throw new IOException("Only method write(File) is supported.");
}
}

Couldn't append the text onto a Google Drive File

I am trying to append text to a text file on the Google Drive. But when I write, it whole file is overwritten. Why can't I just add the text in the end of the file?
DriveFile file = Drive.DriveApi.getFile(mGoogleApiClient, id);
file.open(mGoogleApiClient, DriveFile.MODE_WRITE_ONLY, null).setResultCallback(new ResultCallback<DriveApi.DriveContentsResult>() {
#Override
public void onResult(DriveApi.DriveContentsResult driveContentsResult) {
msg.Log("ContentsOpenedCallBack");
if (!driveContentsResult.getStatus().isSuccess()) {
Log.i("Tag", "On Connected Error");
return;
}
final DriveContents driveContents = driveContentsResult.getDriveContents();
try {
msg.Log("onWrite");
OutputStream outputStream = driveContents.getOutputStream();
Writer writer = new OutputStreamWriter(outputStream);
writer.append(et.getText().toString());
writer.close();
driveContents.commit(mGoogleApiClient, null);
} catch (IOException e) {
e.printStackTrace();
}
}
});
Finally I've found the answer to append the text on the drive document.
DriveContents contents = driveContentsResult.getDriveContents();
try {
String input = et.getText().toString();
ParcelFileDescriptor parcelFileDescriptor = contents.getParcelFileDescriptor();
FileInputStream fileInputStream = new FileInputStream(parcelFileDescriptor
.getFileDescriptor());
// Read to the end of the file.
fileInputStream.read(new byte[fileInputStream.available()]);
// Append to the file.
FileOutputStream fileOutputStream = new FileOutputStream(parcelFileDescriptor
.getFileDescriptor());
Writer writer = new OutputStreamWriter(fileOutputStream);
writer.write("\n"+input);
writer.close();
driveContentsResult.getDriveContents().commit(mGoogleApiClient, null);
} catch (IOException e) {
e.printStackTrace();
}
SO
The reason is that commit's default resolution strategy is to overwrite existing files. Check the API docs and see if there is a way to append changes.
For anyone facing this problem in 2017 :
Google has some methods to append data Here's a link!
Though copying the method from google didn't worked entirely for me , so here is the class which would append data : ( Please note this is a modified version of this code link )
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.preference.PreferenceManager;
import android.util.Log;
import com.google.android.gms.common.api.Result;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.drive.Drive;
import com.google.android.gms.drive.DriveApi.DriveContentsResult;
import com.google.android.gms.drive.DriveApi.DriveIdResult;
import com.google.android.gms.drive.DriveContents;
import com.google.android.gms.drive.DriveFile;
import com.google.android.gms.drive.DriveId;
/**
* An activity to illustrate how to edit contents of a Drive file.
*/
public class EditContentsActivity extends BaseDemoActivity {
private static final String TAG = "EditContentsActivity";
#Override
public void onConnected(Bundle connectionHint) {
super.onConnected(connectionHint);
final ResultCallback<DriveIdResult> idCallback = new ResultCallback<DriveIdResult>() {
#Override
public void onResult(DriveIdResult result) {
if (!result.getStatus().isSuccess()) {
showMessage("Cannot find DriveId. Are you authorized to view this file?");
return;
}
DriveId driveId = result.getDriveId();
DriveFile file = driveId.asDriveFile();
new EditContentsAsyncTask(EditContentsActivity.this).execute(file);
}
};
SharedPreferences sp= PreferenceManager.getDefaultSharedPreferences(EditContentsActivity.this);
Drive.DriveApi.fetchDriveId(getGoogleApiClient(), EXISTING_FILE_ID)
.setResultCallback(idCallback);
}
public class EditContentsAsyncTask extends ApiClientAsyncTask<DriveFile, Void, Boolean> {
public EditContentsAsyncTask(Context context) {
super(context);
}
#Override
protected Boolean doInBackgroundConnected(DriveFile... args) {
DriveFile file = args[0];
SharedPreferences sp=PreferenceManager.getDefaultSharedPreferences(EditContentsActivity.this);
System.out.println("0"+sp.getString("drive_id","1"));
DriveContentsResult driveContentsResult=file.open(getGoogleApiClient(), DriveFile.MODE_READ_WRITE, null).await();
System.out.println("1");
if (!driveContentsResult.getStatus().isSuccess()) {
return false;
}
DriveContents driveContents = driveContentsResult.getDriveContents();
try {
System.out.println("2");
ParcelFileDescriptor parcelFileDescriptor = driveContents.getParcelFileDescriptor();
FileInputStream fileInputStream = new FileInputStream(parcelFileDescriptor
.getFileDescriptor());
// Read to the end of the file.
fileInputStream.read(new byte[fileInputStream.available()]);
System.out.println("3");
// Append to the file.
FileOutputStream fileOutputStream = new FileOutputStream(parcelFileDescriptor
.getFileDescriptor());
Writer writer = new OutputStreamWriter(fileOutputStream);
writer.write("hello world");
writer.close();
System.out.println("4");
driveContents.commit(getGoogleApiClient(), null).await();
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
};
#Override
protected void onPostExecute(Boolean result) {
if (!result) {
showMessage("Error while editing contents");
return;
}
showMessage("Successfully edited contents");
}
}
}
Existing_File_id is the resource id. Here is one link if you need resource id a link

Google Drive uploading a file, and reading a file

.Net guy working on a java app
I am uploading using the following example as my starting point ( I have this working). This shows using FileContent needing a java.io.File which does not contain the actual file only a pointer to the actual file.
We are uploading from a web site and attempting to insert into the drive, I would prefer to do this using a memory Stream like the .Net example. I cannot see that in looking at the FileContent class. So my questing is: Is there a way to insert a file in Google drive that is in memory and not first on the hard drive?
private static File insertFile(Drive service, String title, String description,
String parentId, String mimeType, String filename) {
// File's metadata.
File body = new File();
body.setTitle(title);
body.setDescription(description);
body.setMimeType(mimeType);
// Set the parent folder.
if (parentId != null && parentId.length() > 0) {
body.setParents(
Arrays.asList(new ParentReference().setId(parentId)));
}
// File's content.
java.io.File fileContent = new java.io.File(filename);
FileContent mediaContent = new FileContent(mimeType, fileContent);
try {
File file = service.files().insert(body, mediaContent).execute();
// Uncomment the following line to print the File ID.
// System.out.println("File ID: " + file.getId());
return file;
} catch (IOException e) {
System.out.println("An error occured: " + e);
return null;
}
}
Override the AbstractInputStream build your own FileContent
package com;
import java.io.IOException;
import java.io.InputStream;
import com.google.api.client.http.AbstractInputStreamContent;
import com.google.api.client.util.Preconditions;
public class FileContent extends AbstractInputStreamContent {
private InputStream inputStream = null;
private long inputLength = 0;
public FileContent(String type, InputStream pInputStream) throws IOException {
super(type);
this.inputStream = Preconditions.checkNotNull(pInputStream);
this.inputLength = this.inputStream.available();
}
public long getLength() throws IOException {
return this.inputLength;
}
public boolean retrySupported() {
return false;
}
#Override
public InputStream getInputStream() throws IOException {
return this.inputStream;
}
}

How to add Progress bar to File Copy in Java

so I have class that is used to copy all of a specific file type from one directory to another directory. This class does work, but I am curious on what would be the best method of adding a progress bar to let the users know how far along in copying all the files.
So my question is, what would be the best method of adding a progress bar to this class. As you may see, there is no GUI being made by this class as it stands.
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
public class CopyFilesFromType
{
public static void main(File SourcePath, File DestPath)
{
new CopyFilesFromType().copy("tif", SourcePath.toString(), DestPath.toString());
}
private FileTypeOrFolderFilter filter = null;
private void copy(final String fileType, String fromPath, String outputPath)
{
filter = new FileTypeOrFolderFilter(fileType);
File currentFolder = new File(fromPath);
File outputFolder = new File(outputPath);
scanFolder(fileType, currentFolder, outputFolder);
}
private void scanFolder(final String fileType, File currentFolder, File outputFolder)
{
System.out.println("Scanning folder [" + currentFolder + "]...");
File[] files = currentFolder.listFiles(filter);
for (File file : files) {
if (file.isDirectory()) {
scanFolder(fileType, file, outputFolder);
} else {
copy(file, outputFolder);
}
}
}
private void copy(File file, File outputFolder)
{
try {
System.out.println("\tCopying [" + file + "] to folder [" + outputFolder + "]...");
InputStream input = new FileInputStream(file);
OutputStream out = new FileOutputStream(new File(outputFolder + File.separator + file.getName()));
byte data[] = new byte[input.available()];
input.read(data);
out.write(data);
out.flush();
out.close();
input.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private final class FileTypeOrFolderFilter implements FileFilter
{
private final String fileType;
private FileTypeOrFolderFilter(String fileType)
{
this.fileType = fileType;
}
public boolean accept(File pathname)
{
return pathname.getName().endsWith("." + fileType) || pathname.isDirectory();
}
}
}
Wrap the FileInputStream in a javax.swing.ProgressMonitorInputStream.

Categories

Resources