Is there a JAXB annotation that allows us to hide certain values with an enumeration?
For instance, if I wanted to hide the value BLUE in the following enum:
public enum COLOR {
RED,
YELLOW,
GREEN,
@SomeAnnotation
BLUE
}
Is there a way to do this per spec?
EDIT: Some commenters mentioned this doesn't make sense to want to do. I (respectfully) disagree. There is precedent for this in the JAXB/Web Service world. Here is the situation I am thinking of:
Using Java-First Web Service Design, classes and enums are directly translated into XSDs and exposed via Web Services. Now there may be cases in which we want to hide certain (sensitive?) data from the Web Service, but leave it available for libraries accessing the code directly. For class fields, JAXB provides an @XmlTransient annotation to hide fields that should not be exposed via a Web Service - it only follows that this need can exist for enum values as well.
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB 2 (JSR-222) expert group.
The following example works with EclipseLink JAXB (MOXy), but appears to throw an exception with the version of JAXB included in the JDK I'm using (Oracle JDK 1.6.0_29).
COLORAdapter
I used an XmlAdapter to convert the enum value to a String. If the value is BLUE then I returned null as the String value. This will cause JAXB to not marshal the corresponding node.
package forum10192641;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class COLORAdapter extends XmlAdapter<String, COLOR> {
@Override
public COLOR unmarshal(String v) throws Exception {
return COLOR.valueOf(v);
}
@Override
public String marshal(COLOR v) throws Exception {
if(v == COLOR.BLUE) {
return null;
}
return v.name();
}
}
COLOR
The XmlAdapter is registered using the @XmlJavaTypeAdapter annotation. If you want the adapter applied to all instances of COLOR then you can specify the adapter on the COLOR enum itself.
package forum10192641;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlJavaTypeAdapter(COLORAdapter.class)
public enum COLOR {
RED,
YELLOW,
GREEN,
BLUE
}
Foo
Below is a domain class with three properties of type COLOR:
package forum10192641;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Foo {
private COLOR color1;
private COLOR color2;
private COLOR color3;
public COLOR getColor1() {
return color1;
}
public void setColor1(COLOR color1) {
this.color1 = color1;
}
public COLOR getColor2() {
return color2;
}
public void setColor2(COLOR color2) {
this.color2 = color2;
}
public COLOR getColor3() {
return color3;
}
public void setColor3(COLOR color3) {
this.color3 = color3;
}
}
jaxb.properties
The specify MOXy as your JAXB provider you need to include a file named jaxb.properties in the same package as your domain model with the following entry:
javax.xml.bind.context.factory = org.eclipse.persistence.jaxb.JAXBContextFactory
Demo
package forum10192641;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Foo.class);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
Foo foo = new Foo();
foo.setColor1(COLOR.GREEN);
foo.setColor2(COLOR.BLUE);
foo.setColor3(COLOR.RED);
marshaller.marshal(foo, System.out);
}
}
Output
Below is the output from running the demo code.
<?xml version="1.0" encoding="UTF-8"?>
<foo>
<color1>GREEN</color1>
<color3>RED</color3>
</foo>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With