XStream different alias for same class (Map.class) for different fields - xml-serialization

I am using XStream to convert a Java class which has fields of the type java.util.Map. I have a converter for java.util.Map which displays the key of the Map as an xml element and the value of the map as the value for the xml element. I have registered the converter using registerConverter method. When I perform the marshalling, I get the following output.
<cart account_id="123" shift_id="456" account_postings_id="641">
<supervisor_id>555</supervisor_id>
<payments>
<map sequence="1">
<amount>123.45</amount>
<billing_method>12345</billing_method>
<form>card</form>
<delivery_mode>Q</delivery_mode>
</map>
<map sequence="2">
<amount>123.45</amount>
<person_id>2333</person_id>
<form>cash</form>
<delivery_mode>Q</delivery_mode>
</map>
</payments>
<items>
<map sequence="3">
<amount>1.00</amount>
<type>pay_toll</type>
<toll_id>1234</toll_id>
</map>
</items>
</cart>
Instead of the map tags appearing, I would want to use different tags based on the field name in the class. For example, the Payments list will have tag name payment and the Items list will have a tag name item for each Map element.
How do we dynamically set alias based on field in the same class?
-Anand

I used XStream to create atom feed reports. Entries in the contents can be of different object classes and I wanted to use the class name dynamically. Here is my solution. I created a ObjectContentConverter and passed the XStream on, and then use xstream.aliasField() with getClass().getSimpleName().
private class ObjectContentConverter implements Converter {
XStream xStream;
private ObjectContentConverter(XStream xStream) {
this.xStream = xStream;
}
#Override
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
String className = WordUtils.uncapitalize(source.getClass().getSimpleName());
xStream.aliasField(className, Content.class, "objectContent");
xStream.marshal(source, writer);
}
#Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
#Override
public boolean canConvert(Class type) {
return true; //To change body of implemented methods use File | Settings | File Templates.
}
}
xStream.registerLocalConverter(Content.class, "objectContent", new ObjectContentConverter(xStream));

Related

create a new document from word template with multiple pages using documentformat.openxml

