How can I create Hierarchical Container in Vaadin when I am having the duplicate ItemIds? If No, What is the alternate? - scala

I want to create a tree of user with n level Hierarchy. I have a POJO object and within that I have id,parent_id.
The problem is user can belong in more than 1 group. So, when I am trying to do,
while (iterator.hasNext()) {
val user_pojo_obj = iterator.next()
val key = user_pojo_obj.id
val parent_key = user_pojo_obj.family_id
var child: Item = container.addItem(key)
child.getItemProperty("caption").asInstanceOf[Property[Any]].setValue(user_pojo_obj.name)
child.getItemProperty("POJOobj").asInstanceOf[Property[Any]].setValue(user_pojo_obj)
container.setParent(key, parent_key)
}
I got NullPointerException at the 2nd line, As per my knowledge it because of the addItem() duplication in container, which returns null.
Please suggest me the alternate if this can not be improve. (Using Scala)
Thanxx..

As far as I know, you can not have multiple parents or duplicate itemIds. The following pseudo-code is an alternate solution which builds the tree-like structure (node is your POJO):
counter = 0;
function process(nodes, parent) {
foreach (node in nodes) {
newId = counter++;
item = container.addItem(newId);
// set item caption etc.
if (parent not null)
container.setParent(newId, parent)
process(getNodesWithParent(node), newId);
}
}
process(getNodesWithParent(null), null);
The method getNodesWithParent needs to be defined by you. I guess you will take the iterator, iterate through your POJOs and return those with family_id equals the parameter's id. The overall performance depends on your implementation of getNodesWithParent, so if you have a large data set you should care to be efficient.

Related

Added row moves to last position once filter is removed

In NatTable I am adding a row in filtered table. After removing the filter, the newly added row moves to last position in the table.
But I want to it to stay in the same position, that is next to the row which I added when the table is filtered.
I am currently using the RowInsertCommand. I don't want to add row via model or list which used to populated the table. I want to achieve only via NatTable commands. Is it possible?
It is always hard to follow the explanations and the issue without example code. But I assume you simply copied code from the NatTable examples, so I will explain your issue based on that.
First, the RowInsertCommand has several constructors. If you are using a constructor without a rowIndex or rowPositionparameter, the new object will ALWAYS be added at the end of the list.
When using the filter functionality in NatTable with GlazedLists, the list that is wrapped in the body DataLayer is the FilterList. If you are operating on the FilterList for calculating the rowIndex where the new object should be added and have the FilterList as base list in the RowInsertCommandHandler, the place where the new object is added is transformed between the FilterList and the base EventList, which might not be the desired result.
To solve this you need to create the RowInsertCommandHandler by using the base EventList.
EventList<T> eventList = GlazedLists.eventList(values);
TransformedList<T, T> rowObjectsGlazedList = GlazedLists.threadSafeList(eventList);
SortedList<T> sortedList = new SortedList<>(rowObjectsGlazedList, null);
this.filterList = new FilterList<>(sortedList);
this.baseList = eventList;
bodyDataLayer.registerCommandHandler(new RowInsertCommandHandler<>(this.baseList));
The action that performs the add operation then of course needs to calculate the index based on the base EventList. The following code is part of the SelectionAdapter of an IMenuItemProvider:
int rowPosition = MenuItemProviders.getNatEventData(event).getRowPosition();
int rowIndex = natTable.getRowIndexByPosition(rowPosition);
Object relative = bodyLayerStack.filterList.get(rowIndex);
int baseIndex = bodyLayerStack.baseList.indexOf(relative);
Object newObject = new ...;
natTable.doCommand(new RowInsertCommand<>(baseIndex + 1, newObject));

The Flutter Hashmap<String, List<CustomObject>> is overwriting the List type in the Hashmap on every add

