iterating a HashSet ...
Sometimes i miss some people around me at work or home that can feed me with some java facts.
The last week i work on a from component that contains an AjaxFormLoop to edit a set of drivers (removing/adding) to an parent entity.
Thanks Tapestry it was a fine quick job to design the UI but than began the fight to save
the modified HashSet, many pitfalls i tapped but now the job is done.
my first solution was:
but this throws a ConcurrentModificationException
after a while i found the right (IMHO) solution:
and here the complete component
The last week i work on a from component that contains an AjaxFormLoop to edit a set of drivers (removing/adding) to an parent entity.
Thanks Tapestry it was a fine quick job to design the UI but than began the fight to save
the modified HashSet, many pitfalls i tapped but now the job is done.
my first solution was:
void onAfterSubmit()
{
for (FreightDriver driver : entity.getDrivers())
{
boolean mustRemoved = true;
for (FreightDriver freightDriver : DB.values())
{
if (driver.getId() == freightDriver.getId())
{
mustRemoved = false;
break;
}
}
if (mustRemoved)
entity.getDrivers().remove(driver);
}
}
but this throws a ConcurrentModificationException
after a while i found the right (IMHO) solution:
void onAfterSubmit()
{
ListdriversToDelete = new ArrayList ();
//-------------------------------------------------
// -----> Start to delete drivers from HashSet
//-------------------------------------------------
for (FreightDriver driver : entity.getDrivers())
{
boolean mustRemoved = true;
for (FreightDriver freightDriver : DB.values())
{
if (driver.getId() == freightDriver.getId())
{
mustRemoved = false;
break;
}
}
if (mustRemoved)
driversToDelete.add(driver);
}
for (FreightDriver freightDriver : driversToDelete)
entity.getDrivers().remove(freightDriver);
//-------------------------------------------------
// -----> End delete drivers from HashSet
//-------------------------------------------------
}
and here the complete component
@IncludeStylesheet(value = {"DriverGrid.css"})
public class DriverGrid
{
private static final MapDB = CollectionFactory.newConcurrentMap();
private static final AtomicLong ID_ALLOCATOR = new AtomicLong(System.currentTimeMillis());
@Parameter(required = true, defaultPrefix = BindingConstants.PROP)
private FreightOrder entity;
@Inject
private Session session;
@Inject
private Logger logger;
@Inject
private Messages messages;
/**
* Request object for information on current request.
*/
@Inject
private Request request;
/**
* RenderSupport to get unique client side id.
*/
@Inject
private RenderSupport renderSupport;
/**
* For blocks, messages, crete actionlink, trigger event.
*/
@Inject
private ComponentResources resources;
@Inject
@Property
private Block addRowBlock;
@Property
private FreightDriver gridRow;
@Inject
private EmptyBeanModelSource beanModelSource;
@Inject
private StaffDAO staffDAO;
@Inject
private FreightDriverDAO freightDriverDAO;
@Retain
@Property
private BeanModel gridModel;
/**
* ----------------------------------------------------------
* Drivers Grid
* ----------------------------------------------------------
*/
@Component(parameters = {"source=gridSource", "value=gridRow", "encoder=encoder",
"addrow=block:addRowBlock"})
private AjaxFormLoop grid;
@Component
private AddRowLink addRowLink;
@Component
private RemoveRowLink removeRowLink;
@Component(parameters = {"value=gridRow.driver"})
private StaffAutoTextField inputDriver;
@Component(parameters = {"value=gridRow.freightPrice",
"validate=required,min=0"})
private TextField inputFreightPrice;
@Component(parameters = {"value=gridRow.diversePrice",
"validate=required,min=0"})
private TextField inputDiversePrice;
/**
* get the datasource for the driver grid.
*/
@Log
public CollectiongetGridSource()
{
return DB.values();
}
/**
* Tapestry render phase method.
* Initialize temporary instance variables here.
*/
@Log
public void setupRender()
{
DB.clear();
for (FreightDriver driver : entity.getDrivers())
{
driver.setMapId(ID_ALLOCATOR.getAndIncrement());
DB.put(driver.getMapId(), driver);
}
}
@Log
void onBeginSubmit()
{
}
@Log
void onAfterSubmit()
{
ListdriversToDelete = new ArrayList ();
//-------------------------------------------------
// -----> Start to delete drivers from HashSet
//-------------------------------------------------
for (FreightDriver driver : entity.getDrivers())
{
boolean mustRemoved = true;
for (FreightDriver freightDriver : DB.values())
{
if (driver.getId() == freightDriver.getId())
{
mustRemoved = false;
break;
}
}
if (mustRemoved)
driversToDelete.add(driver);
}
for (FreightDriver freightDriver : driversToDelete)
entity.getDrivers().remove(freightDriver);
//-------------------------------------------------
// -----> End delete drivers from HashSet
//-------------------------------------------------
for (FreightDriver freightDriver : DB.values())
{
if (freightDriver.getId() == 0)
{
freightDriver.setOrder(entity);
entity.getDrivers().add(freightDriver);
}
}
}
/**
* add a new row.
*/
@Log
Object onAddRow()
{
FreightDriver driver = new FreightDriver();
driver.setMapId(ID_ALLOCATOR.getAndIncrement());
DB.put(driver.getMapId(), driver);
return driver;
}
/**
* remove a new row.
*/
@Log
void onRemoveRow(FreightDriver value)
{
DB.remove(value.getMapId());
}
/**
* tells the ajax loop how to encode the items.
*/
@Log
public PrimaryKeyEncoder getEncoder()
{
return new PrimaryKeyEncoder()
{
public Long toKey(FreightDriver value)
{
return value.getMapId();
}
public void prepareForKeys(Listkeys)
{
}
public FreightDriver toValue(Long key)
{
return DB.get(key);
}
};
}
/**
* create response for driver autocompleter.
*/
@OnEvent(value = "selectDriver")
StreamResponse selectDriver()
{
String driverName = request.getParameter("inputDriver");
Liststaffs = staffDAO.findByPartialName(driverName, false);
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("<ul>");
for (Staff staff : staffs)
{
stringBuffer.append("<li id='").
append(staff.getRecId()).
append("'>");
stringBuffer.append(staff.getAddress().getName1()).
append(", ").
append(staff.getAddress().getName2()).
append(" (").
append(staff.getClient().getClientDesc()).
append(")");
stringBuffer.append("</li>");
}
stringBuffer.append("</ul>");
return new TextStreamResponse("text/html", stringBuffer.toString());
}
}
Kommentare
Kommentar veröffentlichen