Parameterized runner class with 2 arguments in constructor - java

I wish to use a Parameterized Junit class to read from a .csv file. I want to:-
Read a 'placeID' (a String) and append it to a base url to form a webpage
Assert that the Place name 'name' (a String) is as I expect it to be for the place
The tab delimited .csv file contains 2 records as follows (will have 100's records eventually):
132
The Big House
I'm currently getting an Illegal argument exception. What's a slicker way of achieving this? I guess having the relative URL and then test data in seperate files would be better.
My code:
#RunWith(Parameterized.class)
public class PlaceTest {
public static WebDriver driver;
private String placeId;
private String name;
private PropertyPage propertyPage;
public PlaceTest(String page, String name) {
this.placeId = page;
this.name = name;
}
#Parameterized.Parameters
public static Collection data() {
return csvFileAsCollectionOfStringArrays(
System.getProperty("user.dir") +
"/src/test/resources/" +
"place_ids.csv");
}
private static Collection<String[]> csvFileAsCollectionOfStringArrays(String csvFileName) {
List<String[]> csvRows = new ArrayList<String[]>();
String rawCSVRow;
BufferedReader csvFileReader = null;
String delimiter = "\t";
System.out.println("Reading data from " + csvFileName);
try {
csvFileReader = new BufferedReader(new FileReader(csvFileName));
} catch (FileNotFoundException e) {
System.out.println("Could not find file " + csvFileName);
e.printStackTrace();
}
int rowNumber = 1;
try {
if (csvFileReader != null) {
while ((rawCSVRow = csvFileReader.readLine()) != null) {
String delimitedItems[] = rawCSVRow.split(delimiter);
csvRows.add(delimitedItems);
rowNumber++;
}
}
} catch (IOException e) {
System.out.println("Error reading row number " + rowNumber);
e.printStackTrace();
}
try {
assert csvFileReader != null;
csvFileReader.close();
} catch (IOException e) {
System.out.println("Error closing file " + e.getMessage());
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
return csvRows;
}
#BeforeClass
public static void startDriver() {
driver = Driver.get();
}
#Before
public void getNextPage() {
propertyPage = new PropertyPage(driver);
driver.get(TestWebApp.getURL() + this.placeId);
}
#Test
public void checkNamePresent() {
WebElement placeName = propertyPage.checkName();
assertEquals("Expected match on name", this.name, placeName.getText());
}
#AfterClass
public static void quitDriver() {
driver.quit();
}
}

Try this:
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import au.com.bytecode.opencsv.CSVReader;
#RunWith(Parameterized.class)
public class PlaceTest {
private String placeId;
private String name;
public PlaceTest(String page, String name) {
this.placeId = page;
this.name = name;
}
#Parameterized.Parameters
public static Collection<String[]> data() {
CSVReader reader = new CSVReader(new InputStreamReader(PlaceTest.class.getResourceAsStream("place_ids.csv")));
List<String[]> lines;
try {
lines = reader.readAll();
return lines;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return new ArrayList<String[]>();
}
#Test
public void checkNamePresent() {
System.out.println(this.placeId + " " + this.name);
}
}
The place_ids.csv has to be in: \src\test\resources\<your package>\place_ids.csv
Update your pom with CSVReader dependency:
<dependency>
<groupId>net.sf.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>2.3</version>
</dependency>
Update:
csv file:
132, Some text
133, Other text
Your example above has one word per line. The code above was compile and tested.

Related

ACE IBM Reading XLSX Excel with java compute node

im new in ACE. I want to create a flow that reads xlsx excel file using java and prints it to the database. Which nodes should I use for this task and is it correct to use only this java compute code as java code?
/*
JAR files to be added to shared-classes folder under server or integration node dir:
dom4j-1.6.1.jar
names.txt
poi-3.9-20121203.jar
poi-ooxml-3.9-20121203.jar
poi-ooxml-schemas-3.9-20121203.jar
xmlbeans-2.3.0.jar
*/
import com.ibm.broker.javacompute.MbJavaComputeNode;
import com.ibm.broker.plugin.MbElement;
import com.ibm.broker.plugin.MbException;
import com.ibm.broker.plugin.MbMessage;
import com.ibm.broker.plugin.MbMessageAssembly;
import com.ibm.broker.plugin.MbOutputTerminal;
import com.ibm.broker.plugin.MbUserException;
import com.ibm.broker.plugin.MbXMLNSC;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class ParseExcel extends MbJavaComputeNode {
public void evaluate(MbMessageAssembly inAssembly) throws MbException {
MbOutputTerminal out = getOutputTerminal("out");
// MbOutputTerminal alt = getOutputTerminal("alternate");
MbMessage inMessage = inAssembly.getMessage();
MbMessageAssembly outAssembly = null;
try {
// create new message as a copy of the input
MbMessage outMessage = new MbMessage(inMessage);
outAssembly = new MbMessageAssembly(inAssembly, outMessage);
// ----------------------------------------------------------
// Add user code below
// get InputBody
MbElement inputBlob = inAssembly.getMessage().getRootElement().getLastChild();
byte[] originalMsgByteArray = (byte[])inputBlob.getLastChild().getValue();
InputStream stream = new ByteArrayInputStream(originalMsgByteArray);
parseXLSX(stream, outMessage);
// End of user code
// ----------------------------------------------------------
} catch (MbException e) {
// Re-throw to allow Broker handling of MbException
throw e;
} catch (RuntimeException e) {
// Re-throw to allow Broker handling of RuntimeException
throw e;
} catch (Exception e) {
// Consider replacing Exception with type(s) thrown by user code
// Example handling ensures all exceptions are re-thrown to be handled in the flow
throw new MbUserException(this, "evaluate()", "", "", e.toString(),
null);
}
// The following should only be changed
// if not propagating message to the 'out' terminal
out.propagate(outAssembly);
}
public void parseXLSX(InputStream fis, MbMessage outMessage){
try {
MbElement outRoot = outMessage.getRootElement();
// create XMNLSC parser
MbElement outBody = outRoot.createElementAsLastChild(MbXMLNSC.PARSER_NAME);
// Create root element.
MbElement excelRoot = outBody.createElementAsLastChild(MbElement.TYPE_NAME, "excel", null);
DataFormatter formatter = new DataFormatter();
XSSFWorkbook wb = new XSSFWorkbook(fis);
XSSFSheet sheet1 = wb.getSheetAt(0);
for (Row row : sheet1) {
// create a row element for current excel row.
MbElement rowMsgElement = excelRoot.createElementAsLastChild(MbElement.TYPE_NAME, "row", null);
for (Cell cell : row) {
// get cell value as text
String text = formatter.formatCellValue(cell);
// create an element called cell in output message with value as cell value
rowMsgElement.createElementAsLastChild(MbElement.TYPE_NAME,"cell",text);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
I tried to add 2 java project in independent resources which reads the excel correctly but i dont know how to add them into flow.First code introduces the table and writes excel to console:
public class GFKTable {
private String reportingProductGroup;
private String region;
private String year;
private String month;
private String brand;
private int salesUnits;
private float salesUnitPercentage;
public GFKTable(){}
public GFKTable(String reportingProductGroup, String region, String year, String month,
String brand,int salesUnits,float salesUnitPercentage) {
super();
this.reportingProductGroup = reportingProductGroup;
this.region = region;
this.year = year;
this.month = month;
this.brand = brand;
this.salesUnits = salesUnits;
this.salesUnitPercentage =salesUnitPercentage;
}
#Override
public String toString() {
return "GFK Table[reportingProductGroup=" + reportingProductGroup + ", region=" +region+", year=" + year + ", month=" + month
+ ", brand=" + brand + ", salesUnits="+salesUnits+", salesUnitPercentage="+salesUnitPercentage+"]";
}
public String getReportingProductGroup() {
return reportingProductGroup;
}
public void setReportingProductGroup(String reportingProductGroup) {
this.reportingProductGroup = reportingProductGroup;
}
public String getRegion() {
return region;
}
public void setRegion(String region) {
this.region= region;
}
public String getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}
public String getMonth() {
return month;
}
public void setMonth(String month) {
this.month = month;
}
public String getBrand(String brand) {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public int getSalesUnits(int salesUnits) {
return salesUnits;
}
public void setSalesUnits(int salesUnits) {
this.salesUnits = salesUnits;
}
public float getSalesUnitPercentage(float salesUnitPercentage) {
return salesUnitPercentage;
}
public void setSalesUnitPercentage(float salesUnitPercentage) {
this.salesUnitPercentage = salesUnitPercentage;
}
}
second code reads the xlsx excel
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class ReadXLSX {
public static void main(String[] args) {
List<GFKTable> gfkList = readXLSXFile("C:\\Users\\Y9GAMF862\\Desktop\\GFKbosluksuz.xlsx");
for(GFKTable gfk : gfkList){
System.out.println(gfk);
}
}
private static List<GFKTable> readXLSXFile(String file) {
List<GFKTable> listGfk = new ArrayList<GFKTable>();
try {
XSSFWorkbook work = new XSSFWorkbook(new FileInputStream(file));
XSSFSheet sheet = work.getSheet("Sheet1");
XSSFRow row;
int i=1;
int salesUnit;
String reportingProductGroup,region,month,brand,year;
float salesUnitPercentage;
while((row = sheet.getRow(i))!=null){
try{
reportingProductGroup = row.getCell(0).getStringCellValue();
}
catch(Exception e){reportingProductGroup = null;}
try{
region = row.getCell(1).getStringCellValue();
}
catch(Exception e){region = null;}
try{
year = row.getCell(2).getStringCellValue();
}
catch(Exception e){year = null;}
try{
month = row.getCell(3).getStringCellValue();
}
catch(Exception e){month = null;}
try{
brand = row.getCell(4).getStringCellValue();
}
catch(Exception e){brand= null;}
try{
salesUnit = (int) row.getCell(5).getNumericCellValue();
}
catch(Exception e){salesUnit = 0;}
try{
salesUnitPercentage = (float) row.getCell(6).getNumericCellValue();
}
catch(Exception e){salesUnitPercentage = 0;}
GFKTable gfk = new GFKTable(reportingProductGroup,region,year,month,brand,salesUnit,salesUnitPercentage);
listGfk.add(gfk);
i++;
}
work.close();
} catch (IOException e) {
System.out.println("Exception is GFKTable fetch data :: "+e.getMessage());
e.printStackTrace();
}
return listGfk;
}
}
also i used these JAR Files for them:
commons-codec 1.15
commons-collections4-4.4
commons-compress-1.21
commons-io-2.11.0
commons-math3-3.6.1
curvesapi-1.07
log4j-api-2.18.0
log4j-to-slf4j-2.8.2
poi-5.2.3
poi-ooxml-5.2.3
poi-ooxml-lite-5.2.3
slf4j-api-1.7.5
slf4j-simple-1.6.4
SparseBitSet-1.2
xmlbeans-5.1.1

Add data to specific record in CSV file

I have a record in a CSV file and i am trying to add some extra info (a name) to the same specific record with the following code but it does not work. There is no error shown but the info i am trying to add just does not appear. What am i missing ?
public class AddName {
public static void main(String[] args) {
String filepath="Zoo.csv";
String editTerm="Fish";
String addedName="Ron";
addToRecord(filepath,editTerm,addedName);
}
public static void addToRecord(String filepath,String editTerm,String addedName){
String animal= "";
try{
FileWriter fw=new FileWriter(filepath,true);
BufferedWriter bw=new BufferedWriter(fw);
PrintWriter pw=new PrintWriter(bw);
if (animal.equals(editTerm)){
pw.println(editTerm+","+addedName);
pw.flush();
pw.close();
}
System.out.println("Your Record was saved");
}
catch(Exception e){
System.out.println("Your Record was not saved");
e.printStackTrace();
}
}
You could consider using a CSV library to help you out with parsing CSVs because it is more complicated than it looks, especially when it comes down to quoting.
Here's a quick example using OpenCSV that clones the original CSV file and adds "Ron" as necessary:
public class Csv1 {
public static void main(String[] args) throws IOException, CsvValidationException {
addToRecord("animal.csv", "animal-new.csv", "fish", "Ron");
}
public static void addToRecord(String filepathIn, String filepathOut, String editTerm, String addedName)
throws IOException, CsvValidationException {
try (CSVReader reader = new CSVReader(new FileReader(filepathIn))) {
try (CSVWriter writer = new CSVWriter(new FileWriter(filepathOut))) {
String[] values;
while ((values = reader.readNext()) != null) {
if (values.length > 2 && values[0].equals(editTerm)) {
values[1] = addedName;
}
writer.writeNext(values);
}
}
}
}
}
Given the file:
type,name,age
fish,,10
cat,,12
lion,tony,10
will produce:
"type","name","age"
"fish","Ron","10"
"cat","","12"
"lion","tony","10"
(You can look for answers about outputting quotes in the resulting CSV)
Here the requirement is to add an extra column if the animal name matches. It's equivalent to changing a particular line in a file. Here's a simple approach to achieve the same, (Without using any extra libraries),
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
public class EditLineInFile {
public static void main(String[] args) {
String animal = "Fish";
Path path = Paths.get("C:\\Zoo.csv");
try {
List<String> allLines = Files.readAllLines(path);
int counter = 0;
for (String line : allLines) {
if (line.equals(animal)) {
line += ",Ron";
allLines.set(counter, line);
}
counter++;
}
Files.write(path, allLines);
} catch (IOException e) {
e.printStackTrace();
}
}
}
You may use this code to replace the file content "Fish" to "Fish, Ron"
public static void addToRecord(String filepath, String editTerm, String addedName) {
try (Stream<String> input = Files.lines(Paths.get(filepath));
PrintWriter output = new PrintWriter("Output.csv", "UTF-8"))
{
input.map(s -> s.replaceAll(editTerm, editTerm + "," + addedName))
.forEachOrdered(output::println);
} catch (IOException e) {
e.printStackTrace();
}
}

How to get list of variable names from Java file?

How can I get the list of variables from a Java file? So far, I've started by reading the file and splitting each word using spaces. unfortunately, this returns all import statements, comments..etc
public ArrayList<String> getVariables(String javaFilePath) {
ArrayList<String> variableList = new ArrayList<String>();
BufferedReader br;
try {
// creating a buffer reader from the file path
br = new BufferedReader(new FileReader(new File(javaFilePath)));
String line;
while ((line = br.readLine()) != null) {
String[] variables = line.split("\\s+");
for (String variable : variables) {
variableList.add(variable);
}
}
br.close();
} catch (FileNotFoundException e) {
logger.error("This is FileNotFoundException error : " + e.getMessage());
} catch (IOException e) {
logger.error("This is IOException error : " + e.getMessage());
}
return variableList;
}
For example: I've java file saved on C:\Sample.java. And it's code looks like this:
package com.test;
import java.io.File;
import java.io.FileInputStream;
public class Sample {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
And the output using the above method returns the following:
package
com.test;
import
java.io.File;
import
java.io.FileInputStream;
public
class
Sample
{
String
name;
public
String
getName()
{
return
name;
}
public
void
setName(String
name)
{
this.name
=
name;
}
}
Question: how do I modify my method shown above in order to get only variables. For example: I want only "name" & "Sample" for the above class.

How do I fix Illegal Start of Expressions with all of my methods?

I have my code. I think it's all right, but it is not. It keeps telling me at the beginning of each method that there is a ';' expected and it's also an 'illegal start of expression' with the void. I do not know how to fix it. Can someone please help me fix these errors?
Here's an example of the Errors:
F:\COMP SCI\Topic 29 - Data Structures -- Robin Hood\Problem Set\RobinHoodApp.java:203: error: ';' expected
void arrayList **()** throws FileNotFoundException();
F:\COMP SCI\Topic 29 - Data Structures -- Robin Hood\Problem Set\RobinHoodApp.java:212: error: illegal start of expression
**void** output()
F:\COMP SCI\Topic 29 - Data Structures -- Robin Hood\Problem Set\RobinHoodApp.java:212: error: ';' expected
void output **()**
My code:
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import static java.lang.System.out;
import java.util.ArrayList;
import javax.swing.JFrame;
public class RobinHoodApp{
public static void main(String[] args) throws FileNotFoundException, IOException {
RobinHood app = new RobinHood();
app.readFile();
app.arrayList();
app.wordCount();
app.countMenAtArms();
app.writeToFile();
}
}
class RobinHood extends JFrame
{
private static final ArrayList<String>words = new ArrayList<>();
private static Scanner book;
private static int count;
private static int wordCount;
public RobinHood()
{
try {
// scrubber();
//Prints All Words 1 by 1: Works!
book = new Scanner(new File("RobinHood.txt") );
book.useDelimiter("\r\n");
} catch (FileNotFoundException ex)
{
out.println("Where's your text fam?");
}
}
void readFile()
{
while(book.hasNext())
{
String text = book.next();
out.println(text);
}
void arrayList() throws FileNotFoundException();
{
Scanner add = new Scanner(new File("RobinHood.txt"));
while(add.hasNext())
{
words.add(add.next());
}
}
void output()
{
out.println(words);
}
void countMenAtArms()
{
//Shows 23 times
String find = "men-at-arms";
count = 0;
int x;
String text;
for(x=0; x< wordCount; x++ )
{
text = words.get(x);
text = text.replaceAll("\n", "");
text = text.replaceAll("\n", "");
if (text.equals(find))
{
count++;
}
}
out.println("The amount of time 'men-at-arms' appears in the book is: " + count);
}
// void scrubber()
// {
//
// }
//
//
void wordCount()
{
{
wordCount=words.size();
out.println("There are "+wordCount+" words in Robin Hood.");
}
}
public void writeToFile()
{
File file;
file = new File("Dominique.dat");
try (FileOutputStream data = new FileOutputStream(file)) {
if ( !file.exists() )
{
file.createNewFile();
}
String wordCountSentence = "There are "+ wordCount +" words in Robin Hood. \n";
String countTheMen = "The amount of time 'men-at-arms' appears in the book is: " + count;
byte[] strToBytes = wordCountSentence.getBytes();
byte[] menToBytes = countTheMen.getBytes();
data.write(strToBytes);
data.write(menToBytes);
data.flush();
data.close();
}
catch (IOException ioe)
{
System.out.println("Error");
}
}
}
}
You should use a Java IDE like Eclipse when programming Java, it would point out to you the most obvious mistakes in your code.
You missed a } after the while loop for your readFile() method (thanks to Sweeper for this one).
The syntax in your arrayList() method is wrong.
void arrayList() throws FileNotFoundException(); {
No semicolon at the end of this defintion, no parenthesis at the end too, you are describing the class, not a method. Here is the correct way:
void arrayList() throws FileNotFoundException {
1 useless } at the end of your class file.
Find below your code, with a proper layout and without syntax errors. Please use an IDE next time, that would avoid you an awful lot of trouble.
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import static java.lang.System.out;
import java.util.ArrayList;
import javax.swing.JFrame;
public class RobinHoodApp {
public static void main(String[] args) throws FileNotFoundException, IOException {
RobinHood app = new RobinHood();
app.readFile();
app.arrayList();
app.wordCount();
app.countMenAtArms();
app.writeToFile();
}
}
class RobinHood extends JFrame
{
private static final ArrayList<String>words = new ArrayList<>();
private static Scanner book;
private static int count;
private static int wordCount;
public RobinHood()
{
try {
// Prints All Words 1 by 1: Works!
book = new Scanner(new File("RobinHood.txt") );
book.useDelimiter("\r\n");
} catch (FileNotFoundException ex)
{
out.println("Where's your text fam ?");
}
}
void readFile()
{
while(book.hasNext())
{
String text = book.next();
out.println(text);
}
}
void arrayList() throws FileNotFoundException
{
Scanner add = new Scanner(new File("RobinHood.txt"));
while(add.hasNext())
{
words.add(add.next());
}
}
void output()
{
out.println(words);
}
void countMenAtArms()
{
// Shows 23 times
String find = "men-at-arms";
count = 0;
int x;
String text;
for(x=0; x< wordCount; x++ )
{
text = words.get(x);
text = text.replaceAll("\n", "");
text = text.replaceAll("\n", "");
if (text.equals(find))
{
count++;
}
}
out.println("The amount of time 'men-at-arms' appears in the book is: " + count);
}
void wordCount()
{
{
wordCount=words.size();
out.println("There are "+wordCount+" words in Robin Hood.");
}
}
public void writeToFile()
{
File file;
file = new File("Dominique.dat");
try (FileOutputStream data = new FileOutputStream(file)) {
if ( !file.exists() )
{
file.createNewFile();
}
String wordCountSentence = "There are "+ wordCount +" words in Robin Hood. \n";
String countTheMen = "The amount of time 'men-at-arms' appears in the book is: " + count;
byte[] strToBytes = wordCountSentence.getBytes();
byte[] menToBytes = countTheMen.getBytes();
data.write(strToBytes);
data.write(menToBytes);
data.flush();
data.close();
}
catch (IOException ioe)
{
System.out.println("Error");
}
}
}
throws FileNotFoundException();
This should be
throws FileNotFoundException
and similarly in all cases.
Rather trivial. Don't just make up the syntax. Look it up.

Weird error when using foreach loop in java

I am working on a little todolist-program and i'm getting a weird bug that i never had before. I have 4 classes: 1 POJO class that contains the todo-data:
public class Todo implements Comparable {
private String title;
private String task;
private boolean done;
public Todo(String title, String task) {
this.title = title;
this.task = task;
}
public String getTitle() {
return title;
}
public void setTitle(String newTitle) {
title = newTitle;
}
public String getTask() {
return task;
}
public void setTask(String newTask) {
task = newTask;
}
public boolean isDone() {
return done;
}
public void setDone(boolean isDone) {
done = isDone;
}
public int compareTo(Object obj) {
Todo todo = (Todo) obj;
return getTitle().compareTo(todo.getTitle());
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Todo {\n");
sb.append("Title: \"");
sb.append(getTitle() + "\";\n");
sb.append("Task: \"");
sb.append(getTask() + "\";\n");
sb.append("}");
return sb.toString();
}
}
Then I have a class that stores and loads my todos:
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class ListStorage {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
FileWriter writer;
BufferedReader reader;
public void storeList(List list, String filename) throws IOException {
String json = gson.toJson(list);
writer = new FileWriter(filename);
writer.write(json);
writer.close();
}
public List loadList(String filename) throws FileNotFoundException {
reader = new BufferedReader(new FileReader(filename));
List list = gson.fromJson(reader, List.class);
return list;
}
}
Then I have a 'Manager' class that is basically my controller:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Manager {
private List<Todo> todos = new ArrayList<>();
private ListStorage storage = new ListStorage();
public List getTodos() {
return todos;
}
public void setTodos(List newTodos) {
todos = newTodos;
}
public ListStorage getStorage() {
return storage;
}
public void add(String title, String task) {
todos.add(new Todo(title, task));
sort();
try {
storage.storeList(todos, "todos");
} catch(Exception e) {
e.printStackTrace();
}
}
public void remove(int index) {
todos.remove(index);
sort();
try {
storage.storeList(todos, "todos");
} catch(Exception e) {
e.printStackTrace();
}
}
private void sort() {
Collections.sort(todos);
}
}
And finally there is my main-class for testing my code (The bug seems to be here):
class CLITodo {
public static void main(String[] args) {
Manager man = new Manager();
man.add("Hello", "Bye");
man.add("Foo", "Bar");
try {
man.setTodos(man.getStorage().loadList("todos"));
} catch(Exception e) {
}
java.util.List<Todo> todos = man.getTodos();
for (Todo t : todos) {
System.out.println(t);
}
}
}
The error message I get when I leave the <Todo> in CLITodo class is:
Exception in thread "main" java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to Todo at CLITodo.main(CLITodo.java:13)
When I remove <Todo> in CLITodo I get this error:
CLITodo.java:13:19: error: incompatible types
for (Todo t : todos) {
^
required: Todo
found: Object
Why does this error occur? My Manager classes getTodos()-Method returns a List of type Todo yet the compiler tells me that it is just an Object (which it is of course but it is a collection as well, which should actually work).
This is the first time this error occured and I really can't seem to find what is causing it.
When you don't specify what nested type to use to deserialize your JSON, like you do here
List list = gson.fromJson(reader, List.class); // All it knows is that the root json is a List
Gson uses LinkedTreeMap.
What you really want is
List list = gson.fromJson(reader, new TypeToken<List<Todo>>(){}.getType());

Categories