Calculated field in Jira - java

I'm writing a plug-in for Jira and I need to add custom calculated column to issue navigator. That's column should show last comment to issue. But in issue navigator values in this column are something like "ClassName#123456", not comment's body. What should I do to return comment's body to this column?
Code so far:
public class LastCommentField extends CalculatedCFType {
private CommentManager commentManager = null;
public LastCommentField(CommentManager commentManager) {
this.commentManager=commentManager;
}
public Object getValueFromIssue(CustomField field, Issue issue) {
Comment lastComment=null;
List<Comment> comments = commentManager.getComments(issue);
if(comments != null && !comments.isEmpty()) {
lastComment = (Comment)comments.get(comments.size() - 1);
}
return lastComment;
}
public String getStringFromSingularObject (Object object) {
return object.toString();
}
public Object getSingularObjectFromString(String value) {
return value;
}
}

This functionality already exists in at least two plugins, e.g. https://marketplace.atlassian.com/plugins/net.customware.jira.utils.customware-jira-utilities
But in the code above, the singular object being used is a Comment object as documented at http://docs.atlassian.com/jira/4.4/com/atlassian/jira/issue/comments/Comment.html
but you probably just want a String, so try
return lastComment.getBody();

Unfortunately I don't know JIRA from the coding side of things, but from the Java side, that sounds a hell of a lot like the object behind the column doesn't have ToString() overriden. What you are seeing is the name of the class followed by the address in memory.
If you could show us the code behind the column, I might be able to make a little more sense of it.

Related

Better method for avoiding null in nested data with Java 7

