I have created a pre-processor that saves an uploaded file to the filesystem as opposed to the database. The initial prototype just used a url (the base of which was passed as a parameter to the pre-processor) to reference the uploaded file. This is working fine.
I would like to use the binary template to publish the file in the appropriate location. This gives us the added benefit of the files following workflow actions (publishing/unpublishing etc).
Attempted solution 1:
I created a simple extension that given a path to the file, would return the file as a byte array (which $sys.binary in the binary template accepts). This solution works given a smaller file, but given a large file (say 600MB) i get an error on the template: “Error reported null”. The jvm memory has been increased to an appropriate level so that is not the issue. The logs do not give any more information. I am thinking this might have something to do with a timeout of some sort, but can’t seem to track it down…also there seems something wrong with allocating a 600mb byte array…
Attempted solution 2:
The $sys.binary field also accepts javax.jcr.property (the field name). So i was trying various ways (via extensions to set $sys.binary) to pass the file through to that with no luck (tried setting an inputstream, PSPurgableTempFile, Values).
What would be the best way to publish a file given its location? Do i need to create a new binary template/ publisher? If so what steps do i take for that?
We’ve done something similar for an intranet in that if a file is over 10mb size then it’s saved to a shared on the network. The path (share name + filename) is then saved as the filename for then binary so the location scheme can either use the actual file name (if below 10mb) or the share name (if over 10mb).
So, in your implementation is it the location scheme that determines what publishes the item in the correct location? Does the file over 10MB actually publish to the correct location? or are you just storing a link to the file and publishing that? If you are publishing the actual file (greater than 10MB), does preview work for the binary template?
The plan is to save the file on the share regardless of the file size. I do have a field to store the full path / absolute filepath so getting that and using it is not a problem.
Does the file over 10MB actually publish to the correct location?
It’s not publish as such. We’ve made a change to the sys_fileinfo exit so when the content item is saved the file is copied to the share. Because we’ve done it this way we can then save the new file name to the item_filename field.
The file content list is then modified to only publish content where there’s an actually binary file saved in the binary field.
What’s really happening under the covers is that the Binary assembler is attempting to create a temporary file object (PSPurgableTempFile) whenever the length of the file is larger than 64K.
I’m very surprised that this is failing without errors. I assume you have looked at system.log. Are there any entries at all?
I would recommend that you change your JEXL function to return a javax.jcr.Value object. This interface has a getStream method which returns an InputStream. The assembler will copy this stream to a PSPurgableTempFile. You don’t need to implement the other methods of Value, just getStream() (and perhaps getType() if you want to be paranoid).
Even though the help doesn’t say so, the Binary assembler will accept Value objects directly, you don’t need to wrap them in a Property.
Thanks for that information. I was able to implement javax.jcr.Value and pass that object on to the binary assembler. After a bit of security enhancements (preventing loading of any file) the extension does what i want it to. I assume that the type i want to return is javax.jcr.PropertyType.REFERENCE? (I don’t think it really matters for what i am doing, but I am not sure if the binary assembler uses that information in any way)