Copy a FileDocument file

5
I have an instance of Filedocument where I uploaded a file. Now I would like to copy this file to a new FileDocument instance. I can copy the attributes of the FileDocument but not the file. How can I copy this file with Microflow of Java?
asked
5 answers
5

In Java you can call the Core.getFileDocumentContent(old filedocument) method to get an inputstream of a FileDocument. You can then create a new FileDocument in Java and use Core.storeFileDocumentContent(context, the new filedocument, the inputstream you got) to store the new file.

answered
5

I just made an example on how to copy a filedocument in a generic way (so you can pass any object to the java action)

Hope this helps you out.

// This file was generated by Mendix Business Modeler 2.5.
//
// WARNING: Only the following code will be retained when actions are regenerated:
// - the import list
// - the code between BEGIN USER CODE and END USER CODE
// - the code between BEGIN EXTRA CODE and END EXTRA CODE
// Other code you write will be lost the next time you deploy the project.
// Special characters, e.g., é, ö, à, etc. are supported in comments.

package myfirstmodule.actions;

import java.io.InputStream;
import system.proxies.FileDocument;
import com.mendix.core.Core;
import com.mendix.core.objectmanagement.member.MendixBoolean;
import com.mendix.systemwideinterfaces.core.IContext;
import com.mendix.systemwideinterfaces.core.UserAction;
import com.mendix.systemwideinterfaces.core.IMendixObject;
import com.mendix.systemwideinterfaces.core.meta.IMetaObject;

/**
 * 
 */
public class CopyFileDocument extends UserAction<Boolean>
{
    private IMendixObject sourceObject;
    private IMendixObject destinationObject;

    public CopyFileDocument(IMendixObject sourceObject, IMendixObject destinationObject)
    {
        super();
        this.sourceObject = sourceObject;
        this.destinationObject = destinationObject;
    }

    @Override
    public Boolean executeAction() throws Exception
    {
        // BEGIN USER CODE
        IContext context = this.getContext();
        if (sourceObject != null && destinationObject != null && isFileDocument(sourceObject.getMetaObject()) && isFileDocument(destinationObject.getMetaObject()))
        {
            MendixBoolean hasContents = (MendixBoolean) sourceObject.getMember(context, FileDocument.MemberNames.HasContents.toString());
            if (hasContents.getValue(context))
            {
                InputStream inputstream = Core.getFileDocumentContent(context, sourceObject);
                if (inputstream != null)
                {
                    Core.storeFileDocumentContent(context, destinationObject, (String) sourceObject.getValue(context, FileDocument.MemberNames.Name.toString()), inputstream );
                    return true;
                }
            }
        }
        return false;
        // END USER CODE
    }

    /**
     * Returns a string representation of this action
     */
    @Override
    public String toString()
    {
        return "CopyFileDocument";
    }

    // BEGIN EXTRA CODE
    private boolean isFileDocument(IMetaObject metaObject)
    {
        if (metaObject.getSuperName() == null || "".equals(metaObject.getSuperName()))
            return FileDocument.entityName.equals(metaObject.getName());
        return isFileDocument(Core.getMetaObject(metaObject.getSuperObject().getName()));
    }
    // END EXTRA CODE
}
answered
2

You can use the Misc.duplicatieFileDocument function which is provided in the community commons module.

answered
1

I am having problems just starting to follow this example to produce a simpler java action to copy an attachment from one object to another. Java API Tutorial

Just trying to declare an InputStream returns an error cannot find symbol:

compile:
    [javac] Compiling 1 source file to D:\Mendix\ESS\deployment\model\lib\bin
    [javac] D:\Mendix\ESS\javasource\tickets\actions\CopyAttachmentToNote.java:38: cannot find symbol
    [javac] symbol  : class InputStream
    [javac] location: class tickets.actions.CopyAttachmentToNote
    [javac]         InputStream inputStream;
    [javac]         ^

Here is part of the java action:

package tickets.actions;

import com.mendix.systemwideinterfaces.core.UserAction; import com.mendix.core.Core; import com.mendix.systemwideinterfaces.core.IContext; import com.mendix.systemwideinterfaces.core.IUser; import com.mendix.systemwideinterfaces.core.IMendixObject;

