I have a palette who's model is populated by a user search of customers. This works perfectly when searching initially, however once a customer is selected and the user continues to search for more customers to select a NPE is thrown.
Code from .tml
<t:palette t:id="custSelect" model="customerModel" t:encoder="stringValueEncoder"
availableLabel="Search Results" t:selected="custSelected" value="custSelected">
${custSelected}
</t:palette>
Coresponding .java
Object listResults(List<TbgWebIntCustomer> customers) {
log.debug("LISTRESULTS");
customerList = new ArrayList<String>();
if (customerList != null) {
customerList.clear();
if (request.isXHR()) {
ajaxResponseRenderer.addRender(resultZone);
}
}
String result;
log.debug("LISTRESULTS2 " + customers.size());
for (int i = 0; i <= customers.size() - 1; i++) {
log.debug("counter: " + i);
TbgWebIntCustomer currentCustomer = customers.get(i);
String customerNumber = currentCustomer.getCustomerId();
// Remove leading zeros
String customerName = currentCustomer.getLocationName();
result = customerNumber + " - " + customerName + " - "
+ currentCustomer.getCity();
log.debug(result);
customerList.add(result);
}
log.debug("LISTRESULTS3");
log.debug("customer list size: " + customerList.size());
getCustomerModel();
log.debug("customermodel after customerlist: "
+ getCustomerModel().size());
if (customerList.size() == 100) {
resultsMessage = "Search returned over 100 results. Showing top 100.";
log.debug(resultsMessage);
} else {
String numResults = Integer.toString(customerList.size());
resultsMessage = "Search returned " + numResults + " customers";
log.debug(resultsMessage);
}
log.debug("LISTRESULTS4");
log.debug("customerModel returns at i 0: " + getCustomerModel().get(0));
return request.isXHR() ? resultZone.getBody() : null;
}
Note: getCustomerModel() returns getCustomerList().
I understand that NPEs in Palette happen when one of the selected options is not present in the model you passed to it however I can't identify where it is I'm doing this. I can post setupRender() code if necessary, just trying to keep OP compact.
Related
I'm testing a Spring Boot Service, and there's one pretty much weird function that needs to be tested. I've made a test that runs successfully, but I'm not getting much coverage. Here's a function I'm testing:
protected String setQueryListField(List<String> model, String fieldName) {
String query = "";
if (model.contains("is blank") && model.size() > 1) {
for (String value : model) {
if (value.equals("is blank")) {
query = query.concat(" AND (" + fieldName + " = null");
} else if (model.size() == 2) {
query = query.concat(" OR " + fieldName + " CONTAINS('" + value + "'))");
} else {
if (model.indexOf(value) == 1) {
query = query.concat(" OR " + fieldName + " CONTAINS('" + value + "', ");
} else if ((model.indexOf(value) + 1) == model.size()) {
query = query.concat("'" + value + "'))");
} else {
query = query.concat("'" + value + "', ");
}
}
}
} else if (model.contains("is blank") && model.size() == 1) {
query = query.concat(" AND " + fieldName + " = null");
} else {
query = query.concat(" AND " + fieldName + " CONTAINS('" + String.join("','", model) + "')");
}
return query;
}
And here is a test I wrote. It runs successfully, as I said, but I'd like to get more coverage. Do you have any suggestions?
#Test
#DisplayName("setQueryListField Test")
void setQueryListField() {
List<String> stringList = new ArrayList<>();
stringList.add("is blank");
VaultService vaultService = Mockito.spy(vaultServiceTest);
doReturn("", "").when(vaultService).setQueryListField(stringList, "field__name");
String response = vaultService.setQueryListField(stringList, "field__name");
System.out.println(response);
stringList.add("test");
String secondResponse = vaultService.setQueryListField(stringList, "external__c");
System.out.println(secondResponse);
}
You are only covering the following if block
else if (model.contains("is blank") && model.size() == 1) {
query = query.concat(" AND " + fieldName + " = null");
}
If you need more coverage you need to try with other inputs so that it covers other branches too. For example, with model.size() > 1.
Also, the following lines are no op as it's mocking the same function that you are trying to test.
VaultService vaultService = Mockito.spy(vaultServiceTest);
doReturn("", "").when(vaultService).setQueryListField(stringList, "field__name");
String response = vaultService.setQueryListField(stringList, "field__name");
Connection conn = SqlConnection.getConnection("jdbc:mysql://localhost:3306/stocks");
Statement statement = conn.createStatement();
File path = new File("/Users/Zack/Desktop/JavaDB/BALANCESHEETS");
for(File file: path.listFiles()) {
if (file.isFile()) {
String fileName = file.getName();
String ticker = fileName.split("\\_")[0];
if (ticker.equals("ASB") || ticker.equals("FRC")) {
if (ticker.equals("ASB")) {
ticker = ticker + "PRD";
}
if (ticker.equals("FRC")) {
ticker = ticker + "PRD";
}
}
//CSVReader reader = new CSVReader(new FileReader(file));
//List entries = reader.readAll();
//ArrayList<String> entry = new ArrayList<String>();
Reader reader = new BufferedReader(new FileReader(file));
StringBuilder builder = new StringBuilder();
int c;
while ((c = reader.read()) != -1) {
builder.append((char) c);
}
String string = builder.toString();
ArrayList<String> stringResult = new ArrayList<String>();
if (string != null) {
String[] splitData = string.split("\\s*,\\s*|\\n");
for (int i = 0; i <splitData.length; i++) {
if (!(splitData[i] == null) || !(splitData[i].length() ==0)) {
stringResult.add(splitData[i].trim());
}
}
}
String columnName = null;
int yearCount = 0;
for (int i = 0; i < stringResult.size(); i++) {
int sL = stringResult.get(i).length();
for (int x = 0; x < sL; x++) {
if (Character.isLetter(stringResult.get(i).charAt(x))) {
yearCount = 0;
System.out.println("index: " + i);
columnName = stringResult.get(i);
columnName = columnName.replace(" ", "_");
System.out.println(columnName);
i++;
break;
}
}
yearCount++;
String value = stringResult.get(i);
System.out.println("Year: " + stringResult.get(yearCount) + " Value: " + value + " Stock: " + ticker + " Column: " + columnName );
if (!(columnName == null)) {
String writeValues = "INSERT INTO BalanceSheet (ticker, Year, " + columnName + ") "
+ "VALUE ('" + ticker + "','" + stringResult.get(yearCount) + "','" + value + "')";
String writeValues2 = "UPDATE BalanceSheet "
+ "SET ticker = '" + ticker + "', "
+ "Year = '" + stringResult.get(yearCount) + "', "
+ columnName + " = '" + value + "' "
+ "WHERE ticker = '" + ticker + "'";
statement.executeUpdate(writeValues2);
}
}
Towards the bottom of the code are two queries I tried, I'm trying to get all data organized by ticker and year into a table, "writeColumns" works but it's making a new row for every new "value" put into "columnName". My second attempt "writeColumns2" doesn't do anything.
I want to update the same row with a certain year for all values and then move onto the next year, then next ticker.
If I have understood your question correctly, you want to insert a row if it doesn't exists but update the values if it already does. You need to use ON DUPLICATE KEY UPDATE
String writeValues = "INSERT INTO BalanceSheet (ticker, Year, " + columnName + ") "
+ "VALUES (?,?,?) "
+"ON DUPLICATE KEY UPDATE " + columnName +"=?";
Statement statement = conn.prepareStatement(writeValues);
statement.setString(1,ticker);
statement.setString(2,stringResult.get(yearCount));
statement.setString(3, value);
This will solve your immidiate problem provided you create a UNIQUE index on ticker,year
However there are lot's of other issues here.
An update for each column - Currently you are doing an insert/update for each column on the table. What you are supposed to do is to insert update all the columns at one.
You are not using prepared statements addressed in my code sample
You shouldn't be doing this at all the best way to batch process data is to use MYSQL's built in LOAD DATA INFILE command. If your data is not in a format that can be easily imported into mysql, what your Java code can do is to transform it into a format that can be. Such a code will be a lot simpler and neater than what you have now
I'm trying to make my own ORM framework. I get the values from object into arrayList and I'm trying to save them in one time. I have to make for loop to save them all, but I'm confused how to make it?
prepareteState = connect.prepareStatement(Query);
for (int y = 1; y <= obs.size() ; y++) {
for(Object obj : obs){
prepareteState.setObject(y, obj);
System.out.println(Query);
System.out.println(prepareteState.toString());
}
}
prepareteState.execute();
thanks for good advices but, i found the solution :) it is a little bit different than the first idea but, works fine for me:) instead of using prepareState and setObject one by one i`m using StringBuilder to make String and execute query
private String makeInsertQuery(List<String> listOfColumnsNames, List<Object> listOfParameters, String tableName){
StringBuilder columns = new StringBuilder();
StringBuilder parameters = new StringBuilder();
String query = null;
if(listOfColumnsNames != null && listOfColumnsNames.size() != 0 && listOfParameters != null && listOfParameters.size() != 0 && tableName != null){
for(String string : listOfColumnsNames){
columns.append(string + ",");
}
columns.deleteCharAt(columns.length() - 1);
for(Object object : listOfParameters){
parameters.append ("'" + object + "'" + ",");
}
parameters.deleteCharAt(parameters.length() - 1);
query = "INSERT " + "INTO " + tableName + " ( " + columns.toString() + " ) " + " VALUES " + "( " + parameters.toString() + " )" ;
}
//TODO if you need check for null
return query;
}
I have created html table in mail body using below code
st = con.createStatement();
rs = st.executeQuery("SELECT nvl(tt.ACTIVITY_NAME,'') as ACTIVITY_NAME, "
+ " nvl(tt.TL_NAME,'') TL_NAME, "
+ " nvl(tt.UW_NAME,'') UW_NAME, "
+ " nvl(tt.TAT_1,'') TAT_1,"
+ " nvl(tt.TAT_2,'') TAT_2, "
+ " nvl(tt.TAT_3,'') TAT_3, "
+ " nvl(tt.TAT_4,'') TAT_4, "
+ " nvl(tt.TAT_4_PLUS ,'') TAT_4_PLUS, "
+ " nvl(tt.g_total ,'') AS GRAND_TOTAL "
+ " FROM uw_activity_tl_uw_tat tt "
+ " WHERE tt.ACTIVITY_NAME = 'First UW' "
+ " ORDER BY tt.TL_NAME,tt.UW_NAME");
StringBuffer sb = new StringBuffer();
ResultSetMetaData rsmd = rs.getMetaData();
int numColumns = rsmd.getColumnCount();
for (int i = 1; i < numColumns + 1; i++) {
String columnName = rsmd.getColumnName(i);
sb.append("<th bgcolor=#fcbe07>" + columnName + "</th>");
}
ArrayList<String> a = new ArrayList<String>();
while (rs.next()) {
a.add(rs.getString(3));
if (rs.getRow() % 2 == 0) {
sb.append("<tr bgcolor=#fcf6cf>");
for (int i = 1; i < numColumns + 1; i++) {
if (rs.getString(i) == null) {
if(i==3)
{
sb.append("<td bgcolor=#fcbe07><b>"+ " "+ "</b></td>");
}
} else {
if (i == 6 || i == 7 || i == 8)
sb.append("<td><FONT COLOR=#ff0000>"
+ rs.getString(i) + "</FONT></td>");
else if(i==3 && (rs.getString(3).equalsIgnoreCase("") || rs.getString(3)==null)){
sb.append("<td bgcolor=#fcbe07><b>"+ rs.getString(i) + "</b></td>");
}else{
sb.append("<td>" + rs.getString(i) + "</td>");
}
}
}
sb.append("</tr>");
} else {
sb.append("<tr>");
for (int i = 1; i < numColumns + 1; i++) {
if (rs.getString(i) == null) {
if(i==3)
{
sb.append("<td bgcolor=#fcbe07><b>"+ " " + "</b></td>");
}
} else {
if (i == 6 || i == 7 || i == 8)
sb.append("<td><FONT COLOR=#ff0000>"
+ rs.getString(i) + "</FONT></td>");
else if(i==3 && (rs.getString(3).equalsIgnoreCase("") || rs.getString(3)==null)){
sb.append("<td bgcolor=#fcbe07><b>"+ rs.getString(i) + "</b></td>");
}else{
sb.append("<td>" + rs.getString(i) + "</td>");
}
}
}
sb.append("</tr>");
}
}
String html = "<html>" + message.getSubject()
+ "</title></head><body><table border=\"1\">"
+ sb.toString() + "</table></body></html>";
message.setContent(html, "text/html");
In the image only one cell is highlighted and I want to highlight the entire row which has any empty cell.Please guide. My query is how to highlight the entire row if any cell is empty.
Short answer: Move the check for the third column and change the <tr> line.
Truthfully, the code you have is a bit of a mess. Personally, I would make the following changes that will make maintence so much easier:
Switch to using classes instead of hard coding bgcolors and so forth.
Set up your system to return associative arrays instead of numeric arrays. That will make reading the code after a lot easier.
Set up intermediate variables to hold the values returned. Do any and all of your calculations and settings things there. THEN dump the entire table-row in one go. That separates your "functional" code from your "display code."
However, in a pinch, something like this will get you going:
tmp = rs.getString(3);
if (tmp == null) {
sb.append("<tr bgcolor=#ffffff>");
} else {
sb.append("<tr bgcolor=#fcf6cf>");
}
BTW - the HTML you generate isn't valid.
Of the top of my head
boolean cellNull = false;
while(rs.next()){
cellNull = false;
cellNull = checkIfAnyFieldIsNull(rs);
if(cellNull)
sb.append("<tr bgcolor=\"#WTH\">");
else
sb.append("<tr>");
//create rest of the row content here
}
private boolean checkIfAnyFieldIsNull(ResultSet rs){
for(i=0 etc..){
if(rs.getString(i) == null)
return true;
}
return false;
}
One way of doing it would be as follows:
Create a POJO class with all the columns that you want to display. Also have a boolean variable, say empty. Set it to true, if any of your column is null
Create a ArrayList and add each instance of your class as you iterate through your resultset
Now use this ArrayList to render your output. Since you already have the boolean variable availabe, you can use this value to set the background color of your row.
I'm trying to write a simple method, that gets events from Google calendar. The problem is that if i'm trying to call getTimes() on my events, i get an Indexoutofbounds exception.
I just can't figure out what the problem is.
Thanks in advance :)
jTextArea1.setText("");
try {
CalendarService myService = new CalendarService("myApp");
myService.setUserCredentials(username, password);
String eventTitle = "";
for (URL u : urls) {
CalendarQuery myQuery = new CalendarQuery(u);
myQuery.setMinimumStartTime(convertStartDateToDateTime());
myQuery.setMaximumStartTime(convertEndDateToDateTime());
myQuery.setFullTextQuery(searchTF.getText());
CalendarEventFeed resultFeed = myService.query(myQuery, CalendarEventFeed.class);
// System.out.println(resultFeed.getTitle().getPlainText());
for (int i = 0; i < resultFeed.getEntries().size(); i++) {
CalendarEventEntry entry = resultFeed.getEntries().get(i);
if (resultFeed.getEntries().size() > 0) {
jTextArea1.setText(jTextArea1.getText()
+ resultFeed.getTitle().getPlainText()
+ "\n");
eventTitle = resultFeed.getEntries().get(i).getTitle().getPlainText();
jTextArea1.setText(jTextArea1.getText() + eventTitle + "\n");
jTextArea1.setText(jTextArea1.getText()
+ "Start: " + resultFeed.getEntries().get(i).getTimes().get(i).getStartTime().toString() + "\n"
+ "Slut: " + resultFeed.getEntries().get(i).getTimes().get(i).getEndTime().toString() + "\n");
}
jTextArea1.setText(jTextArea1.getText() + "\n");
}
}
My guess is something is wrong with your second get(i),
resultFeed.getEntries().get(i).getTimes().get(i).getStartTime().toString()
While the first "i" in the get(i) is guaranteed to work because of i < resultFeed.getEntries().size(); condition in the for loop, the second "i" in the get(i) doesn't have any condition to check its range.
Kindly Post your full exception trace if this isn't your problem.