How can I tell programmatically if a JAXB element is "empty" ?
<fis:MyRequest/>
Normally, with data, it may look like this:
<fis:MyRequest>
<fis:ABC>X</fis:ABC>
<fis:XYZ>6000</fis:XYZ>
</fis:MyRequest>
But sometimes it can be empty and I want to isolate these cases in code.
In this case it is easy to check
if (myRequest.getAbc() == null && myRequest.getXyz() == null) { ... }
But imagine if there are many more sub-elements, this won't be practical.
I thought about generating the myRequest element to a string, and checking if it was a single tag ending with />but this seems like using an elephant to chase a grasshopper (overkill, in other words).
Is there a handy utility function sitting around some place that does this?
Thanks in advance.
Given that the equals() method has been generated (see note below) you can compare the JAXB element to a new instance of the same element type.
MyRequest EMPTY_MYREQYEST = new MyRequest();
if (myRequest.equals(EMPTY_MYREQUEST)) { ... }
I can't see any disadvantage to this approach (?)
note: The -Xequals and -XhashCode flags are most likely required when generating java code from the xsd
Related
So, say I've got lots of values and flags passed into my program from the command line, all stored as variables in some configuration object, config. These variables default to null if they are not provided by the user.
I've then got some other object, say an instance of Dog, which has lots of methods. Depending on the value of a specific command line argument, I may or may not want to call a specific method, possibly passing the argument value to the method.
At the moment I'm doing that like this:
Dog dog = new Dog();
if (config.argumentA != null) {
dog.methodA(config.argumentA);
}
if (config.argumentB != null) {
dog.methodB(config.argumentB);
}
if (config.boolArgument) {
dog.methodC();
}
// ... ... ...
if (config.argumentZ != null) {
dog.methodZ(config.argumentZ);
}
Now I've tried to look for a more elegant way of doing this, since this feels very dirty, but Google and Java jargon have me stumped.
I'm imagining making a map from the arguments' names to the function names, then looping through, checking each argument's value and calling the corresponding method. Does such a mapping exist in Java? Is there any way to do this nicely, or am I going about the problem completely wrong?
P.S.: I'm a bit of a beginner with both Java and problems like this, so pls be gentle :)
Actually this question relates to the programming practices. So like Alan Kay said OOP is basically message passing. Thus your code should not be making these decisions but rather passing this info to some other method of some other class, till the time it's actually needed. Now if you couple this concept with different Design patterns you'll get an elegant piece of code.
Also it's difficult to suggest a particular solution to a problem as abstract as your's.
I wanted to do some processing on values in yml file. Someone suggested me to use snakeYAML's low-level API for this purpose. So I've written some code using that but I'm pretty much stuck due to the following reasons.
Here's the code I've wrote:
public static void main(String[] args) throws Exception{
Yaml yaml = new Yaml();
FileReader contentFromFile=new FileReader("/Users/prakash.tiwari/Desktop/yamlInput.yml");
for (Node node : yaml.composeAll(contentFromFile)) {
System.out.println(node);
}
}
Here is my yamlInput.yml:
Prakash:
Lucky:
Number: 11
Really? : NotAtAll
Here's what was printed on console(It was in a single line, I formatted it and added a comment to make it readable):
<org.yaml.snakeyaml.nodes.MappingNode
(
tag=tag:yaml.org,2002:map,
values=
{
key=<org.yaml.snakeyaml.nodes.ScalarNode (tag=tag:yaml.org,2002:str, value=Prakash)>;
value=355629945 // Why is this a garbage value?
}
{
key=<org.yaml.snakeyaml.nodes.ScalarNode (tag=tag:yaml.org,2002:str, value=Really?)>;
value=
<NodeTuple
keyNode=<org.yaml.snakeyaml.nodes.ScalarNode (tag=tag:yaml.org,2002:str, value=Really?)>;
valueNode=<org.yaml.snakeyaml.nodes.ScalarNode (tag=tag:yaml.org,2002:str, value=NotAtAll)>
>
}
)>
At this point I can extract the valueNode which are also ScalarNode by searching for valueNode=<org.yaml.snakeyaml.nodes.ScalarNode and then process the value in this node .
But the issue is that I don't know why it puts a garbage value while composing map nodes. So here are my questions:
How to correctly compose yaml files so that map nodes appear correctly and not garbage values?
After I'm done processing and have successfully replaced the values with the processed ones, how do I put these back to a yaml file?
If you think this is a rubbish method to start with, please suggest me a better one.
The reason you get the „garbage value“ is because of this section in MappingValue's toString method:
if (node.getValueNode() instanceof CollectionNode) {
// to avoid overflow in case of recursive structures
buf.append(System.identityHashCode(node.getValueNode()));
} else {
buf.append(node.toString());
}
Since the composed graph may contain cycles (because anchors & aliases have been resolved at this stage of parsing), toString will not recurse into Collection nodes (i.e. Mappings and Sequences).
This means that your node tree has indeed be composed correctly and you simply should not use toString to inspect it. That answers your first question.
To write that back to a YAML file, use something like
Emitter emitter = new Emitter(/* e.g. a FileWriter */ writer, new DumperOptions());
for (Event event : yaml.serialize(/* the root node */ node)) {
emitter.emit(event);
}
To answer question 3: In the previous question, you mentioned that you want to change (encrypt) certain values and leave the others untouched. If that is the case, I suggest you use yaml.parse instead of yaml.compose because you lose fewer information when working on the event stream than when working on the composed graph (meaning that the output will be more similar to the input).
You can then go through the generated events, identify the events you want to alter and replace them with the altered events, and then use an Emitter like I showed in the code above.
I showed with some Python code here how to identify events in an event stream from a list of strings (kind-a „YAML-path“), however that code inserts events at the given path instead of altering them. The Python and Java API are somewhat similar, so if you can read Python, that code may help you.
So I have a constructor with 5 different variables, where three of which might be null. It accepts user input and the user does not have to enter anything for three of the five attributes.
Therefore, if the user did not enter anything, the object is created using null for all missing values.
obj = new Object(String, null, null, null, String);
Now I am wondering what would be best practice to cope with this.
I can think of three different scenarios:
Deal with it only in the class using the constructor, i.e. always query whether the value is null (e.g. if(getSomeAttribute == null) { //do something }
Deal with it within the object class, i.e. always return some default value for each missing attribute instead of null
Deal with it within the object lcass, i.e. have helper-methods like isAttributeSet(), returning a boolean value indicating whether the attributes are set, that is: not null.
Although I have problems with the last two, as I think I might run into problems with default values, as sometimes it might hard to know if it is a default value; if I'd always check I could just as well check for null instead of inserting a default value first;
Same with the last one, if I have to check the helper-method, I could just as well check for null directly.
What my problem is with this situation, is that sometimes I might not be the one using the getter and setter methods; how should the one using it know there might be null attributes and which that are.
I know, I should document that within my object class, but still I am wondering if there is a "best practice" way to cope with this.
I believe it should be unusual to always check the documentary (or if there is none, the whole class) for something as simple as this.
Maybe I should not even start with null values within my constructor in the first place? But I think I would run into the same kinds of problems, anyway, so that would not really solve my problem
Read Bloch, Effective Java, 2nd ed. Item 2: "Consider a builder when faced with many constructor parameters."
Excellent advice in an excellent book.
Using a builder pattern would help with the constructor, however the main problem is to do with the design of the class - you want to be sure when you call a get/set method that it isn't one of the null/optional members.
You could use polymorphism to have two objects each with an interface that only exposes the getters and setters supported by the concrete implementation. This makes it impossible to call the wrong getters/setters and it is obvious what the intention is.
This question already has answers here:
Avoiding NullPointerException in Java
(66 answers)
Closed 9 years ago.
I am writing codes that query the database to get the data. There are some classes that consist of Lists, but sometime the list or other attribute can not be initiated and their value is null, so I need to write list!=null || list.isEmpty or attribute != null, before I can use the attribute.
Unfortunately, it easy to forget it, and I really think it is ugly to do it every time when I operate an attribute. I am going to write some code to explain it.
public class SpotVo {
private Double avg;
private String brief;
private ArrayList<HotelVo> hotels;
private int id;
private ArrayList<byte[]> images;
private AddressVo location;
private String name;
private ArrayList<RestaurantVo> restaurants;
}
As you can see, there are some lists and other attributes in this class, there can all be null or empty, can I do something to avoid it?
The answer depends on whether null has a special meaning. For example for a String field does your application need to distinguish between null and ""? For a Collection-valued field does it need to distinguish between null and an empty collection object?
If the answer is "no", then you could write your "data object" classes to normalize the nulls to the respective "in band" values. You could do this in the getters or the setters or the constructors, depending on exactly how the objects are materialized from the database.
A couple of other things you could do are:
Change the database schema to make the respective columns "not null".
If you are using an ORM or a data binding mechanism, try to configure that (via annotations or whatever) to use the "in band" values instead of null.
The point of turning null into "" or an empty array or collection is that you don't need to treat the "in band" value as a special case ... unless the business logic of your application specifically requires this.
In short, if you stamp out the null values systematically, you don't need to test for them in the business logic.
Note that this approach doesn't always work. The case that annoys me is fetching parameters from an HTTPRequest object in a servlet:
The application potentially has to deal with 4 distinct cases:
parameter not present
parameter present with no value / an empty value
parameter present with a non-empty value
parameter present multiple times.
The parameters are being fetched from a standard API rather than a custom class that could be made to normalize the values according to the webapp's requirements.
The easiest way to solve this is with CollectionUtils.isEmpty.
Returns: true if empty or null
This way you can do it in one line.
When it comes to "attributes", there are design patterns that can help with this. Or, you can use Guava's Optional class. You can read more about it here: What's the point of Guava's Optional class
You can write a function that checks if an object is null and/or if it's a String, is it "". Then simply call that function each time you would need to check all of the conditions. Make it return a boolean so that you can just insert it in the if statements.
boolean check(Object o)
{
if (o != null)
{
if (o instanceof String)
{
if (((String) o).equals(""))
return false;
}
return true;
}
return false;
}
Refer to rcook's suggestion in the comments for a better implementation of this.
I think there's two problems here:
One is that you have to check for null values which I absolutely agree is stupid. The problem is that null is a native to the Java language, so the only way to make it slightly nicer is to use methods like the ones mentioned by Steve P and tieTYT. There is however another way of dealing with null by never using it. Of course you cannot completely avoid it, but at least in your own code you should eliminate all null-references. There are a few great arguments for that which I won't cover here, but you can read Avoiding != null statements for more details.
If you're interested a Java-based language, Scala, have developed this nicely by implementing an Option class that can tell whether a value exists or does not (equal to the null value). Nice blog post about it here: http://jim-mcbeath.blogspot.fr/2008/10/avoiding-nulls.html
Having (mostly) stowed the null-issue away, the next problem will be to check for isEmpty or similar when using collections. This is, as you say, a pain in the arse. But I've actually found that these checks can be largely avoided. It all depends on what you need to do with your collection of course, but in most cases collections are used for traversing or manipulation in some way. Using the foreach-loop in Java will make sure nothing is performed if nothing is in the collection. Neat.
There are some cases where a collection must not be empty. Some of these can be avoided though, by having a good design (for instance one that allows empty lists, ensures that no list are empty etc.), but, for the rest of them there are simply no way around. Ever. But, having eliminated the null-checks, calling a few isEmpty now and then isn't that bad :-)
Hope that helped.
What I am trying to achieve is (using Saxon-B 9.1):
1) Run XSLT transformation with object of below Example class as parameter
2) Object's properties are populated using reflexive extension function with selected Nodes
3) Run second XSLT transformation (on different XML input) and pass the above object with populated values as parameter
4) Insert XML nodes from the object into output document
My class is below:
public class Example {
. private NodeSet test;
. public RequestInfo() {}
. public void settest(NodeList t) {
. this.test = t;
. }
. public NodeList gettest() {
. return test;
. }
}
First transformation seems to populate my object fine (using settest() method within XSLT) - I can see correct nodes added to the NodeList.
However, I am getting below error when running 2nd transformation and calling gettest() method from within XSLT:
NodeInfo returned by extension function was created with an incompatible Configuration
I was thinking should I not use NodeList but maybe some different, equivalent type that would be recognised by Saxon? I tried it with NodeSet but got same error message.
Any help on this would be appreciated.
You haven't shown enough information to see exactly what you are doing wrong, but I can try and explain the error message. Saxon achieves its fast performance in part by allocating integer codes to all the names used in your XML documents and stylesheets, and using integer comparisons to compare names. The place where the mapping of integers to names is held is the NamePool, and the NamePool is owned by the Saxon Configuration object; so all documents, stylesheets, etc participating in a transformation must be created under the same Configuration (it's a bit like the DOM rule that all Nodes must be created under the Document they are attached to). The message means that you've got at least two different Configuration objects around. A Configuration gets created either explicitly by your application, or implicitly when you create a TransformerFactory, an XPathFactory, or other such objects.
I wonder whether this mixing of XSLT and Java code is really a good idea? Often when I see it, the Java code is being used because people haven't mastered how to achieve the desired effect in XSLT. There are many good reasons for NOT using the DOM with Saxon: it's very slow, it requires more lines of code, it's not thread-safe, it's harder to debug, ...