ObjectMapper ignores some fileds when mapping to JSON - java

So my issue is that when mapping a class to JSON, it won't map all the fields the class has
Card:
public class Card {
private String name;
private String description;
private StatusCard status;
private List<String> CardHistory;
public enum StatusCard{TODO, INPROGRESS, TOBEREVISED, DONE};
public Card(String name, String desc){
this.name = name;
description = desc;
status = StatusCard.TODO;
CardHistory = new ArrayList<>();
}
public Card(){}
// getters and setters
}
This class is used within another class, in an
ArrayList<Card> cardList, but when I map this class to JSON, this is the only fields it maps
JSON:
... "cardList":[{"name":"test","status":"TODO"}] ...
and I can't figure out why. This is the method that adds a new card by the server:
public String addCard(String projectName, String cardName, String desc, String nickUtente) {
if (projects.isEmpty())
return "No projects are currently present";
if (projectName.isEmpty() || cardName.isEmpty() || desc.isEmpty() || nickUtente.isEmpty())
return "Missing one or more arguments";
for (Project p : projects) {
if (p.getName().equalsIgnoreCase(projectName)){
if (!p.isMember(nickUtente))
return nickUtente + " does not belong to the project";
String code = p.addCard(cardName, desc);
if (code.equalsIgnoreCase("ok")) {
try {
om.writeValue(projectFile,projects);
} catch (IOException e) {
e.printStackTrace();
}
}
return code;
}
}
return "Project " + projectName + " not found";
}
This is the Project class using classes from com.fasterxml.jackson if you need to know:
public class Project implements Serializable {
private String name;
private String nickUtente;
private ArrayList<Card> cardList;
private ArrayList<String> users;
private ArrayList<String> TODO;
private ArrayList<String> INPROGRESS;
private ArrayList<String> TOBEREVISED;
private ArrayList<String> DONE;
private String MulticastAddress;
private int port;
/*
#JsonIgnore
private File projDir;
#JsonIgnore
private final ObjectMapper map;
*/
public Project(String name, String nickUtente, String multiaddr, int port) {
this.name = name;
this.nickUtente = nickUtente;
cardList = new ArrayList<>();
users = new ArrayList<>();
users.add(nickUtente);
TODO = new ArrayList<>();
INPROGRESS = new ArrayList<>();
TOBEREVISED = new ArrayList<>();
DONE = new ArrayList<>();
MulticastAddress = multiaddr;
this.port = port;
// map = new ObjectMapper();
// map.enable(SerializationFeature.INDENT_OUTPUT);
// projDir = new File("./BackupCards/" + name);
// if(!projDir.exists()) projDir.mkdir();
}
public Project(){
// this.map = new ObjectMapper();
// map.enable(SerializationFeature.INDENT_OUTPUT);
}
// getters and setters
public boolean isMember(String user){
if(users.isEmpty())
return false;
for(String s : users) {
if (user.equals(s))
return true;
}
return false;
}
public String addMember(String s) {
if (s.isEmpty()){
System.out.println("Missing name");
return "err";
}
if (users.contains(s)) {
System.out.println("Member exists already");
return "err";
}
users.add(s);
return "ok";
}
public String addCard(String cardName, String desc){
if(cardName.isEmpty() || desc.isEmpty())
return "Missing name and/or description";
Card c = new Card(cardName, desc);
cardList.add(c);
TODO.add(cardName);
/*
File cardFile = new File(projDir + "/" + cardName + ".json");
if (!cardFile.exists()) {
try {
cardFile.createNewFile();
} catch (IOException e) { e.printStackTrace(); }
}
//Backup card file
try {
map.writeValue(cardFile, c);
} catch (IOException e) {
e.printStackTrace();
}*/
return "ok";
}
public String moveCard(String cardName, String startingList, String destList){
if(cardName.isEmpty() || startingList.isEmpty() || destList.isEmpty())
return "Missing one or more arguments";
for(Card c : cardList){
if(c.getName().equalsIgnoreCase(cardName)){
switch(destList){
case "TODO":
if(startingList.equals("TODO"))
return "Card is already in " + startingList;
return "Cannot move card back to TODO";
case "INPROGRESS":
if(startingList.equals("INPROGRESS"))
return "Card already is in INPROGRESS";
if(startingList.equals("DONE"))
return "Card is done. Cannot change status anymore";
if(TODO.contains(cardName)){
TODO.remove(cardName);
INPROGRESS.add(cardName);
c.setStatus("INPROGRESS");
c.getCardHistory().add(startingList);
//System.out.println("Card moved from TODO to INPROGRESS");
return "ok";
}
if(TOBEREVISED.contains(cardName)){
TOBEREVISED.remove(cardName);
INPROGRESS.add(cardName);
c.setStatus("INPROGRESS");
c.getCardHistory().add(startingList);
//System.out.println("Card moved from TOBEREVISED to INPROGRESS");
return "ok";
}
return "Card not found";
case "TOBEREVISED":
if(!startingList.equals("INPROGRESS"))
return "Can only move to TOBEREVISED from INPROGRESS";
if(INPROGRESS.contains(cardName)){
INPROGRESS.remove(cardName);
TOBEREVISED.add(cardName);
c.setStatus("TOBEREVISED");
c.getCardHistory().add(startingList);
//System.out.println("Card moved FROM INPROGRESS TO TOBEREVISED");
return "ok";
}
case "DONE":
if(startingList.equals("TODO"))
return "Cannot move card to DONE from TODO";
if(INPROGRESS.contains(cardName)){
INPROGRESS.remove(cardName);
DONE.add(cardName);
c.getCardHistory().add(startingList);
c.setStatus("DONE");
//System.out.println("Moved card from INPROGRESS to DONE");
return "ok";
}
if(TOBEREVISED.contains(cardName)){
TOBEREVISED.remove(cardName);
DONE.add(cardName);
c.setStatus("DONE");
c.getCardHistory().add(startingList);
//System.out.println("Moved card from TOBEREVISED to DONE");
return "ok";
}
return "Card not found";
}
}
}
return "Card not found";
}
public void showMembers() {
if (users.isEmpty())
System.out.println("No user belongs to this project");
for (String s : users)
System.out.println(s);
}
public void showCards() {
if (TODO.isEmpty() && INPROGRESS.isEmpty() && TOBEREVISED.isEmpty() && DONE.isEmpty())
System.out.println("No cards to be shown");
if (TODO.isEmpty()) {
System.out.println("No cards TODO");
} else {
System.out.println("Cards TODO:");
for (String s : TODO)
System.out.println(s);
}
if (INPROGRESS.isEmpty()) {
System.out.println("No cards IN PROGRESS");
} else {
System.out.println("Cards INPROGRESS:");
for (String s : INPROGRESS)
System.out.println(s);
}
if (TOBEREVISED.isEmpty())
System.out.println("No cards TOBEREVISED");
else {
System.out.println("Cards TOBEREVISED:");
for (String s : TOBEREVISED)
System.out.println(s);
}
if (DONE.isEmpty())
System.out.println("No cards DONE");
else {
System.out.println("Cards DONE:");
for (String s : DONE)
System.out.println(s);
}
}
public Card getCard(String name) {
if (cardList.isEmpty())
return null;
for (Card c : cardList){
if (c.getName().equalsIgnoreCase(name))
return c;
}
return null;
}
public List<UserStatusInfo> getCardList() {
if(cardList.isEmpty())
return null;
List<UserStatusInfo> list = new ArrayList<>();
for(Card c : cardList)
list.add(new UserStatusInfo(c.getName(),c.getStatus()));
return list;
}
/* public void delProjDir(){
try {
Files.walk(projDir.toPath()).sorted(Comparator.reverseOrder()).map(Path::toFile)
.forEach(File::delete);
} catch (IOException e) {
e.printStackTrace();
}
}
*/
}

