The code below is for javax.activation.DataHandler.getDataContentHandler, 1.41, 07/05/14.
If the dataContentHandler member variable is null when the method is called, then it gets set by the 'if' clause at [1] (which is what happens in my program).
It then immediately gets overwritten in the if clause at [2].
Am I missing something, or is that unlikely to be the intended behaviour?
private synchronized DataContentHandler getDataContentHandler() {
// make sure the factory didn't change
if (factory != oldFactory) {
oldFactory = factory;
factoryDCH = null;
dataContentHandler = null;
transferFlavors = emptyFlavors;
}
if (dataContentHandler != null)
return dataContentHandler;
String simpleMT = getBaseType();
if (factoryDCH == null && factory != null)
factoryDCH = factory.createDataContentHandler(simpleMT);
if (factoryDCH != null)
dataContentHandler = factoryDCH;
if (dataContentHandler == null) { // [1]
if (dataSource != null)
dataContentHandler = getCommandMap().
createDataContentHandler(simpleMT, dataSource);
else
dataContentHandler = getCommandMap().
createDataContentHandler(simpleMT);
}
// getDataContentHandler always uses these 'wrapper' handlers
// to make sure it returns SOMETHING meaningful...
if (dataSource != null) // [2]
dataContentHandler = new DataSourceDataContentHandler(
dataContentHandler,
dataSource);
else
dataContentHandler = new ObjectDataContentHandler(
dataContentHandler,
object,
objectMimeType);
return dataContentHandler;
}
I
Am I missing something, or is that unlikely to be the intended behaviour?
Looks like that is the intended behavior per the comment:
// getDataContentHandler always uses these 'wrapper' handlers
// to make sure it returns SOMETHING meaningful...
If you look closely at the code, the 'dataContentHandler' is passed as an argument to 'new DataSourceDataContentHandler' and 'new ObjectDataContentHandler'. That is the 'wrapping' referred to in the comment.
Related
For the below piece of code Sonar throws me a critical violation - Correctness - Nullcheck of status value previously dereferenced
Can someone suggest on this on what am I doing wrong here?
code
public boolean isExactMacthBill(AddressResponse response) {
boolean exactMatch = false;
if (null != response && null != response.getHostResponse()) {
HostResponseDetail hostResponse = response.getHostResponse();
String addressStatus = hostResponse.getMatchStatus();
ResponseDetail status = hostResponse.getStatus();
String addressMatchCode = status.getCode();
if (null != response.getMatchedAddresses() && response.getMatchedAddresses().size() > 0 && status != null) {
if (addressStatus.equalsIgnoreCase(Constants.USPS_MATCH)
|| (addressStatus.equalsIgnoreCase(Constants.PARTIAL_MATCH)
&& addressMatchCode.equalsIgnoreCase("3SXU"))) {
exactMatch = true;
} else
exactMatch = false;
}
}
return exactMatch;
}
The actual problem is in the line after the highlighted one - you've got:
if (... && status != null)
Just remove that check and I think SonarLint will be happy. It unnecessary, because if status is null then status.getCode() will already have thrown an exception before you reach that condition.
Fundamentally, you need to know whether getStatus() should ever return null - whether you have to handle that situation explicitly. If you do, you should check it before your call to status.getCode(), and react accordingly. If you don't, it's fine to call the getCode() method - if your assumption is incorrect, you'll get a NullPointerException as normal, which is probably the most appropriate result for the scenario of "the world isn't as I expect it to be". But you shouldn't try to "handle" it being null after you've already depended on it being non-null.
status can be null when it is received from hostResponse.getStatus();; so when the line String addressMatchCode = status.getCode(); is called it can result in a Null Reference Exception.
You should verify all the variables if there are null before calling methods on them.
Move your addressMatchCode inside your if condition which null check the status.
public boolean isExactMacthBill(AddressResponse response) {
boolean exactMatch = false;
if (null != response && null != response.getHostResponse()) {
HostResponseDetail hostResponse = response.getHostResponse();
String addressStatus = hostResponse.getMatchStatus();
ResponseDetail status = hostResponse.getStatus();
if (null != response.getMatchedAddresses() && response.getMatchedAddresses().size() > 0 && status != null) {
String addressMatchCode = status.getCode();
if (addressStatus.equalsIgnoreCase(Constants.USPS_MATCH)
|| (addressStatus.equalsIgnoreCase(Constants.PARTIAL_MATCH)
&& addressMatchCode.equalsIgnoreCase("3SXU"))) {
exactMatch = true;
} else
exactMatch = false;
}
}
return exactMatch;
}
I tried to find a similar question, but I didn't succeed.
In a bean, I'm looping through a ViewEntryCollection several times, adding or deleting entries. Could someone tell me exactly when these objects should be recycled? I want to be able to reuse the whole collection so I don't want to destroy any objects I might still need.
My code:
public static int FTSearchAll(ViewEntryCollection vec, View vw, String cat, String query) throws NotesException {
...
for (ViewEntry ve = nav.getFirst(); ve != null; ) {
ViewEntry next = nav.getNext(ve);
Document doc = ve.getDocument();
if (doc == null)
continue;
try {
Vector v = session.evaluate(query, doc);
if (v != null && v.size() > 0 && (Double) v.elementAt(0) != 0) {
vec.addEntry(ve, false);
} else {
for (ViewEntry dce = vec.getFirstEntry(); dce != null;) {
ViewEntry dcnext = vec.getNextEntry(dce);
if (dce.getNoteID().equals(ve.getNoteID())) {
vec.deleteEntry(dce);
incinerate(dce);
break;
}
dce = dcnext;
}
}
} catch (NotesException ne) {
} finally {
incinerate(ve, doc);
}
ve= next;
}
As always: thanks!
The rule is quite simple: when a Java object pointing to a Notes C object is about to go onto the garbage heap, .recycle() must have been called.
So you need to do that for all entries inside the loop.
My little rule of thumb: the block (think { ... } ) that created a Notes Java object must call its .recycle() function at the end.
Saves you lot of headaches
I see this, but not completely sure whether I miss something or the code keeps its functionality... :S
for (ViewEntry ve = nav.getFirst(); ve != null; ) {
ViewEntry next = nav.getNext(ve);
Document doc = ve.getDocument();
if (doc == null) {
incinerate(ve); // << new
ve = next; // << new
continue;
}
try {
Vector v = session.evaluate(query, doc);
if (v != null && v.size() > 0 && (Double) v.elementAt(0) != 0) {
vec.addEntry(ve, false);
} else {
for (ViewEntry dce = vec.getFirstEntry(); dce != null;) {
ViewEntry dcnext = vec.getNextEntry(dce);
if (dce.getNoteID().equals(ve.getNoteID())) {
vec.deleteEntry(dce);
incinerate(dce, dcnext); // << new
break;
}
incinerate(dce); // << new
dce = dcnext;
}
}
} catch (NotesException ne) {
} finally {
incinerate(ve, doc);
}
ve = next;
}
Maybe it would be better to check another implementation.
Anyway, I recommend you to use the OpenNTF Domino API and get rid of recycle, and you will get also a proper iteration over entries:
http://www.openntf.org/main.nsf/project.xsp?r=project/OpenNTF%20Domino%20API
I am using auto generated JPAController of Netbeans 8 using Java 1.8.
public void create(Physical physical) {
if (physical.getTalentCollection() == null) {
physical.setTalentCollection(new ArrayList<Talent>());
}
EntityManager em = null;
try {
em = getEntityManager();
em.getTransaction().begin();
Specialmark specialmarkId = physical.getSpecialmarkId();
System.out.println(specialmarkId+ "...nullValue");
if (specialmarkId != null) {
System.out.println(specialmarkId+ "...ain't right");
specialmarkId = em.getReference(specialmarkId.getClass(), specialmarkId.getId());
physical.setSpecialmarkId(specialmarkId);
}
.....
}
During physical object creation, Specialmark (part of physical object) is an optional.
It can have a value or be null.
Specialmark in the table physical allows you to have null values.
When Specialmark is null, the if (specialmarkId != null) {...} should skipped. Instead, it got ignored and proceed.
the error message is
"... An instance of a null PK has been incorrectly provided for this find operation.
at db.jpa.PhysicalJpaController.create(PhysicalJpaController.java:57)"
System.out.println(specialmarkId+ "...nullValue");
output "null...nullValue" it shows specialmarkId value is null
System.out.println(specialmarkId+ "...ain't right");
Output "null...ain't right" shows if (specialmarkId != null) {...} has been ignored even specialmarkId is null.
Why does (specialmarkId != null) {...} not work?
I guess specialmarkId is not really null, but specialmarkId.toString() is overwriten for it to return the string "null".
Instead of
System.out.println(specialmarkId+ "...nullValue");
try something like
System.out.println((specialmarkId != null?
specialmarkId.toString() + "(not null)": "(this IS REALLY NULL)")
+ "...nullValue");
I have a java code in which there are multiple return statements in a single method. But for code cleaning purpose, I can have only one return statement per method. What can be done to overcome this.
Here is a method from my code:-
public ActionForward login(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
// Kill any old sessions
//request.getSession().invalidate();
DynaValidatorForm dynaform = (DynaValidatorForm)form;
// validate the form
ActionErrors errors = form.validate(mapping, request);
if(!errors.isEmpty()) {
this.saveErrors(request, errors);
return mapping.getInputForward();
}
// first check if token is set
if(!isTokenValid(request, true)) {
String errmsg="There was a problem with your login. Please close your browser then reopen it and try again. Make sure to click the Login button only ONCE.";
request.setAttribute("errormessage", errmsg);
saveToken(request);
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
}
// check the form for input errors
String errmsg = checkInput(form);
if (errmsg != null) {
request.setAttribute("errormessage", errmsg);
saveToken(request);
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
}
// no input errors detected
String resumekey = null;
// check for valid login
ObjectFactory objFactory = ObjectFactory.getInstance();
DataAccessor dataAccessor = objFactory.getDataAccessor();
request.setCharacterEncoding("UTF-8");
String testcode = dynaform.getString("testcode").trim();
String studentname = dynaform.getString("yourname").trim();
String password = dynaform.getString("password").trim();
// 4/3/07 - passwords going forward are ALL lower case
if (!CaslsUtils.isEmpty(password)) {
password = password.toLowerCase();
}
try{
resumekey = new String(studentname.getBytes("ISO-8859-1"),"UTF-8");
} catch (Exception e) {
log_.error("Error converting item content data to UTF-8 encoding. ",e);
}
String hashWord = CaslsUtils.encryptString(password);
// Make sure this is short enough to fit in the db
if (hashWord.length() > ConstantLibrary.MAX_PASSWORD_LENGTH) {
hashWord = hashWord.substring(0, ConstantLibrary.MAX_PASSWORD_LENGTH);
}
Login login = dataAccessor.getLogin(testcode, hashWord, false);
if (login == null || !login.getUsertype().equals(Login.USERTYPE_SUBJECT)) {
request.setAttribute("errormessage", "Incorrect test code or password.");
saveToken(request);
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
}
// Check if the login has expired
if (login.getLoginexpires() != null && login.getLoginexpires().before(new Date())) {
request.setAttribute("errormessage", "Your login has expired.");
saveToken(request);
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
}
// Check if the password has expired
if (login.getPasswordexpires() != null && login.getPasswordexpires().before(new Date())) {
request.setAttribute("errormessage", "Your login password has expired.");
saveToken(request);
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
}
HttpSession session = request.getSession();
session.setAttribute(ConstantLibrary.SESSION_LOGIN, login);
session.setAttribute(ConstantLibrary.SESSION_STUDENTNAME, studentname);
List<Testtaker> testtakers = null;
try {
//invalidate the old session if the incoming user is already logged in.
synchronized(this){
invalidateExistingSessionOfCurrentUser(request, studentname, testcode);
testtakers = dataAccessor.getTesttakersByResumeKey(studentname, login);// Adding this code to call getTesttakersByResumeKey instead of getTesttakers to improve the performance of the application during student login
}
} catch (Exception e) {
log.error("Exception when calling getTesttakers");
CaslsUtils.outputLoggingData(log_, request);
throw e;
}
session = request.getSession();
if(testtakers!=null)
{
if(testtakers.size() == 0) {
// new student -> start fresh
log_.debug("starting a fresh test");
// if this is a demo test, skip the consent pages and dump them directly to the select test page
if (login.getTestengine().equals(Itemmaster.TESTENGINE_DEMO)) {
return mapping.findForward("continue-panel");
}
}
// send them to fill out the profile
// check for custom profiles
String[] surveynames = new String[4];
List<Logingroup> logingroups = dataAccessor.getLoginGroupsByLogin(login.getLoginid());
for(Logingroup logingroup : logingroups) {
Groupmaster group = logingroup.getGroupmaster();
log_.debug(String.format("group: {groupid: %d, grouptype: %s, groupname: %s}", new Object[] {group.getGroupid(), group.getGrouptype(), group.getName()}));
Set<Groupsurvey> surveys = group.getGroupsurveys();
if(surveys.size() > 0) {
// grab the first (and only) one
Groupsurvey survey = surveys.toArray(new Groupsurvey[0])[0];
if(group.getGrouptype().equalsIgnoreCase(Groupmaster.GROUPTYPE_CLASS)) {
surveynames[0] = survey.getSurveyname();
} else if (group.getGrouptype().equalsIgnoreCase(Groupmaster.GROUPTYPE_SCHOOL)){
surveynames[1] = survey.getSurveyname();
} else if (group.getGrouptype().equalsIgnoreCase(Groupmaster.GROUPTYPE_DISTRICT)){
surveynames[2] = survey.getSurveyname();
} else if (group.getGrouptype().equalsIgnoreCase(Groupmaster.GROUPTYPE_STATE)){
surveynames[3] = survey.getSurveyname();
}
}
}
// match the most grandular survey
for(int i=0; i < surveynames.length; ++i) {
if(surveynames[i] != null) {
saveToken(request);
return mapping.findForward("student-profile-"+surveynames[i]);
}
}
// no custom profile, send them to the default
saveToken(request);
return mapping.findForward("student-profile");
}
// get the set of availible panels
Set<Panel> availiblePanels = dataAccessor.getAvailiblePanels(login, studentname);
if(availiblePanels.size() == 0) {
// no panels availible. send to all done!
log_.debug(String.format("No panels availible for Login:%s with resumekey:%s", login.toString(), studentname));
session.setAttribute("logoutpage", true);
resetToken(request);
return mapping.findForward("continue-alldone");
}
//Eventum #427 - Prevent test takers from retaking a finished test.
TestSubjectResult testSubjecResult=dataAccessor.getTestSubjectResult(login, resumekey);
if(testSubjecResult != null){
if(testSubjecResult.getRdscore() != null && testSubjecResult.getWrscore() != null && testSubjecResult.getLsscore() != null && testSubjecResult.getOlscore() != null){
if(testSubjecResult.getRdscore().getFinishtime() != null && testSubjecResult.getWrscore().getFinishtime() != null && testSubjecResult.getLsscore().getFinishtime() != null && testSubjecResult.getOlscore().getFinishtime() != null){
log_.debug(String.format("Already completed all the Skill Tests.", login.toString(), studentname));
session.setAttribute("logoutpage", true);
resetToken(request);
return mapping.findForward("continue-alldone");
}
}
}
// get a list of resumeable testtakers
List<Testtaker> resumeableTesttakers = new ArrayList<Testtaker>();
for(Testtaker testtaker : testtakers) {
if(testtaker.getPhase().equals(ConstantLibrary.PHASE_GOODBYE)) {
// testtaker is done with test. skip.
continue;
}
if(testtaker.getCurrentpanelid() == null) {
// testtaker is the profile testtaker
continue;
}
resumeableTesttakers.add(testtaker);
}
// sort them from least recent to latest
Collections.sort(resumeableTesttakers, new Comparator<Testtaker>() {
#Override
public int compare(Testtaker o1, Testtaker o2) {
// TODO Auto-generated method stub
//return 0;
return new CompareToBuilder()
.append(o1.getLasttouched(), o2.getLasttouched())
.toComparison();
}
});
if(resumeableTesttakers.size() == 0 && availiblePanels.size() > 0) {
// nobody is resumeable but there are panels left to take
// send them to the panel choice
// TODO: This is probably a misuse of Struts.
log_.info("No resumeable testtakers. Sending to panel select");
saveToken(request);
ActionForward myForward = (new ActionForward("/do/capstartpanel?capStartPanelAction=retest&lasttesttakerid="
+ testtakers.get(0).getTesttakerid(), true));
return myForward;// mapping.findForward(ConstantLibrary.FWD_CONTINUE + "-panel");
} else {
// grab the one most recently created and take their test
log_.info(String.format("Resuming with choice of %d testtakers", resumeableTesttakers.size()));
// we're forwarding to resume at this point, so we should do the some of the initialization
// that would have happened if we were still using getTesttaker() instead of getTesttakers() above.
session.setAttribute(ConstantLibrary.SESSION_LOGIN, login);
session.setAttribute(ConstantLibrary.SESSION_TESTTAKER, resumeableTesttakers.get(resumeableTesttakers.size()-1));
saveToken(request);
return mapping.findForward(ConstantLibrary.FWD_RESUME);
}
}
It's not a worth changing multiple returns to a single return statement per method. Actually, that will unnecessarily increase the burden of storing the result in a local variable and then making the return finally,
ActionForward result = null;
//scenario 1
result = ...
//scenario 2
result = ...
//scenario 3
result = ...
//finally
return result;
Hope this helps, but, it doesn't make much sense to me
As pointed out by others, having a single return statement does not necessarily make your code cleaner. However, in this case splitting up the method in smaller pieces probably makes the code more readable.
For example, this part:
// first check if token is set
if(!isTokenValid(request, true)) {
String errmsg="There was a problem with your login. Please close your browser then reopen it and try again. Make sure to click the Login button only ONCE.";
request.setAttribute("errormessage", errmsg);
saveToken(request);
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
}
// check the form for input errors
String errmsg = checkInput(form);
if (errmsg != null) {
request.setAttribute("errormessage", errmsg);
saveToken(request);
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
}
could be replaced by introducing two methods and using those to write:
If(tokenNotSet() || formHasErrors()){
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
}
By doing this on multiple places the structure of the algorithm becomes more clear, possibly giving you more insight in how this code could be refactored to adhere to your coding guidelines.
I would set a an action forward variable at the start of the method.
ActionForward actionForwardToReturn = null;
Then replace each of these two lines
return mapping.getInputForward();
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
with these two lines :
actionForwardToReturn = mapping.getInputForward()
actionForwardToReturn = mapping.findForward(ConstantLibrary.FWD_CONTINUE);
finally return the variable.
return actionForwardToReturn;
This shouldn't be too difficult :)
On a side note... (actually the orginal answer to the question) :
Multiple return statements can make it hard to debug code.
I personally would have just one action object that you return at the end of the method. The benefit of this, is that i can put a break point right on the return statement and look at exactly what that object is.
Any logging or other cross cutting concern I would want to add later, would only have to be done at one point. Otherwise I would have to add a log statement to every line where you are returning.
The complexity added to a method in an attempt to remove multiple return statements is many a times not worth it, especially in a method such as yours.There's nothing wrong with using them in this case.
Like user3580294 there's nothing wrong with multiple return statements. However you could combine the last two if statements since they are essentially returning the same thing.
Use #Octopus 's method if you absolutely have to have one return statement
How can i replace assertions with if's? Example:
public Wezel<Wartosc,Indeks> getWujek()
{
assert rodzic != null; // Root node has no uncle
assert rodzic.rodzic != null; // Children of root has no uncle
return rodzic.getBrat();
}
An assertion is roughly equivalent to:
if (!condition) {
throw new AssertionError();
}
public Wezel<Wartosc,Indeks> getWujek()
{
if(rodzic == null) { // Root node has no uncle
throw new Exception("Root node has no uncle");
}
if(rodzic.rodzic == null) {
throw new Exception("Children of root have no uncle");
}
return rodzic.getBrat();
}
Replacing these assertions would take the form of the following validation:
if (rodzic == null)
throw new MyValidationException("rodzic cannot be null");
if (rodzic.rodzic == null)
throw new MyValidationException("rodzic.rodzic cannot be null");
return rodzic.getBrat();
Note that there's a distinction between throwing an Exception and an Error - Exceptions are meant to be caught and handled farther up, while Errors indicate a situation that you can't recover from. For example, you might consider a defining and using a MyValidationError if the failed check is irrecoverable.