/** * */ public class CopyAttachmentToNote extends UserAction<boolean> { private IMendixObject SourceRecord; private IMendixObject TargetRecord;

public CopyAttachmentToNote(IMendixObject SourceRecord, IMendixObject TargetRecord)
{
    super();
    this.SourceRecord = SourceRecord;
    this.TargetRecord = TargetRecord;
}

@Override
public Boolean executeAction() throws Exception
{
    // BEGIN USER CODE

    InputStream inputStream;

What is causing this issue?

answered
1

Thanks for the help offered so far, but I am still having problems. The tutorial seems to assume knowledge that I do not have, and perhaps others are in the same situation. Why do you not post a complete working example, rather than just snippets of code? Here is what happened when I tried to follow the example. I started again and tried to reproduce the exact environment of the example:

I created new objects called GenericObject and Attachment and linked them. I created a new Java action with inputs sourceObject and destinationObject. I then copied the code snippets into the java source code, which resulted in:

// This file was generated by Mendix Business Modeler 2.5.
//
// WARNING: Only the following code will be retained when actions are regenerated:
// - the import list
// - the code between BEGIN USER CODE and END USER CODE
// - the code between BEGIN EXTRA CODE and END EXTRA CODE
// Other code you write will be lost the next time you deploy the project.
// Special characters, e.g., é, ö, à, etc. are supported in comments.

package myfirstmodule.actions;

import com.mendix.systemwideinterfaces.core.UserAction;
import com.mendix.systemwideinterfaces.core.IMendixObject;

/**
 * 
 */
public class Java_action extends UserAction<Boolean>
{
    private IMendixObject sourceObject;
    private IMendixObject destinationObject;

    public Java_action(IMendixObject sourceObject, IMendixObject destinationObject)
    {
        super();
        this.sourceObject = sourceObject;
        this.destinationObject = destinationObject;
    }

    @Override
    public Boolean executeAction() throws Exception
    {
        // BEGIN USER CODE

        Attachment newAttachment;
        InputStream inputStream;
        for (IMendixObject iMendixObject: getAttachments(sourceObject, context))
        {
        inputStream = Core.getFileDocumentContent(iMendixObject);
        newAttachment = Attachment.create(context);
        newAttachment.setAttachment_GenericObject(destinationObject);
        Core.storeFileDocumentContent(context, newAttachment.getMendixObject(), (String) iMendixObject.getValue(system.proxies.Document.MemberNames.Name.toString()),  inputStream);
}
        return true;
        // END USER CODE
    }

    /**
     * Returns a string representation of this action
     */
    @Override
    public String toString()
    {
        return "Java_action";
    }

    // BEGIN EXTRA CODE

    public static List<IMendixObject> getAttachments(GenericObject object, IContext context) throws CoreException
    {
    String attachmentEntityName = Attachment.entityName;
    String relationName = Attachment.MemberNames.Attachment_GenericObject.toString();
    String currentObjectID = object.getGUID();
    return Core.retrieveXPathQueryEscaped(context, "//%s[%s='%s']", attachmentEntityName, relationName, currentObjectID);
}

    // END EXTRA CODE
}

Trying to run this gives lots of errors, starting...

compile:
    [javac] Compiling 4 source files to D:\Mendix\Test\TestProject2\deployment\model\lib\bin
    [javac] D:\Mendix\Test\TestProject2\javasource\myfirstmodule\actions\Javaaction.java:60: cannot find symbol
    [javac] symbol  : class GenericObject
    [javac] location: class myfirstmodule.actions.Javaaction
    [javac]     public static List<imendixobject> getAttachments(GenericObject object, IContext context) throws CoreException

Importing other classes as Bas has suggested does not get past this initial error.

Edit Nov 18: Bas, I guess that might be part of the problem and tried with specific objects as follows:

 public class CopyAttachmentToNote extends UserAction<boolean>
{
    private IMendixObject _SourceRecord;
    private system.proxies.FileDocument SourceRecord;
    private IMendixObject _TargetRecord;
    private shared.proxies.Notes TargetRecord;

public CopyAttachmentToNote(IMendixObject SourceRecord, IMendixObject TargetRecord)
{
    super();
    this.__SourceRecord = SourceRecord;
    this.__TargetRecord = TargetRecord;
}

@Override
public Boolean executeAction() throws Exception
{
    this.SourceRecord = __SourceRecord == null ? null : system.proxies.FileDocument.initialize(this.getContext(), __SourceRecord);

    this.TargetRecord = __TargetRecord == null ? null : shared.proxies.Notes.initialize(this.getContext(), __TargetRecord);

    // BEGIN USER CODE

    InputStream inputStream;
    inputStream = Core.getFileDocumentContent(SourceRecord);

    Core.storeFileDocumentContent(context,TargetRecord.getMendixObject(),
     (String)iMendixObject.getValue(shared.proxies.Notes.MemberNames.Name.toString()),
     inputStream);

I'm trying to do a simple example, using the FileDocument as the source and an existing Notes (specialization of FileDocuemnt) as the target. This gives several errors, but the first is:

getFileDocumentContent(com.mendix.systemwideinterfaces.core.IContext,com.mendix.systemwideinterfaces.core.IMendixObject) in com.mendix.core.Core cannot be applied to (system.proxies.FileDocument)
    [javac]         inputStream = Core.getFileDocumentContent(SourceRecord);
    [javac]                           ^

Eclipse says 'The method getFileDocumentContent(IContext, IMendixObject) in the type Core is not applicable for the arguments (FileDocument)'

answered