Xstream parsing multiple list - java

I have a xml file where there are multiple arrays in the root element. Whenever am trying to use the implicitcollection declaration, the xstream is only processing the last declaration and everything else remains null. In the below code the first array ERRORS remains null whereas DEBITS is parsed.
public class XMLParser {
/**
* #param args
* #throws Exception
*/
public static void main(String[] args){
String xmlString = "<DebitsWSDS xmlns=\"\"> " +
" <DEBITS> " +
" <DEBIT_ID>-1</DEBIT_ID> " +
" </DEBITS> " +
" <DEBITS> " +
" <DEBIT_ID>-2</DEBIT_ID> " +
" </DEBITS> " +
" <ERRORS> " +
" <ERROR_ID>1</ERROR_ID> " +
" </ERRORS> " +
" <ERRORS> " +
" <ERROR_ID>2</ERROR_ID> " +
" </ERRORS> " +
"</DebitsWSDS> ";
DebitsWSDS debitsWSDS;
try {
debitsWSDS = convertFeesSetXMLResultToDebitsWSDS(xmlString);
System.out.println(debitsWSDS.ERRORS==null);
System.out.println(debitsWSDS.DEBITS==null);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static DebitsWSDS convertFeesSetXMLResultToDebitsWSDS(String xml) throws Exception{
XStream xstream = new XStream(new StaxDriver());
xstream.alias("DebitsWSDS", DebitsWSDS.class);
xstream.addImplicitCollection(DebitsWSDS.class, "DEBITS");
xstream.addImplicitCollection(DebitsWSDS.class, "ERRORS");
xstream.alias("ERROR_ID", String.class);
//System.out.println(xml);
DebitsWSDS debitsWSDS =(DebitsWSDS)xstream.fromXML(xml);
return debitsWSDS;
}
}
public class DebitsWSDS {
public List<ERROR> ERRORS;
public List<DEBIT> DEBITS;
public class ERROR {
public String ERROR_ID;
}
public class DEBIT {
public String DEBIT_ID;
}
}

I'm not quite sure what you'd expect it to do. XStream is a bean/XML mapping tool, and you effectively have two XML lists mapped to the same List element in your bean. If you really want that XML strucutre I would construct your bean using a SAX parser or similar, create an empty list and let the parser callbacks add to that list.

Related

Saving List<T> as String

I've been trying to save a list of data as Strings, but when I try a method .toString on List, it returns address in memory instead of data.
public class Item {
Integer price = 20;
Integer modelNumber = 100;
String description = "Description";
String title = "Title";
Boolean wasBought = true;
}
public static void main(String[] args) {
List<Item> data = new ArrayList<>();
data.add(new Item());
System.out.println(data.toString());
}
You need to override toString function in your Item class. Add the following snippet into your Item class:
#Override
public String toString() {
return "Item{" +
"price=" + price +
", modelNumber=" + modelNumber +
", description='" + description + '\'' +
", title='" + title + '\'' +
", wasBought=" + wasBought +
'}';
}
Output:
[Item{price=20, modelNumber=100, description='Description', title='Title', wasBought=true}]
You can convert List to json format string by json utils, e.g. jackson or fastjson, in case you may need to convert it to Objects later.
Simply use Lombok (Add Lombok jar into classpath) #ToString annotate for Item class, it will do the needful output https://projectlombok.org/features/ToString

Youtube Search Command for JDA Discord Music Bot

I've been working on a Discord bot for a few days now.
Initially only with simpler commands etc. But slowly I also devoted myself to the topic of music bot.
I also use the YouTube Data API for this and everything works so far. However, I would now like to incorporate a Youtube Search Command or build it into another (Play Command). I already have half a search command.
So far you can do $play (song title)
and the first track found will be selected.
However, I want to be able to see the first 10 search results and then choose between them.
I have already figured out how to display the search results, but now I need a little help with how to enter a command, after you have already entered another.
So you enter: $play Faded
Then a normal EmbedBuilder comes up and shows you the search results, and then you can select the desired track by entering 1, 2, 3, 4, 5, 6, 7, 8, 9 or 10.
This is the code:
public class PlayCommand implements ServerCommand {
private final YouTube youTube;
public PlayCommand() {
YouTube temp = null;
try {
temp = new YouTube.Builder(
GoogleNetHttpTransport.newTrustedTransport(),
JacksonFactory.getDefaultInstance(),
null
)
.setApplicationName("JDA Discord Bot")
.build();
} catch (Exception e) {
e.printStackTrace();
}
youTube = temp;
}
#Override
public void performCommand(List<String> args, Member m, TextChannel channel, Message message) throws RiotApiException {
String input = String.join(" ", args.subList(1, args.size() - 1));
if (!isUrl(input)) {
String ytSearched = searchYoutube(channel, input);
if (ytSearched == null) {
channel.sendMessage("Keine Ergebnisse!").queue();
return;
}
input = ytSearched;
}
PlayerManager manager = PlayerManager.getInstance();
manager.loadAndPlay(channel, input);
manager.getGuildMusicManager(channel.getGuild()).player.setVolume(100);
}
private boolean isUrl(String input) {
try {
new URL(input);
return true;
} catch (MalformedURLException ignored) {
return false;
}
}
#Nullable
private String searchYoutube(TextChannel channel, String input) {
String youtubeKey = "AIzaSyDoQ4OInMTYth7hdlWwQSIaHuxpxxv7eJs";
try {
List<SearchResult> results = youTube.search()
.list("id,snippet")
.setQ(input)
.setMaxResults(10L)
.setType("video")
.setFields("items(id/kind,id/videoId,snippet/title,snippet/thumbnails/default/url)")
.setKey(youtubeKey)
.execute()
.getItems();
if (!results.isEmpty()) {
String videoId = results.get(0).getId().getVideoId();
/*EmbedBuilder builder = new EmbedBuilder();
builder.setTitle("Suchergebnisse");
builder.setColor(Color.RED);
builder.setDescription( "1. " + results.get(0).getSnippet().getTitle() + "\n" +
"2. " + results.get(1).getSnippet().getTitle() + "\n" +
"3. " + results.get(2).getSnippet().getTitle() + "\n" +
"4. " + results.get(3).getSnippet().getTitle() + "\n" +
"5. " + results.get(4).getSnippet().getTitle() + "\n" +
"6. " + results.get(5).getSnippet().getTitle() + "\n" +
"7. " + results.get(6).getSnippet().getTitle() + "\n" +
"8. " + results.get(7).getSnippet().getTitle() + "\n" +
"9. " + results.get(8).getSnippet().getTitle() + "\n" +
"10. " + results.get(9).getSnippet().getTitle());
channel.sendMessage(builder.build()).queue();
*/
return "https://www.youtube.com/watch?v=" + videoId;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
I think you are looking for an EventWaiter.
With JDA-Utilities you can achieve what you want.
You just basically wait for an event, check if it's suitable for the use case of yours (eg: is a specific event, or contains a specific text)
Check out this stackoverflow answer about EventWaiter and adding it as an EventListener.
You would want to check if the received text for example is part of the youtube search result. Also don't forget about having a time limit for accepting answers.

Why do I get, and how do I solve this "String to object of type <objecttype>" error

I am (being an absolute beginner), trying to create a simple tool, that creates some objects and links them.
The objects are:
Customers
Licenses (2 types, extends class)
The idea is to use (one of) the customer company name when creating a license, so the license is linked to a customer.
I use ArrayLists to store the data.
I tried to use the getter for Customer cCompany, but when I try to actually create a new license object, I get errors about incompatible types (String to object of type customer)
How can I fix that error?
Any help is highly appreciated, but please explain well, me being an absolute beginner. I probably overcomplicate stuff....
Some code extracts:
From Main:
public class Main {
public static void main(String[] args) {
//Create customers
List <Customer> customers = new ArrayList <> (10);
customers.add(new Customer("TestCompany","John Doe",1234567890,"John#testcompany.com"));
....
//Create Elvis licenses (based on superclass License)
List <ElvisLicense> ellicenses = new ArrayList <> (10);
ellicenses.add(new ElvisLicense("TestCompany","VendorA",1234,"1234-A","Solutions Server gold","1234-dtbk-87654-nlof",10, true , true));
Class: Customer:
class Customer {
String cCompany;
private String cName;
private int cPhone;
private String cEmail;
public Customer( String cCompany, String cName,int cPhone, String cEmail)
{
this.cCompany = cCompany;
this.cName = cName;
this.cPhone = cPhone;
this.cEmail = cEmail;
}
//This getter should be used to link the license to the customer (Done in License.java)
public String getcCompany() {
return cCompany;
}
Class License (Superclass)
class License {
// Used no modifier to set access for Class/Package and Subclass inside the package
Customer licenseCompany;
String lVendor;
int lContractNumber;
String lCertificateNumber;
String lProductName;
String lLicenseKey;
int lNumberOfSeats;
public License(Customer cCompany, String lVendor, int lContractNumber, String lCertificateNumber,
String lProductName, String lLicenseKey, int lNumberOfSeats)
{
licenseCompany = cCompany;
this.lVendor = lVendor;
this.lVendor = lVendor;
this.lContractNumber = lContractNumber;
this.lCertificateNumber = lCertificateNumber;
this.lProductName = lProductName;
this.lLicenseKey = lLicenseKey;
this.lNumberOfSeats = lNumberOfSeats;
}
public Customer getLicenseCompany() {
return licenseCompany;
}
public void setLicenseCompany(Customer licenseCompany) {
this.licenseCompany = licenseCompany;
}
//preparations to allow for example printing the content of an arraylist element
#Override
public String toString(){
return "Customer name " + getLicenseCompany() + "\n" + "Vendor name " + getlVendor() + "\n" + "Contract number: " + getlContractNumber() + "\n"
+ "Certificate number: " + getlCertificateNumber() + "\n" +
"Product name " + getlProductName() + "\n" + "Licence key: " + getlLicenseKey() + "\n"
+ "Number of seats: " + getlNumberOfSeats();
}
}
And the extended class:
public class ElvisLicense extends License{
private boolean elIsBundle;
private boolean elIsSubscription;
public ElvisLicense(
Customer licenseCompany,
String lVendor,
int lContractNumber,
String lCertificateNumber,
String lProductName,
String lLicenseKey,
int lNumberOfSeats,
boolean elIsBundle,
boolean elIsSubscription
)
{
super(
licenseCompany,
lVendor,
lContractNumber,
lCertificateNumber,
lProductName,
lLicenseKey,
lNumberOfSeats);
this.elIsBundle = elIsBundle;
this.elIsSubscription = elIsSubscription;
}
.....
#Override
public String toString(){
return "Customer name " + licenseCompany + "\n"
+ "Vendor name " + lVendor + "\n"
+ "Contract number: " + lContractNumber + "\n"
+ "Certificate number: " + lCertificateNumber + "\n"
+ "Product name " + lProductName + "\n"
+ "Licence key: " + lLicenseKey + "\n"
+ "Number of seats: " + lNumberOfSeats + "\n"
+ "Number of seats: " + elIsBundle + "\n"
+ "Number of seats: " + elIsSubscription;
}
}
I expect that the Customername is used when creating a new license.
Below line is wrong.
ellicenses.add(new ElvisLicense("TestCompany","VendorA",1234,"1234-A","Solutions Server gold","1234-dtbk-87654-nlof",10, true , true));
As license need customer object an parameter. Instead, you should create customer object first.
ellicenses.add(new ElvisLicense(new Customer("TestCompany","VendorA",1234,"1234-A"),"Solutions Server gold","1234-dtbk-87654-nlof",10, true , true));
for reusing that customer list to avoid create company.
for(Customer customer : customers){
// here you need some way to offer other parameters except customer parameter.
License license = new new ElvisLicense(customer,"Solutions Server gold","1234-dtbk-87654-nlof",10, true , true);
ellicenses.add(license);
}
What you need to do is to use one of the Customer objects you have already created when creating the ElvisLicense object. To more easily find that customer by name I suggest you store them in a map instead of a list with the name as a key.
Map<String, Customer> customerMap = new HashMap<>();
Customer customer = new Customer("TestCompany","John Doe",1234567890,"John#testcompany.com"));
customerMap.put(customer.getcCompany(), customer);
so when creating the license you look up the customer
List <ElvisLicense> ellicenses = new ArrayList <> (10);
Customer customer = customerMap.get("TestCompany");
if (customer != null) {
ElvisLicense license = new ElvisLicense(customer,"VendorA",1234,"1234-A","Solutions Server gold","1234-dtbk-87654-nlof",10, true , true));
ellicenses.add(license);
} else {
//If the customer isn't found you need some kind of error handling, better than below :)
System.out.println("Can't create a license, no customer found");
}

Using JSONAssert to check if an item exists in a JSON array

I have a JSONObject that is similar to something like this:
{
"category":"abc"
"staus":""open"
"external":[
{"name":"123", "type":"OTHER"},
{"name":"678", "type":"ALPHA"},
{"name":"890", "type":"DELTA"}
]
}
If I want to use JSONAssert to check if the item {"name":"678"} exists and I don't know the item's order and the number of items in the "external" array, how should I do in Java?
It seems the ArrayValueMatcher should be the way to go but I just cannot get it works.
Please help
You could use JsonPath for this usecase :
JSONArray array = JsonPath.read(json, "$.external[?(#.name == '678')]");
Assertions.assertThat(array).hasSize(1);
Here is a complete example using JsonAssert:
#Test
public void foo() throws Exception {
String jsonString = "{\n" +
" \"category\":\"abc\",\n" +
" \"staus\":\"open\",\n" +
" \"external\":[\n" +
" {\"name\":\"123\", \"type\":\"OTHER\"},\n" +
" {\"name\":\"678\", \"type\":\"ALPHA\"},\n" +
" {\"name\":\"890\", \"type\":\"DELTA\"}\n" +
" ]\n" +
"}";
JsonAssert.with(jsonString).assertThat("$.external[*].name", hasItem(equalTo("678")));
}

Bean reference is coming as null

I have a context config file like so :
applicationContect.xml:
<bean id="CalcValidate" class="com.fmr.pmsvcs.orders.fixture.utility.CalcValidate" >
<property name="orderRestServiceL" >
<ref local="OrderRestService" />
</property>
</bean>
And my class looks like bellow :
CalcValidate.java
public class CalcValidate {
public static OrderRestService orderRestServiceL;
public static OrderRestService getOrderRestServiceL() {
return orderRestServiceL;
}
public static void setOrderRestServiceL(OrderRestService orderRestServiceL) {
CalcValidate.orderRestServiceL = orderRestServiceL;
}
public static String getNetAssets(String user, BigInteger fundid,
Order CalcOrder) throws Exception {
PortfolioReferenceParameter par =
orderRestServiceL.netAssets(user, fundid);
if (par.getPortfolios().get(0) == null
&& CalcOrder.getPortfolioTna() == null
&& CalcOrder.getPortfolioTnaUsd() == null) {
System.out
.println(" ##### PASS Portfolio Net Asset are null in service and DB");
return OrderFixtureConstants.TRUE;
}
// *** Validate against Net Asset in Fund Base Currency
if (!par.getPortfolios().get(0).getTotalNetAssets()
.equals(CalcOrder.getPortfolioTna())) {
return ("FAIL net Asset in response ["
+ CalcOrder.getPortfolioTna()
+ " ] doesn't match net Asset in DB ["
+ par.getPortfolios().get(0).getTotalNetAssets() + " ]");
}
System.out.println(" ##### PASS net Asset in response ["
+ CalcOrder.getPortfolioTna()
+ " ] does match net Asset in DB ["
+ par.getPortfolios().get(0).getTotalNetAssets() + " ]");
// *** Validate against Net Asset in Fund Base Currency
if (!par.getPortfolios().get(0).getTotalNetAssetsUSD()
.equals(CalcOrder.getPortfolioTnaUsd())) {
return ("FAIL net Asset USD in response ["
+ CalcOrder.getPortfolioTnaUsd()
+ " ] doesn't match net Asset in DB ["
+ par.getPortfolios().get(0).getTotalNetAssetsUSD() + " ]");
}
System.out.println(" ##### PASS net Asset in response ["
+ CalcOrder.getPortfolioTnaUsd()
+ " ] does match net Asset in DB ["
+ par.getPortfolios().get(0).getTotalNetAssetsUSD() + " ]");
return OrderFixtureConstants.TRUE;
}
}
In later part of my class I am calling a method like orderRestServiceL.getMethod();
Here "orderRestServiceL" coming as null. Anybody has any Idea how to resolve this?
Your issue seems to be related to the Java class field.
it is declared as static while it should be non-static:
public class CalcValidate {
private OrderRestService orderRestServiceL;
public OrderRestService getOrderRestServiceL() {
return orderRestServiceL;
}
public void setOrderRestServiceL(OrderRestService orderRestServiceL) {
this.orderRestServiceL = orderRestServiceL;
}

Categories