I have a Microsoft Word template with some content controls. It contains a table of contents and some extra information.
On the page, I have set some content controls where I would like to inject a new text from a RESTful service. If the RESTful service returns an array of data (objects), I need to replicate the information on each page based on the Word template.
Any idea on how can I do that using the Open XML SDK (DocumentFormat.OpenXml)?
Edit:
I found this post here, which is great, but I don't know how can I apply the array of data to multiple pages from the same template.
So, how can I create multiple pages from the same template in a new document? The data comes in as an array.
The sample code below (which is unit-tested and works) does what you are trying to achieve. It is based on the following interpretation of the question and assumptions:
"Control place holders" means "Rich Text content controls", which are called block-level structured document tags (SDTs) in Open XML lingo and are thus represented by the SdtBlock class in the Open XML SDK.
The content controls have tags, meaning the relevant w:sdt elements have grandchild elements like <w:tag="tagValue" />. Those tags are used to link the data received from the REST service to the content controls.
The data is provided as a Dictionary<string, string>, mapping tag values to the content control text (data).
The general approach is to perform a pure functional transformation of the main document part of your WordprocessingDocument. The void WriteContentControls(WordprocessingDocument) method wraps the outermost pure functional transformation object TransformDocument(OpenXmlElement). The latter uses an inner pure functional transformation object TransformSdtBlock(OpenXmlElement, string).
public class ContentControlWriter
{
private readonly IDictionary<string, string> _contentMap;
/// <summary>
/// Initializes a new ContentControlWriter instance.
/// </summary>
/// <param name="contentMap">The mapping of content control tags to content control texts.
/// </param>
public ContentControlWriter(IDictionary<string, string> contentMap)
{
_contentMap = contentMap;
}
/// <summary>
/// Transforms the given WordprocessingDocument by setting the content
/// of relevant block-level content controls.
/// </summary>
/// <param name="wordDocument">The WordprocessingDocument to be transformed.</param>
public void WriteContentControls(WordprocessingDocument wordDocument)
{
MainDocumentPart part = wordDocument.MainDocumentPart;
part.Document = (Document) TransformDocument(part.Document);
}
private object TransformDocument(OpenXmlElement element)
{
if (element is SdtBlock sdt)
{
string tagValue = GetTagValue(sdt);
if (_contentMap.TryGetValue(tagValue, out string text))
{
return TransformSdtBlock(sdt, text);
}
}
return Transform(element, TransformDocument);
}
private static object TransformSdtBlock(OpenXmlElement element, string text)
{
return element is SdtContentBlock
? new SdtContentBlock(new Paragraph(new Run(new Text(text))))
: Transform(element, e => TransformSdtBlock(e, text));
}
private static string GetTagValue(SdtElement sdt) => sdt
.Descendants<Tag>()
.Select(tag => tag.Val.Value)
.FirstOrDefault();
private static T Transform<T>(T element, Func<OpenXmlElement, object> transformation)
where T : OpenXmlElement
{
var transformedElement = (T) element.CloneNode(false);
transformedElement.Append(element.Elements().Select(e => (OpenXmlElement) transformation(e)));
return transformedElement;
}
}
This should provide enough input for implementing your specific solution even if the details vary (e.g., regarding how you map your array of data to the specific content controls). Further, if you don't use block-level structured document tags (SdtBlock, Rich Text content controls) but but rather inline-level structured document tags (SdtRun, plain text content controls), the principle is the same. Instead of the Paragraph instances (w:p elements) contained in SdtContentBlock instances, you would have Run instances (w:r elements) contained in SdtContentRun instances.
Update 2019-11-23: My CodeSnippets GitHub repository contains the code for the ContentControlWriter and AltChunkAssemblyTests classes. The latter shows how the ContentControlWriter class can be used.

ZK: loading value/text into selectbox

I have a selectbox and want to load the value and text into the template, similar to an HTML dropdown box. I am using ZK framework with Java on the back end.
<selectbox id="buListbox" model="${$composer.buModel}" >
<template name="model">
<label value="${each}" />
</template>
</selectbox>
When using ZK, you don't need the value to identify the selected object like in HTML.
When using the MVC pattern, binding a model via model attribute, the selected item is also stored in that model and can be retrieved in java via model.getSelection().
Furthermore, a model is not restricted to lists of String, but it can hold any object type you want. In the template section, you can display any property of that object. Then the properties' toString() method is used to get the value which is displayed. This also applies to ${each} itself.
Example:
Assuming your model is a ListModelList of type ValueType:
public class ValueType {
private String value;
private String text;
public ValueType(String value, String text) {
this.value=value;
this.text=text;
}
public String getText() {
return this.text;
}
public String getValue() {
return this.value;
}
}
private ListModelList<ValueType> typesModel;
public ListModelList<ValueType> getTypesModel() {
return typesModel;
}
You than can use the selectbox's model/template to display it's text property:
<selectbox id="typesSelectbox" model="${$composer.typesModel}">
<template name="model">
${each.text}
</template>
</selectbox>
In java, you then get the selected item via typeModel.getSelection() .
Here you can find a working ZKFiddle example.

JSF: store form data to a map

I'm developing a JSF page that contains a form with a lot of input string values. I don't want to create a corresponding field in the bean for each input . Is it possible to use a map instead.
Here's what i want my form input element to look like:
<h:inputText value='#{myBean.data["key"]}' /> // or something like this
And the bean contains the map as follows:
class myBean {
Map data;
...
}
What should getter and setter for map operation look like if I create such a code?
Nothing special. Just a standard getter as you should always use for model properties.
public Map<String, Object> getData() {
return data;
}
A setter is not mandatory as it won't be used anyway. EL will use map's own put() method for that. You only need to make sure that the map is already precreated in bean's (post)constructor, JSF/EL won't do that for you.
public MyBean() {
data = new HashMap<String, Object>();
}

