How can I invoke *this* on a JRBeanCollectionDataSource? - list

I am passing a list of images to my report. I want to render it inside a List object in the report.
I have used JasperReports lists before and I'm aware that I can reference each field of an element in a list using the $F{} tag, but how can I reference the element of the list itself?
Basically i would like to use something like $F{this}, or $F{self}. Is there such a thing?

Yes, you can use the alias _THIS.
The quote from the JasperReports Ultimate Guide:
A special field mapping can be used to access the current JavaBean object itself. Thus, when a field uses _THIS as description or name, the data source will return the current JavaBean object as field value. This is useful when the report needs to extract from the current object some data that does not correspond to a property that follows JavaBeans standards (for instance, the data is returned by a method that takes some arguments), or when the current object needs to be passed to as argument to a method called in one of the report expressions.
The sample of using _THIS
The snippet of jrxml file:
<subDataset name="dataset1">
<field name="city" class="java.lang.String">
<fieldDescription><![CDATA[_THIS]]></fieldDescription>
</field>
</subDataset>
The snippet of JavaBean:
public class AddressBean {
private String city;
private Integer id;
private PersonBean person;
public AddressBean getAddress() {
return this;
}
public String getCity() {
return city;
}
public Integer getId() {
return id;
}
The JasperReports Ultimate Guide is here.
You can also read the answer by GenericJon on How to access the root element of the datasource in jasperreports question.

Related

How do we retrieve values of Custom Lists(dropdown) in Netsuite

I have record type "XYZ" which has field called "award area" which is of type list/record. "award area" is of type custom list and is a drop down control.
Using Suitetalk how can I retrieve those values from that drop down?
Thank you
I think something like this should work. It's for translating the results from the internalId's returned into the actual text type, you maybe be able to leverage it in another way. Maybe you could create a lookup list with something like this(C#):
public Dictionary<string, Dictionary<long, string>> getCustomFieldLists()
{
return
nsService.search(new CustomListSearch())
.recordList.Select(a => (CustomList) a)
.ToDictionary(a => a.name,
a => a.customValueList.customValue
.ToDictionary(b => b.valueId, c => c.value));
}
var valueLookup = getCustomFieldLists()["award area"];
Here's how I did it for myself, because I was irritated with the fact the NetSuite doesn't just provide us an easy way to access these. And I wanted the following data for reference:
The Internal ID of the Custom List
The Name of the Custom List
The Internal ID of the Custom List Item
The name Value of the Custom List Item
I wanted/needed access to all of those things, and I wanted to be able to obtain the name Value of the Custom List Item by just providing the Internal ID of the Custom List and the Internal ID of the Custom List Item. So, in my homemade integration client, similar to David Rogers' answer, but without all the fancy Linq, I figured out that the best solution was a Dictionary>>.
This way, for the outer Dictionary, I could set the key to the internal IDs of the Custom Lists, and for the inner Dictionary I could set the key to the internal IDs of the Custom List Items themselves. Then, I would get the name of the Custom List for "free" as the beginning part of the Tuple, and the actual name Value for "free" as the value of the internal Dictionary.
Below is my method code to generate this object:
/// <summary>
/// Gets the collection of all custom lists, and places it in the public CustomListEntries object
/// </summary>
/// <returns></returns>
private Dictionary<string, Tuple<string, Dictionary<long, string>>> GetCustomLists()
{
Dictionary<string, Tuple<string, Dictionary<long, string>>> customListEntries = new Dictionary<string, Tuple<string, Dictionary<long, string>>>();
SearchPreferences sp = SuiteTalkService.searchPreferences; //Store search preferences to reset back later, just need body fields this one time
SuiteTalkService.searchPreferences = new SearchPreferences() { bodyFieldsOnly = false };
SearchResult sr = SuiteTalkService.search(new CustomListSearch());
SuiteTalkService.searchPreferences = sp; //Restore search preferences
foreach (CustomList cl in sr.recordList)
{
Dictionary<long, string> customListItems = new Dictionary<long, string>();
if (cl.customValueList == null) continue;
foreach (CustomListCustomValue clcv in cl.customValueList.customValue)
{
customListItems.Add(clcv.valueId, clcv.value);
}
customListEntries.Add(cl.internalId, new Tuple<string, Dictionary<long, string>>(cl.name, customListItems));
}
return customListEntries;
}
Then, in the constructors of my Integration class, I can set my object to the return result:
public Dictionary<string, Tuple<string, Dictionary<long, string>>> CustomListEntries = GetCustomLists();
And finally, whenever I need access TO those values, since I set all of this up ahead of time, I can do the following:
dr[Class] = SuiteTalkIntegrator.CustomListEntries[lorr.typeId].Item2[long.Parse(lorr.internalId)];
In this case above, my "lorr" object is a ListOrRecordRef object that I obtained from the SearchColumnSelectCustomField.searchValue from the search results of a SavedSearch. I don't know if this will work for anyone else that finds this code, but since I was frustrated in finding an easy answer to this problem, I thought I'd share my solution with everyone.
Frankly, I'm most frustrated that this functionality isn't just given to us out of the box, but I've noticed that NetSuite has made a lot of bad design choices in their SuiteTalk API, like not making a custom class of "RecordField" for their record fields and not placing their record fields under an IEnumerable of RecordField so that programmers can loop through all values in a record in a generic way without having to EXPLICITLY name them and re-construct the same code logic over and over again... ugh...

WSOS Identity - PIP Extension with a Set of Multiple Elements Returns Blank

Our testing demonstrated that the WSO2 PIP extension module implements a "Set" class connecting with the PDP integration (=AttributeFinder). This interface currently is only capable to transfer one single element.
Once we use a customized look-up for our groups definitions, generating a Set with multiple elements of type String, the WSO2 PDP returns a blank String with no information.
Sample Code from WSO2:
#Override
public Set<String> getAttributeValues(String subject, String resource, String action,
String environment, String attributeId, String issuer) throws Exception {
Set<String> roles = new HashSet<String>();
String role = findRole(subject);
if(role != null){
roles.add(role);
}
return roles;
}
PIP Extension Example Source for download:
https://svn.wso2.org/repos/wso2/carbon/platform/trunk/components/identity/org.wso2.carbon.identity.samples.entitlement.pip/src/main/java/org/wso2/carbon/identity/samples/entitlement/pip/
Our look-up program is using a String based data type, which matches the data type of the element, see XACML code below:
.
<AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="http://w3.red.com/subject/groupsUserBelong" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"></AttributeDesignator>
Access groups handling is a very common task in the XACML logic processing, so this is a crucial function for implementing XACML policies and rules.
Is this failure behaviour a bug (returns blank), or does WSO2 XACML deliver a programmatic implementation for a Set using multiple elements of Strings, automatically generating a string-bag according to the number of data elements, one String per element?
To complete the analysis, please check the sample code above, as well
as the matching abstract class named AbstractPIPAttributeFinder.
Both reference the return value named as "roles" and in the abstract class it is described as "values". Once the object to return is defined as a Set and the field names descries it in a plural, its basically self explaining the the values transported could be one or multiple elements that are part of the Set construction, usually each element of a String data-type.
The logic works well with a single element and it fails when using
multiple elements, which at the XACML interface returns a "blank" string in place of a "String-bag".
After detailed analysis of the PIP data flow through modules, we circled the issue inside the PIP extension program. Below you find the logic used to address and transfer the data fields. The new logic is able to transport multiple elements (for ex. groups, or roles) which was tested with an ObligationExpression as well as with a String-bag comparison, which both executed successfully after deploy of the new extension code.
public Set<String> getAttributeValues(String subject, String resource,
String action, String environment, String attributeId, String issuer)
throws Exception {
Set<String> myHash = new HashSet<String>();
Map<String, String> myMap = null;
if (attributeId.trim().equalsIgnoreCase("http://w3.red.com/subject/versionOfPIP")) {
myHash.add(myversion.toString().trim());
System.out.println(myversion.toString().trim());
} else if (attributeId.trim().equalsIgnoreCase("http://w3.red.com/subject/groupsUserBelong")) {
String myGroups = RedRedGroupAttrFinder.
getOnlyGroups(RedRedGroupAttrFinder.redGroupHTTPsSlaphAPI(subject));
ArrayList<String> myGroupsArrayL =RedRedGroupAttrFinder.convertStringToArraylist(myGroups);
for (String element : myGroupsArrayL) {
myHash.add(element.toString().trim());
}
} else if (attributeId.trim().equalsIgnoreCase("http://w3.red.com/subject/employeeCountryCode")) {
myMap = LdapHash.searchRedPagesByIntranetEmail(subject);
myHash.add(myMap.get(attributeId.substring(26).toString().trim()));
} else {
myHash.add("never");
}
return myHash;
}
}

Sitecore 7 LinQ POCO classes - How to Fetch data from Treelist?

I am just starting out using SOLR integration with Sitecore 7. I managed to follow some guides and built a "POCO" class (inheriting from SearchResultItem) which allows me to perform the LINQ queries and search data as shown in the sample below:
public class MySearchItem: SearchResultItem
{
[IndexField("Text Field")]
public string TextField
{
get;
set;
}
[IndexField("Drop Link")]
public ID DropLink
{
get;
set;
}
[IndexField("Tree List")]
public IEnumerable<ID> TreeList
{
get;
set;
}
}
When I get to perform a query, using the code below, I am observing the TextField and DropLink properties in the results item to be correctly populated, with the content and ID for TextField and DropLink respectively. The TreeList property is however being retrieved as null. I have checked the obvious and made sure that the hints correctly reflect the field name in the sitecore template, and according to the "Developer's Guide to Item Buckets and Search" document for sitecore 7 IEnumerable is supported automatically.
var index = ContentSearchManager.GetIndex("sitecore_master_index");
using (var context = index.CreateSearchContext())
{
var results = context.GetQueryable<MySearchItem>();
results = results.Where(item => item.TemplateName == "Custom Sitecore Template");
}
The field is located in the indexer since a call to results.First()["TreeList"] seems to show the data I'm after. Would this be the right approach in reading the data?
Furthermore, would it be at all possible to put in other types in my "POCO" class? Let's say I want to query the property of an item within the Tree List. How would I go about implementing this? Am I right in assuming that a TypeConverter for the type of my Tree List would be required for sitecore to correctly resolve the TreeList in a type other than the ID to do something like the below?
[IndexField("Tree List")]
public IEnumerable<TreeListItem> TreeList
{
get;
set;
}
Any help/guidance towards understanding this behavior would be greatly appreciated.
Thanks!
Update
I have filed this as a bug report as suggested in this post. In case anyone comes across this, they confirmed this is an issue and suggested the following workaround:
Add the following lines to the section of the Sitecore.ContentSearch.Solr.Indexes.config file:
<typeMatch typeName="guidCollection" type="System.Collections.Generic.IEnumerable`1[System.Guid]" fieldNameFormat="{0}_sm" multiValued="true" settingType="Sitecore.ContentSearch.SolrProvider.SolrSearchFieldConfiguration, Sitecore.ContentSearch.SolrProvider" />
<typeMatch typeName="stringCollection" type="System.Collections.Generic.IEnumerable`1[System.String]" fieldNameFormat="{0}_sm" multiValued="true" settingType="Sitecore.ContentSearch.SolrProvider.SolrSearchFieldConfiguration, Sitecore.ContentSearch.SolrProvider" />
<typeMatch typeName="intCollection" type="System.Collections.Generic.IEnumerable`1[System.Int32]" fieldNameFormat="{0}_im" multiValued="true" settingType="Sitecore.ContentSearch.SolrProvider.SolrSearchFieldConfiguration, Sitecore.ContentSearch.SolrProvider" />
Hope this helps!
I had the same issue and from inspecting the config file Sitecore.ContentSearch.Solr.Indexes.config it seems that the type is not mapped with the Solr Provider.
This is indeed weird as in the documentation Developer's Guide to Item Buckets and Search, it clearly states that out of the box it should be able to map types of IEnumerable<T>.
Can you please try changing the type of your multilist field from IEnumerable<ID> to List<Guid> instead and check if this solves your issue ?

Web Service Class of AS in Flex 4

I am trying to receive data from the Web Service and I am getting the Data from Web Service back but it is form of [object Object]. Can anybody help me on this.
Below is the code for my web service:
public class WebServiceAccess
{
private var webService:WebService;
private var serviceOperation:AbstractOperation;
private var myValueObjects:ValueObjects;
private var method:String;
[Bindable]
public var employeeData:ArrayCollection;
[Bindable]
public var employees:ArrayCollection;
public function WebServiceAccess(url:String, method:String)
{
webService = new WebService();
this.method = method;
webService.loadWSDL(url);
webService.addEventListener(LoadEvent.LOAD, ServiceRequest);
}
public function ServiceRequest():void
{
serviceOperation = webService.getOperation(method);
serviceOperation.addEventListener(FaultEvent.FAULT, DisplayError);
serviceOperation.addEventListener(ResultEvent.RESULT, DisplayResult);
serviceOperation.send();
}
public function DisplayError(evt:FaultEvent):void
{
Alert.show(evt.fault.toString());
}
public function DisplayResult(evt:ResultEvent):void
{
employeeData = evt.result as ArrayCollection;
Alert.show(employeeData.toString());
}
}
First of all, evt.result is not an ArrayCollection, it is an Object (unless your SOAP service/WSDL are completely screwed up/malformed XML).
Second, you can't just display an Array or ArrayCollection (or generic Object, even) as a String (even though the .toString() method always seems to imply that) anyway, you have to parse the data to get what you want from it.
Now, the WebService class is nice in that it automatically parses the XML file that a SOAP service returns into a single usable Object. So that is actually the hard part.
What you need to do is call various properties of the object to get the data you need.
So if the XML return (look at your WSDL to see what the return should be, I also highly suggest soapUI) is this:
<employee name="Josh">
<start date="89384938984"/>
<photo url="photo.jpg"/>
</employee>
And you wanted to display "Josh" and the photo, you would do this.
var name:String = e.result.employee.name;
var url:String = e.result.employee.photo.url;
It does get more complicated. If the WSDL allows for multiple nodes with the same name at the same level, it does return an ArrayCollection. Then you have to loop through the array and find the exact item you need.
Just remember: The WSDL is god. Period. If it says there can be multiple "employee" nodes, you have to code accordingly, even if you don't see more than one in your tests. The issue is that there always could be multiple nodes.

Does f:attribute support other things than String?

I have the need to implement an ice:commandButton that passes a list to its backing bean. I'm not in a portlet scope, but in a tag scope.
I know that when I retrieve an f:attribute from the actionListener I get an object that has to be casted.
I want to know if I can map f:attribute to a List<MyClass>, where the actual instance of the list is actually an ArrayList and MyClass is serializable.
Something like:
MyTag.xhtml
<ice:commandButton actionListener="#{TagBean.doPrintItems}">
<f:attribute name="collection" value="#{items}" />
</ice:commandButton>
//[other things]
MyPortlet.jspx
<my:printPopup items="#{BackingBean.itemsToPrint}" />
BackingBean.java
class BackingBean {
private List<MyClass> itemsToPrint;
//getter and setter of course
}
TagBean.java
class TagBean {
private List<MyClass> collection;
//getter and setter of course
public void doPrint(ActionEvent e) {
collection = (List<MyClass>) e.getComponent().getAttributes().get("collection");
}
Do you think this is feasible? Thanks
The <f:attribute> gives you the possibility to add custom component attributes. They will be stored in the component tree state in the server side. So it can be any Java object type you want. The method UIComponent#getAttributes() also hints that less or more; it returns a Map<String, Object>, not a Map<String, String>. I believe your doubt is based on the fact that HTTP request parameters can only be strings. But component attributes should not be confused with HTTP request parameters.