Bitmap becomes null - java

I am working on a project in which I have to pass data from an activity to another. I try to use bitmap in order to pass around images. After I retrieve the image from Firebase storage I can output it with System.out but if I try to read it outside the fetch method it returns null in console.
for (DocumentSnapshot result : Objects.requireNonNull(task.getResult()).getDocuments()
) {
title = Objects.requireNonNull(result.get("Author")).toString();
author = Objects.requireNonNull(result.get("Title")).toString();
edition = Objects.requireNonNull(result.get("Edition")).toString();
isbn = Objects.requireNonNull(result.get("ISBN")).toString();
category = Objects.requireNonNull(result.get("Category")).toString();
reviews = result.get("Reviews");
Bitmap[] bitmap = new Bitmap[1];
try {
final File local_file = File.createTempFile("android_dev", "jpg");
storageRef.getFile(local_file).addOnCompleteListener(bitmap_task -> {
if (bitmap_task.isSuccessful()){
System.out.println("Sucess");
bitmap[0] = BitmapFactory.decodeFile(local_file.getAbsolutePath());
System.out.println(bitmap[0] + " yes yes");
}else {
System.out.println("Failure!");
}
});
} catch (IOException e) {
e.printStackTrace();
}
if (category.equals(finalBook_category)) {
if (title.contains(search) || author.contains(search) || edition.contains(search) || isbn.contains(search)) {
System.out.println(bitmap[0] + "What is happening");
books_list.add(new LibraryBook(author, title, edition, isbn, category, reviews, bitmap[0]));
}
}
}
setAdapter();
} else {
System.out.println("Nope");
}
});
}

Are you referring to this line
System.out.println(bitmap[0] + "What is happening");
as the point where you don't see the expected bitmap output? If so, it's because the getFile() is method that returns a Task, with the addOnCompleteListener callback. So it's not synchronous. So your code is reaching this section:
if (category.equals(finalBook_category)) {
if (title.contains(search) || author.contains(search) || edition.contains(search) || isbn.contains(search)) {
System.out.println(bitmap[0] + "What is happening");
books_list.add(new LibraryBook(author, title, edition, isbn, category, reviews, bitmap[0]));
}
}
before the bitmap has been fetched from your storage bucket. Put that if statement below this line instead:
System.out.println(bitmap[0] + " yes yes");
so that it waits until the callback and you know you have downloaded the image before using it.

Related

Checking which parameter is missing from file content