Number format in ZKOSS label

is there any way to format number in ZK label component that looks like like
<label value="${each.value}" /> ? Values are doubles and I want to separate thousands etc... I know that doublebox for example has format property but what if I just want to display number as label? Thanks for any help.
Feature Request
First of all I have opened a feature request for this on ZK's tracking system you can find it here. Please follow this if you want updates.
Ways of implementing
There are in fact ways of implementing this depending on what pattern & techniques you are using.
MVC & EL
You can create an EL function which will do the formatting for you in your ZUL file. First of all create a class such as this:
public class FormatElNumber {
public static String formatStock(double stock) {
final NumberFormat nf = NumberFormat.getInstance();
nf.setMaximumFractionDigits(2);
return nf.format(stock);
}
}
This will output numbers with two decimal places. Secondly you need to add this to the top of your zul file:
<?xel-method prefix="c" name="formatStock" class="demo.grid.hierarchy.FormatElNumber"
signature="java.lang.String formatStock(double)"?>
Then when you have a label you can do as follows:
<label style="color:red;" value="${c:formatStock(each.averageHigh)}" />
More infomration on this technique is available here.
MVVM
The MVVM is actually easier to implement, you create what's called a Converter, for example (please note this class is untested, but you get the idea).
public class NumberFormatConverter implements Converter {
#Override
public Object coerceToBean(Object val, Component comp, BindContext ctx) {
return null;
}
#Override
public Object coerceToUi(Object val, Component comp, BindContext ctx) {
if(!(val instanceof Integer)) {
throw new IllegalArgumentException("The argument must be a number!");
}
final Object tmp = ctx.getConverterArg("length");
int length = 0;
if(tmp instanceof Integer) {
length = (Integer)tmp;
}
final NumberFormat nf = NumberFormat.getInstance();
nf.setMaximumFractionDigits(length);
return nf.format(val);
}
}
Then all you do in your zul file is specify you would like to use a converter on the value, for example:
<label value="#load(vm.message) #converter(vm.myConverter)"/>
For more information on this technique you can refer here.
From the docs: http://books.zkoss.org/wiki/ZUML_Reference/EL_Expressions/Core_Methods/formatNumber
<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?>
<zk>
<label value="${c:formatNumber(2332315231, '$ ###,###,###.00')}" />
</zk>

Binding a bean property to a TextField in GXT 3.0

I am working on a ExtGWT 3.0 (beta) application.
I have a simple Java bean containing one property:
public class MyBean {
private String content;
// getter and setter here...
}
I want to bind the property to a TextField.
I have created an interface:
interface MyBeanProperties extends PropertyAccess<MyBean> {
ValueProvider<MyBean, String> content();
}
But what's next? How do I tell the TextField to bind to that particular property of a particular MyBean object?
PropertyAccess is used to generically refer to an objects properties, often for data widgets that use a Store like the grid or charts. For binding a form to a bean, check out GWT's editor framework at http://code.google.com/webtoolkit/doc/latest/DevGuideUiEditors.html. There are some examples for this with GXT at http://www.sencha.com/examples/#ExamplePlace:basicbinding%28uibinder%29
Roughly, you'll build a form widget that wraps all the properties you need, and make an editor driver for that editor and its bean:
public class MyBeanEditor implements Editor<MyBean> {
// do any kind of widget setup you like, just make sure to have methods/fields
// package protected or higher that extends Editor (Field extends Editor)
TextField content;
}
//... declare the driver
interface Driver extends SimpleBeanEditorDriver<MyBean, MyBeanEditor> {}
//... use the driver to bind a form to a bean
Driver driver = GWT.create(Driver.class);
driver.initialize(myBeanEditorInstance);
driver.edit(myBean);
//... when save is clicked (or a timer, or whatever), get the value and do
// something with it
MyBean model = driver.flush();