Get error string from Jericho SourceFormatter - jericho-html-parser

I'm using jericho's SourceFormatter to do indentation of HTML.
Right now if there is an issue in my HTML formatter sends it to server console.
How can I catch error and output it into my log system (actually I want to get it as a String/Object)?
Here is example of code I use
private String indent(String html) {
SourceFormatter formatter = new SourceFormatter(new Source(html));
formatter.setIndentString("\t");
formatter.setTidyTags(false);
formatter.setCollapseWhiteSpace(true);
return formatter.toString(); // if HTML have issues, they go to server's consol
}
LoggerProvider - represent loggin system of hericho

I found that it is possible to realize Logger interface and use it as your own logger.
class LoggerCustom implements net.htmlparser.jericho.Logger {
...
}
And than pass it's object to Source object.
Source source = new Source(html);
LoggerCustom logger = new LoggerCustom();
source.setLogger(logger); // here I pass my Logger object.
SourceFormatter formatter = new SourceFormatter(source);
formatter.setIndentString("\t");
formatter.setTidyTags(false);
formatter.setCollapseWhiteSpace(true);
String result = formatter.toString();

Related

How to create HL7 message ORU_R01 type using HAPI 2.4

I am newbie to HL7. I am trying to construct HL7 message ORU_R01 type using HAPI 2.4. I got incorrect message format when I add patient details in the below code; otherwise the format is ok. How to fix this issue? is there any example to construct HL7 ORU message with PID,ORC,OBR and OBX?
Output without patient
MSH|^~\&|IM|ABC-ClinPath|ABC-vet|ABC-VetMed|20180412124041||ORU^R01
Output with patient (If I comment the patient details in the code)
PID||TEST|||^TESTlinPath|ABC-vet|ABC-VetMed|20180412124041||ORU^R01
import ca.uhn.hl7v2.model.v24.message.ORM_O01;
import ca.uhn.hl7v2.HapiContext;
import ca.uhn.hl7v2.DefaultHapiContext;
import ca.uhn.hl7v2.parser.Parser;
import ca.uhn.hl7v2.model.v24.segment.MSH;
import ca.uhn.hl7v2.model.v24.group.ORM_O01_PATIENT;
public class CreateORUMessage {
private String sendingApplication = "IM";
private String sendingFacility = "ABC-ClinPath";
private String receivingApplication = "ABC-vet";
private String receivingFacility = "ABC-VetMed";
private void createHL7Message(){
try{
ORM_O01 order = new ORM_O01();
//ORU_R01 oru = new ORU_R01();
// Populate the MSH Segment
// Example - MSH|^~\&|HISA_8592|HISF_2603|||200706081131||ADT^A04|HL7O.1.11379|D|2.1
MSH mshSegment = order.getMSH();
mshSegment.getFieldSeparator().setValue("|");
mshSegment.getEncodingCharacters().setValue("^~\\&");
mshSegment.getSendingApplication().getNamespaceID().setValue(sendingApplication);
mshSegment.getSendingFacility().getNamespaceID().setValue(sendingFacility);
mshSegment.getReceivingApplication().getNamespaceID().setValue(receivingApplication);
mshSegment.getReceivingFacility().getNamespaceID().setValue(receivingFacility);
mshSegment.getDateTimeOfMessage().getTimeOfAnEvent().setValue("20180412124041");
mshSegment.getMessageType().getMessageType().setValue("ORU");
mshSegment.getMessageType().getTriggerEvent().setValue("R01");
//PID - patient details
ORM_O01_PATIENT orm_pid = order.getPATIENT();
orm_pid.getPID().getPid5_PatientName(0).getGivenName().setValue("TEST");
orm_pid.getPID().getPid2_PatientID().getCx1_ID().setValue("TEST");
// Now, let's encode the message and look at the output
HapiContext context = new DefaultHapiContext();
Parser parser = context.getPipeParser();
String encodedMessage = parser.encode(order);
System.out.println("Printing ER7 Encoded Message:");
System.out.println(encodedMessage);
//String msg = order.encode();
//System.out.println(msg);
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String args[]){
new CreateORUMessage().createHL7Message();
}
}
I tried other way too, but it's not worked :(
String msg = order.encode();
System.out.println(msg);
Your problem most likely is, that the segment separator character in HL7 is CR, which just resets the cursor to the start of the line and the next line overwrites the previous one. This only affects writing the message to the console. Writing to file or sending over TCP should be fine without any further conversions.
I had the same problem in an application once, this is my solution below.
ORU_R01 outMessage = new ORU_R01();
outMessage.setParser(hapiContext.getPipeParser());
outMessage.initQuickstart("ORU", "R01", "T");
MSH mshSegment = outMessage.getMSH();
mshSegment.getMsh3_SendingApplication().getHd1_NamespaceID().setValue("MIG-TOOL");
/* some code removed */
PID pidSegment = outMessage.getRESPONSE().getPATIENT().getPID();
pidSegment.getPid3_PatientIDInternalID(0).parse(reportData.getPatientId());
/* some more code removed */
LOGGER.trace("Generated message contents:\n" + replaceNewlines(outMessage.encode()));
And the code for replaceNewLines() is quite simple
private static String replaceNewlines(String input) {
return input.replaceAll("\\r", "\n");
}

Serilog printing contextual property

I am using Serilog and want to print some information message that contains contextual property.
For example:
var logger = Log.ForContext("FirstName", "Yosi");
logger.Information("Hello {FirstName}")
and this works as expected, but when I add parameter to the log message it self, I get unexpected result.
var logger = Log.ForContext("FirstName", "Yosi");
logger.Information("Hello {FirstName} {LastName}", "Attias")
I expect the result to be:
Hello Yosi Attias
but I get:
Hello Attias {LastName}
Is there a fix for that? am I missing something? or this is a bug?
Message templates are only evaluated against the parameters that are passed in to the logging method. Log statements are intended to work consistently regardless of any other configuration/context in the program.
If you want to add additional properties to the logging output, add them to the outputTemplate argument of whatever sink you are configuring:
Log.Logger = new LoggerConfiguration()
.WriteTo.ColoredConsole(outputTemplate:
"{Timestamp:HH:mm} [{Level}] ({LastName}) {Message}{NewLine}{Exception}")
.CreateLogger();
use refection to add properties and their values automatically to log them all in Serilog:
public static Task GenericLog(MyClassLog myclassLog, string message=null)
{
if (string.IsNullOrEmpty(message)) message = nameof(myclassLog);
var properties = typeof(MyClassLog).GetProperties();
var propertyEnrichers = new PropertyEnricher[properties.Length];
for (int i = 0; i < properties.Length; i++)
propertyEnrichers[i] =
new PropertyEnricher(
properties[i].Name,
properties[i].GetValue(myclassLog)
);
var withProps = Log.ForContext(propertyEnrichers);
withProps.Debug(message);
return Task.CompletedTask;
}

changing Html.Raw into string without html markup in a razor view

Quite simple question. I have the following code
#Html.Raw(following.Description).ToString()
when this comes from database it has some markup in it (its a forum post but i want to show a snippet in the list without the markup
is there any way to remove this and replace this line or shall I just regex it from the controller?
Here is a utility class extension method that is able to strip tags from fragments without using Regex:
public static string StripTags(this string markup)
{
try
{
StringReader sr = new StringReader(markup);
XPathDocument doc;
using (XmlReader xr = XmlReader.Create(sr,
new XmlReaderSettings()
{
ConformanceLevel = ConformanceLevel.Fragment
// for multiple roots
}))
{
doc = new XPathDocument(xr);
}
return doc.CreateNavigator().Value; // .Value is similar to .InnerText of
// XmlDocument or JavaScript's innerText
}
catch
{
return string.Empty;
}
}

Writing an Integration Test in Grails that will test DB persistence

My Integration-Test for my grails application is returning a null object when I try to get a domain object using grails dynamic get method.
This is a simplified example of my problem. Lets say I have a controller TrackerLogController that uses a service TrackerLogService to save an updated Log domain for another Tracker domain.
Domain Tracker:
class Tracker {
int id
String name
static hasMany = [logs: Log]
}
Domain Log:
class Log {
int id
String comment
static belongsTo = [tracker: Tracker]
}
Controller TrackerLogController save:
def TrackerLogService
def saveTrackerLog() {
def trackerId = params.trackerId
def trackerInstance = Tracker.get(trackerId)
Log log = TrackerLogService.saveTrackerLogs(trackerInstance, params.comment)
if( log.hasErrors() ){
//render error page
}
//render good page
}
Service TrackerLogService save:
Log saveTrackerLogs( Tracker tracker, String comment) {
Log log = new Log(tracker: tracker, comment: comment)
log.save()
return log
}
So now I want to write an Integration-Test for this service but I'm not sure if I should be writing one just for the simple logic in the controller (if error, error page else good page) I would think I would write a Unit test for that, and an Integration-Test to check the persistence in the Database.
This is what I have for my Integration-Test:
class TrackerLogServiceTests {
def trackerLogService
#Before
void setUp(){
def tracker = new Tracker(id: 123, name: "First")
tracker.save()
//Now even if I call Tracker.get(123) it will return a null value...
}
#Test
void testTrackerLogService() {
Tacker trackerInstance = Tracker.get(123) //I have tried findById as well
String commit = "This is a commit"
//call the service
Log log = trackerLogService.saveTrackerLogs(trackerInstance , commit)
//want to make sure I added the log to the tracker Instance
assertEquals log , trackerInstance.logs.findByCommit(commit)
}
}
So for this example my trackerInstance would be a null object. I know the Grails magic doesn't seem to work for Unit tests without Mocking, I thought for Intigration-Tests for persistence in the DB you would be able to use that grails magic.
You can't specify the id value unless you declare that it's "assigned". As it is now it's using an auto-increment, so your 123 value isn't used. It's actually ignored by the map constructor for security reasons, so you'd need to do this:
def tracker = new Tracker(name: "First")
tracker.id = 123
but then it would get overwritten by the auto-increment lookup. Use this approach instead:
class TrackerLogServiceTests {
def trackerLogService
private trackerId
#Before
void setUp(){
def tracker = new Tracker(name: "First")
tracker.save()
trackerId = tracker.id
}
#Test
void testTrackerLogService() {
Tacker trackerInstance = Tracker.get(trackerId)
String commit = "This is a commit"
//call the service
Log log = trackerLogService.saveTrackerLogs(trackerInstance , commit)
//want to make sure I added the log to the tracker Instance
assertEquals log , trackerInstance.logs.findByCommit(commit)
}
}
Also, unrelated - don't declare the id field unless it's a nonstandard type, e.g. a String. Grails adds that for you, along with the version field. All you need is
class Tracker {
String name
static hasMany = [logs: Log]
}
and
class Log {
String comment
static belongsTo = [tracker: Tracker]
}

Grails service not saving Domain Object When triggered by Message Queue

I have a grails application that has a service that creates reports. The report is defined as:
class Report {
Date createDate
String reportType
List contents
static constraints = {
}
}
The service generates a report and populates contents as a list that is returned by createCriteria.
My problem is that my service claims to be saving the Report, no errors turn up, logging says that its all there, but when I go to call show from the controller on that report, it says contents is null.
Another relevant bit, my Service is called by an ActiveMQ message queue. The message originating from my report controller.
Controller:
class ReportController {
def scaffold = Report
def show = {
def rep = Report.get(params.id)
log.info("Report is " + (rep? "not null" : "null")) //says report is not null
log.info("Report content is " + (rep.contents? "not null" : "null")) //always says report.contents is null.
redirect(action: rep.reportType, model: [results: rep.contents, resultsTotal: rep.contents.size()])
}
}
My service that creates the report:
class ReportService {
static transactional = false
static expose = ['jms']
static destination = "Report"
void onMessage(msg)
{
this."$msg.reportType"(msg)
}
void totalQuery(msg)
{
def results = Result.createCriteria().list {
//This returns exactly what i need.
}
Report.withTransaction() {
def rep = new Report(createDate: new Date(), reportType: "totalQuery", contents: results)
log.info("Validation results: ${rep.validate()}")
if( !rep.save(flush: true) ) {
rep.errors.each {
log.error(it)
}
}
}
}
Is there something obvious that I'm missing here? My thought is that since all my unit tests work, that the hibernate context is not being passed through the message queue. But that would generate Exceptions wouldn't it? I've been beating my head on this problem for days, so a point in the right direction would be great.
Thanks,
You can't define an arbitrary List like that, so it's getting ignored and treated as transient. You'd get the same behavior if you had a def name field, since in both cases Hibernate doesn't know the data type, so it has no idea how to map it to the database.
If you want to refer to a collection of Results, then you need a hasMany:
class Report {
Date createDate
String reportType
static hasMany = [contents: Result]
}
If you need the ordered list, then also add in a List field with the same name, and instead of creating a Set (the default), it will be a List:
class Report {
Date createDate
String reportType
List contents
static hasMany = [contents: Result]
}
Your unit tests work because you're not accessing a database or using Hibernate. I think it's best to always integration test domain classes so you at least use the in-memory database, and mock the domain classes when testing controllers, services, etc.

Resources