1

I am trying to serialize an object type enum declared in my serializable class. I have already red all topics here but I did not find an answer to my issue. I hope someone can help me here. I actually am trying to serialize 2 objects type SType and CbitSet but I get the follow result:

<rSIt>
  <sType>S_V_INC</sType>
  <bits/>
  <mHave>true</mHave>
</rSIt>

I am expecting something like:

<rSIt>
  <sType>
     <code>VI</code>
     <description>V Inc</description>
     <name>S_V_INC</name>
  </sType>
  <bits>
    <words>{long[7]@5285}</words>
    <wordsInUse>7</wordsInUse>
    <sizeIsSticky>false</sizeIsSticky>
  <bits>
  <mHave>true</mHave>
</rSIt>

Here is my code:

    @XmlRootElement(name="rSIt")
    @XmlAccessorType(XmlAccessType.FIELD)
    public class RSIt implements Serializable{
        private static final long serialVersionUID = -5848959699974019999L;
        @XmlElement
        private SType sType;
        @XmlElement
        private CbitSet bits = new CbitSet();
        @XmlElement
        private boolean mHave = true;

        public SType getSType() {
            return this.sType;
        }
        public void setSType(SType sType) {
            this.sType = sType;
        }
        public CbitSet getBits() {
            return this.bits;
        }

        public boolean ismHave() {
            return this.mHave;
        }
        public void setmHave(boolean mHave) {
            this.mHave = mHave;
        }

        public RSIt() {
            super();
        }

        public RSIt(SType sType, boolean mHave) {
            super();
            this.sType = sType;
            this.mHave = mHave;
        }

        public RSIt(SType sType, boolean mHave, Integer bit) {
            super();
            this.sType = sType;
            this.mHave = mHave;
            this.bits.set(bit);
        }
        }
    This is the implementation of SType  class (it is an Enum class):
    public enum SType {
        S_V_INC ("VI", "V Inc"),
        S_V_EXC ("VE", "V Exc"),
        S_RP_INC ("RI", "RP Inc"),
        S_RP_EXC ("RE", "RP Exc"),
        S_V_AN_F ("VA", "V F All");

        private final String code;
        private final String description;
        SearchType (String code, String description) {
            this.code = code;
            this.description = description;
        }
        public String getCode() {
            return code;
        }
        public String getDescription() {
            return description;
        }
    }
    This is the implementation of CbitSet class
    import java.util.BitSet;
    @XmlRootElement(name="rSIt")
    @XmlAccessorType(XmlAccessType.FIELD)
    public class CbitSet extends BitSet implements Serializable{
        private static final long serialVersionUID = 476550000000055127L;

        private static final long longOne = 1;
        private static final long long64 = 64;

        public CbitSet() {
            super();
        }

        public long[] toLongArray() {
            long[] longs = new long[this.size() / 64];
            for (int i = 0; i < longs.length; i++)
                for (int j = 0; j < 64; j++)
                    if (this.get(i * 64 + j))
                        longs[i] |= longOne << j;
            return longs;
        }

        public void fromLongArray(long[] longs) {
            for (int i=0; i<longs.length*64; i++) {
                if ((longs[i/64]&(longOne<<(i%long64))) != 0) {
                    this.set(i);
                }
            }
        }

        public String toBitString() {
            StringBuilder sb = new StringBuilder();
            for (int x = 0; x < this.size(); x++) {
                if (this.get(x)) {
                    sb.append("1");
                } else {
                    sb.append("0");
                }
            }
            return sb.toString();       
        }

        public void fromBitString(String string) {
            int pos = 0;
            for (byte chr : string.getBytes()) {
                if ('1' == chr) {
                    this.set(pos);
                }
                pos++;
            }
        }
        public void set(List<Integer> bits) {
            set(bits,true);
        }
        public void set(List<Integer> bits, boolean value) {
            if (bits != null) {
                for (Integer bit : bits) {
                    if (bit != null) {
                        this.set(bit.intValue(), value);
                    }
                }
            }
        }
        public void set(Integer bitIndex) {
            if (bitIndex != null) {
                super.set(bitIndex);
            }
        }
        public void set(Integer bitIndex, boolean value) {
            if (bitIndex != null) {
                super.set(bitIndex, value);
            }
        }   
    }

    Thank you for your help guys.
Irina Avram
  • 1,492
  • 2
  • 20
  • 35

1 Answers1

0

I am also learning ... and I tend to agree with the answer from another SO question (here) that