The problem is here
public List<UserStatusInfo> getCardList() {
if(cardList.isEmpty())
return null;
List<UserStatusInfo> list = new ArrayList<>();
for(Card c : cardList)
list.add(new UserStatusInfo(c.getName(),c.getStatus()));
return list;
}
You have private property ArrayList<Card> cardList and public method List<UserStatusInfo> getCardList(). Since ObjectMapper follows JavaBean conventions during serialization it only accesses public properties and public getter methods, so when cardList is mapped into JSON, not cardList property is actually serialized, but result of getCardList() method invocation hence not Card instances are serialized but UserStatusInfo instances (that seem to have only name and status).
You have to create ArrayList<Card> getCardList() method that returns cardList property, and rename current List<UserStatusInfo> getCardList() to something else
OR
Extend UserStatusInfo class so that it has all corresponding properties from Card

Related

Copy the list of pojo to clipboard

Lang: Java
We are trying to copy the list of pojo to the clipboard in the table format.
Bullet point: what we are trying to achieve here :
1. convert list of pojo into table format
2. If the user copy it in some excel sheet then the it should be copied easily or even if the user try to copy in notepad it should print in the table format.
3. Add some meta data to clipboard to determine the pojo when we will import the table again.
For converting the list of pojo to table format i have used the jtable but i am not able to export all the jtable content to clipboard.
can anyone suggest if i should follow the jtable approach and copy the table to clipboard or any other solution is also available.
Update: as suggested in the comment I tried using the flavours
public class ClipboardTest implements ClipboardOwner {
public static void main(String[] args) {
ClipboardTest clipboardTest = new ClipboardTest();
clipboardTest.copyToClipboard();
//clipboardTest.getFromClipboard();
}
public void copyToClipboard() {
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
Pojo data = new Pojo("1", "2", "ame2", "2", "2");
MyObjectSelection dataSelection = new MyObjectSelection(data);
StringSelection selection = new StringSelection("testing string");
clipboard.setContents(dataSelection, ClipboardTest.this);
System.out.println("copied to clipboard");
}
public void getFromClipboard() {
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
Transferable clipboardContent = clipboard.getContents(this);
DataFlavor[] flavors = clipboardContent.getTransferDataFlavors();
System.out.println("flavors.length = " + flavors.length);
for (int i = 0; i < flavors.length; i++) {
System.out.println("flavor[" + i + "] = " + flavors[i]);
}
}
// ClipboardOwner implementation
#Override
public void lostOwnership(Clipboard clipboard, Transferable transferable) {
System.out.println("ClipboardTest: Lost ownership");
}
}
---
myobjectselection.java
public class MyObjectSelection implements Transferable, ClipboardOwner {
private static DataFlavor dmselFlavor = new DataFlavor(Pojo.class,
"Test data flavor");
private Pojo selection;
public MyObjectSelection(Pojo selection) {
this.selection = selection;
}
// Transferable implementation
#Override
public DataFlavor[] getTransferDataFlavors() {
System.out.println("getTransferDataFlavors");
DataFlavor[] ret = { dmselFlavor };
return ret;
}
#Override
public boolean isDataFlavorSupported(DataFlavor flavor) {
return dmselFlavor.equals(flavor);
}
#Override
public synchronized Object getTransferData(DataFlavor flavor)
throws UnsupportedFlavorException {
if (isDataFlavorSupported(flavor)) {
return this.selection;
} else {
throw new UnsupportedFlavorException(dmselFlavor);
}
}
// ClipboardOwner implementation
#Override
public void lostOwnership(Clipboard clipboard, Transferable transferable) {
System.out.println("MyObjectSelection: Lost ownership");
}
}
--
pojo.java
public class Pojo implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String name;
private String name1;
private String name2;
private String name3;
private String name4;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getName1() {
return name1;
}
public void setName1(String name1) {
this.name1 = name1;
}
public String getName2() {
return name2;
}
public void setName2(String name2) {
this.name2 = name2;
}
public String getName3() {
return name3;
}
public void setName3(String name3) {
this.name3 = name3;
}
public String getName4() {
return name4;
}
public void setName4(String name4) {
this.name4 = name4;
}
public Pojo(String name, String name1, String name2, String name3,
String name4) {
super();
this.name = name;
this.name1 = name1;
this.name2 = name2;
this.name3 = name3;
this.name4 = name4;
}
}
When i am trying to copy the string value to clipboard it is working but when i am trying to copy the pojo then is it not working.
For every flavor you want to support, you must provide methods to encode the object in the specified format.
This means you'll likely need to provide an encoder for plain text, html and CVS to cover the basics.
So, based on your Pojo, I wrote a Transferable that supports:
List (of Pojos)
HTML
CVS
Plain text
And serialised (as an additional to List, but it's essentially the same)
PojoTransferable
public class PojoTransferable implements Transferable {
public static final DataFlavor POJO_LIST_DATA_FLAVOR = new DataFlavor(List.class, "application/x-java-pojo-list;class=java.util.List");
public static final DataFlavor HTML_DATA_FLAVOR = new DataFlavor("text/html", "HTML");
public static final DataFlavor CSV_DATA_FLAVOR = new DataFlavor("text/csv", "CVS");
public static final DataFlavor PLAIN_DATA_FLAVOR = new DataFlavor("text/plain", "Plain text");
public static final DataFlavor SERIALIZED_DATA_FLAVOR = new DataFlavor(Pojo.class, "application/x-java-serialized-object; Pojo");
private static String[] HEADERS = new String[]{"name", "name1", "name2", "name3", "name4"};
private static Pojo POJO_HEADER = new Pojo("name", "name1", "name2", "name3", "name4");
private List<Pojo> pojos;
public PojoTransferable(List<Pojo> pojos) {
this.pojos = pojos;
}
#Override
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[]{POJO_LIST_DATA_FLAVOR, HTML_DATA_FLAVOR, CSV_DATA_FLAVOR, SERIALIZED_DATA_FLAVOR, PLAIN_DATA_FLAVOR};
}
#Override
public boolean isDataFlavorSupported(DataFlavor flavor) {
boolean supported = false;
for (DataFlavor mine : getTransferDataFlavors()) {
if (mine.equals(flavor)) {
supported = true;
break;
}
}
return supported;
}
#Override
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
Object data = null;
if (POJO_LIST_DATA_FLAVOR.equals(flavor)) {
data = pojos;
} else if (HTML_DATA_FLAVOR.equals(flavor)) {
data = new ByteArrayInputStream(formatAsHTML().getBytes());
} else if (SERIALIZED_DATA_FLAVOR.equals(flavor)) {
data = pojos;
} else if (CSV_DATA_FLAVOR.equals(flavor)) {
data = new ByteArrayInputStream(formatAsCVS().getBytes());
} else if (PLAIN_DATA_FLAVOR.equals(flavor)) {
data = new ByteArrayInputStream(formatAsPlainText().getBytes());
} else {
throw new UnsupportedFlavorException(flavor);
}
return data;
}
protected String formatAsCVS(Pojo pojo) {
StringJoiner sj = new StringJoiner(",");
sj.add(pojo.getName());
sj.add(pojo.getName2());
sj.add(pojo.getName3());
sj.add(pojo.getName4());
return sj.toString();
}
public String formatAsCVS() {
StringBuilder sb = new StringBuilder(128);
sb.append(formatAsCVS(POJO_HEADER));
for (Pojo pojo : pojos) {
sb.append(formatAsCVS(pojo));
}
return "";
}
protected Map<Integer, Integer> columnWidthsFor(Pojo pojo) {
Map<Integer, Integer> columnWidths = new HashMap<>();
columnWidths.put(0, pojo.getName().length());
columnWidths.put(1, pojo.getName1().length());
columnWidths.put(2, pojo.getName2().length());
columnWidths.put(3, pojo.getName3().length());
columnWidths.put(4, pojo.getName4().length());
return columnWidths;
}
protected void apply(Map<Integer, Integer> pojoWidths, Map<Integer, Integer> columnWidths) {
for (int index = 0; index < 5; index++) {
int currentWidth = 2;
if (columnWidths.containsKey(index)) {
currentWidth = columnWidths.get(index);
}
int columnWidth = 2;
if (pojoWidths.containsKey(index)) {
columnWidth = pojoWidths.get(index);
}
columnWidths.put(index, Math.max(currentWidth, columnWidth));
}
}
protected String formatAsPlainText(Pojo pojo, String format) {
return String.format(format, pojo.getName(), pojo.getName1(), pojo.getName2(), pojo.getName3(), pojo.getName4());
}
public static String fill(int padding) {
return String.format("%" + padding + "s", "").replace(" ", "-");
}
public String formatAsPlainText() {
Map<Integer, Integer> columnWidths = new HashMap<>();
apply(columnWidthsFor(POJO_HEADER), columnWidths);
for (Pojo pojo : pojos) {
apply(columnWidthsFor(pojo), columnWidths);
}
StringJoiner sjFormat = new StringJoiner("|");
StringJoiner sjSep = new StringJoiner("+");
for (int index = 0; index < 5; index++) {
int currentWidth = 0;
if (columnWidths.containsKey(index)) {
currentWidth = columnWidths.get(index);
}
sjFormat.add(" %-" + currentWidth + "s ");
sjSep.add(fill(currentWidth + 2));
}
sjFormat.add("%n");
sjSep.add("\n");
String seperator = sjSep.toString();
String format = sjFormat.toString();
StringBuilder sb = new StringBuilder(128);
sb.append(formatAsPlainText(POJO_HEADER, format));
for (Pojo pojo : pojos) {
sb.append(seperator);
sb.append(formatAsPlainText(pojo, format));
}
return sb.toString();
}
public String formatAsHTML() {
StringBuilder sb = new StringBuilder(128);
sb.append("<html><body>");
sb.append("<table border='1'>");
sb.append("<tr>");
for (String header : HEADERS) {
sb.append("<th>").append(header).append("</th>");
}
sb.append("</tr>");
for (Pojo pojo : pojos) {
sb.append("<tr>");
sb.append("<td>").append(pojo.getName()).append("</td>");
sb.append("<td>").append(pojo.getName1()).append("</td>");
sb.append("<td>").append(pojo.getName2()).append("</td>");
sb.append("<td>").append(pojo.getName3()).append("</td>");
sb.append("<td>").append(pojo.getName4()).append("</td>");
sb.append("</tr>");
}
sb.append("</table>");
return sb.toString();
}
}
Test...
Then I wrote a really simple test...
List<Pojo> pojos = new ArrayList<>(25);
pojos.add(new Pojo("one", "two", "three", "four", "five"));
PojoTransferable pt = new PojoTransferable(pojos);
Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
cb.setContents(pt, new ClipboardOwner() {
#Override
public void lostOwnership(Clipboard clipboard, Transferable contents) {
System.out.println("Lost");
}
});
try {
Object data = cb.getData(PojoTransferable.POJO_LIST_DATA_FLAVOR);
if (data instanceof List) {
List listOfPojos = (List)data;
System.out.println("listOfPojos contains " + listOfPojos.size());
for (Object o : listOfPojos) {
System.out.println(o);
}
}
} catch (UnsupportedFlavorException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
When I run it, it prints out...
listOfPojos contains 1
test.Pojo#5b480cf9
which tells use that the List flavor worked (for our needs), but then I opened up a text edit, Word and Excel and pasted the contents into them...
nb: Excel used the HTML formatting, go figure

Compare value is not null or empty of any class java

I want compare values of any class in java no matter the type, for example i have next class:
public class Car {
private int windows;
private int doors;
private int drive;
private String model;
public int getWindows() {
return windows;
}
public void setWindows(int windows) {
this.windows = windows;
}
public int getDoors() {
return doors;
}
public void setDoors(int doors) {
this.doors = doors;
}
public int getDrive() {
return drive;
}
public void setDrive(int drive) {
this.drive = drive;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
}
And this other:
public class Moto {
private String model;
private String color;
private int year;
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
}
And i want compare if is not null or empty attributes of this class, for example :
if(Validator.myClass(objectValue)){
}
else{
}
Class Validador example:
public class Validador {
public static boolean myClass(Object obj){
Class myClass = null;
String cla = obj.toString();
int a = cla.indexOf("#");
cla = cla.substring(0, a);
try {
myClass = Class.forName(cla);
Field[] fields = myClass.getDeclaredFields();
int contador =0;
for (Field field : fields) {
System.out.println("Field type is: " + field.getType());
System.out.println("Field name is: " + field.getName());
if(!field.getName().equals("") && field.getName() != null){
contador++;
}
}
log.info(contador);
} catch (Exception e) {
}
return true;
}
}
This line not compare if value is not null or empity this attribute:
if(!field.getName().equals("") && field.getName() != null){
How to do that?
I currently do it in the following way:
if(Nameclass != null && Nameclass.getNameAttributeA != null && !Nameclass.getNameAttributeA.equals(""){
}else{
}
Update
Not compare 2 object, only one, but not matter type Object, for example: i have obejct Car.class i want compare all or any attribute this class or do the same with others Object(class).
Thanks!
Instead of writing your own validator you can use Apache Commons Validator https://commons.apache.org/proper/commons-validator/apidocs/org/apache/commons/validator/package-summary.html
You can check if and object is not null with the following code:
if(motoObject!=null) {
} else {
}
But your question is not so clear. Can you add further details?
You should use Class Types, for example in class Car you can use:
private Integer doors;//default is null
The method you can use for your validation is:
public static boolean validator(Object myObject) {
Field[] fields = myObject.getClass().getDeclaredFields();
for (Field field : fields) {
try {
Object objectValue = field.get(myObject);
if (objectValue == null || objectValue.toString().length() == 0) {
System.out.println("null or empty field = '" + field.getName() + "' in : " + myObject.getClass().getCanonicalName());
return false; //or you can throw a exception with a message, is better that return a boolean
}
} catch (IllegalArgumentException | IllegalAccessException ex) {
Logger.getLogger(MyClass.class.getName()).log(Level.SEVERE, "Something is wrong", ex);
}
}
return true;
}
pd. Sorry for my english, isn't so good

Create map of maps from eclipse toString()

Eclipse can auto-generate a toString() method from a object's fields. If those fields are objects then they too may have similarly auto-generated toString() methods.
e.g. a President object might look like this:
President [country=USA, name=Name [title=Mr, forename=Barack, surname=Obama], address=Address [houseNumber=1600, street=Pennsylvania Avenue, town=Washington]]
which is easier to read if I format it:
President [
country=USA,
name=Name [
title=Mr,
forename=Barack,
surname=Obama],
address=Address [
houseNumber=1600,
street=Pennsylvania Avenue,
town=Washington]]
What is the best way to parse this String to create a map of maps?
I've got a solution, but it's not pretty. I was hoping to be able to avoid the low level String manipulation somehow, but here it is:
import java.util.LinkedHashMap;
import java.util.Map;
public class MappedObject {
public String className;
public Map<String, String> leafFields = new LinkedHashMap<>();
public Map<String, MappedObject> treeFields = new LinkedHashMap<>();
#Override
public String toString() {
return "[className=" + className
+ (leafFields.isEmpty() ? "" : ", leafFields=" + leafFields)
+ (treeFields.isEmpty() ? "" : ", treeFields=" + treeFields)
+ "]";
}
public static MappedObject createFromString(String s) {
MappedObject mo = new MappedObject();
new Mapper(s).mapObject(mo);
return mo;
}
private static class Mapper {
private String s;
public Mapper(String s) {
this.s = s;
}
private String mapObject(MappedObject mo) {
mo.className = removeFirstNCharacters(s.indexOf(' '));
while (s.contains("=")) {
removeLeadingNonLetters();
String key = removeFirstNCharacters(s.indexOf('='));
removeFirstNCharacters(1); // remove the =
String leafValue = getLeafValue();
if (leafValue != null) {
mo.leafFields.put(key, leafValue);
if (s.startsWith("]")) { // that was the last field in the tree
return s;
}
} else {
MappedObject treeField = new MappedObject();
mo.treeFields.put(key, treeField);
s = new Mapper(s).mapObject(treeField);
}
}
return s; // s contains only close brackets - ]
}
private void removeLeadingNonLetters() {
int i = 0;
while (!Character.isLetter(s.charAt(i))) {
i++;
}
removeFirstNCharacters(i);
}
private String removeFirstNCharacters(int n) {
String value = s.substring(0, n);
s = s.substring(value.length());
return value;
}
private String getLeafValue() {
int endIndex = getEndIndex();
if (!s.contains("[") || s.indexOf('[') > endIndex) {
return removeFirstNCharacters(endIndex);
}
return null;
}
/** The end of the value, if it's a leaf field. */
private int getEndIndex() {
if(s.contains(",")) {
return Math.min(s.indexOf(','), s.indexOf(']'));
}
return s.indexOf(']');
}
}
}

Why am I getting an exception main "thread" error?

I have created two classes (and two interfaces) and then a main code. I just debugged the main code because I was getting an error that was preventing my code from working properly. I know that the problem in my Project03.java file is in line 29 and the line is input = userInput.nextLine(); . The error is:
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1585)
at Project03.main(Project03.java:29)
Why is the error coming up and how can I prevent it? Thank you!
The codes are below:
SimpleMusicTrack.java
import java.util.Scanner;
import java.lang.Object;
public class SimpleMusicTrack implements PlayListTrack {
private String name;
private String artist;
private String albumName;
// Convenience constructor for unit testing
public SimpleMusicTrack(String name, String artist, String album) {
this.name = name;
this.artist = artist;
this.albumName = album;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getArtist() {
return this.artist;
}
public void setArtist(String artist) {
this.artist = artist;
}
public String getAlbum() {
return this.albumName;
}
public void setAlbum(String album) {
this.albumName = album;
}
public boolean getNextTrack(Scanner infile) {
if (infile == null)
return false;
while (infile.hasNext()) {
this.setName(infile.nextLine());
this.setArtist(infile.nextLine());
this.setAlbum(infile.nextLine());
return true;
}
return false;
}
public boolean equals(Object obj) {
boolean songInfo;
if (obj instanceof MusicTrack) {
MusicTrack name1 = (MusicTrack) obj;
if (this.name.equals(name1.getName())
&& this.artist.equals(name1.getArtist())
&& this.albumName.equals(name1.getArtist())) {
songInfo = true;
} else {
songInfo = false;
}
} else {
songInfo = false;
}
return songInfo;
}
public String toString() {
String allSongInfo;
allSongInfo = this.artist + " / " + this.name;
return allSongInfo;
}
}
PlayListTrack.java
import java.util.Scanner;
public interface PlayListTrack {
public String getName();
public void setName(String name);
public String getArtist();
public void setArtist(String artist);
public String getAlbum();
public void setAlbum(String album);
public boolean getNextTrack(Scanner infile);
// Attempts to read a play list track entry from a Scanner object
// Sets the values in the object to the values given in
// the file
// If it successfully loads the track, return true
// otherwise, return false
}
SimplePlayList.java
import java.util.*;
import java.util.Queue;
public class SimplePlayList implements PlayList {
Queue<PlayListTrack> queue;
public SimplePlayList(Scanner in) {
queue = new LinkedList<PlayListTrack>();
readFile(in);
}
public void readFile(Scanner in) {
Scanner inScanner = new Scanner(System.in);
Queue<PlayListTrack> queue = new LinkedList<PlayListTrack>();
while (in.hasNext()) {
queue.add(new SimpleMusicTrack(in.nextLine(), in.nextLine(), in
.nextLine()));
}
inScanner.close();
}
public PlayListTrack getNextTrack() {
while (!queue.isEmpty()) {
queue.remove();
}
return queue.peek();
}
public PlayListTrack peekAtNextTrack() {
while (!queue.isEmpty()) {
queue.peek();
}
return queue.peek();
}
public void addTrack(PlayListTrack track) {
while (!queue.isEmpty()) {
queue.add(track);
}
}
public boolean isEmpty() {
while (!queue.isEmpty()) {
return false;
}
return true;
}
}
PlayList.java
public interface PlayList {
public PlayListTrack getNextTrack();
// Removes track from PlayList and returns it to the caller
// Should return a null value if the PlayList is empty
public PlayListTrack peekAtNextTrack();
// Returns next entry to the caller, but leaves it in the list
public void addTrack(PlayListTrack track);
// Adds this track to the play list in the appropriate order
public boolean isEmpty();
// Returns true if the play list is empty
}
Project03.java
import java.io.File;
import java.io.*;
import java.util.Scanner;
public class Project03 {
public static void main(String[] args) {
Scanner userInput = new Scanner(System.in);
System.out.print("Enter database filename: ");
String fileName = userInput.nextLine();
try {
File file = new File(fileName);
Scanner musicList = new Scanner(file);
String input = "P";
PlayList playList = new SimplePlayList(musicList);
while (!"Q".equalsIgnoreCase(input)) {
if ("A".equalsIgnoreCase(input)) {
displayAddTrackOption(userInput, playList);
input = "";
} else {
displayNextSong(playList);
System.out.print("> ");
input = userInput.nextLine();
}
}
displayRemainingTracks(playList);
} catch (FileNotFoundException e) {
System.out.println("Sorry, could not find your file");
}
}
private static void displayRemainingTracks(PlayList playList) {
System.out
.println("Tracks remaining in play list------------------------------------------------------------");
if (!playList.isEmpty()) {
boolean hasAnotherTrack = true;
int lineNumber = 1;
while (hasAnotherTrack) {
MusicTrack currentTrackToPlay = (MusicTrack) playList
.getNextTrack();
if (currentTrackToPlay != null) {
System.out.printf("%d - %s / %s / %s\n", lineNumber,
currentTrackToPlay.getName(),
currentTrackToPlay.getArtist(),
currentTrackToPlay.getAlbum());
lineNumber++;
} else
hasAnotherTrack = false;
}
} else
System.out.println("No tracks remaining");
}
private static void displayAddTrackOption(Scanner userInput,
PlayList playList) {
String title, artist, album, confirmation;
System.out.print("Track name: ");
title = userInput.nextLine();
System.out.print("Artist name: ");
artist = userInput.nextLine();
System.out.print("Album name: ");
album = userInput.nextLine();
System.out.println("New Track: " + title);
System.out.println("Artist: " + artist);
System.out.println("Album: " + album);
System.out.print("Are you sure you want to add this track [y/n]? ");
confirmation = userInput.nextLine();
if ("Y".equalsIgnoreCase(confirmation)) {
playList.addTrack((PlayListTrack) new SimpleMusicTrack(title,
artist, album));
}
}
private static void displayNextSong(PlayList playList) {
MusicTrack currentMusicTrackToPlay;
MusicTrack nextMusicTrackToPlay;
currentMusicTrackToPlay = (MusicTrack) playList.getNextTrack();
nextMusicTrackToPlay = (MusicTrack) playList.peekAtNextTrack();
if (currentMusicTrackToPlay != null) {
System.out.println("Currently playing: "
+ currentMusicTrackToPlay.getName() + " / "
+ currentMusicTrackToPlay.getArtist());
} else {
System.out.println("Currently playing: No Song Playing");
}
if (nextMusicTrackToPlay != null) {
System.out.println("Next track to play: "
+ nextMusicTrackToPlay.getName() + " / "
+ nextMusicTrackToPlay.getArtist());
} else {
System.out.println("Play list is empty, no more tracks");
}
System.out.println("[P]lay next track");
System.out.println("[A]dd a new track");
System.out.println("[Q]uit");
}
}
You're using two Scanner's on the same stream (System.in). The first being userInput in the main method of your Project03 class. The second being inScanner in the readFile method of your SimplePlayList class:
public void readFile(Scanner in) {
Scanner inScanner = new Scanner(System.in); // <-- remove this line
Queue<PlayListTrack> queue = new LinkedList<PlayListTrack>();
while (in.hasNext()) {
queue.add(new SimpleMusicTrack(in.nextLine(), in.nextLine(), in
.nextLine()));
}
inScanner.close(); // <--- remove this line
}
Using multiple scanners on the same stream is the underlying problem. Scanners can (and will) consume the stream - this may (will) lead to unexpected side-effects. Best not to do it.
If the input is closed, then the input [...] is closed for everyone - and that's not much fun for anyone.
"Details" on why multiple scanners are bad: Do not create multiple buffered wrappers on an InputStream
- from user166390's answer on How to use multiple Scanner objects on System.in?

How to read elements of arraylist of a class defined in another class in java?

I am working on a project for my college.
i have two classes as "Email_info" and "contacts". In class "contacts", i made an Arraylist of type "Email_info". This class contacts is used to add data to a XML file("contacts.xml" ), and uses variables of email_info class. The problem is whenever i try to access elements of this "contacts.xml" file after unmarshalling the file, i get address as "mailwidgetaa.Email_info#12d3a4e9" instead of the actual data( which should be like, e_id- abc#gmail.com, pass- password). So how do I do get the actual data ?
below is the full code::
package mailwidgetaa;
#XmlRootElement
public class Contacts {
List<Email_info> contacList = new ArrayList<Email_info>();
#XmlElement
public List<Email_info> getContacList() {
return contacList;
}
public void setContacList(List<Email_info> contacList) {
this.contacList = contacList;
}
}
#XmlRootElement
class Email_info {
String e_id;
String u_name;
String pass;
#XmlElement
public String getE_id() {
return e_id;
}
public void setE_id(String e_id) {
this.e_id = e_id;
}
#XmlElement
public String getU_name() {
return u_name;
}
public void setU_name(String u_name) {
this.u_name = u_name;
}
#XmlElement
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
}
public class Mailwidgetaa {
public static void main(String[] args) {
contatcs con = new contacts();
con = null;
try {
JAXBContext jaxbc1 = JAXBContext.newInstance(Contacts.class);
Unmarshaller unmarsh = jaxbc1.createUnmarshaller();
con = (Contacts) unmarsh.unmarshal(new File("contacts.xml"));
} catch (Exception e) {
System.out.println("Exception " + e.getMessage());
}
Email_info ein = new Email_info();
ein.setE_id(ui);
ein.setU_name(un);
con.getContacList().add(ein);
try {
JAXBContext jaxbc = JAXBContext.newInstance(Contacts.class);
Marshaller marsh = jaxbc.createMarshaller();
marsh.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marsh.marshal(con, new File("contacts.xml"));
} catch (JAXBException e) {
System.out.println("EXCEPTION" + e.getMessage());
}
}
Iterator e= con.contacList.iterator();
while(e.hasNext()){
System.out.println(e.next());
}
}
That's because you haven't implemented toString method in your Email_Info class. Implement it like:
#Override
public String toString() {
return "e_id: " + e_id + " u_name: " + u_name + " pass: " + pass;
}

Categories

Resources