I have a TransferReader class which reads a file containing transfer data from bank account to another using the following form:
SenderAccountID,ReceiverAccountID,Amount,TransferDate
"473728292,474728298,1500.00,2019-10-17 12:34:12" (unmodified string)
Suppose that the file has been modified before being read so that one of the above mentioned paramaters are missing, and I want to check which of those are missing.
"474728298,1500.00,2019-10-17 12:34:12" (modified string)
I am using a BufferedReader to read each line, and then splitting each element into a String[] using String.split(",") as delimeter.
As already realized, because the Sender Account ID and Receiver Account ID are right next to one another within a record there is no real way of knowing which ID might be missing unless a delimiter remains in its' place indicating a Null value. There are however mechanisms available to determine that it is indeed one of the two that is missing, which one will need to be carried out through User scrutiny and even then, that may not be good enough. The other record column fields like Amount and Transfer Date can be easily validated or if missing can be implicated within a specific File Data Status Log.
Below is some code that will read a data file (named Data.csv) and log potential data line (record) errors into a List Interface object which is iterated through and displayed within the Console Window when the read is complete. There are also some small helper methods. Here is the code:
private void checkDataFile(String filePath) {
String ls = System.lineSeparator();
List<String> validationFailures = new ArrayList<>();
StringBuilder sb = new StringBuilder();
// 'Try With Resources' used here to auto-close reader.
try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
String line;
int lineCount = 0;
// Read the file line-by-line.
while ((line = reader.readLine()) != null) {
line = line.trim();
lineCount++;
if (lineCount == 1 || line.equals("")) {
continue;
}
sb.delete(0, sb.capacity()); // Clear the StringBuilder object
// Start the Status Log
sb.append("File Line Number: ").append(lineCount)
.append(" (\"").append(line).append("\")").append(ls);
// Split line into an Array based on a comma delimiter
// reguardless of the delimiter's spacing situation.
String[] lineParts = line.split("\\s{0,},\\s{0,}");
/* Validate each file line. Log any line that fails
any validation for any record column data into a
List Interface object named: validationFailures
*/
// Are there 4 Columns of data in each line...
if (lineParts.length < 4) {
sb.append("\t- Invalid Column Count!").append(ls);
// Which column is missing...
// *** You may need to add more conditions to suit your needs. ***
if (checkAccountIDs(lineParts[0]) && lineParts.length >= 2 && !checkAccountIDs(lineParts[1])) {
sb.append("\t- Either the 'Sender Account ID' or the "
+ "'ReceiverAccountID' is missing!").append(ls);
}
else if (lineParts.length >= 3 && !checkAmount(lineParts[2])) {
sb.append("\t- The 'Amount' value is missing!").append(ls);
}
else if (lineParts.length < 4) {
sb.append("\t- The 'Transfer Date' is missing!").append(ls);
}
}
else {
// Is SenderAccountID data valid...
if (!checkAccountIDs(lineParts[0])) {
sb.append("\t- Invalid Sender Account ID in column 1! (")
.append(lineParts[0].equals("") ? "Null" :
lineParts[0]).append(")");
if (lineParts[0].length() < 9) {
sb.append(" <-- Not Enough Or No Digits!").append(ls);
}
else if (lineParts[0].length() > 9) {
sb.append(" <-- Too Many Digits!").append(ls);
}
else {
sb.append(" <-- Not All Digits!").append(ls);
}
}
// Is ReceiverAccountID data valid...
if (!checkAccountIDs(lineParts[1])) {
sb.append("\t- Invalid Receiver Account ID in coloun 2! (")
.append(lineParts[1].equals("") ? "Null" :
lineParts[1]).append(")");
if (lineParts[1].length() < 9) {
sb.append(" <-- Not Enough Or No Digits!").append(ls);
}
else if (lineParts[1].length() > 9) {
sb.append(" <-- Too Many Digits!").append(ls);
}
else {
sb.append(" <-- Not All Digits!").append(ls);
}
}
// Is Amount data valid...
if (!checkAmount(lineParts[2])) {
sb.append("\t- Invalid Amount Value in column 3! (")
.append(lineParts[2].equals("") ? "Null" :
lineParts[2]).append(")").append(ls);
}
// Is TransferDate data valid...
if (!checkTransferDate(lineParts[3], "yyyy-MM-dd HH:mm:ss")) {
sb.append("\t- Invalid Transfer Date Timestamp in column 4! (")
.append(lineParts[3].equals("") ? "Null" :
lineParts[3]).append(")").append(ls);
}
}
if (!sb.toString().equals("")) {
validationFailures.add(sb.toString());
}
}
}
catch (FileNotFoundException ex) {
System.err.println(ex.getMessage());
}
catch (IOException ex) {
System.err.println(ex.getMessage());
}
// Display the Log...
String timeStamp = new SimpleDateFormat("yyyy/MM/dd - hh:mm:ssa").
format(new Timestamp(System.currentTimeMillis()));
String dispTitle = "File Data Status at " + timeStamp.toLowerCase()
+ " <:-:> (" + filePath + "):";
System.out.println(dispTitle + ls + String.join("",
Collections.nCopies(dispTitle.length(), "=")) + ls);
if (validationFailures.size() > 0) {
for (String str : validationFailures) {
if (str.split(ls).length > 1) {
System.out.println(str);
System.out.println(String.join("", Collections.nCopies(80, "-")) + ls);
}
}
}
else {
System.out.println("No Issues Detected!" + ls);
}
}
private boolean checkAccountIDs(String accountID) {
return (accountID.matches("\\d+") && accountID.length() == 9);
}
private boolean checkAmount(String amount) {
return amount.matches("-?\\d+(\\.\\d+)?");
}
private boolean checkTransferDate(String transferDate, String format) {
return isValidDateString(transferDate, format);
}
private boolean isValidDateString(String dateToValidate, String dateFromat) {
if (dateToValidate == null || dateToValidate.equals("")) {
return false;
}
SimpleDateFormat sdf = new SimpleDateFormat(dateFromat);
sdf.setLenient(false);
try {
// If not valid, it will throw a ParseException
Date date = sdf.parse(dateToValidate);
return true;
}
catch (ParseException e) {
return false;
}
}
I'm not exactly sure what your particular application process will ultimately entail but if other processes are accessing the file and making modifications to it then it may be wise utilize a locking mechanism to Lock the file during your particular process and Unlock the file when it is done. This however will most likely require you to utilize a different reading algorithm since locking a file must be done through a writable channel. Using the FileChannel and FileLock classes from the java.nio package could possibly assist you here. There would be examples of how to utilize these classes within the StackOverflow forum.

