// *************************************************************************************************************************** | |
// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * | |
// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * | |
// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * | |
// * with the License. You may obtain a copy of the License at * | |
// * * | |
// * http://www.apache.org/licenses/LICENSE-2.0 * | |
// * * | |
// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * | |
// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * | |
// * specific language governing permissions and limitations under the License. * | |
// *************************************************************************************************************************** | |
package org.apache.juneau.dto.cognos; | |
import java.util.*; | |
import org.apache.juneau.*; | |
import org.apache.juneau.annotation.*; | |
import org.apache.juneau.xml.annotation.*; | |
/** | |
* Represents a Cognos dataset. | |
* | |
* <p> | |
* When serialized to XML, creates the following construct (example pulled from <c>AddressBookResource</c>): | |
* <p class='bcode w800'> | |
* <xt><?xml</xt> <xa>version</xa>=<xs>'1.0'</xs> <xa>encoding</xa>=<xs>'UTF-8'</xs><xt>?></xt> | |
* <xt><c:dataset <xa>xmlns:c</xa>=<xs>'http://developer.cognos.com/schemas/xmldata/1/'</xs>></xt> | |
* <xt><c:metadata></xt> | |
* <xt><c:item</xt> <xa>name</xa>=<xs>'name'</xs> <xa>type</xa>=<xs>'xs:String'</xs> | |
* <xa>length</xa>=<xs>'255'</xs><xt>/></xt> | |
* <xt><c:item</xt> <xa>name</xa>=<xs>'age'</xs> <xa>type</xa>=<xs>'xs:int'</xs><xt>/></xt> | |
* <xt><c:item</xt> <xa>name</xa>=<xs>'numAddresses'</xs> <xa>type</xa>=<xs>'xs:int'</xs><xt>/></xt> | |
* <xt></c:metadata></xt> | |
* <xt><c:data></xt> | |
* <xt><c:row></xt> | |
* <xt><c:value></xt>Barack Obama<xt></c:value></xt> | |
* <xt><c:value></xt>52<xt></c:value></xt> | |
* <xt><c:value></xt>2<xt></c:value></xt> | |
* <xt></c:row></xt> | |
* <xt><c:row></xt> | |
* <xt><c:value></xt>George Walker Bush<xt></c:value></xt> | |
* <xt><c:value></xt>67<xt></c:value></xt> | |
* <xt><c:value></xt>2<xt></c:value></xt> | |
* <xt></c:row></xt> | |
* <xt></c:data></xt> | |
* <xt></c:dataset></xt> | |
* </p> | |
* | |
* <p> | |
* Only 2-dimensional POJOs (arrays or collections of maps or beans) can be serialized to Cognos. | |
* | |
* <h5 class='section'>Example:</h5> | |
* | |
* The construct shown above is a serialized <c>AddressBook</c> object which is a subclass of | |
* <c>LinkedList<Person></c>. | |
* The code for generating the XML is as follows... | |
* <p class='bcode w800'> | |
* Column[] items = { | |
* <jk>new</jk> Column(<js>"name"</js>, <js>"xs:String"</js>, 255), | |
* <jk>new</jk> Column(<js>"age"</js>, <js>"xs:int"</js>), | |
* <jk>new</jk> Column(<js>"numAddresses"</js>, <js>"xs:int"</js>) | |
* .addPojoSwap( | |
* <jk>new</jk> PojoSwap<Person,Integer>() { | |
* <ja>@Override</ja> | |
* <jk>public</jk> Integer swap(Person p) { | |
* <jk>return</jk> p.<jf>addresses</jf>.size(); | |
* } | |
* } | |
* ) | |
* }; | |
* | |
* DataSet ds = <jk>new</jk> DataSet(items, <jsf>addressBook</jsf>, BeanContext.<jsf>DEFAULT</jsf>); | |
* | |
* String xml = XmlSerializer.<jsf>DEFAULT_SQ</jsf>.serialize(ds); | |
* </p> | |
*/ | |
@SuppressWarnings("unchecked") | |
@Bean(typeName="dataset", bpi="metadata,data") | |
public class DataSet { | |
private Column[] metaData; | |
private List<Row> data; | |
/** Bean constructor. */ | |
public DataSet() {} | |
/** | |
* Constructor. | |
* | |
* @param columns The meta-data that represents the columns in the dataset. | |
* @param o | |
* The POJO being serialized to Cognos. | |
* Must be an array/collection of beans/maps. | |
* @param session The bean session used to convert POJOs to strings. | |
* @throws Exception An error occurred trying to serialize the POJO. | |
*/ | |
public DataSet(Column[] columns, Object o, BeanSession session) throws Exception { | |
metaData = columns; | |
data = new LinkedList<>(); | |
if (o != null) { | |
if (o.getClass().isArray()) | |
o = Arrays.asList((Object[])o); | |
if (o instanceof Collection) { | |
Collection<?> c = (Collection<?>)o; | |
for (Object o2 : c) { | |
Row r = new Row(); | |
Map<?,?> m = null; | |
if (o2 instanceof Map) | |
m = (Map<?,?>)o2; | |
else | |
m = session.toBeanMap(o2); | |
for (Column col : columns) { | |
Object v; | |
if (col.pojoSwap != null) | |
v = col.pojoSwap.swap(session, o2); | |
else | |
v = m.get(col.getName()); | |
r.add(v == null ? null : v.toString()); | |
} | |
data.add(r); | |
} | |
} | |
} | |
} | |
/** | |
* Represents a row of data. | |
* | |
* <p> | |
* When serialized to XML, creates the following construct (example pulled from <c>AddressBookResource</c>): | |
* <p class='bcode w800'> | |
* <xt><row></xt> | |
* <xt><value></xt>Barack Obama<xt></value></xt> | |
* <xt><value></xt>52<xt></value></xt> | |
* <xt><value></xt>2<xt></value></xt> | |
* <xt></row></xt> | |
* </p> | |
*/ | |
@Bean(typeName="row") | |
public static final class Row { | |
private List<String> values = new LinkedList<>(); | |
void add(String value) { | |
values.add(value); | |
} | |
/** | |
* Returns the values in this row. | |
* | |
* @return The values in this row. | |
*/ | |
@Xml(format=XmlFormat.COLLAPSED, childName="value") | |
public List<String> getValues() { | |
return values; | |
} | |
} | |
//----------------------------------------------------------------------------------------------------------------- | |
// Bean properties | |
//----------------------------------------------------------------------------------------------------------------- | |
/** | |
* Bean property getter: <property>metadata</property>. | |
* | |
* @return The value of the <property>metadata</property> property on this bean, or <jk>null</jk> if it is not set. | |
*/ | |
@Beanp("metadata") | |
public Column[] getMetaData() { | |
return metaData; | |
} | |
/** | |
* Bean property setter: <property>metadata</property>. | |
* | |
* @param metaData The new value for the <property>metadata</property> property on this bean. | |
* @return This object (for method chaining). | |
*/ | |
@Beanp("metadata") | |
public DataSet setMetaData(Column[] metaData) { | |
this.metaData = metaData; | |
return this; | |
} | |
/** | |
* Bean property getter: <property>data</property>. | |
* | |
* @return The value of the <property>data</property> property on this bean, or <jk>null</jk> if it is not set. | |
*/ | |
@Beanp("data") | |
public List<Row> getData() { | |
return data; | |
} | |
/** | |
* Bean property setter: <property>data</property>. | |
* | |
* @param data The new value for the <property>data</property> property on this bean. | |
* @return This object (for method chaining). | |
*/ | |
@Beanp("data") | |
public DataSet setData(List<Row> data) { | |
this.data = data; | |
return this; | |
} | |
} |