file name passthrough and extending a class to override a method
I needed to pass through a file with Ensemble but the operation wasn't writing some filenames as given because the EnsLib.File.PassthroughOperation 'sanitizes' filenames removing characters that are not valid on some operating
systems;
09000655_AEDC_C3344059_A/E_Martin Browne_09000655_201706221018.pdf
09000655_AEDC_C3344059_A#47E_Martin_Browne_09000655_201706221018.pdf
Oh No! It has stripped out my semicolon and ampersand! I need them! (and they are valid filename characters in windows)
I needed a class that ignores the file name parameter and instead writes the destination file with the same name as the source file.
To do this I extended the class EnsLib.File.PassthroughOperation with my own class that overrides the OnMessage() method.
Changing the SETTINGS to remove the File name field from the basic settings in the operation:
Parameter SETTINGS As %String = "-Filename:Basic";
Removing the ..Adapter.CreateTimestamp() function from the line that sets the tFilename variable:
Set tFilename=..Adapter.CreateTimestamp(##class(%File).GetFilename(pRequest.OriginalFilename),..Filename)Set tFilename=##class(%File).GetFilename(pRequest.OriginalFilename)
(thanks to Andrew Harris at the WRC for this excellent tip!)
Andrew provide more excellent advice;
You may still wish to filter out certain characters from the file name, e.g. “/”. There is a discussion here:
https://stackoverflow.com/questions/457994/what-characters-should-be-restricted-from-a-unix-file-name2.
Sadly I didn't implement this because I am not passing files to another OS.
--
Final version;
/// this version does not modify the filename in any way. /// Accepts objects of type Ens.StreamContainer and saves the /// encapsulated stream data to a file using the File OutboundAdapter. Class EalingPackage.file.PassthroughOperation Extends EnsLib.File.PassthroughOperation { Parameter ADAPTER = "EnsLib.File.OutboundAdapter"; /// Name of file to output the document(s) to. /// not stripped of characters illegal in target filenames). /// Timestamping options ignored. /// only use where source and destination filename rules are consistant. (same OS and OS version) Property Filename As %String(MAXLEN = 1000, MINLEN = 1) [ InitialExpression = "%f_%Q", Required ]; Parameter SETTINGS As %String = "-Filename:Basic"; Method OnMessage(pRequest As Ens.StreamContainer, Output pResponse As %Persistent) As %Status { Quit:'$IsObject(pRequest.Stream) $$$ERROR($$$EnsErrGeneral,"No Stream contained in StreamContainer Request") Set tFilename=##class(%File).GetFilename(pRequest.OriginalFilename) Set tSC=..Adapter.PutStream(tFilename, pRequest.Stream) Do pRequest.%Save() ; re-save in case PutStream() optimization changed the Stream filename Quit tSC } }