The Flutter Hashmap<String, List > is overwritting the List type in the Hashmap on every single unique Key. So basically the code looks like:
HashMap<String, List<Jobs> > ElementJobMap = new HashMap<String, List<Jobs> >();
for (int i = 0; i < _JobsList.length; i++) {
String Key = _JobsList[i].elementID.toString();
if (ElementJobMap.containsKey(Key)) {
if (Key == _JobsList[i].elementID.toString()) {
ElementJobMap.update(Key, (value) {
value.add(_JobsList[i]);
return value;
});
}
} else {
ElementJobMap[Key] = tmpList;
}
}
So if there are two different String keys and each key has a unique list filled with several values in each. If I write to the List every instance is updated and so it is all the same data. Should be noted this code might have pointless stuff in it, but I've just been spitballing for awhile now.
ElementJobMap[Key] = tmpList;
You seem to be adding the exact same list instance as a base of every entry. Then you add to this single instance. If you want your hashmap to hold a different list instance for every key, you need to actually create one.
That said, you should probably look into grouping methods provided through packages, there is no point in trying to do it manually.

Stackoverflow Exception using PredicateBuilder with Entity Framework

I have Predicate builder, which is having predicate and inner predicate and building a dynamic filter based on conditions, let's say I am selecting one department, under that department I am getting list of employees, once I get the list of employees, I need to load the respective records for each and every employee who belongs to the selected department.
Implementation is already done long back and it works fine if department is having not too many employees, once it goes beyond 500 or 1000, the predicate builder is causing a stack overflow. Please see my code snippet for this - I am using .net framework 4.5.2.
Getting stackoverflow exception when assigning to inner predicate at this line with in loop, when record is beyond 1000 or 500, it loops based on the employee records.
Expression<Func<EmployeeTable, bool>> predicate = PredicateBuilder.True<EmployeeTable>();
var innerPredicate = PredicateBuilder.False<EmployeeTable>();
case FilterBy.EmployeeName:
if (!isEmpNameFilterExists)
{
foreach (string empName in item.FieldCollection)
{
innerPredicate = innerPredicate.Or(x => x.Name.Equals(empName,
StringComparison.OrdinalIgnoreCase));
}
predicate = predicate.And(innerPredicate.Expand());
}
break;
This might happen due to the (usually sufficient) but small stack for .NET applications (https://stackoverflow.com/a/823729/2298807). Evaluation on predicates is usually done as part of lamda functions and they use the stack. I do not now the predicate library in detail but I assume a use of recursive functions.
Anyhow: I would suggest to use Contains by building a List<string> containing the names:
Expression<Func<EmployeeTable, bool>> predicate =
PredicateBuilder.True<EmployeeTable>();
var innerPredicate = PredicateBuilder.False<EmployeeTable>();
case FilterBy.EmployeeName:
if (!isEmpNameFilterExists)
{
List<string> namesList = new List<string>();
foreach (string empName in item.FieldCollection)
{
namesList.Add(empName);
}
predicate = predicate.And(x => namesList.Contains(x.Name));
}
break;
Note: Please check the syntax as I do not have a VS environment available at the moment.
I have added my own Expression builder engine, i.e. much better way to generate the Predicate.
PredicateBuilder works well with LINQ to Object, With EntityFramework its having the issue, because it generates the Lambda methods with full namespace of models and keep on adding with multiple search criteria. I felt like its having the limitations with large number of filters in Entity framework. In my case i was passing 728 count to just one field of Model, it was breaking with Stack-overflow exceptions.
728 lambdas method would be adding to the stack with full specific NAMESPACES.
Custom Expression is working totally fine in my case. Please find below Source code for the same.
var entityType = typeof(Emptable);
var parameter = Expression.Parameter(entityType, "a");
var containsMethod = typeof(string).GetMethod("Equals", new[] { typeof(string) });
//Switch Statement for EmployeeName Filter.
case FilterBy.EmployeeName:
if (!isEmpNameFilterExists)
{
var propertyExpression = Expression.Property(parameter, "EmployeeName");
foreach (string empName in item.FieldCollection)
{
var innerExpression = Expression.Call(propertyExpression, containsMethod, Expression.Constant(empName));
body = Expression.OrElse(body, innerExpression);
}
}
break;

Spring Batch - Invoke read() method in Reader multiple times

I am trying to implement calling read() method in the itemReader multiple times.
For Eg:
I have a list of POJO in which I will have one string variable with values either A or B or C.
I have to sort this list based on alphabetical order and segment it into three list for each value. i.e., list for value A and list for value B
and list for value C.
I need to send each list to the read() method in the itemReader one by one.
Once List for A is processed and write, then I need to send List for B and so on..
Is this doable? Any help is appreciated.
Although I am not very clear on what you are trying to achieve, I don't see any reason it cannot be done.
I assume you mean either of this:
1. You want the "item" to be process to be a whole list of POJO with same ABC Type, or
2. You want the item to be the POJO itself, and you want them to be processed in order of ABC Type
2 is straight-forward. At the first read, prepare all the POJOs, sort it. I assume they are in some kind of
In psuedo code, it looks like this
class MyReader implements ItemReader<MyPojo> {
private List<MyPojo> values;
MyPojo read() {
if (values == null) {
values = getPojos();
sort values;
}
if (values.isEmpty()){
return null;
} else {
return values.popFront();
}
}
}
1 is nothing more complicated. You will need to group POJOs with same ABC type in same list, and return the lists one by one. It can be easily done by using a TreeMap<String, List<MyPojo>>
In psuedo code, it looks like this
class MyReader implements ItemReader<List<MyPojo>> { // note the item is List<MyPojo>
private NavigableMap<String, List<MyPojo>> values;
List<MyPojo> read() {
if (values == null) {
values = new TreeMap<>();
pojos = getPojos();
for (pojo : pojos) {
if (values do not contain pojo.abcType() ) {
values.put(pojo.abcType(), new ArrayList(pojo));
} else {
values.get(pojo.abcType()).add(pojo);
}
}
}
if (values.isEmpty()){
return null;
} else {
return values.popFirstEntry().value();
}
}
}
If your list of items is fully available (you have a List<Pojo> loaded with all items) you can:
use a ListItemReader and inject into the ordered list
use a custom ItemReader and sort items after first ItemReader.read()
About break the best way is to use a custom CompletionPolicy based on pojo 'string variable'; in this manner your writer will receive a list where POJO's 'string variable' has the same values for all list items (check How to read csv lines chunked by id-column with Spring-Batch? for sample code).

DataReader with duplicate column names

What is the best way of handling trying to get data from a DataReader that has more than one column with the same name?
Because of the amount of work involved and because we don't want to lose support from a vendor by changing the stored procedures we are using to retrieve the data, I am trying to find another way to get access to a column that shows up more than once in a datareader without having to rewrite the stored procedures.
Any Ideas?
EDIT:
Ok, the function that actually populates from a datareader is used in multiple places so there is a possibility that the function can be called by different stored procedures. What I did was to do a GetName using the index to check if it is the correct column, and if it is, then pull its value.
If you know the index of the column, then access it by the index.
Can't you use column ordinals? 0 for the 1st, 1 for the 2nd, and so on?
You will have to reference the column by index no; i.e. reader[5].ToString(); to read the data in column 5.
Based on original poster's approach described in the "Edit" paragraph, here's an extension method that will give the value based on the column name and the index of that name, e.g., 0 for the first instance of name, 1 for the second, etc:
using System;
namespace WhateverProject {
internal static class Extentions {
// If a query returns MULTIPLE columns with the SAME name, this allows us to get the Nth value of a given name.
public static object NamedValue(this System.Data.IDataRecord reader, string name, int index) {
if (string.IsNullOrWhiteSpace(name)) return null;
if (reader == null) return null;
var foundIndex = 0;
for (var i = 0; i < reader.FieldCount; i++) {
if (!reader.GetName(i).Equals(name, StringComparison.CurrentCultureIgnoreCase)) continue;
if (index == foundIndex) return reader[i];
foundIndex++;
}
return false;
}
}
}
Use it thus:
var value1 = reader.NamedValue("duplicatedColumnName", 0);
var value2 = reader.NamedValue("duplicatedColumnName", 1);