How can I provide custom error messages using JAXP DocumentBuilder? - java

I want to provide my own message from the validation done in DocumentBuilder, rather than the one from XMLMessages.properties.
Now I see that a property error-reporter needs to be set to a class which extends XMLErrorReporter.
However, I've not been able to get ComponentManager from Document/Builder/Factory.
Doing parsing of string in SAXParseException is the last option, but I'm just thinking there may be a 'best practice' way of doing it.

have you already looked at DocumentBuilder#setErrorHandler?
if yes, could you explain why this approach doesn't work for you?

Related

Convert Byte[] to xml

I'm using Axon 2.4.6.
I have a Saga the payload of which was serialized in binary using XStreamSerializer.
The saga looks like this:
public class MySaga extends AbstractAnnotatedSaga {
...
private MyEvent myEvent;
...
}
It contains one event which is the initialize event of the related aggregate object.
Right now I'm having is a deserialization problem because I changed MyEvent by adding one property to it.
I figured out a workaround to this by adding the serialize id that the deserializer is expecting, however this solution might not be the best since I'm on production data right now and would be nice if I was able to somehow upcast the sagas.
So what I intend to do is create a custom serializer that extends JavaSerializer and tweak the SerializedObject<S> that is coming in. The problem is that the SerializedObject is in hex/binary so I need a way to convert it in to an org.dom4j object for instance so I could add the missing property and then be able to deserialize it in to MySaga.
I tried several approaches like
ByteArrayInputStream bos = new ByteArrayInputStream((byte [])serializedObject.getData());
or new XStream();
but they all go from the binary representation straight to the object deserialization, what I need is to get the dom4j or even xml conversion first.
I can't figure out how to do it.
I have to say that Axon 2 is not something I have experience with but let me try to help you nonetheless.
As I can find on the docs, Axon provide an example of how to write an upcaster here using the correct 2.4 documentation link.
What is not clear for me, based on your question, is if you are using the JavaSerializer or an XStreamSerializer (or JacksonSerializer to make it complete).
In the case you are using XML, the docs will provide you an example of an upcaster. What is good to mention (and check) is that you can also look into xStream.ignoreUnknownElements() which will make your Serializer lenient meaning it won't fail when trying to deserialize something which contains an attribute it does not know (very useful I would say).
If you are using JSON, you also have the FAIL_ON_UNKNOWN_PROPERTIES "feature" that can be disabled in this case to make it lenient.
Making your serializers lenient seems to be the correct route if you ask me. If you really need to add a default/derived value to the new field, than the upcaster route is the one you should pick.
KR,
Edit 1: triggered by the comment given by Steven, this led me to add this edit and ask you how long do you expect this Saga to live. Now that I noticed the Event is part of your Saga, I would rather write a new Saga that does not contains the Event as part of it but just fields not coupling it to any specific Event.

What is the proper media-type for HAL+JSON?

