Data Loss when XMLSerialization occurs with derived and base class inheritance - c#-4.0

When I tried to serialize a generic list of objects, I get some data loss, with any of the variables that are used by the derived classes. I used to have those variables in the derived class, but since the base class was getting serialized I assumed the derived variables would get ignored.
The Code:
[XmlInclude(typeof(AchievementStock))]
[XmlInclude(typeof(AchievementCash))]
[XmlInclude(typeof(AchievementStockSpecify))]
public abstract class Achievement : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected string _title;
protected string _description;
protected int _cashValue;
protected bool _completed;
//Cash
protected int _amountCash;
protected bool _greater;
//Stocks
protected int _amountStocks;
//StockSpecify
protected string _stockName;
protected int _amount;
public abstract void CheckAchievement(AssetManager assetManager, AchievementManager achievementManager);
public Achievement()
{
}
public Achievement(string title, string description, int cashValue, bool completed)
{
Title = title;
Description = description;
_cashValue = cashValue;
_completed = completed;
}
public void PropertyChangedEvent(string assetName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(assetName));
}
}
}
public class AchievementCash : Achievement
{
public AchievementCash(string title, string description, int cashValue, bool completed, int amountCash, bool greater)
: base(title, description, cashValue, completed)
{
_amountCash = amountCash;
_greater = greater;
}
public AchievementCash()
{
}
public override void CheckAchievement(AssetManager assetManager, AchievementManager achievementManager)
{
}
}
public class AchievementStock : Achievement
{
public AchievementStock(string title, string description, int cashValue, bool completed, int amountStocks)
: base(title, description, cashValue, completed)
{
_amountStocks = amountStocks;
}
public AchievementStock()
{
}
public override void CheckAchievement(AssetManager assetManager, AchievementManager achievementManager)
{
}
}
public class AchievementStockSpecify : Achievement
{
public AchievementStockSpecify(string title, string description, int cashValue, bool completed, string stockName, int amount)
: base(title, description, cashValue, completed)
{
_stockName = stockName;
_amount = amount;
}
public AchievementStockSpecify()
{
}
public override void CheckAchievement(AssetManager assetManager, AchievementManager achievementManager)
{
}
}
The variables that become default value are:
//Cash
protected int _amountCash;
protected bool _greater;
//Stocks
protected int _amountStocks;
//StockSpecify
protected string _stockName;
protected int _amount;
Anyone have any ideas on why this is occurring?

You must have public fields rather than protected fields as only public properties and fields can be serialized by XMLSerializer.

Related

Model mapper mapping Map<String,Object> to class which extends another generic class not working for list field

