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.
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
}
You can use the Misc.duplicatieFileDocument function which is provided in the community commons module.
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?
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)'