web stats
Mirth Tools: User defined functions - Page 4 - Mirth Community

Go Back   Mirth Community > Mirth Connect > Support

Reply
 
Thread Tools Display Modes
  #31  
Old 09-26-2014, 05:49 AM
mulleg mulleg is offline
What's HL7?
 
Join Date: May 2010
Posts: 4
mulleg is on a distinguished road
Default Using results from xmlToHL7 function

The xmlToHL7 function is really helpful, but I had some problems using it with javascript string functions until I added a null string:

var deSerializedLocation = xmlToHL7(msg.PV1['PV1.3'])+'';

After which I could use it as a javastring variable.
Reply With Quote
  #32  
Old 10-22-2014, 12:43 PM
Shamil Shamil is offline
OBX.3 Kenobi
 
Join Date: May 2013
Posts: 153
Shamil is on a distinguished road
Default

Am I right that user defined functions are not available for Deploy, Preprocessor, Postprocessor and Undeploy scripts in 3.1?
Reply With Quote
  #33  
Old 10-22-2014, 12:47 PM
narupley's Avatar
narupley narupley is online now
Mirth Employee
 
Join Date: Oct 2010
Posts: 7,123
narupley is on a distinguished road
Default

Quote:
Originally Posted by Shamil View Post
Am I right that user defined functions are not available for Deploy, Preprocessor, Postprocessor and Undeploy scripts in 3.1?
They are. Make sure your context is set appropriately. Set it to Global if you're not sure.
__________________
Step 1: JAVA CACHE...DID YOU CLEAR ...wait, ding dong the witch is dead?

Nicholas Rupley
Work: 949-237-6069
Always include what Mirth Connect version you're working with. Also include (if applicable) the code you're using and full stacktraces for errors (use CODE tags). Posting your entire channel is helpful as well; make sure to scrub any PHI/passwords first.


- How do I foo?
- You just bar.
Reply With Quote
  #34  
Old 10-27-2014, 09:06 AM
narupley's Avatar
narupley narupley is online now
Mirth Employee
 
Join Date: Oct 2010
Posts: 7,123
narupley is on a distinguished road
Default Unescape \Xdd..\ HL7 Escape Sequences

Quote:
UPDATE: I've created a public GitHub repository to track these example channels, code templates, scripts, or whatever else!

https://github.com/nextgenhealthcare/connect-examples

To start with I only added the ones I wrote, because I didn't want to presume and add code from others without their explicit permission. Pull requests welcome!
This has been asked before, and recently again, so I just created a template for it.

