My Xml Should look like:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<results>
<version>1.0</version>
<status>ok</status>
<lastUpdate>2011-11-21 09:23:59.0</lastUpdate>
<total>2</total>
<row>
<areaId></areaId>
<nameEng></nameEng>
<nameGer></nameGer>
</row>
… more <row></row> blocks …
</results>
How can i achieve this..?
At the moment i have the following.. but i dont know how i can return the album2 to the outputstream as a String...
List<Row> rows = new ArrayList<Row>();
while(rs.next()){
int albumId = rs.getInt(1);
int bookDocId = rs.getInt(2);
String picUrl = rs.getString(3);
String descEng = rs.getString(4);
String descGer = rs.getString(5);
Row row = new Row();
row.setAlbumId(albumId);
row.setBookDocId(bookDocId);
row.setPicUrl(picUrl);
row.setDescEng(descEng);
row.setDescGer(descGer);
rows.add(row);
}
Album album = new Album();
album.setRows(rows);
File file = new File("album.xml");
JAXB.marshal(album, file);
Album album2 = JAXB.unmarshal(file, Album.class);
file.deleteOnExit();
EDIT:
#XmlRootElement
public class Album {
private List<Row> rows = new ArrayList<Row>();
#XmlElement(name="row")
public List<Row> getRows(){
return this.rows;
}
public void setRows(List<Row> rows){
this.rows = rows;
}
Row.class:
public class Row {
private int albumId;
private int bookDocId;
private String picUrl;
private String descEng;
private String descGer;
public int getAlbumId() {
return albumId;
}
public int getBookDocId() {
return bookDocId;
}
public String getPicUrl() {
return picUrl;
}
public String getDescEng() {
return descEng;
}
public String getDescGer() {
return descGer;
}
public void setAlbumId(int albumId) {
this.albumId = albumId;
}
public void setBookDocId(int bookDocId) {
this.bookDocId = bookDocId;
}
public void setPicUrl(String picUrl) {
this.picUrl = picUrl;
}
public void setDescEng(String descEng) {
this.descEng = descEng;
}
public void setDescGer(String descGer) {
this.descGer = descGer;
}
}
}
This is my code, it works well
#javax.xml.bind.annotation.XmlType
#javax.xml.bind.annotation.XmlAccessorType(javax.xml.bind.annotation.XmlAccessType.FIELD)
public class Album
{
long version;
String status;
java.util.List<Row> rows;
}
#javax.xml.bind.annotation.XmlType
#javax.xml.bind.annotation.XmlAccessorType(javax.xml.bind.annotation.XmlAccessType.FIELD)
public class Row
{
String areaId;
String nameEng;
String nameGer;
}
Test
public static void main(final String[] args) throws IOException
{
Album al = new Album();
List<Row> rows = new ArrayList<Row>();
final Row row1 = new Row();
row1.areaId = "area1";
row1.nameEng = "eng1";
row1.nameGer = "ger1";
final Row row2 = new Row();
row2.areaId = "area2";
row2.nameEng = "eng2";
row2.nameGer = "ger2";
rows.add(row2);
rows.add(row1);
al.status = "stat";
al.rows = rows;
final File file = new File("D:/test.xml");
final FileOutputStream out = new FileOutputStream(file);
JAXB.marshal(al, out);
final Album after = JAXB.unmarshal(file, Album.class);
assert after.status.equals(al.status);
assert after.rows.size() == al.rows.size();
}
You can change access to private and add getters, setters
To return like String use
ByteArrayOutputStream output = new ByteArrayOutputStream();
JAXB.marshal(al, output);
output.toString();
If you're asking how to write an Album to an output stream rather than write it to a file, then the answer is simple: JAXB.marshal(Object, OutputStream).
If you're asking how to transform an Album into an XML string, then the answer is also simple: JAXB.marshal(Object, String).
If you're asking something else, please clarify your question.
Related
I have a Java class which uses BufferedReader to obtain information from a text file, then store the information into an Array called newData . I want to store a certain part of the information to the VegTypes[f] = new VegType(); but I not sure what code should I write here to obtain that part of information.
Without completing this part, I am not able to continue working on another Array Object which is Vegs[i] = new Veg(newData[0], newData[1], newData[2],); for storing information together with VegTypes Array Object.
Below is my code of the Java class:
public class theVegetable {
private Veg[] Vegs;
private VegType[] VegTypes;
public theVegetable() {
int quantity;
int vegQuantity;
String vegLine;
try {
BufferedReader br = new BufferedReader(new FileReader("vegetableInfo.txt"));
quantity = Integer.parseInt(vegLine.readLine());
Vegs = new Veg[quantity];
for (int i = 0; i < quantity; i++) {
vegLine = br.readLine();
String[] newData = vegLine.split(";");
vegQuantity = Integer.parseInt(newData[3]);
//For loop to store information into VegTypes
for (int f = 0; j < vegQuantity; f++) {
VegTypes[f] = new VegType();
}
//Vegs Array Object to store information plus VegTypes
Vegs[i] = new Veg(newData[0], newData[1], newData[2],);
}
br.close();
} catch (FileNotFoundException e) {
System.out.println("File not found.");
}
}
}
Below is my vegetableInfo.txt text file:
3
Tomato;class1;Malaysia Tomato;2;MT100A;MT1;200;90;MT20A;MT2;600;80;Malaysia product
Avocado;class2;Europe Avocado;4;EA100A;EA1;300;90;EA14A;EA2;90;80;EA230A;EA3;43;50.9;EA470A;EA4;400;76;Europe product
Cabbage;class3;Malaysia Cabbage;3;MC100A;MC1;500;20;MC49A;MC2;500;50;MC800A;MC3;600;10.3;Malaysia product
The number 3 at the top of the text file is for the int quantity; variable to store the amount.
The kind of information I want the VegTypes[f] = new VegType(); to store are MT100A;MT1;200;90;MT20A;MT2;600;80;, the number 2 besides the Malaysia Tomato are for int vegQuantity; variable. Same thing goes for other vegetables in the text file.
Constructor of my private VegType[] VegTypes; Array Object:
private String vegCode;
private String vegBatch;
private int vegBatchQuantity;
private double vegGrade;
public VegType(String inVegCode, String inVegBatch, int inVegBatchQuantity, double inVegGrade) {
vegCode = inVegCode;
vegBatch = inVegBatch;
vegBatchQuantity = inVegBatchQuantity;
vegGrade = inVegGrade;
}
My Veg Class:
public class Veg {
private String vegetableName;
private String classLevel;
private String productionCountry;
private VegType[] VegTypes;
private String productType;
//Constructor
public Veg(String inVegetableName, String inClassLevel, String inProductionCountry, VegType[] inVegTypes, String inProductType) {
vegetableName = inVegetableName;
classLevel = inClassLevel;
productionCountry = inProductionCountry;
vegType = inVegTypes;
productType = inProductType;
}
public String getVegetableName() {
return vegetableName;
}
public String getClassLevel() {
return classLevel;
}
public String getProductionCountry() {
return productionCountry;
}
public String getProductType() {
return productType;
}
}
This is wrong:
//For loop to store information into VegTypes
for (int f = 0; j < vegQuantity; f++) {
VegTypes[f] = new VegType();
}
you need to use f to adjust the index into your array of fields.
for (int f = 0; j < vegQuantity; f++) {
String vegCode = newLine[f*4 + 4];
String vegBatch = newLine[f*4 + 5];
int vegQuantity = Integer.parse(newLine[f*4 + 6]);
double vegGrade = Double.parse(newLine[f*4 + 7]);
VegTypes[f] = new VegType(vegCode, vegBatch, vegQuantity, vegGrade);
}
class VegType {
private String vegCode;
private String vegBatch;
private int vegBatchQuantity;
private double vegGrade;
public VegType(String inVegCode, String inVegBatch, int inVegBatchQuantity, double inVegGrade) {
vegCode = inVegCode;
vegBatch = inVegBatch;
vegBatchQuantity = inVegBatchQuantity;
vegGrade = inVegGrade;
}
#Override
public String toString() {
return vegCode+" "+vegBatch+" "+vegBatchQuantity+" "+vegGrade;
}
}
class Veg {
private String vegetableName;
private String classLevel;
private String productionCountry;
private VegType[] VegTypes;
private String productType;
//Constructor
public Veg(String inVegetableName, String inClassLevel, String inProductionCountry, VegType[] inVegTypes, String inProductType) {
vegetableName = inVegetableName;
classLevel = inClassLevel;
productionCountry = inProductionCountry;
VegTypes = inVegTypes;
productType = inProductType;
}
#Override
public String toString() {
return vegetableName+" "+classLevel+" "+productionCountry+" "+VegTypes+" "+productType;
}
public String getVegetableName() {
return vegetableName;
}
public String getClassLevel() {
return classLevel;
}
public String getProductionCountry() {
return productionCountry;
}
public String getProductType() {
return productType;
}
}
class TheVegetable {
private Veg[] Vegs;
private VegType[] VegTypes;
public TheVegetable() throws IOException {
int quantity;
int vegQuantity;
String vegLine;
try {
BufferedReader br = new BufferedReader(new FileReader("vegetableInfo.txt"));
quantity = Integer.parseInt(br.readLine());
Vegs = new Veg[quantity];
for (int i=0; i<quantity; i++) {
vegLine = br.readLine();
String[] newData = vegLine.split(";");
vegQuantity = Integer.parseInt(newData[3]);
VegTypes=new VegType[vegQuantity];
for(int j=4, k=0; j<newData.length-1; j+=4, k++) {
VegTypes[k] = new VegType(newData[j], newData[j+1], Integer.parseInt(newData[j+2]), Double.parseDouble(newData[j+3]));
}
Vegs[i]=new Veg(newData[0], newData[1], newData[2], VegTypes, newData[newData.length-1]);
}
br.close();
} catch (FileNotFoundException e) {
System.out.println("File not found.");
}
}
}
This question already has answers here:
Javafx tableview not showing data in all columns
(3 answers)
Closed 1 year ago.
im working on a project and i need to populate a TableView with data from a database. in this same project i've worked with other TableView and i had no problem so far. but i already tried a lot of stuff, checked the solution to this: Javafx tableview not showing data in all columns and didnt work either, i already dont know what to do, hope you can help me, ill show you the code:
TableView column fill:
private void fillColumns(){
TableColumn<Exam, String> column1 = new TableColumn<>("Estudio");
column1.setCellValueFactory(new PropertyValueFactory<>("estudio"));
TableColumn<Exam, String> column2 = new TableColumn<>("Doctor");
column2.setCellValueFactory(new PropertyValueFactory<>("doctor"));
TableColumn<Exam, String> column3 = new TableColumn<>("Fecha");
column3.setCellValueFactory(new PropertyValueFactory<>("fecha"));
TableColumn<Exam, String> column4 = new TableColumn<>("Descripcion");
column4.setCellValueFactory(new PropertyValueFactory<>("descripcion"));
TableColumn<Exam, String> column5 = new TableColumn<>("Precio");
column5.setCellValueFactory(new PropertyValueFactory<>("precio"));
TableColumn<Exam, String> column6 = new TableColumn<>("Paciente");
column6.setCellValueFactory(new PropertyValueFactory<>("paciente"));
//add columns
tvExam.getColumns().clear();
tvExam.getColumns().add(column1);
tvExam.getColumns().add(column2);
tvExam.getColumns().add(column3);
tvExam.getColumns().add(column4);
tvExam.getColumns().add(column5);
tvExam.getColumns().add(column6);
column1.prefWidthProperty().bind(tvExam.widthProperty().multiply(0.2));
column2.prefWidthProperty().bind(tvExam.widthProperty().multiply(0.3));
column3.prefWidthProperty().bind(tvExam.widthProperty().multiply(0.1));
column4.prefWidthProperty().bind(tvExam.widthProperty().multiply(0.2));
column5.prefWidthProperty().bind(tvExam.widthProperty().multiply(0.1));
column6.prefWidthProperty().bind(tvExam.widthProperty().multiply(0.1));
}
My Exam Class:
public class Exam {
protected SimpleStringProperty estudio = null;
protected SimpleStringProperty doctor = null;
protected SimpleStringProperty fecha = null;
protected SimpleStringProperty descripcion = null;
protected SimpleFloatProperty precio;
protected SimpleStringProperty paciente = null;
public Exam() {
}
public Exam(String estudio, String doctor, String fecha, String descripcion, float precio, String paciente){
this.estudio = new SimpleStringProperty(estudio);
this.descripcion = new SimpleStringProperty(descripcion);
this.doctor = new SimpleStringProperty(doctor);
this.fecha = new SimpleStringProperty(fecha);
this.precio = new SimpleFloatProperty(precio);
this.paciente = new SimpleStringProperty(paciente);
}
public String getpaciente() {
return paciente.get();
}
public void setpaciente(String paciente) {
this.paciente = new SimpleStringProperty(paciente);
}
public String getestudio() {
return estudio.get();
}
public void setestudio(String estudio) {
this.estudio = new SimpleStringProperty(estudio);
}
public String getdoctor() {
return doctor.get();
}
public void setdoctor(String doctor) {
this.doctor = new SimpleStringProperty(doctor);
}
public String getfecha() {
return fecha.get();
}
public void setfecha(String fecha) {
this.fecha = new SimpleStringProperty(fecha);
}
public String getdescripcion() {
return descripcion.get();
}
public void setdescripcion(String descripcion) {
this.descripcion = new SimpleStringProperty(descripcion);
}
public float getprecio() {
return precio.get();
}
public void setprecio(float precio) {
this.precio = new SimpleFloatProperty(precio);
}
}
my filling function with data from database (i already checked and the data is there, the problem is the tableview):
while (resultSet.next()) {
Exam nuevo = new Exam();
nuevo.setdoctor(resultSet.getString("fecha"));
nuevo.setestudio(resultSet.getString("estudio"));
nuevo.setpaciente(resultSet.getString("paciente"));
nuevo.setdescripcion(resultSet.getString("descripcion"));
nuevo.setfecha(resultSet.getString("fecha"));
nuevo.setprecio(resultSet.getFloat("precio"));
tvExam.getItems().add(fila);
}
Rename the getters and setters using camelCase.
This is a java standard:
public String getFoo()
{
return this.foo;
}
public void setFoo(String foo)
{
this.foo = foo;
}
I have a class that has an enum declared in it, like this:
private enum Marker {
NONE {
#Override
public String[] createResultLine(String columnName, String value, String[] buf) {
return null;
}
},
STRING {
#Override
public String[] createResultLine(String columnName, String value, String[] buf) {
buf[COLUMN_VALUE_STRING] = value;
buf[COLUMN_VALUE_FLOAT] = "";
buf[COLUMN_NAME] = columnName;
buf[BLOCK_ID] = blockId;
buf[PIPELINE_ID] = pipelineId;
return buf;
}
},
FLOAT {
#Override
public String[] createResultLine(String columnName, String value, String[] buf) {
buf[COLUMN_VALUE_STRING] = "";
buf[COLUMN_VALUE_FLOAT] = value;
buf[COLUMN_NAME] = columnName;
buf[BLOCK_ID] = blockId;
buf[PIPELINE_ID] = pipelineId;
return buf;
}
};
public abstract String[] createResultLine(String columnName, String value, String[] buf);
}
and here is the complete class and the usage
final class CSVDataModifier {
private final Path src;
private int rowNumber = 0;
private static String blockId = "" ;
private static String pipelineId = "" ;
private static String ElasticHostURL = "";
public CSVDataModifier(Path src, /*Path dest, */ String b_id, String p_id, String elasticUrl) {
this.src = src;
this.blockId = b_id;
this.pipelineId = p_id;
this.ElasticHostURL = elasticUrl;
}
private static final int ROW_NUMBER = 0;
private static final int COLUMN_NAME = 1;
private static final int COLUMN_VALUE_STRING = 2;
private static final int COLUMN_VALUE_FLOAT = 3;
private static final int BLOCK_ID = 4;
private static final int PIPELINE_ID = 5;
private static final String[] COLUMN_NAMES = { "row_number", "column_name", "column_value_string", "column_value_float", "blockId", "pipelineId" };
private ExecutorService executorService = Executors.newFixedThreadPool( 100 );
public void apply() throws IOException, InterruptedException {
try (CSVReader reader = new CSVReader(new FileReader(src.toFile())))
{
List<String[]> csvLines = new ArrayList<>();
// key - ordered list of columns in source file
Map<String, Marker> columnNameFloatMarker = getSourceColumnNamesWithFloatMarker(reader.readNext());
int posRowNumber = getRowNumberPosition(columnNameFloatMarker.keySet());
if (columnNameFloatMarker.isEmpty()) {
System.out.println( "empty!" );
return;
}
String[] buf = new String[COLUMN_NAMES.length];
reader.forEach(values -> {
buf[ROW_NUMBER] = values[posRowNumber];
int col = 0;
String[] resultLine;
for (Map.Entry<String, Marker> entry : columnNameFloatMarker.entrySet()) {
String columnName = entry.getKey();
Marker marker = entry.getValue();
if ((resultLine = marker.createResultLine(columnName, values[col], buf)) != null) {
// writer.writeNext( resultLine );
csvLines.add( resultLine );
rowNumber++;
}
col++;
}
if (csvLines.size() >= 75)
{
List<String[]> tmp = new ArrayList<>( );
tmp.addAll( csvLines );
csvLines.clear();
executorService.execute(new BulkThread(ElasticHostURL, new ArrayList<>( tmp )));
}
});
if (csvLines.size() > 0) {
List<String[]> tmp = new ArrayList<>( );
tmp.addAll( csvLines );
csvLines.clear();
executorService.execute(new BulkThread(ElasticHostURL, new ArrayList<>( tmp )));
}
}
executorService.shutdown();
executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
System.out.println( "Total Lines: " + rowNumber );
}
private static final String FLOAT = "_float";
private static final String STRING = "_string";
private enum Marker {
NONE {
#Override
public String[] createResultLine(String columnName, String value, String[] buf) {
return null;
}
},
STRING {
#Override
public String[] createResultLine(String columnName, String value, String[] buf) {
buf[COLUMN_VALUE_STRING] = value;
buf[COLUMN_VALUE_FLOAT] = "";
buf[COLUMN_NAME] = columnName;
buf[BLOCK_ID] = blockId;
buf[PIPELINE_ID] = pipelineId;
return buf;
}
},
FLOAT {
#Override
public String[] createResultLine(String columnName, String value, String[] buf) {
buf[COLUMN_VALUE_STRING] = "";
buf[COLUMN_VALUE_FLOAT] = value;
buf[COLUMN_NAME] = columnName;
buf[BLOCK_ID] = blockId;
buf[PIPELINE_ID] = pipelineId;
return buf;
}
};
public abstract String[] createResultLine(String columnName, String value, String[] buf);
}
// Source column pre-processing to avoid string comparision;
private static Map<String, Marker> getSourceColumnNamesWithFloatMarker(String... columns) {
if (columns == null || columns.length == 0)
return Collections.emptyMap();
Map<String, Marker> map = new LinkedHashMap<>();
for (int i = 0; i < columns.length; i++) {
String columnName = columns[i];
Marker marker = Marker.NONE;
if (columnName.endsWith(FLOAT)) {
columnName = columnName.substring(0, columnName.length() - FLOAT.length());
marker = Marker.FLOAT;
} else if (columnName.endsWith(STRING)) {
columnName = columnName.substring(0, columnName.length() - STRING.length());
marker = Marker.STRING;
}
if (map.put(columnName, marker) != null)
throw new IllegalArgumentException("Column duplication in the source file");
}
return map;
}
private static int getRowNumberPosition(Set<String> columnNames) {
int i = 0;
for (String columnName : columnNames) {
if ("row_number".equals(columnName))
return i;
i++;
}
throw new IllegalArgumentException("Source file does not contain 'row_number' column");
}
}
The problem is that the private members
private static String blockId = "" ;
private static String pipelineId = "" ;
can't be referenced in the private enum Marker if they're not static, and also they're being initialized in the constructor
public CSVDataModifier(Path src, /*Path dest, */ String b_id, String p_id, String elasticUrl) {
this.src = src;
this.blockId = b_id;
this.pipelineId = p_id;
this.ElasticHostURL = elasticUrl;
}
I can see the only way to do that, to declare the private member not as static , is to turn the private enum Marker into an internal class or maybe something else.
Since I'm new to Java and to the OOP world, can I get any guidance to solve this issue?
This code is quite hardcore and needs massive refactoring because it is violating most of programming principles
The answer for your question is to extract those fields to another class like ModifierSetup and provide it to the createResultLine as a parameter
public class ModifierSetup {
private String pipelineId;
private String ElasticHostURL;
// all args constructor
}
// inside your CSVDataModifier
private ModifierSetup setup;
public CSVDataModifier(Path src, /*Path dest, */ String b_id, String p_id, String elasticUrl) {
this.src = src;
this.blockId = b_id;
this.setup = new ModifierSetup(p_id, elasticUrl);
}
// ...
if ((resultLine = marker.createResultLine(columnName, values[col], buf, this.setup)) != null) {
// ...
public abstract String[] createResultLine(String columnName, String value, String[] buf, ModifierSetup modifierSetup);
but that's definitely not enough. Many of your fields should be extracted like this. Instead of weird 'singleton' enum implementation you should provide some common interface like
public interface ResultLineCreator {
ResultData createResultLine(ColumnMetaData columnMetaData, ModifierSetup modifierSetup, ResultData result); // in ColumnMetaData you can encapsulate columnName and value, inside ResultData result data
}
and proper local implementations of it, the reader should be wrapped with some kind of supplier etc etc - just think about how many responsibilities this class has - even if you will resolve your problem it won't be working/maintanable/testable/clear
I'm making console app for Planting house. House has 6 rows and each row has 25 Sections. I built this structure using arraylists of rows and sections. Now I want to add plants to the section from user input. I
I have tried multiple ways to do it creating different methods which you can see in the comments but nothing is working, the Object Plant is either not getting created or not getting added to ArrayList plants.
public class Section {
private int number;
private List<TomatoPlant> plants;
public int getNumber() {
return number;
}
public Section(int number, List<TomatoPlant> plants) {
this.number = number;
this.plants = plants;
}
public Section(int number){
this.number=number;
//this.addPlants();
this.plants= new ArrayList<>();
}
public List getPlants() {
return this.plants;
}
public void addPlants(Cocktailtomatos cocktailtomato) {
//this.plants= new ArrayList<>();
this.plants.add(cocktailtomato);
this.plants.add(Cocktailtomatos.createCocktailtomato("ss", "A", 1));
}
#Override
public String toString() {
return "Section{" +
"number=" + number +
", plants=" + plants +
'}';
}
public void addPlant(String id, String row, int sectionnumber) {
Cocktailtomatos cocktailtomato = new Cocktailtomatos(id, row, sectionnumber, true, false, false, 0, 10);
this.addPlants(cocktailtomato);
}
}
public class Manager {
private static Manager ourInstance = new Manager();
public static Manager getInstance() {
return ourInstance;
}
private Manager() {
}
Planthouse planthouse = new Planthouse();
public void addCocktailTomato(){
Scanner scanner = new Scanner(System.in);
System.out.println("Input Id:");
String id = scanner.nextLine();
System.out.println("Input Row");
String row = scanner.nextLine();
System.out.println("Input sectionnumber");
Integer sectionnumber = scanner.nextInt();
//Cocktailtomatos cocktailtomato = Cocktailtomatos.createCocktailtomato(id, row, sectionnumber);
//cocktailtomato.setId(row + sectionnumber + "_" + id);
//planthouse.getRow(row).getSection(sectionnumber).getPlants().add(cocktailtomato);
//System.out.println("ID: ");
//Cocktailtomatos cocktailtomato = new Cocktailtomatos(id, row, sectionnumber, true, false, false, 0, 10);
//planthouse.getRow(row).getSection(sectionnumber).getPlants().add(cocktailtomato);
//Cocktailtomatos cocktailtomato = Cocktailtomatos.createCocktailtomato(id, row, sectionnumber);
//planthouse.getRow(row).getSection(sectionnumber).addPlants(cocktailtomato);
planthouse.getRow(row).getSection(sectionnumber).addPlant(id, row, sectionnumber);
//this.getPlantlist();
}
public int getPlantlist() {
Scanner scanner = new Scanner(System.in);
System.out.println("Input row:");
String row = scanner.nextLine();
System.out.println("Input sectionnumber:");
Integer sectionnumber = scanner.nextInt();
//return planthouse.getRow(row).getSection(sectionnumber).getPlants();
//System.out.println(planthouse.getRow(row).getSection(sectionnumber).getPlants().size());
System.out.println(planthouse.getRows());
//System.out.println(planthouse.getRow("A").getSections().size());
//for(int i=0; i<planthouse.getRow("A").getSections().size(); i++){
//System.out.println(planthouse.getRow("A").getSections().get(i).getPlants());
//}
//for(int i=0; i<planthouse.getRows().size(); i++){
// System.out.println(planthouse.getRows().get(i));
// }
return planthouse.getRow(row).getSection(sectionnumber).getPlants().size();
}
}
public class Planthouse {
private ArrayList<Row> rows = new ArrayList<>();
public Planthouse(){
this.initRows();
}
public Planthouse(ArrayList<Row> rows) {
this.setRows(rows);
}
public ArrayList<Row> getRows() {
return rows;
}
private void initRows() {
this.rows= new ArrayList<>();
this.rows.add(new Row("A"));
this.rows.add(new Row("B"));
this.rows.add(new Row("C"));
this.rows.add(new Row("D"));
this.rows.add(new Row("E"));
this.rows.add(new Row("F"));
}
public void setRows(ArrayList<Row> rows) {
this.rows = rows;
}
public void printPlanthouse(){
for(Row row: rows) {
System.out.println(row.getId());
row.printSections();
}
}
public Row getRow(String rowId) {
Row row = new Row(rowId);
return row;
}
public void addPlant(){
}
public Section getSection(Row row, Section section) {
Planthouse planthouse = new Planthouse();
planthouse.getRow(row.getId()).getSection(section.getNumber());
return section;
}
}
public class Row {
private String id;
private ArrayList<Section> sections;
public Row(String id) {
this.id = id;
this.initSections();
}
public Row(String id, ArrayList<Section> sections) {
this.id = id;
this.setSections(sections);
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public ArrayList<Section> getSections() {
return sections;
}
public void setSections(ArrayList<Section> sections) {
this.sections = sections;
}
public void initSections() {
this.sections = new ArrayList<>();
for (int i = 1; i <=25; i++) {
this.sections.add(new Section(i));
}
}
public void printSections() {
for (Section section : sections) {
System.out.println(section.getNumber());
}
}
public Row(){
}
#Override
public String toString() {
return "Row{" +
"id='" + id + '\'' +
", sections=" + sections +
'}';
}
public Section getSection(int sectionnumber){
//Section section = new Section(sectionnumber);
Section section = sections.get(sectionnumber-1);
return section;
}
}
Method getPlantList() prints out all rows with its sections and each section with its plants, and after user adds a plant into section these sections are being printed empty (without plants). So I come to conclusion that either plant is not created or not added to an arraylist. Can someone suggest me where is the problem? Thank you.
The current getRow creates everytime a new Row not placed in the entire data hierarchy.
public Row getRow(String rowId) {
for (Row row : rows) {
if (row.getId().equals(rowId)) {
return row;
}
}
// Either throw new IllegalArgumentException(); or:
Row row = new Row(rowId);
rows.add(row);
return row;
}
Instead, or additionally to a list you might want to use a Map from rowId to a Row.
Map<String, Row> rowMap = new HashMap<>();
Map<String, Row> rowMap = new TreeMap<>(); // Sorted
Map<String, Row> rowMap = new LinkHashMap<>(); // In order of insertion, chronological
String rowId = "A";
rowMap.put(rowId, row);
Row row = rowMap.get(rowId);
SOLVED
Changed Contents contents to:
// Lists
#XStreamImplicit(itemFieldName = "Contents")
public List<Contents> Contents = new ArrayList<Contents>();
I'm trying to deserialize the following XML:
<?xml version="1.0" encoding="UTF-8"?>
<Items>
<Item>
<type>Test</type>
<uid>1</uid>
<depends>1</depends>
<catid>1</catid>
<label>Test</label>
<defaultVal>default</defaultVal>
<answer>Test</answer>
<Contents>
<Content>
<uid>1</uid>
<label>Test</label>
</Content>
</Contents>
</Item>
</Items>
The problem is that when I reach Contents it crashes due to going deeper by another level.
This is how i DeSerialize my XML, it works without the contents.
public static Object DeSerializeFromXML(String xml, Class items, Class item)
{
XStream xstream = new XStream();
xstream.processAnnotations(new Class[] { items, item });
return xstream.fromXML(xml);
}
Here's how I call the DeSerialize method:
Items reader = (Items)Data.Serialization.Instance().DeSerializeFromXML(xml, Items.class, Item.class);
And as last my Objects:
Items.cs
#XStreamAlias("Items")
public class Items
{
public Items() { items = new ArrayList<Item>(); }
#XStreamImplicit(itemFieldName = "Item")
public List<Item> items = new ArrayList<Item>();
}
Item.cs
#XStreamAlias("Item")
public class Item
{
// Type
public String type = "";
// Ids
public int uid = 0;
public int catid = 0;
public int depends = 0;
// Values
public String label = "";
public String defaultVal = "";
public String answer = "";
// Lists
public Contents content;
public Item()
{
}
public Item(String type, int uid, int catid, int depends, String label,
String defaultval, String answer)
{
this.type = type;
this.uid = uid;
this.catid = catid;
this.depends = depends;
this.label = label;
this.defaultVal = defaultval;
this.answer = answer;
content = new Contents();
}
#XStreamAlias("Contents")
public static class Contents
{
public Contents()
{
contents = new ArrayList<Content>();
}
#XStreamImplicit(itemFieldName = "Content")
public List<Content> contents = new ArrayList<Content>();
}
Content.cs
#XStreamAlias("Content")
public class Content
{
public int uid = 0;
public String label = "";
public Content()
{
}
public Content(int uid, String label)
{
this.uid = uid;
this.label = label;
}
I'm not quite sure if my annotations for the next level are correct.
Any help is appreciated.
Solved it by changing Contents to a list and adding the XStream marshall to it.
#XStreamImplicit(itemFieldName = "Contents")
public List<Contents> Contents = new ArrayList<Contents>();