Enums in Java are meant to be immutable objects, in which case there is no point in serializing any of their fields.

However, if, for any reason, that you insist to get the marshalled result as you have specified, I found that I could do that by changing SType from an enum to a class, and then embedding another enum called EnumSType in it.

The code looks like this:

package SerializationQuestion1;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

@XmlRootElement(name="sType")
@XmlAccessorType(XmlAccessType.FIELD)   
public class SType {
    public enum EnumSType {
        S_V_INC ("VI", "V Inc"),
        S_V_EXC ("VE", "V Exc"),
        S_RP_INC ("RI", "RP Inc"),
        S_RP_EXC ("RE", "RP Exc"),
        S_V_AN_F ("VA", "V F All");

        @XmlElement
        private final String code;
        @XmlElement
        private final String description;
        EnumSType (String code, String description) {   // Bug fix 1
            this.code = code;
            this.description = description;
        }
        public String getCode() {
            return code;
        }
        public String getDescription() {
            return description;
        }
    }

    @XmlTransient
    private EnumSType sType;

    public EnumSType getsType() {
        return sType;
    }

    public void setsType(EnumSType sType) {
        this.sType = sType;
    }

    public SType () {};

    public SType (EnumSType sType) {
        this.sType = sType;
    }

    @XmlElement
    public String getCode() { return this.sType.getCode();};

    @XmlElement
    public String getDescription() { return this.sType.getDescription();};

    @XmlElement
    public String getName() { return this.sType.name();};
}

To instantiate an RSIt object, the code looks like this now:

RSIt rsit = new RSIt(new SType(EnumSType.S_V_INC), true, null);

The following was my marshalled output:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<rSIt>
    <sType>
        <code>VI</code>
        <description>V Inc</description>
        <name>S_V_INC</name>
    </sType>
    <bits/>
    <mHave>true</mHave>
</rSIt>
Community
  • 1
  • 1
leeyuiwah
  • 6,562
  • 8
  • 41
  • 71
  • 1
    Thank you very much leeyuiwah for your quick response. The only problem if I do that is that, I will have to modify multiple projects that are using this enum class. I am trying to think there is another alternative... – Vanessa Paradissio Dec 28 '16 at 17:26
  • No one has an idea regarding the CbitSet bits object ? – Vanessa Paradissio Dec 28 '16 at 19:27
  • What is an example input? – leeyuiwah Dec 28 '16 at 19:30
  • What is the definition of `words`, `wordsInUse`, and `sizeIsSticky`? And what does it mean by `long[7]@5285` – leeyuiwah Dec 28 '16 at 19:32
  • private long[] words; – Vanessa Paradissio Dec 28 '16 at 19:35
  • Please give an example input. – leeyuiwah Dec 28 '16 at 19:38
  • These fields are from BitSet class that my CBitSet class implements. private long[] words; private transient int wordsInUse = 0; private transient boolean sizeIsSticky = false; – Vanessa Paradissio Dec 28 '16 at 19:44
  • {long[7]@5285} 7 false – Vanessa Paradissio Dec 28 '16 at 19:45
  • I looked through your code for `CbitSet` multiple times. I didn't see it has the three fields called `words`, `wordsInUse`, nor `sizeIsSticky`. There are only two constants called `long64` and `longOne`. I realized that your `CbitSet` extends `BitSet`, but I don't think those three fields are exposed by the class. – leeyuiwah Dec 28 '16 at 19:49
  • Yes, that is exact leeyuiwah. I actually will need to declare an attribute called toLongArray that will get the value of the public long[] toLongArray() method. So that I can get the long array value by doing this RSIt.getBits().getToLongArray, once toLongArray is serialized. – Vanessa Paradissio Dec 28 '16 at 19:59
  • Even if `BitSet` internally has `words`, `wordsInUse`, and `sizeIsSticky`, they are internal to the class and have been declared `private` (not `protected`), so your class `CbitSet` does not have access to their values. – leeyuiwah Dec 28 '16 at 20:29
  • leeyuiwah, I am totally agree with you, that is why few methods like set are defined into my CbitSet class to modify their values. I was wrong when I asked my question at the begining but what I am trying to do is that I need to create an ettibute that hold the result of toLongArray() method and serialize this toLongArray data, because I need it. I really can not serialize CBitSetAgain thank you for your help leeyuiwah. I did something like that: private static final long longOne = 1;private static final long long64 = 64; @XmlElement(name="toLongArray") private long[] toLongArray; – Vanessa Paradissio Dec 28 '16 at 20:43