I'm using Spring to create a RESTful service and I'm curious about the syntax for media-types.
From my understanding, the general media-type for HAL+JSON is application/hal+json. Also, from my understanding, a vendor-specific custom media-type that supports HAL+JSON would be something like application/vnd.api.entity.hal+json. However, I have also seen application/vnd.api.entity+hal+json. Which one is correct?
Also, what would the correct wild-card type be for HAL+JSON? Would it be application/*.hal+json or application/*+hal+json. Links to any pertinent RFC's would be appreciated. Thanks!
application/vnd.api.entity+json
application/vnd.api.entity.hal+json would only make sense if you plan to provide your data also without support for HAL. The client has to know the structure of the content anyway and HAL is part of it.
application/vnd.api.entity+hal+json is just wrong. The standard states that only registered suffixes should be used. It also refers to them as "Structured Syntax Suffixes". So it's quite clear that it's about how to read data not about its meaning. Only one suffix is allowed and more wouldn't make sense.
Think about it as application/semantic+syntax, or application/what's in it + how to read it.

How to send a message using Apache Camel?

I am trying to create a sample application hosted at "mina:tcp://localhost:9991" that sends a very simple message to a server hosted at "mina:tcp://localhost:9990".
Now admittedly I have some problems understanding how to do this. My first approach was to create a class called Message, that has two fields: String order and String host. However, I am terribly confused on how to do this.
First I tried to follow the loadbalancer-example basing myself on the ReportGenerator and create a MessageGenerator class that could create a message and return it:
http://camel.apache.org/loadbalancing-mina-example.html
However, there is a problem, I need parameters to create my Message, something that doesn't happen when creating the Report from the example:
//Message constructor
public Message(String order, String host){
//constructor stuff
}
By reading Camel in Action I know how to use beans to call methods that have no parameters, however I still do not understand how I should use them to call a method that has several parameters (Am I forced to use processors?)
Then i realized that perhaps I am complicating things a little bit and there is an easier way to send messages. So I tried another approach that resulted in a small sample of code that does not work as well. I have created a separate question for that matter:
Apache camel send a simple message
Obviously I am doing something wrong and I don't get what. So, I have 2 questions:
Manning's Camel in Action defines an Easy way and a Hard way to use beans, but I did not understand the easy way of using beans with parameters. Can someone provide an example of it?
Is there a way to send a message composed of several fields in Camel (an easy way, without processors) that does not involve using beans? If so, how?
There are several ways to sends Messages in Camel. According to the help provided in the Camel forums, the two best are:
Using beans linked to POJOS and routes (example: http://camel.apache.org/loadbalancing-mina-example.html)
Using the Producer Template (docs: http://camel.apache.org/producertemplate.html)
Hope it helps someone one day.

Is it possible to prevent a class from using a method in java?

Suppose I have a class called Foo. This class will be modified by many people, and WILL print information to the console. To this effect, we have the following method:
private void print(String message){ ... }
which prints out to the screen in the format we want.
However, while reviewing code from other devs I see that they constantly call System.out.println(...)
instead, which results in barely-readable printouts.
My question is the following: is it possible to prevent any and every use of System.out.println() in Foo.java? If so, how?
I've tried looking this up, but all I found had to do with inheritance, which is not related to my question.
Thanks a lot!
N.S.
EDIT: I know that whatever I have to do to prevent the use of a method could be removed by a dev, but we have as a policy never to remove code marked //IMPORTANT so it could still be used as a deterrent.
EDIT2: I know I can simply tell the devs not to do it or use code reviews to filter the "errors" out but 1) I'm already doing it and it costs a lot of time and 2) the question is whether this is possible or not, NOT how to deal with my devs.
public methods are just that - public. There is no way to restrict access to them.
This kind of problem is usually "solved" by setting up some code-checker like PMD or checkstyle and integrating them into the continuous integration build. So violations of these stuff will be emailed to someone with a big hammer :-)
Although communicating that developers should not use System.out directly would be preferred, you could set System.out to another PrintStream, then use the alternative PrintStream in the private method. That way, when people use System.out.println they won't output anything but you'll still be able to use the alternative PrintStream... something like they do here: http://halyph.blogspot.com/2011/07/how-to-disable-systemout.html
Pre-commit hooks for your revision control system (SVN, Git, Mercurial) can grep for uses of System.{err,out} and prevent commit if they occur.
http://stuporglue.org/svn-pre-commit-hook-which-can-syntax-check-all-files/ is an example that takes an action for different changed files based on file extension for SVN. You should be able to modify that example to take an example based on some subset of Java files and reject if something like the following is true
egrep -q '\bSystem\.(err|out)\b'
You can redirect System.out calls to a streams that ignores the output or that redirects it to your logging system.
System.setOut(printStream);
You can also kill those using System.out.println in a production environment.
You can replace the OutputStream of System with your own implementation that would either throw an exception, or redirect the call to your own print implementation (which you would need to make public).
No, it's not possible to 100% prevent a class from ever using a specific method in Java.
Having that said...
My suggestion would be to add code analysis to your build process and failing the build on any occurrence of System.out.println. A good place to start if you're interested in going this route would be to check out PMD.
Also... have some constructive discussions with your developers and talk about why they're doing what they're doing. Good luck.

Customising log4j logging for sensitive data

I have a class which contains sensitive information (Credit card info, phone numbers etc).
I want to be able to pass this class to log4j, but have it obscure certain information.
If I have a class UserInformation which has getPhoneNumber, getCreditCardNumber methods, how would I customise log4j or this class so that it will obscure the numbers correctly.
I want the credit card number to be output as xxxx-xxxx-xxxx-1234 and the phone number to be output as xxxx-xxx-xxx given that these would be 1234-1234-1234-1234 and 1234-567-890
Thanks
You could try to implement this by writing a custom log record formatter that obscures those patterns. But I think that is a bit dodgy ... because someone could accidentally or deliberately circumvent this by tweaking the logger configuration files, etc.
I think it would be better idea to do one of the following, depending on how you are assembling the log messages:
Change the logger calls in your code to assemble the log messages using alternative getter methods on UserInformation that obscure the sensitive fields.
Change the toString method on UserInformation to obscure the details.
I'd write an obfuscating formatter for those fields and use that to write to the log file.
I'd also ask why you would continue to use String primitives instead of objects that could encapsulate the appropriate behavior.
Update: The best option is probably to wrap your real objects in an Obfuscated-ClassName wrapper that implements the same interface but returns obfuscated versions (by delegating to the real object and obfuscating the result) and hand those to the logging system. This only works if you are actually passing in these objects yourself, and not if they are part of an object tree - that might make the whole situation a bit more complex.
old:
Maybe you should just add getPhoneNumberForLogging()/getObfuscatedPhoneNumber() type functions? (Of course you have to take into account that if you hand an object containing this data to another object/process you cannot control access to the 'normal' functions so technically you don't shield the data at all - although it might be possible to make the methods that show sensitive data package local accessible only?)
You could also investigate the call stack on every call and try to figure out if you want to return the full data or the obfuscated version - this will add quite a bit of overhead and might be very tricky to debug.

Categories

Resources