I am trying to create my custom configuration object from Map using model mapper. Everything gets mapped properly excepts the fields property which is coming fro Generic super class.
My target object is
public class ADParserConfig extends CustomParserConfig<ADParserConfigField> {
private String pattern;
public String getPattern() {
return pattern;
}
public void setPattern(String pattern) {
this.pattern = pattern;
}
}
This extends generic class CustomParserConfig
public class CustomParserConfig<T extends CustomParserConfigField> {
protected List<T> fields;
protected String timeStampField;
public List<T> getFields() {
return fields;
}
public void setFields(List<T> fields) {
this.fields = fields;
}
public String getTimeStampField() {
return timeStampField;
}
public void setTimeStampField(String timeStampField) {
this.timeStampField = timeStampField;
}
}
Where CustomParserConfigField is
public class CustomParserConfigField {
protected String name;
protected Integer index;
protected String type;
protected String format;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getIndex() {
return index;
}
public void setIndex(Integer index) {
this.index = index;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getFormat() {
return format;
}
public void setFormat(String format) {
this.format = format;
}
}
I am trying to map Map using below function
ADParserConfig adParserConfig = getConfig(map,ADParserConfig.class);
public <T extends CustomParserConfig> T getConfig(Map<String,Object> configObject, Class<T> classType){
ModelMapper modelMapper = new ModelMapper();
return modelMapper.map(configObject,classType);
}
Everything excepts fields gets mapped properly for the below map.
{fields=[{name=timeStamp, type=timestamp, format=dd/mm/yyyy HH:MM:SS a}, {name=logName, type=string}], pattern=(?<timeStamp>\d{2}\/\d{2}\/\d{4}\s\d{2}:\d{2}:\d{2}\s[AMPMampm]{2})?\s(LogName=(?<logName>[\w\s\W]+))?\sSourceName=(?<sourceName>[\w\s\W]+)\sEventCode=(?<eventCode>[0-9]*), timeStampField=timestamp}
Please help. Why is issue happens only for fields object ? Do I need to specify something else in mapper configurations ?
It looks like a bug and it had been fixed by #370

issues with parcelable extension: getting unmarshalling unknown type code exception

long story short, I have one settlementItemeBase class as my father and two children. I want to make the father class parcelable so as extension happens, my two child classes be parcelable as well. I don't exactly know what I'm doing right or wrong. I searched little bit but nothing helped me.
here are my classes:
SettlementItemBase:
public class SettlementItemBase implements Parcelable{
public SettlementItemBase(){}
protected SettlementItemBase(Parcel in) {
}
public static final Creator<SettlementItemBase> CREATOR = new Creator<SettlementItemBase>() {
#Override
public SettlementItemBase createFromParcel(Parcel in) {
return new SettlementItemBase(in);
}
#Override
public SettlementItemBase[] newArray(int size) {
return new SettlementItemBase[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
}
}
first child class:
public class FirstClass extends SettlementItemBase {
private int id;
private int cardId;
private String cardNumber;
private String expDate;
private String currency;
private String url;
public FirstClass(){
id = 0;
cardId = 0;
cardNumber = "";
expDate = "";
currency = "";
url = "";
}
protected FirstClass(Parcel in) {
super(in);
id = in.readInt();
cardId = in.readInt();
cardNumber = in.readString();
expDate = in.readString();
currency = in.readString();
url = in.readString();
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeInt(cardId);
dest.writeString(cardNumber);
dest.writeString(expDate);
dest.writeString(currency);
dest.writeString(url);
}
public int getId() {
return id;
}
public int getCardId() {
return cardId;
}
public String getCardNumber() {
return cardNumber;
}
public String getExpDate() {
return expDate;
}
public String getCurrency() {
return currency;
}
public String getUrl() {
return url;
}
}
second child class:
public class SecondClass extends SettlementItemBase{
private int id;
private String currency;
private String accountNumber;
private String ibanNumber;
public SecondClass(int id, String currency,
String accountNumber, String ibanNumber){
this.id = id;
this.currency = currency;
this.accountNumber = accountNumber;
this.ibanNumber = ibanNumber;
}
protected SecondClass(Parcel in){
super(in);
id = in.readInt();
currency = in.readString();
accountNumber = in.readString();
ibanNumber = in.readString();
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeString(currency);
dest.writeString(accountNumber);
dest.writeString(ibanNumber);
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCurrency() {
return currency;
}
public String getAccountNumber() {
return accountNumber;
}
public String getIbanNumber() {
return ibanNumber;
}
}
I'm passing and getting an ArrayList of both child class' items with intent putParcelableArrayListExtra and getParcelableArrayListExtra methods and get the following error:
Parcel android.os.Parcel#2d0fde33: Unmarshalling unknown type code 3276849 at offset 172
any help would be appreciated 3>
well I'm posting this for those who may run into the same problem as me.
the problem was solved after adding the Creator statement to the child classes.
for one of the child classes it would be like:
public static final Creator<FirstClass> CREATOR = new Creator<FirstClass>() {
#Override
public FirstClass createFromParcel(Parcel in) {
return new FirstClass(in);
}
#Override
public FirstClass[] newArray(int size) {
return new FirstClass[size];
}
};
hope this helps. 3>

JaxB Marshaling in camel

I am new to Apache camel and Jax b concept in java.
I have a list of java objects in a camel queue. I want to Marshall it to an xml with Javs DSL(without using spring).
Could any one guide me to do that?
I have the following POJO class
public class MyPojo {
private int groupId;
private int memberId;
private String details;
public int getgroupId() {
return groupId;
}
public void setgroupId(int groupId) {
this.groupId = groupId;
}
public int getMemberId() {
return memberId;
}
public void setMemberId(int memberId) {
this.memberId = memberId;
}
public String getdetails() {
return details;
}
public void setdetails(String details) {
this.details = details;
}}
following is my camel code for jaxb implementation
JaxbDataFormat jaxbMarshal = new JaxbDataFormat();
jaxbMarshal.setContextPath("com.test");
jaxbMarshal.setPartClass("com.test.MyPojo");
from("direct:javaObjects") //this direct having the list of MYPojo Objects
.marshal(jaxbMarshal)
.to("src/output");
I am getting below exception(I added maven dependency for jaxb in classpath)
Failed to create route route4 at: >>> Marshal[org.apache.camel.model.dataformat.JaxbDataFormat#3feb2dda] <<< in route: Route(route4)[[From[direct:javaObjects]] -> [Marshal[org.apa... because of Data format 'jaxb' could not be created. Ensure that the data format is valid and the associated Camel component is present on the classpath
I have created the jaxb.index file(new->File from eclipse). the content of the file should be annotation class name
In our case it should be
MyPojo
and its needs to be placed in context path. in our case it should be placed in
com.test location
and the annotated Pojo class is
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement
public class MyPojo {
#XmlElement
private int groupId;
#XmlElement
private int memberId;
#XmlElement
private String details;
public int getgroupId() {
return groupId;
}
public void setgroupId(int groupId) {
this.groupId = groupId;
}
public int getMemberId() {
return memberId;
}
public void setMemberId(int memberId) {
this.memberId = memberId;
}
public String getdetails() {
return details;
}
public void setdetails(String details) {
this.details = details;
}}
You can use your pojo with some annotations:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name="MY-POJO")
#XmlType(propOrder = {"groupId", "memberId", "details"})
public class MyPojo {
#XmlElement(name = "groupId")
private int groupId;
#XmlElement(name = "memberId")
private int memberId;
#XmlElement(name = "details")
private String details;
public int getgroupId() {
return groupId;
}
public void setgroupId(int groupId) {
this.groupId = groupId;
}
public int getMemberId() {
return memberId;
}
public void setMemberId(int memberId) {
this.memberId = memberId;
}
public String getdetails() {
return details;
}
public void setdetails(String details) {
this.details = details;
}}

proxy pattern no suitable methods found to override? Help i'm not sure what just went wrong

This is all in the form...
namespace Proxy_Pattern
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
double bankAmount = 1000.00;
private void btnCheck_Click(object sender, EventArgs e)
{
double amount;
amount = double.Parse(txtAmount.Text);
CheckProxy cp =new CheckProxy();
cp.CheckTransactionRequest(amount);
lbltotal.Text = bankAmount.ToString();
}
private void btnCreditCard_Click(object sender, EventArgs e)
{
}
}
abstract class BankSubject
{
public abstract void CreditTransactionRequest(double amount);
public abstract void CheckTransactionRequest(double amount);
}
class RealBankSubject : BankSubject
{
double bank;
public RealBankSubject(double m_bacc)
{
bank = m_bacc;
}
public override void CreditTransactionRequest(double num)
{
bank -= num;
}
public override void CheckTransactionRequest(double num)
{
bank += num;
}
}
Does not implement inherited abstract members.... but why?
class CreditCardProxy : BankSubject
{
RealBankSubject realSubject;
double amount;
public CreditCardProxy (double m_bacc)
{
amount = m_bacc ;
}
no suitable method to override?... how is this an error? I have a method right here?
public override void CreditTransactionRequest()
{
if (realSubject == null)
{
realSubject = new RealBankSubject(amount);
}
realSubject.CreditTransactionRequest(amount);
}
public override void CheckTransactionRequest()
{
}
}
class CheckProxy : BankSubject
{
RealBankSubject realSubject;
double amount;
public override void CreditTransactionRequest()
{
}
public override void CheckTransactionRequest()
{
if (realSubject == null)
{
realSubject = new RealBankSubject(amount);
}
realSubject.CheckTransactionRequest(amount);
}
}
}
In your proxy, you are not specifying the amount as a parameter to the method:
public override void CreditTransactionRequest();
So it cannot override
public abstract void CreditTransactionRequest(double amount);
as the method signature doesn't not match
CreditTransactionRequest in CreditCardProxy does not take any arguments but CreditTransactionRequest in BankSubject does. This is why you can not override the method the signatures do not match.

How can I set the RowKey to a new value with a sequence

I have the following class:
public class Note : TableServiceEntity
{
public Note( )
{
}
public Note(string pK)
{
PartitionKey = pK,
RowKey = Seq.GetSequence().ToString();
}
public string Description { get; set; }
}
What I need is to set the RowKey to the value generated by the sequence. Can anyone explain how to do this with a constructor? What I get is a syntax error: Virtual member call in constructor.
public static class Seq
{
static int index;
public static int GetSequence()
{
return index++;
}
}
public class Note : TableServiceEntity
{
public Note(string partitionKey, string rowKey)
: base(partitionKey, Seq.GetSequence().ToString()) { }
}

Resources