Can`t Redirect inside If statement in Servlet

I am working on a Web application and in my Servlet i do validation. If i have some empty input or something, i want it to redirect to the same page. But i am having some problem. If i try to make the redirect inside if statement (without else statement) it does not redirect, it would just go below and produce an error.
how could i make it work? without having multiple if/else statements.
Here is my simplified code:
if (dateOfDelivery.equals(" ") || dateOfDelivery.equals("")) {
String errorMsq = "Error create Order, enter return Date";
log.error(errorMsq);
new ErrorRedirect().sendRedirect(ErrorRedirect.ERROR_MAIN_MENU_URL + errorMsq, response);
} else {
LocalDate sqlDateOfDelivery = LocalDate.parse(dateOfDelivery, dateFormat);
Long defaultPenalty = 0L;
OrderValidation.redirectIfBookCountInStockZero(book, response);
if (book.getCountInStock() == 0 || book.getCountInStock() < 0) {
String errorMsq = "Book count in stock equals zero!";
new ErrorRedirect().sendRedirect(ErrorRedirect.ERROR_MAIN_MENU_URL + errorMsq, response);
} else {
Order order = Order.builder()....
response.sendRedirect(allBooksList);
My new ErrorRedirect().sendRedirect() it is simple wrapper which i wrote.
Just return from handler after sending redirect, something like:
if (dateOfDelivery.equals(" ") || dateOfDelivery.equals("")) {
String errorMsq = "Error create Order, enter return Date";
log.error(errorMsq);
new ErrorRedirect().sendRedirect(ErrorRedirect.ERROR_MAIN_MENU_URL + errorMsq, response);
return "redirected...";
}

How to wait until processes finish Java AWS Lambda

I want to wait until my processes finish before I return my speechlet response, otherwise it seems to cut my process off and thus, not complete it, I actually believe it may freeze the process, but thats not my desire.
How do I go about waiting?
#Override
public SpeechletResponse onIntent(SpeechletRequestEnvelope<IntentRequest> requestEnvelope) {
IntentRequest request = requestEnvelope.getRequest();
Intent intent = request.getIntent();
String intentName = (intent != null) ? intent.getName() : null;
if (intentName == null) return null;
switch (intentName) {
case IntentTitle.NEW_TICKET:
switch (request.getDialogState()) {
case STARTED:
return Response.getDialogueResponse(intent, true);
case IN_PROGRESS:
return Response.getDialogueResponse(intent, false);
case COMPLETED:
String numberString = intent.getSlot(SlotTitle.ID).getValue();
if (!NumberUtils.isCreatable(numberString)) return Response.ERROR;
Member member = Info.GUILD.getMemberById(numberString);
User sender = UserDB.getUser(member);
CommissionTicket commissionTicket = new CommissionTicket(sender);
commissionTicket.create();
//wait until processes finish before continuing
return Response.NEW_TICKED_CREATED;
}
}
return null;
}
UPDATE:
Had a look at the CloudWatch logs, and well, pretty much what I expected was happening is happening... have a look at the times for these logs (I ran them 3 different times, so 3 different times are logged, but apart of the same lambda session)
public void create() {
System.out.println("log2");
GuildController guildController = Info.GUILD.getController();
guildController.createTextChannel(ticketType.name().toLowerCase() + "-" + creator.getName() + "-" + id.value()).queue(channel -> {
System.out.println("log3");
ChannelManager channelManager = channel.getManager();
GuildManager guildManager = channelManager.getGuild().getManager();
List<Member> members = guildManager.getGuild().getMembers();
List<Member> admins = new ArrayList<>();
for (Member member : members) {
for (Role role : member.getRoles()) {
if (!role.getName().equalsIgnoreCase(Info.ADMIN_STRING)) continue;
admins.add(member);
}
}
System.out.println("log4");
for (Member member : members) {
if (member.equals(creator.getMember())) continue;
channel.createPermissionOverride(member).setDeny(Permission.MESSAGE_READ).queue();
}
System.out.println("log5");
for (Member admin : admins) {
if (admin.equals(creator.getMember())) continue;
channel.createPermissionOverride(admin).setAllow(Permission.MESSAGE_READ).queue();
}
System.out.println("log6");
BotMessage botMessage = new BotMessage();
botMessage
.setTitle("New Ticket! User: " + creator.getName())
.setColour(Color.CYAN)
.setDescription("Please enter your full request here! \n" +
"Make sure to let us know whether you are looking for a quote/timeframe,\n" +
"or have a budget in mind, and we will work around you!\n\n" +
"A sales representative will be with you as soon as possible!")
.send((TextChannel) channel);
System.out.println("log7");
this.textChannel = (TextChannel) channel;
TicketDB.addTicket(this);
System.out.println("log8");
}
);
Logs:
https://gyazo.com/0ad2baa8d1438be8364dd1112159c4f4
https://gyazo.com/e197f33335046afe3c9f8f1ace267d30
UPDATE
Implemented the Future class, worked, but still a bit buggy.
It now completely creates the ticket, which is great, however, when I go to send the same call again, it for some reason sends a message in the same channel before preceding to create the next ticket.
So, to simulate...
Function call through AWS Lambda
Creates ticket completely
Function call through AWS Lambda again
Sends a message or two in the previous tickets channel
Creates new ticket completely
https://gyazo.com/dc6e4391f4964f41a73f1c3be92190f9
#Override
public SpeechletResponse onIntent(SpeechletRequestEnvelope<IntentRequest> requestEnvelope) {
IntentRequest request = requestEnvelope.getRequest();
Intent intent = request.getIntent();
String intentName = (intent != null) ? intent.getName() : null;
if (intentName == null) return null;
switch (intentName) {
case IntentTitle.NEW_TICKET:
switch (request.getDialogState()) {
case STARTED:
return Response.getDialogueResponse(intent, true);
case IN_PROGRESS:
return Response.getDialogueResponse(intent, false);
case COMPLETED:
String numberString = intent.getSlot(SlotTitle.ID).getValue();
if (!NumberUtils.isCreatable(numberString)) return Response.ERROR;
Member member = Info.GUILD.getMemberById(numberString);
User sender = UserDB.getUser(member);
System.out.println("log1");
Future<Ticket> commissionTicket = new CommissionTicket(sender).create();
try {
commissionTicket.get(10000, TimeUnit.MILLISECONDS);
} catch (Exception e) {
e.printStackTrace();
}
//wait until processes finish before continuing
return Response.NEW_TICKED_CREATED;
}
}
return null;
}
In the Ticket class:
public Future<Ticket> create() {
System.out.println("log2");
GuildController guildController = Info.GUILD.getController();
RequestFuture<Channel> channelRequestFuture = guildController.createTextChannel(ticketType.name().toLowerCase() + "-" + creator.getName() + "-" + id.value()).submit();
try {
Channel channel = channelRequestFuture.get(10000, TimeUnit.MILLISECONDS);
System.out.println("log3");
ChannelManager channelManager = channel.getManager();
GuildManager guildManager = channelManager.getGuild().getManager();
List<Member> members = guildManager.getGuild().getMembers();
List<Member> admins = new ArrayList<>();
for (Member member : members) {
for (Role role : member.getRoles()) {
if (!role.getName().equalsIgnoreCase(Info.ADMIN_STRING)) continue;
admins.add(member);
}
}
System.out.println("log4");
for (Member member : members) {
if (member.equals(creator.getMember())) continue;
channel.createPermissionOverride(member).setDeny(Permission.MESSAGE_READ).queue();
}
System.out.println("log5");
for (Member admin : admins) {
if (admin.equals(creator.getMember())) continue;
channel.createPermissionOverride(admin).setAllow(Permission.MESSAGE_READ).queue();
}
System.out.println("log6");
BotMessage botMessage = new BotMessage();
botMessage
.setTitle("New Ticket! User: " + creator.getName())
.setColour(Color.CYAN)
.setDescription("Please enter your full request here! \n" +
"Make sure to let us know whether you are looking for a quote/timeframe,\n" +
"or have a budget in mind, and we will work around you!\n\n" +
"A sales representative will be with you as soon as possible!")
.send((TextChannel) channel);
System.out.println("log7");
this.textChannel = (TextChannel) channel;
TicketDB.addTicket(this);
System.out.println("log8");
Future<Ticket> future = ConcurrentUtils.constantFuture(this);
return future;
} catch (Exception e) {
e.printStackTrace();
}
if (!userIsInTicket(creator)) users.add(creator);
return null;
}
I'm not sure what's going on inside commissionTicket.create(); (I assume it's your code, not part of some library, and that it's running asynchronously somehow), but one solution would be to have that method return a Future<> object and then wait on it to finish. Something along the lines of:
Future<CommissionTicket> commissionTicketFuture = CommissionTicket.create(sender);
commissionTicketFuture.get(SOME_TIMEOUT, TimeUnit.MILLIS);
return Response.NEW_TICKET_CREATED;

reducing number of return statements in a method

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

ConcurrentModificationException when edting the data in the arraylist to text file

private void btnOKActionPerformed(java.awt.event.ActionEvent evt)
{
try
{
if(txtStaffID.getText(0, 2).equals("AD"))
{
for(Admin admin:admincontrolpanel.adminList)
{
if(txtUsername.getText().equals("") || txtPassword.getText().equals("") || txtName.getText().equals("") || txtEmail.getText().equals("") || txtContactNumber.getText().equals("") || txtICNumber.getText().equals(""))
{
JOptionPane.showMessageDialog(null, "Please fill in the blank", "ERROR", JOptionPane.ERROR_MESSAGE);
}
else if(txtUsername.getText() != null && txtPassword.getText() != null && txtName.getText() != null && txtEmail.getText() != null && txtContactNumber.getText() != null && txtICNumber.getText() != null)
{
admin.setId(txtStaffID.getText());
admin.setUsername(txtUsername.getText());
admin.setPassword(txtPassword.getText());
admin.setName(txtName.getText());
admin.setEmail(txtEmail.getText());
admin.setContactNumber(txtContactNumber.getText());
admin.setIcNumber(txtICNumber.getText());
Admin newAdmin = new Admin(admin.getId(),admin.getUsername(),admin.getPassword(),admin.getName(),admin.getEmail(),admin.getContactNumber(),admin.getIcNumber());
admincontrolpanel.adminList.remove(admin);
admincontrolpanel.adminList.add(newAdmin);
}
}
JOptionPane.showMessageDialog(null, "Successfully Added!", "Add Staff", JOptionPane.PLAIN_MESSAGE);
dispose();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
Inside the text file got these data...
AD001|jeff|jeff|jeff|jeff#gmail.com|123456|123456
AD002|admin|admin|admin|admin#gmail.com|123456|123456
When I press OK button to edi...it shows me this ConcurrentModificationException error....Anyone can help me to take a look of it??
Admin is the class...adminList is the arraylist...
try
{
PrintWriter pw = new PrintWriter("Admin.txt");
for(Admin admin:admincontrolpanel.adminList)
{
pw.println(admin.getId() + "|" + admin.getUsername() + "|" + admin.getPassword() + "|" + admin.getName() + "|" + admin.getEmail() + "|" + admin.getContactNumber() + "|" + admin.getIcNumber());
}
pw.close();
}
catch(Exception e)
{
e.printStackTrace();
}
This is the code i want to write into the text file from arraylist....
then it gave me this kind of data inside the arraylist...can edit it..but deleted the 1st data and add a new data into it
AD002|admin|admin|admin|admin#gmail.com|123456|123456
AD002|admin|admin|admin|admin#gmail.com|999|123456
A quick search through SO would have quickly shown you possible solutions..you can use a standard for loop and loop until the previous list's size, instead of using an implicit Iterator the way you are:
ArrayList<Admin> = admincontrolpanel.adminList;
int adminListSize = adminList.size();
for(int i=0;i<adminListSize;i++) {
Admin admin = adminList.get(i);
Or you can use a ListIterator to loop through the list using an Iterator and modify it.
Also, admincontrolpanel is not a good variable name. Use camelCase.
for(Admin admin:admincontrolpanel.adminList)
Through this loop you are iterating adminList(ArrayList)
Admin newAdmin = new Admin(admin.getId(),admin.getUsername(),admin.getPassword(),admin.getName(),admin.getEmail(),
admin.getContactNumber(),admin.getIcNumber());
admincontrolpanel.adminList.remove(admin);
admincontrolpanel.adminList.add(newAdmin);
above in last two line you are removing and adding ArrayList item which is not allowed here because you already iterating ArrayList. you can not do iterating and modifying ArrayList at the same time here. thats why you are facing Concurrent..exception.
This problem may occur due to thread inside another thread. For example if your are executing some code in your first thread and along this you have another thread inside this thread. then this problem occur.

Categories