unescapeXSequences: Recursively iterates through all descendant nodes of an E4X XML object and replaces any \Xdd..\ escape sequences with the corresponding character(s). The given charset will be used for string conversion (US-ASCII if not specified). Any encoding characters (e.g. "|^~\&") detected in the replacement will instead be replaced with the appropriate escape sequence (e.g. "\F\").

Parameters:
  • node: The node to recursively iterate through.
  • charset: The character encoding set to use when converting bytes to Unicode code points. If not specified, US-ASCII will be used.
  • encodingCharacters: The HL7 encoding characters to exclude from the replacement. For example if the sequence \X7C\ is encountered, then it will be replaced with "\F\" instead of a literal "|" character. If not specified, the function will attempt to infer the characters from the MSH.1 and MSH.2 fields, or default to "|^~\&".

Examples:
  • Replace all X escape sequences, using the default charset and inferring encoding characters:
    Code:
    unescapeXSequences(msg);
  • Replace all X escape sequences using a specific charset:
    Code:
    unescapeXSequences(msg, 'UTF-8');

The code:

Code:
function unescapeXSequences(node, charset, encodingCharacters) {
	if (!charset) {
		charset = 'US-ASCII';
	}

	if (!encodingCharacters) {
		encodingCharacters = node.MSH['MSH.1'].toString().split('').concat(node.MSH['MSH.2'].toString().split(''));
		if (encodingCharacters.length == 0) {
			encodingCharacters = ['|', '^', '~', '\\', '&'];
		}
	}

	for each (child in node.children()) {
		if (child.hasComplexContent()) {
			unescapeXSequences(child, charset, encodingCharacters);
		} else if (!/MSH\.[12]/.test(child.name())) {
			var childString = child.toString();
			var matched = false;

			for each (match in childString.match(/\\X([\dA-F]{2})+\\/ig)) {
				matched = true;
				var hexString = match.substr(2, match.length-3);
				var buffer = java.nio.ByteBuffer.allocate(hexString.length / 2);

				while (hexString.length > 0) {
					var intValue = new java.lang.Integer((java.lang.Character.digit(hexString.substr(0,1), 16) << 4) + java.lang.Character.digit(hexString.substr(1,1), 16));
					buffer.put(intValue.byteValue());
					hexString = hexString.substr(2);
				}

				childString = childString.replace(match, new java.lang.String(buffer.array(), charset));
			}

			if (matched) {
				if (encodingCharacters.length > 3) {
					childString = childString.replace(encodingCharacters[3], '\\E\\');
				}
				if (encodingCharacters.length > 0) {
					childString = childString.replace(encodingCharacters[0], '\\F\\');
				}
				if (encodingCharacters.length > 1) {
					childString = childString.replace(encodingCharacters[1], '\\S\\');
				}
				if (encodingCharacters.length > 2) {
					childString = childString.replace(encodingCharacters[2], '\\R\\');
				}
				if (encodingCharacters.length > 4) {
					childString = childString.replace(encodingCharacters[4], '\\T\\');
				}

				node.children()[child.childIndex()] = <{child.name()}>{childString}</{child.name()}>;
			}
		}
	}
}
Attached Files
File Type: xml unescapeXSequences.xml (2.4 KB, 68 views)
__________________
Step 1: JAVA CACHE...DID YOU CLEAR ...wait, ding dong the witch is dead?

Nicholas Rupley
Work: 949-237-6069
Always include what Mirth Connect version you're working with. Also include (if applicable) the code you're using and full stacktraces for errors (use CODE tags). Posting your entire channel is helpful as well; make sure to scrub any PHI/passwords first.


- How do I foo?
- You just bar.

Last edited by narupley; 06-08-2018 at 10:36 AM.
Reply With Quote
  #35  
Old 10-27-2014, 09:42 AM
andresilva3 andresilva3 is offline
OBX.1 Kenobi
 
Join Date: Oct 2014
Posts: 27
andresilva3 is on a distinguished road
Default

Using your template began to give this error
Quote:
TypeError: Cannot read property "PID" from undefined
Reply With Quote
  #36  
Old 11-04-2014, 06:58 AM
narupley's Avatar
narupley narupley is online now
Mirth Employee
 
Join Date: Oct 2010
Posts: 7,123
narupley is on a distinguished road
Default Encrypt PDF files with password

Quote:
UPDATE: I've created a public GitHub repository to track these example channels, code templates, scripts, or whatever else!

https://github.com/nextgenhealthcare/connect-examples

To start with I only added the ones I wrote, because I didn't want to presume and add code from others without their explicit permission. Pull requests welcome!
In response to a recent thread:

encryptPDF: Encrypts a PDF with a password. Either a Base64 string or by array can be passed in, and the output can be written to a file or returned as a Base64 string.

Parameters:
  • pdfBase64OrBytes: The PDF data to encrypt. May be a Base64 string, or a byte array.
    password: The password to use for encryption.
    outputFilename: (Optional) The filename to output the encrypted PDF to. If omitted, the data will be returned from the function as a Base64 string.

Examples:
  • Take a Base64 encoded PDF in OBX.5.5, encrypt it, and put it back into the OBX:
    Code:
    msg['OBX']['OBX.5']['OBX.5.5'] = encryptPDF(msg['OBX']['OBX.5']['OBX.5.5'].toString(), 'password');

The code:
Code:
function encryptPDF(pdfBase64OrBytes, password, outputFilename) {
	var document;
	var fos;

	try {
		var pdfBytes;
		if (pdfBase64OrBytes instanceof Array) {
			pdfBytes = pdfBase64OrBytes;
		} else {
			pdfBytes = FileUtil.decode(pdfBase64OrBytes);
		}

		var inputStream = new java.io.ByteArrayInputStream(pdfBytes);
		document = org.apache.pdfbox.pdmodel.PDDocument.load(inputStream);

		var accessPermission = new org.apache.pdfbox.pdmodel.encryption.AccessPermission();
		accessPermission.setCanAssembleDocument(false);
		accessPermission.setCanExtractContent(true);
		accessPermission.setCanExtractForAccessibility(false);
		accessPermission.setCanFillInForm(false);
		accessPermission.setCanModify(false);
		accessPermission.setCanModifyAnnotations(false);
		accessPermission.setCanPrint(true);
		accessPermission.setCanPrintDegraded(true);

		var policy = new org.apache.pdfbox.pdmodel.encryption.StandardProtectionPolicy(UUIDGenerator.getUUID(), password, accessPermission);
		policy.setEncryptionKeyLength(128);
		document.protect(policy);

		if (outputFilename) {
			fos = new java.io.FileOutputStream(new java.io.File(outputFilename));
			document.save(fos);
		} else {
			var baos = new java.io.ByteArrayOutputStream();
			document.save(baos);
			return FileUtil.encode(baos.toByteArray());
		}
	} finally {
		if (document) {
			document.close();
		}
		if (fos) {
			fos.close();
		}
	}
}
Attached Files
File Type: xml encryptPDF.xml (1.7 KB, 81 views)
__________________
Step 1: JAVA CACHE...DID YOU CLEAR ...wait, ding dong the witch is dead?

Nicholas Rupley
Work: 949-237-6069
Always include what Mirth Connect version you're working with. Also include (if applicable) the code you're using and full stacktraces for errors (use CODE tags). Posting your entire channel is helpful as well; make sure to scrub any PHI/passwords first.


- How do I foo?
- You just bar.

Last edited by narupley; 06-08-2018 at 10:36 AM.
Reply With Quote
  #37  
Old 04-22-2015, 02:34 PM
narupley's Avatar
narupley narupley is online now
Mirth Employee
 
Join Date: Oct 2010
Posts: 7,123
narupley is on a distinguished road
Default Execute Runtime Command

Quote:
UPDATE: I've created a public GitHub repository to track these example channels, code templates, scripts, or whatever else!

https://github.com/nextgenhealthcare/connect-examples

To start with I only added the ones I wrote, because I didn't want to presume and add code from others without their explicit permission. Pull requests welcome!
This is something that crops up from time to time. Some of you may know (or can find out via searching) that to execute an arbitrary command on your local OS shell, you can use java.lang.Runtime. However, a lot of people are confused about the correct way to use it. Hopefully this code template will help out.

executeRuntimeCommand: Executes a command or an array of the command and arguments using a local OS shell. Returns an object containing the exit value, output, and errors.

Parameters:
  • args: This can be either a string, or an array of strings. If you pass in a single string, it treats it as the entire command string, like "ls -l". If you pass in an array, it treats the first element as the command, and each subsequent element as parameters for the command. The array method is preferred, because you don't have to worry about quoting parameters that have spaces in them.
  • charset: (Optional) The charset encoding to use when reading the output from the command. If omitted, the JVM default charset will be used.

Examples:
  • Execute a single command string (in this case, tailing system messages on Linux), and outputs results:
    Code:
    var result = executeRuntimeCommand('tail /var/log/messages');
    
    logger.info('Exit value: ' + result.exitValue);
    logger.info('Output: ' + result.stdout);
    if (result.stderr != '') {
    	logger.error('Errors: ' + result.stderr);
    }
  • Same thing, but this time using an array:
    Code:
    var result = executeRuntimeCommand(['tail', '/var/log/messages']);
    
    logger.info('Exit value: ' + result.exitValue);
    logger.info('Output: ' + result.stdout);
    if (result.stderr != '') {
    	logger.error('Errors: ' + result.stderr);
    }

The code:

Code:
function executeRuntimeCommand(args, charset) {
	var process = java.lang.Runtime.getRuntime().exec(args);
	var stdoutConsumer = new StreamConsumer(process.getInputStream(), charset);
	var stderrConsumer = new StreamConsumer(process.getErrorStream(), charset);
	return {
		exitValue : process.waitFor(),
		stdout : stdoutConsumer.getOutput(),
		stderr : stderrConsumer.getOutput()
	};
}

function StreamConsumer(is, charset) {
	var output = '';
	
	var thread = new java.lang.Thread({
		run: function() {
			if (typeof charset !== 'undefined') {
				output = org.apache.commons.io.IOUtils.toString(is, charset);
			} else {
				output = org.apache.commons.io.IOUtils.toString(is);
			}
		}
	});

	this.interrupt = function() {
		thread.interrupt();
	}

	this.getOutput = function() {
		thread.join();
		return output;
	};

	thread.start();
}
Attached Files
File Type: xml executeRuntimeCommand.xml (1.2 KB, 158 views)
__________________
Step 1: JAVA CACHE...DID YOU CLEAR ...wait, ding dong the witch is dead?

Nicholas Rupley
Work: 949-237-6069
Always include what Mirth Connect version you're working with. Also include (if applicable) the code you're using and full stacktraces for errors (use CODE tags). Posting your entire channel is helpful as well; make sure to scrub any PHI/passwords first.


- How do I foo?
- You just bar.

Last edited by narupley; 06-08-2018 at 10:36 AM.
Reply With Quote
  #38  
Old 07-09-2015, 10:55 AM
mcalKno mcalKno is offline
 
Join Date: Apr 2015
Location: Pennsylvania
Posts: 247
mcalKno is on a distinguished road
Default replaceValue

replaceValue: Replace an expected received value with a new value

This came in handy when having to replace hospital local codes with standard codes for the HIE. It just keeps the transformer a bit cleaner. It checks that the segment and field exist and if the value1 parameter exists, it will replace it with the value2 parameter.

Parameters:
segName - Segment to modify
field - Field in segment to modify
subComponent - Sub component within field to modify
value1 - receiving value
value2 - replacement value

Examples:
Code:
replaceValue('PID','PID.8','PID.8.1','Female','F');
replaceValue('PID','PID.8','PID.8.1','M','Male');
Code:
Code:
function replaceValue(segName,field,subComponent,value1,value2) {
	for each(seg in msg.children())
	{
		if(seg.name().toString() == segName)
		{
			var segField = seg[field][subComponent].toString();
			if(segField.length > -1)
			{
				if(seg[field][subComponent].toString() == value1)
				{
					seg[field][subComponent] = value2;
				}
			}
		}
	}
}
Reply With Quote
  #39  
Old 11-20-2015, 08:28 AM
aitougan aitougan is offline
Mirth Newb
 
Join Date: Apr 2013
Posts: 7
aitougan is on a distinguished road
Default

JavaScript Pooled Database Connections (and queries)

The code template "getPoolDbConn" creates a pool of 20 database connections using a very simple call: getPoolDbConn(DatabaseType, DatabaseName, ServerAddress, UserName, Password);
where
DatabaseType: is one of "mysql", "oracle", "postgres(ql)" or "sqlserver" (case insensitive)
DatabaseName: the name of the database you are connecting to, e.g. "mirthresults", "my_staging_db"
The rest is self-explanatory
The function returns an object of type java.sql.Connection

The code template "queryPoolDbConn" runs a database query using "getPoolDbConn()". It takes the same arguments as getPoolDbConn plus two: sql_string and args.
sql_string is any valid SQL select statement that may use ? in place of arguments.
args is an array of Java objects to be used with the query, most common ones are java.lang.String and java.lang.Long.
Example:
var sql = "select * from subject where subject_key = ?";
var args = [new java.lang.Long(12345)];
var db_res = queryPoolDbConn("postgres", "mirthresults", "localhost", "mirthuser", "secretpassword", sql, args);
If no arguments are to be specified pass a null instead of args.
The function returns a CachedResultSet that can be used directly (returned) by Database Reader or it can be iterated over in custom code.

The code template "updatePoolDbConn" executes an update or insert SQL statement using "getPoolDbConn()" and returns the number of affected rows.
Its syntax is identical to "queryPoolDbConn()":
var sql = "update staging_table set processed = 1 where key = ?;";
var args = [new java.lang.Long($('staging_key'))];
var row_count = updatePoolDbConn("mysql", "stagingdb", "localhost", "staginguser", "secretpassword", sql, args);
Attached Files
File Type: txt getPoolDbConn_hikari.txt (3.0 KB, 109 views)
File Type: txt queryPoolDbConn.txt (1.6 KB, 60 views)
File Type: txt updatePoolDbConn.txt (1.5 KB, 54 views)
Reply With Quote
  #40  
Old 02-04-2016, 09:41 AM
sanderson sanderson is offline
OBX.1 Kenobi
 
Join Date: Dec 2015
Posts: 45
sanderson is on a distinguished road
Default What about attributes

Hi, is there a simple method in e4x to check for the xexistence of attributes in a node. IE a countAttr() or something, without having to know what the attribute names are the XML schema I have to work with has child attributes in elements where there is no data. So using the strip function removed the element even though there is a populated attribute.

I know this goes against what I understood element/attribute to be about but the schema is not mine so I can't change it.

I haven't found a suitable method or property as yet in the docs. If anyone know such a thing off the top of their head, I'd be very grateful.

Thanks in advance

Stu.
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -8. The time now is 07:10 AM.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Mirth Corporation