I have to analyze a huge data stream which often includes incomplete data. Currently the code is littered with null checks at multiple levels, as there could be incomplete data at any level.
So for example I might have to retrieve:
Model.getDestination().getDevice().getName()
I tried to create a method to try and reduce the null checks to a single method whereby I enter:
IsValid(Model.getDestination(), Model.getDestination().getDevice(), Model.getDestination().getDevice().getName())
this method fails because it evaluates all parameters before it sends them, rather than checking each at a time like
Model.getDestination() != null && Model.getDestination().getDevice() != null && etc
but is there a way I could pass in Model.getDestination().getDevice().getName() and do the check at each level without having to evaluate it or split it up before I pass it?
What I really want it to do is if there is a null/nullexception it should quietly return "", and continue processing incoming data
I know there are ways to do this elegantly in Java 8, but I am stuck with Java 7
I struggled with a similar problem with deeply nested structures, and if I'd have had the opportunity to introduce additional structures just to navigate the underlying data, I think, I had done that.
This was C# which in the meantime has a save navigation/Elvis operator, for which we'll wait in vain with Java (proposed for Java 7 but discarded. Groovy has it btw.). Also looks like there are arguments against using Elvis, even if you have it). Also lambdas (and extension methods) didn't improve things really. Also every other approach has been discredited as ugly in other posts here.
Therefore I propose a secondary structure purely for navigation, each element with a getValue() method to access the original structure (also the shortcuts proposed by #Michael are straight forward to add this way). Allowing you null save navigation like this:
Model model = new Model(new Destination(null));
Destination destination = model.getDestination().getValue(); // destination is not null
Device device = model.getDestination().getDevice().getValue(); // device will be null, no NPE
String name = destination.getDevice().getName().getValue(); // name will be null, no NPE
NavDevice navDevice = model.getDestination().getDevice(); // returns an ever non-null NavDevice, not a Device
String name = navDevice.getValue().getName(); // cause an NPE by circumventing the navigation structure
With straight forward original structures
class Destination {
private final Device device;
public Destination(Device device) {
this.device = device;
}
public Device getDevice() {
return device;
}
}
class Device {
private final String name;
private Device(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
And secondary structures for the purpose of save navigation.
Obviously this is debatable, since you always can access the original structure directly and run into a NPE. But in terms of readability perhaps I'd still take this, especially for large structures where a shrub of ifs or optionals really is an eyesore (which matters, if you have to tell, which business rules actually were implemented here).
A memory/speed argument could be countered by using only one navigation object per type and re-set their internals to approriate underlying objects as you navigate.
class Model {
private final Destination destination;
private Model(Destination destination) {
this.destination = destination;
}
public NavDestination getDestination() {
return new NavDestination(destination);
}
}
class NavDestination {
private final Destination value;
private NavDestination(Destination value) {
this.value = value;
}
public Destination getValue() {
return value;
}
public NavDevice getDevice() {
return new NavDevice(value == null ? null : value.getDevice());
}
}
class NavDevice {
private final Device value;
private NavDevice(Device value) {
this.value = value;
}
public Device getValue() {
return value;
}
public NavName getName() {
return new NavName(value == null ? null : value.getName());
}
}
class NavName {
private final String value;
private NavName(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
Option 1 - if statement
You already provided it in your question. I think using am if statementlike the following is perfectly acceptable:
Model.getDestination() != null && Model.getDestination().getDevice() != null && etc
Option 2 - javax Validation and checking the result - before sending
You could make use of javax validation.
See: https://www.baeldung.com/javax-validation
You would annotate the fields that you want with #NotNull.
Then you could use programmatic validation.
You could check the validation result to see if there is a problem.
Example:
So in your class you would do:
#NotNull
Public String Destination;
And you could feed your object to the validater:
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
Set<ConstraintViolation<Model>> violations = validator.validate(Model);
for (ConstraintViolation<User> violation : violations) {
log.error(violation.getMessage());
}
Option 3 - fromNullable and Maps ( if you have Java 8)
I'm taking this one from https://softwareengineering.stackexchange.com/questions/255503/null-checking-whilst-navigating-object-hierarchies . This is very simular to your question.
import java.util.Optional;
Optional.fromNullable(model)
.map(Model::getDestination)
.map(Lounge::getDevice)
.ifPresent(letter -> .... do what you want ...);
Option 4 - Just using a try/catch
Everyone hates this one due to the slowness of exception.
So you want to simplify Model.getDestination().getDevice().getName(). First, I want to list a few things that should not be done: Don't use exceptions. Don't write an IsValid method, because it just doesn't work, because all functions (or methods) are strict in Java: that means that every time you call a function, all arguments are evaluated before they are passed to the function.
In Swift I would just write let name = Model.getDestination()?.getDevice()?.getName() ?? "". In Haskell it would be like name <- (destination >>= getDevice >>= getName) <|> Just "" (assuming the Maybe monad). And this has different semantics from this Java code:
if(Model.getDestination() && Model.getDestination().getDevice() && Model.getDestination().getDevice().getName() {
String name = Model.getDestination().getDevice().getName();
System.out.println("We got a name: "+name);
}
because this snippet calls getDestination() 4 times, getDevice() 3 times, getName() 2 times. This has more than just performance implications: 1) It introduces race conditions. 2) If any of the methods have side-effects, you don't want them to be called multiple times. 3) It makes everything harder to debug.
The only correct way of doing it is something like this:
Destination dest = Model.getDestination();
Device device = null;
String name = null;
if(dest != null) {
device = dest.getDevice();
if(device != null) {
name = device.getName();
}
}
if(name == null) {
name = "";
}
This code sets name to Model.getDestination().getDevice().getName(), or if any of these method calls return null, it sets name to "". I think correctness is more important than readability, especially for production applications (and even for example code IMHO). The above Swift or Haskell code is equivalent to that Java code.
If you have a production app, I guess that something like that is what you are already doing, because everything that is fundamentally different than that is error-prone.
Every better solution has to provide the same semantics and it MUST not call any of the methods (getDestination, getDevice, getName) more than once.
That said, I don't think you can simplify the code much with Java 7.
What you can do of course, is shorten the call chains: E.g. you could create a method getDeviceName() on Destination, if you need this functionality often. If this makes the code more readable depends on the concrete situation.
Forcing you to code on this low level also has advantages: you can do common subexpression elimination, and you'll see the advantages of it, because it will make the code shorter. E.g. if you have:
String name1 = Model.getDevice().getConnection().getContext().getName();
String name2 = Model.getDevice().getConnection().getContext().getLabel();
you can simplify them to
Context ctx = Model.getDevice().getConnection().getContext();
String name1 = ctx.getName();
String name2 = ctx.getLabel();
The second snippet has 3 lines, while the first snippet has only two lines. But if you unroll the two snippets to include null-checks, you will see that the second version is in fact much shorter. (I'm not doing it now because I'm lazy.)
Therefore (regarding Optional-chaining), Java 7 will make the code of the performance-aware coder look better, while many more high-level languages create incentives to make slow code. (Of course you can also do common subexpression elimination in higher level languages (and you probably should), but in my experience most developers are more reluctant to do it in high level languages. Whereas in Assembler, everything is optimized, because better performance often means you have to write less code and the code that you write is easier to understand.)
In a perfect word, we would all use languages that have built-in optional chaining, and we would all use it responsibly, without creating performance problems and race conditions.
You can use try-catch. Because there is no processing required in your case, like
try{
if(IsValid(Model.getDestination(), Model.getDestination().getDevice(), Model.getDestination().getDevice().getName())){
}catch(Exception e){
//do nothing
}
Alternatively you can improve your isValid method by passing only Model object
boolean isValid(Model model){
return (model != null && model.getDestination() != null && model.getDestination().getDevice() != null && model.getDestination().getDevice().getName() != null)
}

DAO with Null Object Pattern

After Reading:
Effective Java (See Item 43) - Joshua Bloch
Clean Code (Don't Return Null) - Uncle Bob
Avoiding != null statements
Null Object pattern
I was looking for an answer to the question of what a DAO should return when a search ends up to be for an entity that does not exist for non-collection objects.
Collection object is really ok by using empty array or emptyList methods. But with non-collections it might be harder. An alternative solution is to never return null and instead use the Null Object pattern.
But I have no idea to integrate with Null Object pattern with DAO and I really excited to see great integration with Null Object pattern and DAO pattern especially for model(dto) object return case.
I would appreciate and welcome any best design pattern, scenario and suggestion.
Indeed introducing null reference is probably one of the worse mistake in the programming languages' history even its creator Tony Hoare calls it his billion-dollar mistake.
Here are the best alternatives to null according to your Java version:
1. Java 8 and above
Starting from Java 8 you can use java.util.Optional.
Here is an example of how you could use it in your case:
public Optional<MyEntity> findMyEntity() {
MyEntity entity = // some query here
return Optional.ofNullable(entity);
}
2. Prior to Java 8
Before Java 8 you can use com.google.common.base.Optional from Google Guava.
Here is an example of how you could use it in your case:
public Optional<MyEntity> findMyEntity() {
MyEntity entity = // some query here
return Optional.fromNullable(entity);
}
All you need to do is return an empty object - say a customer entry you would have in your DAO something like
if (result == null) { return new EmptyUser(); }
where EmptyUser extends User and returns appropriate entries to getter calls to allow the rest of your code to know it is an empty object (id = -1 etc)
A small example
public class User {
private int id;
private String name;
private String gender;
public String getName() {
//Code here
}
public void setName() {
//Code here
}
}
public class EmptyUser extends User {
public int getId() {
return -1;
}
public String getName() {
return String.Empty();
}
}
public User getEntry() {
User result = db.query("select from users where id = 1");
if(result == null) {
return new EmptyUser();
}
else {
return result;
}
}
In my experience, in real-life scenarios where a single entity should be returned returning a null is actually either a data inconsistency error or lack of data whasoever. In both cases the really good thing to do is to crate and throw your own DataNotFoudException. Fail fast.
I'm using mybatis as ORM and recently I started writing some theoretically single-result mapper selects as returning lists and validating checking the amount of returned data in dao, and throwing exceptions when the returned amounts do not match dao's method assumptions. It works pretty well.

Checking for NullPointerException, correctness or personal belief?

In my code, I am making a lot of checks for null so that I don't get a NullPointerException usually i am just doing like this:
if(variable != null){
//do something with the variable
}
Is the following better in any way or is it just a matter or personal belief?
if( !variable.equals(null) ){
//do something with the variable
}
Is there a more efficient way to make this check?
Btw I do have done my research already but I cant seem to find concrete evidence to prove either point.
P.S This is a NOT duplicate of Avoiding != null statements, on that the best answer is that you should either use Assert, which cannot be used to run code rather than just display a message, or actually throw the exception which I dont want either. This post is addressing a different issue of the same subject.
if(!variable.equals(null) ){
//do something with the variable
}
If variable is null NPE occurs. First method is far better.
EDIT:
Using Optional:
Consider that you have Person object and want to getSalary(). Unfortunately age can be null - in that case you want default value. You can do Integer salary = Optional.ofNullable(person.getSalary()).orElse(2000). It will return salarty from person or 2000 in case salary is null.
Or you can use java.util.Optional from Java 8.
Very nice examples are on JavaCodeGeeks.
Optional is usually used in java.util.stream lambdas for "functional-style operations".
As others already said, the variant
if(!variable.equals(null))
can NPE itself when variable is null. Furthermore, you have to be sure that the equals method also is null-safe for all object types you use. Thus, if you absolutely need to check, use ==.
As for better solutions (we're going opinion-based here): I think that this ecessive null-checking is a sign of brittle software and suboptimal interface definition. What I currently try to do more and more is use the javax.validation annotation #NotNull to harden my interfaces and get rid off all these runtime checks:
private #NotNull String getName() {...} // guaranteed not to return null
...
if(getName() == null) { // superfluos, your IDE gives a shout if configurd correctly
...
}
... give it a shot :)
Edit (as an answer to the comment, as I need code-formatting):
Here's a complete cut&paste-example from my current eclipse setup:
package stuff;
import javax.validation.constraints.NotNull;
public class Try3 {
public #NotNull String getName() { return ""; }
public void test() {
if(getName() == null)
System.out.println("Cannot happen due to contract");
}
}
Ensure, that the imported type is indeed javax.validation.constraints.NotNull (as other frameworks also have a NotNull annotation, which may be defined in a different way). For eclipse, you also have to check "Enable annotation-based null analysis" in the project settings under JavaCompiler / Errors/Warnings and customize the annotations to use, as eclipse defaults to some home-brewed annotations. The customization can be accessed via the link "Configure" after the checkbox for using default annotations in the same settings page. Hope that helps!
There are two approaches:
public void calculate(Class variable) {
Assert.notNull(variable, "variable was null");
//calculations
}
//and
if (variable == null) {
//bad
} else {
calculate(variable);
}
The second one is the most common one. If your variable is a String consider using Guava.StringUtils with it's fantastic isBlank method which checks if the String is null or ""
Summarizing:
if (variable == null) {
//bad
} else {
//good
}
The above is standard approach. The better approach will be:
private boolean isNull(Class variable) {
return variable == null;
}
if (isNull(variable)) {
} else {
}
I used to do call the below method all the time which checks for nullpointer exception
public static boolean isAvailable(Object data) {
return ((data!=null) && (data.toString().trim().length() > 0));
}

Change parameter of method

Say I have a following function in java, may be not good example but just came in mind ;)
public StudentEntity updateStudent(StudentEntity studentEntity)
{
studentEntity.setName(...);
studentEntity.setAddress(...);
return studentEntity;
}
Is above approach valid?
Can we store a studentEntity in separate variable and update and return it.
For example
public StudentEntity updateStudent(StudentEntity studentEntity)
{
StudentEntity _studentEntity = studentEntity;
_studentEntity.setName(...);
_studentEntity.setAddress(...);
return _studentEntity;
}
Is this correct ? How mutator methods should be? Please make me correct if wrong!
There is no reason to write
StudentEntity _studentEntity = studentEntity;
It's just redundant.
If you are just updating and return prefer first way. The second way creates unnecessary confusion while reading the code aswell.

Returning an arraylist and iterating throught the returned list

Im trying to return an arraylist from the method getNumbers (which contains strings)
public ArrayList<String> getNumbers(){
return (numeros);
}
Then by using a searcher im trying to compare between a variable m (which contains the desired info to look for) and the returned list.
public class NumberSearcher {
Reader reader = new KeyboardReader();
public NumberSearcher(ArrayList<Contacto> contactos){
String m = reader.read();
for(int i = 0; i<contactos.size();i++){
if(contactos.get(i).getPhoneNumbers().contains(m)){
contactos.get(i).display();
}
}
}
}
I have succeded in creating a searcher using this very same style but only when using methods that return String alone.
The problem is its not working. If there there would be a match it should display the contact information but it seem it isnt "comparing" properly because nothing happens.
It's difficult to understand what you're asking here. Your getNumbers method doesn't get called from the second code block, so I don't see where that is relating to anything. It's also unclear what you mean the problem is. Can you try to give us a more detailed description of what is going wrong?
Anyways, I'll try to give you some general advice here, but without knowing the issue it's hard to say how much this will help.
Firstly, it is almost always recommended to have your method's return type as the List interface, rather than a specific implementation (ArrayList, etc). You can specify a return type from within the method but this way they client doesn't need to know what the underlying data structure is, and you are also flexible to future data structure changes.
public List<String> getNumbers(){
return (numeros);
}
Secondly, I would probably change the name 'getNumbers' to something slightly more precise - if I see a 'getNumbers' method I expect it to return some numeric entities, not a list of strings. If they are phone numbers then explicity call it 'getPhoneNumbers'.
Though I'm not entirely sure I understand what you asking, I think this may solve your issues:
for(int i = 0; i < contactos.size(); i++) {
Contacto next = contactos.get(i);
if(next.getEmails().contains(m)) {
next.display();
}
}
And as an afterthought, is there any specific reason you're only checking string containment? I would suggest that you check case-insensitive equality unless you really do want to find out if the string just contains the element.
Is this what you are looking for?
public class EmailSearcher {
Reader reader = new KeyboardReader();
public EmailSearcher(ArrayList<Contacto> contactos){
while(reader.read() != 'keyThatTerminates') {
String m = reader.read();
for(int i = 0; i<contactos.size();i++){
var row = contactos.get(i);
if(row.getEmails().contains(m)){
row.display();
}
}
}
}
}

Categories