jaxb difference bwteen java 7 and java 6 - jaxb

I have a jaxb code which used to work in java 6, but after I update to java 7, it generated xml file differently.
in java 6, the file looks like this:
<ns2:recommendation>
<id>4</id>
<type>ARTICLE</type>
<name>Application-4</name>
<description>Great app called Application-4</description>
<publisher>Medio</publisher>
<category>Productivity</category>
<updated>01062001</updated>
<rating>4.0</rating>
<price>.99</price>
<currency>USD</currency>
<iconURI>http://medio.com</iconURI>
<downloadURI>http://medio.com</downloadURI>
<ns2:extensions>
<ns2:extension ns2:key="Sample">
<ns2:value>Extension</ns2:value>
</ns2:extension>
</ns2:extensions>
<ratingCount>35213614</ratingCount>
<downloadCount>12435854</downloadCount>
</ns2:recommendation>
in java 7, it is:
<ma:recommendation>
<id>3</id>
<type>ARTICLE</type>
<name>Application-3</name>
<description>Great app called Application-3</description>
<publisher>Medio</publisher>
<category>Productivity</category>
<updated>01062001</updated>
<rating>4.0</rating>
<price>.99</price>
<currency>USD</currency>
<iconURI>http://medio.com</iconURI>
<downloadURI>http://medio.com</downloadURI>
<_extensions>
<entry>
<key>Sample</key>
<value>Extension</value>
</entry>
</_extensions>
<ratingCount>35213614</ratingCount>
<downloadCount>12435854</downloadCount>
</ma:recommendation>
the difference is the extensions tag, which maps to a java code that doesn't change. anyone knows how to fix it?
java code for extensions:
#XmlRootElement(namespace = XMLNamespace.URL)
#XmlAccessorType(XmlAccessType.NONE)
#XmlType(namespace = XMLNamespace.URL)
public final class ExtensionMap extends HashMap<String, String> {
/** Serialized version unique identifier. */
private static final long serialVersionUID = -7235844731135521813L;
/**
* Default constructor to support JAXB binding.
*/
public ExtensionMap() {
super();
}
/**
* Default constructor to support JAXB binding.
* #param capacity The expected capacity of the map.
*/
public ExtensionMap(int capacity) {
super(capacity);
}
/**
* The list of wrapped Map entries that are structured for binding to XML
* with JAXB.
*
* #return The list of wrapped Map entries that are structured for binding
* to XML with JAXB.
*/
#XmlElement(name = "extension", namespace = XMLNamespace.URL, required = false)
#SuppressWarnings("unused")
private List<ExtensionMapElement> getEntries() {
return new ListAdapter();
}
/**
* The list of wrapped Map entries that are structured for binding to XML
* with JAXB.
*
* #param entries The list of wrapped Map entries that are structured for binding
* to XML with JAXB.
*/
#SuppressWarnings("unused")
private void setEntries(List<ExtensionMapElement> entries) {
if (entries != null) {
for (ExtensionMapElement entry : entries) {
put(entry.getKey(), entry.getValue());
}
}
}
/**
* Adapter for the list collection.
*
*/
private class ListAdapter implements List<ExtensionMapElement> {
#Override
public boolean add(ExtensionMapElement e) {
put(e.getKey(), e.getValue());
return true;
}
#Override
public void add(int index, ExtensionMapElement element) {
add(element);
}
#Override
public boolean addAll(Collection<? extends ExtensionMapElement> c) {
if (c != null) {
for (ExtensionMapElement element : c) {
add(element);
}
}
return true;
}
#Override
public boolean addAll(int index, Collection<? extends ExtensionMapElement> c) {
addAll(c);
return true;
}
#Override
public void clear() {
ExtensionMap.this.clear();
}
#Override
public boolean contains(Object o) {
throw new UnsupportedOperationException("Not supported yet.");
}
#Override
public boolean containsAll(Collection<?> c) {
throw new UnsupportedOperationException("Not supported yet.");
}
#Override
public ExtensionMapElement get(int index) {
throw new UnsupportedOperationException("Not supported yet.");
}
#Override
public int indexOf(Object o) {
throw new UnsupportedOperationException("Not supported yet.");
}
#Override
public boolean isEmpty() {
return ExtensionMap.this.isEmpty();
}
#Override
public Iterator<ExtensionMapElement> iterator() {
return new Iterator<ExtensionMapElement>() {
private Iterator<Map.Entry<String, String>> _iter = ExtensionMap.this.entrySet().iterator();
#Override
public boolean hasNext() {
return _iter.hasNext();
}
#Override
public ExtensionMapElement next() {
return new ExtensionMapElement(_iter.next());
}
#Override
public void remove() {
throw new UnsupportedOperationException("Not supported yet.");
}
};
}
#Override
public int lastIndexOf(Object o) {
throw new UnsupportedOperationException("Not supported yet.");
}
#Override
public ListIterator<ExtensionMapElement> listIterator() {
throw new UnsupportedOperationException("Not supported yet.");
}
#Override
public ListIterator<ExtensionMapElement> listIterator(int index) {
throw new UnsupportedOperationException("Not supported yet.");
}
#Override
public boolean remove(Object o) {
throw new UnsupportedOperationException("Not supported yet.");
}
#Override
public ExtensionMapElement remove(int index) {
throw new UnsupportedOperationException("Not supported yet.");
}
#Override
public boolean removeAll(Collection<?> c) {
throw new UnsupportedOperationException("Not supported yet.");
}
#Override
public boolean retainAll(Collection<?> c) {
throw new UnsupportedOperationException("Not supported yet.");
}
#Override
public ExtensionMapElement set(int index, ExtensionMapElement element) {
add(element);
return null;
}
#Override
public int size() {
return ExtensionMap.this.size();
}
#Override
public List<ExtensionMapElement> subList(int fromIndex, int toIndex) {
throw new UnsupportedOperationException("Not supported yet.");
}
#Override
public Object[] toArray() {
throw new UnsupportedOperationException("Not supported yet.");
}
#Override
public <T> T[] toArray(T[] a) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
}
/**
* A utility type that wraps map entries to support a mapping between a
* {#link java.util.Map} interface and a class that can be bound to XML using
* JAXB.
*/
#XmlRootElement(namespace = XMLNamespace.URL)
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(namespace = XMLNamespace.URL)
final class ExtensionMapElement implements Serializable {
/**
* Serialized version unique identifier.
*/
private static final long serialVersionUID = 8211130122512683829L;
/**
* The key of the wrapped map entry.
*/
#XmlAttribute(name = "key", namespace = XMLNamespace.URL, required = true)
private String _key;
/**
* The value of the wrapped map entry.
*/
#XmlElement(name = "value", namespace = XMLNamespace.URL, required = true)
private String _value;
/**
* Default constructor to support JAXB Binding.
*/
public ExtensionMapElement() {
}
/**
* Wraps a map entry with an instance of this class.
*
* #param e
* The map entry to wrap.
*/
public ExtensionMapElement(Map.Entry<String, String> e) {
_key = e.getKey();
_value = e.getValue();
}
/**
* The key of the wrapped map entry.
*
* #return The key of the wrapped map entry.
*/
public String getKey() {
return _key;
}
/**
* The value of the wrapped map entry.
*
* #return The value of the wrapped map entry.
*/
public String getValue() {
return _value;
}
}

Use
public final class ExtensionMap {
private Map<String, String> holder = new HashMap<String, String>();
public String put(String key, String value)
{
return holder.put(key, value);
}
// ...
instead of extanding HashMap.
Java 6 uses
public List<ExtensionMapElement> getEntries()
to get entries, but Java 7 ignore this method becouse you class extends HashMap

Related

How do I make a class definition for an ArrayList<byte[]>

I am trying to make my class implement VersionedPortable.
It has a field
ArrayList<byte[]> someMessages = new ArrayList<>();
How do I specify this field in my ClassDefiniton?
I assume it would be something like
new ClassDefinitionBuilder(FACTORY_ID, MESSAGE_BUNDLE_CLASS_ID, VERSION_ID)
.addPortableArrayField("someMessages", ?? what goes here ??)
And how would I read and write them?
Arrays of arrays are not supported in the Portable format by default. However, you can use the following trick to wrap the nested array as a separate Portable type and write your field as a Portable array.
class Foo implements Portable {
private ArrayList<byte[]> messages;
#Override
public int getFactoryId() {
return 1;
}
#Override
public int getClassId() {
return 1;
}
#Override
public void writePortable(PortableWriter writer) throws IOException {
Portable[] wrappedMessages = messages.stream()
.map(ByteArrayWrapper::new)
.toArray(Portable[]::new);
writer.writePortableArray("messages", wrappedMessages);
}
#Override
public void readPortable(PortableReader reader) throws IOException {
messages = Arrays.stream(reader.readPortableArray("messages"))
.map(item -> ((ByteArrayWrapper) item).getArray())
.collect(Collectors.toCollection(ArrayList::new));
}
}
class ByteArrayWrapper implements Portable {
private byte[] array;
public ByteArrayWrapper() {
}
public ByteArrayWrapper(byte[] array) {
this.array = array;
}
#Override
public int getFactoryId() {
return 1;
}
#Override
public int getClassId() {
return 2;
}
#Override
public void writePortable(PortableWriter writer) throws IOException {
writer.writeByteArray("array", array);
}
#Override
public void readPortable(PortableReader reader) throws IOException {
array = reader.readByteArray("array");
}
public byte[] getArray() {
return array;
}
}

JAXB not unmarshalling all fields

I am working on a JavaFX application which facilitates all kind of sport related training sessions. Each session consists of multiple exercises, whereas each exercise is repeated multiple times in a few sets. I created some test data and marshalled it. As it turned out, some fields of the Exercise class objects were written but not all of them. By adding the #XmlElement(name="someTagName") tag to each getter of each field I managed that all fields are marshalled and the xml file looks like expected. However, when I unmarshall the xml file, only those fields, which were written without the #XmlElement tag are read and most of the fields only have the default value from the constructor. What am I missing in order to unmarshall all fields?
Here is the class that I want to marshall/unmarshall
package domain;
import jakarta.xml.bind.annotation.XmlAttribute;
import jakarta.xml.bind.annotation.XmlElement;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class Exercise extends SelectableDomainObj {
protected StringProperty name;
protected StringProperty mediaFilePath;
protected IntegerProperty repsPerSet;
protected IntegerProperty numOfSets;
protected IntegerProperty breakBetweenSetsInSecs;
protected IntegerProperty displayTimeInSecs;
protected DoubleProperty startSpeed;
protected DoubleProperty endSpeed;
protected BooleanProperty withMetronom;
protected BooleanProperty showIntro;
/**
* Set some reasonable default values from lifting domain
*/
public Exercise() {
mediaFilePath = new SimpleStringProperty();
name = new SimpleStringProperty();
numOfSets = new SimpleIntegerProperty(3);
repsPerSet = new SimpleIntegerProperty(8);
breakBetweenSetsInSecs = new SimpleIntegerProperty(60);
displayTimeInSecs = new SimpleIntegerProperty(-1);
startSpeed = new SimpleDoubleProperty(1.0);
endSpeed = new SimpleDoubleProperty(1.0);
withMetronom = new SimpleBooleanProperty(false);
showIntro = new SimpleBooleanProperty(false);
}
#XmlElement(name="name")
public String getName() {
return name.get();
}
public void setName(String name) {
this.name.set(name);
}
public StringProperty nameProperty() {
return name;
}
#XmlElement(name="mediaFilePath")
public String getMediaFilePath() {
return mediaFilePath.get();
}
public void setMediaFilePath(String mediaFilePath) {
this.mediaFilePath.set(mediaFilePath);
}
public StringProperty mediaFilePathProperty() {
return mediaFilePath;
}
#XmlElement(name="repsPerSet")
public Integer getRepsPerSet() {
return repsPerSet.get();
}
public void setRepsPerSet(int repsPerSet) {
this.repsPerSet.set(repsPerSet);
}
public IntegerProperty repsPerSetProperty() {
return repsPerSet;
}
#XmlElement(name="numOfSets")
public int getNumOfSets() {
return numOfSets.get();
}
public void setNumOfSets(int numOfSets) {
this.numOfSets.set(numOfSets);
}
public IntegerProperty numOfSetsProperty() {
return numOfSets;
}
#XmlElement(name="breakBetweenSetsInSec")
public Integer getBreakBetweenSetsInSecs() {
return breakBetweenSetsInSecs.get();
}
public void setBreakBetweenSetsInSecs(int breakBetweenSetsInSecs) {
this.breakBetweenSetsInSecs.set(breakBetweenSetsInSecs);
}
public IntegerProperty displayTimeInSecsProperty() {
return displayTimeInSecs;
}
#XmlElement(name="displayTimeInSecs")
public Integer getDisplayTimeInSecs() {
return displayTimeInSecs.get();
}
public void setDisplayTimeInSecs(int displayTime) {
this.displayTimeInSecs.set(displayTime);
}
public IntegerProperty breakBetweenSetsInSecsProperty() {
return breakBetweenSetsInSecs;
}
#XmlElement(name="showIntro")
public Boolean isShowIntro() {
return showIntro.getValue();
}
public void setShowIntro(boolean showIntro) {
this.showIntro.set(showIntro);
}
public BooleanProperty showIntroProperty() {
return showIntro;
}
#XmlElement(name="withMetronom")
public Boolean isWithMetronom() {
return withMetronom.getValue();
}
public void setWithMetronom(boolean withMetronom) {
this.withMetronom.set(withMetronom);
}
public BooleanProperty withMetronomProperty() {
return withMetronom;
}
#XmlElement(name="startSpeed")
public Double getStartSpeed() {
return startSpeed.get();
}
public void setStartSpeed(double startDuration) {
this.startSpeed.set(startDuration);
}
public DoubleProperty startSpeedProperty() {
return startSpeed;
}
#XmlElement(name="endSpeed")
public Double getEndSpeed() {
return endSpeed.get();
}
public void setEndSpeed(double endDuration) {
this.endSpeed.set(endDuration);
}
public DoubleProperty endSpeedProperty() {
return endSpeed;
}
public double getSpeed(int rep) {
if(getStartSpeed().equals(getEndSpeed())) {
return getStartSpeed();
}
double min, max;
if(getStartSpeed() > getEndSpeed()) {
max = getStartSpeed();
min = getEndSpeed();
} else {
min = getStartSpeed();
max = getEndSpeed();
}
double diff = max - min;
double increment = diff / (getRepsPerSet()-1);
return min + rep * increment;
}
#Override
public String toString() {
return getName();
}
}
I used this to marshall
public void save(Session session) {
try {
JAXBContext jc = JAXBContext.newInstance(Session.class);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(session, new File(System.getProperty("user.home"), ".sifuSays/sessions/" + session.getName() + ".xml"));
} catch (JAXBException e) {
System.err.println("Cannot save session " + session.getName());
e.printStackTrace();
}
}
which generates the following xml file
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Session>
<exerciseList>
<exercise>
<selected>true</selected>
<breakBetweenSetsInSec>5</breakBetweenSetsInSec>
<displayTimeInSecs>-1</displayTimeInSecs>
<endSpeed>3.0</endSpeed>
<mediaFilePath>Tan Pak Gan.mp4</mediaFilePath>
<name>Solo Tan Pak Gan Drill</name>
<numOfSets>2</numOfSets>
<repsPerSet>3</repsPerSet>
<showIntro>false</showIntro>
<startSpeed>1.0</startSpeed>
<withMetronom>false</withMetronom>
</exercise>
<exercise>
<selected>true</selected>
<breakBetweenSetsInSec>5</breakBetweenSetsInSec>
<displayTimeInSecs>-1</displayTimeInSecs>
<endSpeed>1.0</endSpeed>
<mediaFilePath>Chain Punches.mp4</mediaFilePath>
<name>Solo Ein-Arm-Zyklus</name>
<numOfSets>2</numOfSets>
<repsPerSet>4</repsPerSet>
<showIntro>true</showIntro>
<startSpeed>1.0</startSpeed>
<withMetronom>true</withMetronom>
</exercise>
<exercise>
<selected>true</selected>
<breakBetweenSetsInSec>5</breakBetweenSetsInSec>
<displayTimeInSecs>10</displayTimeInSecs>
<endSpeed>1.0</endSpeed>
<mediaFilePath>birddogs.jpg</mediaFilePath>
<name>Stetching</name>
<numOfSets>1</numOfSets>
<repsPerSet>1</repsPerSet>
<showIntro>true</showIntro>
<startSpeed>1.0</startSpeed>
<withMetronom>false</withMetronom>
</exercise>
</exerciseList>
<breakBetweenExercisesInSec>10</breakBetweenExercisesInSec>
<name>MMA - Solo</name>
</Session>
and this is the unmarshaller code
public ObservableList<Session> loadSessions() {
sessions = FXCollections.observableArrayList();
try {
List<File> xmlSessionFiles = Stream.of(
new File(System.getProperty("user.home"), ".sifuSays/sessions/").listFiles())
.filter(file -> !file.isDirectory())
.filter(file -> file.getName().endsWith("xml"))
.collect(Collectors.toList());
for(File xmlSessionFile: xmlSessionFiles) {
JAXBContext jc = JAXBContext.newInstance(Session.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Session session = (Session) unmarshaller.unmarshal(xmlSessionFile);
sessions.add(session);
}
} catch (JAXBException e) {
System.err.println("Cannot load sessions");
e.printStackTrace();
}
return sessions;
}
While numOfSets is marshalled, repsPerset is not. Neither startSpeed or stopSpeed are unmarshalled and neither withMetronom or showIntro. But name and mediaFilePath are marshalled. What's wrong?
You are mixing up boxed (Double, Integer) and unboxed (double, int) types. I recommend sticking to boxed types for marshalling since otherwise you'll end up with things set to 0 that you weren't expecting.

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

How to pass parameters to Primefaces LazyDataModel load function

I have a implemented a lazy loading Datatable with primefaces that implements
load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String,Object> filters)
Now I need to pass parameters from my page to this method (i.e., I have a filter section in my page, the filters are not part of the table, and are independent objects!). My parameters are stored in the page's managed bean.
How can I achieve this?
Thanks!
Make the parameter(s) a property of the bean, and pass them directly to the service that fetches the data from the db (in this example the service is the EJB MyObjFacade myObjFacade):
#ManagedBean
#ViewScoped
public class MyBean {
#EJB
private MyObjFacade myObjFacade;
private LazyDataModel<MyObjType> model; // getter
private MyParameter myParameter;
#PostConstruct
public void init() {
model = new LazyDataModel<MyObjType> () {
#Override
public List<MyObjType> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
model.setRowCount(myObjFacade.count(filters, myParameter));
return myObjFacade.getResultList(first, pageSize, sortField, sortOrder, filters, myParameter);
}
};
model.setRowCount(myObjFacade.count(new HashMap<String, String> ()));
}
}
You simply have to provide the service implementing count and getResultList methods.
After many hours searching I finally did it. I leave here my solution for further reference.
//Managed Bean - View
public class DummyLazySearchPageBean {
private LazyDataModel<DummyObject> results;
private String searchFilter;//to simulate search filter
private DummyBusinessClass dummyBusinessClass;
public DummyLazySearchPageBean() {
results = new SearchsLazyLoader();
}
// GETTERS AND SETTERS
#SuppressWarnings("serial")
private final class SearchsLazyLoader extends LazyDataModel<DummyObject> {
#Override
public List<DummyObject> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String,Object> filters) {
//Simulate BD model
List<DummyObject> data = new ArrayList<DummyObject>();
dummyBusinessClass = new DummyBusinessClass();
data = dummyBusinessClass.search(searchFilter, 5000);
//rowCount
this.setRowCount(data.size());
//paginate
if(data.size() > pageSize) {
try {
return data.subList(first, first + pageSize);
}
catch(IndexOutOfBoundsException e) {
return data.subList(first, first + (data.size() % pageSize));
}
}
else {
return data;
}
}
}
public final void search(){
results = new SearchsLazyLoader();
}
}
Just Create Constructor of SearchsLazyLoader with parameter input.
This is sample of my code:
package com.mandiri.askes.model.lazy;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.Query;
import org.hibernate.Session;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
import com.mandiri.askes.model.Participant;
import com.mandiri.askes.utils.CallAble;
import com.mandiri.askes.utils.HibernateUtil;
public class LazyPesertaDataModel extends LazyDataModel<Participant> {
private static final long serialVersionUID = 1L;
private String keyword;
public LazyPesertaDataModel(String keyword) {
if (StringUtils.isNotEmpty(keyword)) {
this.keyword = keyword;
}else{
this.keyword = "";
}
}
/**
* Collect Peserta Badan Usaha as Data Model Primefaces
*
*/
#Override
public List<Participant> load(int first, int pageSize, String sortField,
SortOrder sortOrder, Map<String, String> filters) {
List<Participant> listPesertaBpjs = new ArrayList<Participant>();
listPesertaBpjs = getLazyDataPeserta(first, pageSize, sortField);
this.setRowCount(countAllRecord());
return listPesertaBpjs;
}
/**
* Get Peserta Data using hibernate pagination <b>(Lazy Loading)</b> Technique.
*
* #author Dibrut
* #param firstRecord
* #param maxResult
* #return
*/
#SuppressWarnings("unchecked")
public List<Participant> getLazyDataPeserta(final int firstRecord, final int maxResult, final String sortField) {
return HibernateUtil.doInTransaction(new CallAble<List<Participant>>() {
#Override
public List<Participant> call(Session session) throws Exception {
List<Participant> pesertaList = new ArrayList<Participant>();
String hql = "FROM com.dibrut.learn.model.Participant P"
+ " WHERE P.name LIKE :keyword";
Query query = session.createQuery(hql).setFirstResult(firstRecord).
setMaxResults(maxResult).setString("keyword", "%"+keyword+"%");
pesertaList = query.list();
return pesertaList;
}
});
}
/**
* Count total participant
* #return
* #author Dibrut
*/
public int countAllRecord(){
return HibernateUtil.doInTransaction(new CallAble<Integer>() {
#Override
public Integer call(Session session) throws Exception {
String hql = "FROM com.dibrut.learn.model.Participant P"
+ " WHERE P.name LIKE :keyword";
Long totalPesertaBu = (Long) session.createQuery(hql).
setString("keyword", "%"+ keyword+"%").
uniqueResult();
return totalPesertaBu.intValue();
}
});
}
public String getKeyword() {
return keyword;
}
public void setKeyword(String keyword) {
this.keyword = keyword;
}
}
if you want to search the data, just call the constructor with parameter of your managedBean property. for example you have searchParticipant method in your ManagedBean:
public void searchParticipant() {
this.participantLazyModel = new LazyPesertaDataModel(this.keyword);
}
where the keyword is value of inputText from your page.

Unmarshalling an XML document to Oracle Object Type using JAXB annotations

I am trying to unmarshal an XML document into an Oracle SQL Object Type.
Below is the sample XML :
<?xml version="1.0" encoding="UTF-8"?>
<order>
<ordernumber>123-01</ordernumber>
<customername>Idea Networks</customername>
<item>
<itemnumber>T-01</itemnumber>
<quantity>1</quantity>
<amount>10</amount>
</item>
<item>
<itemnumber>T-20</itemnumber>
<quantity>3</quantity>
<amount>8</amount>
</item>
</order>
Below is the definition of the oracle object type in oracle database :
CREATE OR REPLACE TYPE Item AS OBJECT
(
ItemNumber VARCHAR2(240)
,Quantity NUMBER
,Amount NUMBER
);
CREATE OR REPLACE TYPE ItemsArray IS TABLE OF Item;
CREATE OR REPLACE TYPE ItemOrder AS OBJECT
(
OrderNumber VARCHAR2(240)
,CustomerName VARCHAR2(240)
,Items ItemsArray
);
Now I used Jpublisher to generate the java classes for the object
java oracle.jpub.Doit -user=scott/tiger -sql=ItemOrder -package=xxcmpon.order.test
I have got total 5 classes generated (Item.java,ItemRef.java,ItemOrder.java,ItemOrderRef.java,Itemsarray.java)
The ItemOrder class looks as below :
package xxcmpon.order.test;
import java.sql.SQLException;
import java.sql.Connection;
import oracle.jdbc.OracleTypes;
import oracle.sql.ORAData;
import oracle.sql.ORADataFactory;
import oracle.sql.Datum;
import oracle.sql.STRUCT;
import oracle.jpub.runtime.MutableStruct;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
#XmlRootElement(name="order")
#XmlType(name = "ItemOrder", propOrder = {
"ordernumber",
"customername",
"items"
})
public class ItemOrder implements ORAData, ORADataFactory
{
public static final String _SQL_NAME = "SCOTT.ITEMORDER";
public static final int _SQL_TYPECODE = OracleTypes.STRUCT;
protected MutableStruct _struct;
protected static int[] _sqlType = { 12,12,2003 };
protected static ORADataFactory[] _factory = new ORADataFactory[3];
static
{
_factory[2] = Itemsarray.getORADataFactory();
}
protected static final ItemOrder _ItemOrderFactory = new ItemOrder();
public static ORADataFactory getORADataFactory()
{ return _ItemOrderFactory; }
/* constructors */
protected void _init_struct(boolean init)
{ if (init) _struct = new MutableStruct(new Object[3], _sqlType, _factory); }
public ItemOrder()
{ _init_struct(true); }
public ItemOrder(String ordernumber, String customername, Itemsarray items) throws SQLException
{ _init_struct(true);
setOrdernumber(ordernumber);
setCustomername(customername);
setItems(items);
}
/* ORAData interface */
public Datum toDatum(Connection c) throws SQLException
{
return _struct.toDatum(c, _SQL_NAME);
}
/* ORADataFactory interface */
public ORAData create(Datum d, int sqlType) throws SQLException
{ return create(null, d, sqlType); }
protected ORAData create(ItemOrder o, Datum d, int sqlType) throws SQLException
{
if (d == null) return null;
if (o == null) o = new ItemOrder();
o._struct = new MutableStruct((STRUCT) d, _sqlType, _factory);
return o;
}
/* accessor methods */
public String getOrdernumber() throws SQLException
{ return (String) _struct.getAttribute(0); }
public void setOrdernumber(String ordernumber) throws SQLException
{ _struct.setAttribute(0, ordernumber); }
public String getCustomername() throws SQLException
{ return (String) _struct.getAttribute(1); }
public void setCustomername(String customername) throws SQLException
{ _struct.setAttribute(1, customername); }
public Itemsarray getItems() throws SQLException
{ return (Itemsarray) _struct.getAttribute(2); }
public void setItems(Itemsarray items) throws SQLException
{ _struct.setAttribute(2, items); }
}
The Item class looks as below :
package xxcmpon.order.test;
import java.sql.SQLException;
import java.sql.Connection;
import oracle.jdbc.OracleTypes;
import oracle.sql.ORAData;
import oracle.sql.ORADataFactory;
import oracle.sql.Datum;
import oracle.sql.STRUCT;
import oracle.jpub.runtime.MutableStruct;
import javax.xml.bind.annotation.XmlType;
#XmlType(name = "Item", propOrder = {
"itemnumber",
"quantity",
"amount"
})
public class Item implements ORAData, ORADataFactory
{
public static final String _SQL_NAME = "SCOTT.ITEM";
public static final int _SQL_TYPECODE = OracleTypes.STRUCT;
protected MutableStruct _struct;
protected static int[] _sqlType = { 12,2,2 };
protected static ORADataFactory[] _factory = new ORADataFactory[3];
protected static final Item _ItemFactory = new Item();
public static ORADataFactory getORADataFactory()
{ return _ItemFactory; }
/* constructors */
protected void _init_struct(boolean init)
{ if (init) _struct = new MutableStruct(new Object[3], _sqlType, _factory); }
public Item()
{ _init_struct(true); }
public Item(String itemnumber, java.math.BigDecimal quantity, java.math.BigDecimal amount) throws SQLException
{ _init_struct(true);
setItemnumber(itemnumber);
setQuantity(quantity);
setAmount(amount);
}
/* ORAData interface */
public Datum toDatum(Connection c) throws SQLException
{
return _struct.toDatum(c, _SQL_NAME);
}
/* ORADataFactory interface */
public ORAData create(Datum d, int sqlType) throws SQLException
{ return create(null, d, sqlType); }
protected ORAData create(Item o, Datum d, int sqlType) throws SQLException
{
if (d == null) return null;
if (o == null) o = new Item();
o._struct = new MutableStruct((STRUCT) d, _sqlType, _factory);
return o;
}
/* accessor methods */
public String getItemnumber() throws SQLException
{ return (String) _struct.getAttribute(0); }
public void setItemnumber(String itemnumber) throws SQLException
{ _struct.setAttribute(0, itemnumber); }
public java.math.BigDecimal getQuantity() throws SQLException
{ return (java.math.BigDecimal) _struct.getAttribute(1); }
public void setQuantity(java.math.BigDecimal quantity) throws SQLException
{ _struct.setAttribute(1, quantity); }
public java.math.BigDecimal getAmount() throws SQLException
{ return (java.math.BigDecimal) _struct.getAttribute(2); }
public void setAmount(java.math.BigDecimal amount) throws SQLException
{ _struct.setAttribute(2, amount); }
}
The Itemsarray class looks as below :
package xxcmpon.order.test;
import java.sql.SQLException;
import java.sql.Connection;
import oracle.jdbc.OracleTypes;
import oracle.sql.ORAData;
import oracle.sql.ORADataFactory;
import oracle.sql.Datum;
import oracle.sql.ARRAY;
import oracle.sql.ArrayDescriptor;
import oracle.jpub.runtime.MutableArray;
import javax.xml.bind.annotation.XmlElement;
public class Itemsarray implements ORAData, ORADataFactory
{
public static final String _SQL_NAME = "SCOTT.ITEMSARRAY";
public static final int _SQL_TYPECODE = OracleTypes.ARRAY;
MutableArray _array;
private static final Itemsarray _ItemsarrayFactory = new Itemsarray();
public static ORADataFactory getORADataFactory()
{ return _ItemsarrayFactory; }
/* constructors */
public Itemsarray()
{
this((Item[])null);
}
public Itemsarray(Item[] a)
{
_array = new MutableArray(2002, a, Item.getORADataFactory());
}
/* ORAData interface */
public Datum toDatum(Connection c) throws SQLException
{
return _array.toDatum(c, _SQL_NAME);
}
/* ORADataFactory interface */
public ORAData create(Datum d, int sqlType) throws SQLException
{
if (d == null) return null;
Itemsarray a = new Itemsarray();
a._array = new MutableArray(2002, (ARRAY) d, Item.getORADataFactory());
return a;
}
public int length() throws SQLException
{
return _array.length();
}
public int getBaseType() throws SQLException
{
return _array.getBaseType();
}
public String getBaseTypeName() throws SQLException
{
return _array.getBaseTypeName();
}
public ArrayDescriptor getDescriptor() throws SQLException
{
return _array.getDescriptor();
}
/* array accessor methods */
public Item[] getArray() throws SQLException
{
return (Item[]) _array.getObjectArray(
new Item[_array.length()]);
}
public Item[] getArray(long index, int count) throws SQLException
{
return (Item[]) _array.getObjectArray(index,
new Item[_array.sliceLength(index, count)]);
}
public void setArray(Item[] a) throws SQLException
{
_array.setObjectArray(a);
}
public void setArray(Item[] a, long index) throws SQLException
{
_array.setObjectArray(a, index);
}
public Item getElement(long index) throws SQLException
{
return (Item) _array.getObjectElement(index);
}
public void setElement(Item a, long index) throws SQLException
{
_array.setObjectElement(a, index);
}
}
To the above classes I have added the JAXB annotations for reading the XML document.
I am trying to unmarshal the xml document and print it through a sample script as shown below :
public class Main {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(ItemOrder.class);
Unmarshaller u = jc.createUnmarshaller();
Marshaller m = jc.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
try {
ItemOrder orderx = (ItemOrder)u.unmarshal(new FileInputStream("order.xml"));
Itemsarray items = orderx.getItems();
System.out.println("Order Number : " + orderx.getOrdernumber());
//Item[] itemo = items.getArray();
//System.out.println("Item Number : " + itemo[0].getItemnumber());
m.marshal(orderx, System.out);
} catch(javax.xml.bind.UnmarshalException e){
System.out.println("Main: " + e);
} catch(Exception e1){
System.out.println("Main: " + e1);
e1.printStackTrace();
}
}
}
[ttr12#rstnssiovm0015 test]$ java xxcmpon.order.test.Main
Order Number : 123-01
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<order>
<ordernumber>123-01</ordernumber>
<customername>Idea Networks</customername>
</order>
[ttr12#rstnssiovm0015 test]$
I am expecting the output to be displayed with the items as shown below :
<?xml version="1.0" encoding="UTF-8"?>
<order>
<ordernumber>123-01</ordernumber>
<customername>Idea Networks</customername>
<item>
<itemnumber>T-01</itemnumber>
<quantity>1</quantity>
<amount>10</amount>
</item>
<item>
<itemnumber>T-20</itemnumber>
<quantity>3</quantity>
<amount>8</amount>
</item>
</order>
I think I am missing some annotation to bind the items array, which I am not able figure out.
Can somebody please let me know what is the annotation I am missing and where to add that?
Thanks for your help.
I would suggest you to prepare the ItemOrder object with several Item's in it programmatically and then marshal it to the standard output. The marshaled XML will obviously different from one you created manually. It will give you an idea, what is wrong with your original XML.
You, presumably will be able to unmarshal that XML back into the Java- class without any problem.

Resources