Need to sort a list using Wicket - list

I am working on a very simple program, looking like this:
public class WicketApplication extends WebApplication implements Comparable<Object>{
private List<Person> persons = Arrays.asList(
new Person("Mikkel", "20-02-91", 60169803),
new Person("Jonas", "02-04-90", 86946512),
new Person("Steffen", "15-07-90", 12684358),
new Person("Rasmus", "08-12-93", 13842652),
new Person("Michael", "10-10-65", 97642851));
/**
* #see org.apache.wicket.Application#getHomePage()
*/
#Override
public Class<? extends WebPage> getHomePage() {
return SimpleView.class;
}
public static WicketApplication get() {
return (WicketApplication) Application.get();
}
/**
* #return #see org.apache.wicket.Application#init()
*/
public List<Person> getPersons() {
return persons;
}
public List<Person> getSortedList(){
return Collections.sort(persons);
//This won't work before implementing comparator i know, but how??
}
#Override
public void init() {
super.init();
// add your configuration here
}
#Override
public int compareTo(Object o) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
That was the class where i just put my people into a list.
public class SimpleView extends SimpleViewPage {
public SimpleView() {
ListView persons = new ListView("persons", getPersons()) {
#Override
protected void populateItem(ListItem item) {
Person person = (Person) item.getModelObject();
item.add(new Label("name", person.getName()));
item.add(new Label("birthdate", person.getBirthdate()));
item.add(new Label("phone", person.getPhone()));
}
};
add(persons);
add(new Label("size", "Number of people " + getPersons().size()));
}
}
And here is what i do with the people.
Basicly i want the program to show a table with all the data(this already works).
Now i want to be able to sort them. But i can't for the life of me figure it out. I'm still rather new at programming, and i want to have a button below my table that can sort on name, bday or phone number. Was thinking about trying to Comparable, but can't remember it that well, and not sure how it works with Wicket..
Thanks for the help in advance :)

What you need is the DataView component, which provides all the support you need for sorting (and paging, should you require it later on).
Here's a working example, if you click on the "Source Code" link in the top right corner, you can see that most of the things you want from a sortable table work out of the box. All you need is to create a suitable data provider.
If you use DataView with a SortableDataProvider, you don't need to worry about writing your own dynamic Comparator. (Which is not a terribly hard task itself, but it's easy to get it wrong.)

Related

Writing List of Items using JdbcBatchItemWriter

Currently i am using JpaItemWriter to write the list of objects as below which is working fine.
Now i want to change the JpaItemWriter to JdbcBatchItemWriter due to performance issue.
public class MyItemWriter implements ItemWriter<List<MyDomainObject>> {
#Override
public void write(List<? extends Lists<MyDomainObject>> items) {
JpaItemWriter<MyDomainObject> writer = new JpaItemWriter<>();
for(List<MyDomainObject> o : items)
{
writer.write(o);
}
}
}
Suggest a sample snippets which uses the JdbcBatchItemWriter to write the List of objects will helps. Tried using the ItemSqlParameterSourceProvider it did't help ending up in org.springframework.dao.InvalidDataAccessApiUsageException: No value supplied for the SQL parameter exception
You example is not correct. You are creating a JpaItemWriter in the write method, so a new instance is created on each call to write. This is probably the cause of your performance issue.
More importantly, lifecycle methods of the delegate writer (open/update/close) will not be honored (it is not the case for JpaItemWriter which does not implement ItemStream but this would be a problem if the delegate is an item stream). Your MyItemWriter implementation should be something like:
public class MyItemWriter implements ItemWriter<List<MyDomainObject>> {
private JpaItemWriter jpaItemWriter;
public MyItemWriter(JpaItemWriter jpaItemWriter) {
this. jpaItemWriter = jpaItemWriter;
}
#Override
public void write(List<? extends Lists<MyDomainObject>> items) {
for(List<MyDomainObject> o : items) {
this. jpaItemWriter.write(o);
}
}
}
Now if you want to use the JdbcBatchItemWriter to write a list of lists, see Spring Batch - Using an ItemWriter with List of Lists.
Edit: Added a sample code of how to set the delegate as requested in comments:
#Bean
public ListUnpackingItemWriter<T> itemWriter() {
JdbcBatchItemWriter<T> jdbcBatchItemWriter = null; // configure your jdbcBatchItemWriter
ListUnpackingItemWriter<T> listUnpackingItemWriter = new ListUnpackingItemWriter<>();
listUnpackingItemWriter.setDelegate(jdbcBatchItemWriter);
return listUnpackingItemWriter;
}

How to unit test a method that uses a dependency to copy an object?

Consider the following code (in C# but it could be any other language):
public interface IObjectCopier
{
void Copy<T>(T source, T target);
}
public class Model
{
public string Name { get; set; }
}
public class ViewModel
{
private readonly IObjectCopier _objectCopier;
public ViewModel(IObjectCopier objectCopier)
{
_objectCopier = objectCopier;
}
public Model ViewBindData { get; set; }
public void Load(Model model)
{
_objectCopier.Copy(model, ViewBindData);
}
}
How do I construct a unit test for the Load method? If I mock IObjectCopier then I need to supply a mock implementation of the Copy method. In this example it is trivial but in a real world scenario Model can be large with sub models and the mocking exercise feel like it is just copying what the IObjectCopier implementation does.
The problem is simplified if I could change the Copy method to the following:
T Copy<T>(T source);
As in this case the mock setup is drastically simplified. The problem is that there are view bindings to the Model object and I cannot simply destroy and re-create the object.
Is there an elegant way to get around this problem?
If you're using mocks, then the only thing you care about is that the copier is invoked with the 2 parameters.
So in some sort of pseudo code
test "populates model from view data" {
objectCopiermock = mock(IObjectCopier)
model = new Model() //create empty or use a TestDataBuilder
viewBindData = new viewBindData() //create empty or use a TestDataBuilder
viewModel = new ViewModel(objectCopiermock)
viewModel.viewBindData(viewBindData)
viewModel.Load(model)
verifyMock(objectCopiermock).copy(model, viewBindData)
}
The important thing with mocks is to verify the interactions, and not the values inside model or viewBindData.
If this is confused, don't panic! (tm) - and I would suggest you to read a bit about the difference between the London and Chicaco/Detroit schools of TDD

Should the CustomEventArgs method implement another Interface?

Hi I am using test driven development and seem to be in an area I am not familiar. Could you Please check and let me know what changes I should make in my code to make it "unit testable" ?
Code to be tested:
public void PurchaseItemList()
{
//call methods to checkavailablility
If(!productAvailable)
{
purchaseItemEventArgs.IsSuccessfull = false;
}
else
{
purchaseItemEventArgs.IsSuccessfull = true;
// code to update model.
purchaseItemEventArgs.ItemsPurchased = GetItemsPurchased()
}
}
Now the issue I face is that I cannot mock the purchaseItemEventArgs class as it does not implement any interface. I am using moq for testing. Any advise on the code changes to make it unit testable would be very helpfull.
Thanks
Since GetItemsPurchased() is a method of your class, you could make it protected virtual. So you could then define a test class like this:
class TestableMyClass : MyClass{
private Items _items;
public TestableMyClass(Items items) : base() {
_items = items;
}
protected Items GetItemsPurchased(){
return _items;
}
}
And then, in your tests, replace new MyClass by new TestableMyClass(myItems).
This way, your actual GetItemsPurchased() won't be called in your tests, and you can inject the items you want.

Why is AutoFixture Customization causing inherited properties to not be filled?

I wrote the following customization and have it applied as part of a composite on most of my tests. My entities have a read-only Id, but I'm using their SetId method in this customization to make sure all entities have some Id if they are transient (don't have an Id already).
public class SetEntityIdCustomization : ICustomization {
public void Customize(IFixture fixture) {
var engine = ((Fixture)fixture).Engine;
fixture.Customizations.Add(new Postprocessor(
engine, o => {
var entity = o as BaseEntity;
if (entity == null || !entity.IsTransient()) {
return;
}
entity.SetId(fixture.CreateAnonymous<Guid>());
}));
}
}
This has been working great, until I discovered a very odd thing today. If I feed a test one of my entities that directly inherits from BaseEntity, all is well and it's writeable properties are auto-filled. However, if I ask for an entity that inherits from something further down from BaseEntity, my customization prevents the properties from auto-filling.
The User entity in this test method is filled properly:
public class User : BaseEntity {
public string Email { get; set; }
public int CoolThings { get; set; }
}
...
[Theory, AutoDomainData]
public void SomeTest(User user, ...) {
// user.Email and user.CoolThings have auto-filled values, as expected.
...
}
However, the AwesomeUser entity in the following test does not get any of the same properties auto-filled.
public class AwesomeUser : User {
...
}
...
[Theory, AutoDomainData]
public void SomeOtherTest(AwesomeUser user, ...) {
// user.Email nor user.CoolThings have auto-filled values. What gives?
...
}
In both test cases, the Id property is auto-filled because of my customization. If I remove my customization, the SomeOtherTest's AwesomeUser instance gets its inherited properties auto-filled just fine. I must assume that my customization is what is messing things up.
Is there a better way to get all my BaseEntity instances to set their Id, or is there something else I'm missing with AutoFixture? I've applied my customization first, in the middle, and last, to no avail.
The solution provided above is a pretty clever attempt, but not something I've seen before. A more idiomatic solution would be something like this:
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(
new FilteringSpecimenBuilder(
new Postprocessor(
new BaseEntityBuilder(
new ConstructorInvoker(
new ModestConstructorQuery())),
new AutoPropertiesCommand().Execute),
new BaseEntitySpecification()));
}
private class BaseEntityBuilder : ISpecimenBuilder
{
private readonly ISpecimenBuilder builder;
private readonly IRequestSpecification specification;
public BaseEntityBuilder(ISpecimenBuilder builder)
{
this.builder = builder;
this.specification = new BaseEntitySpecification();
}
public object Create(object request, ISpecimenContext context)
{
if (!this.specification.IsSatisfiedBy(request))
return new NoSpecimen(request);
var b = (BaseEntity)this.builder.Create(request, context);
b.SetId((Guid)context.Resolve(typeof(Guid)));
return b;
}
}
private class BaseEntitySpecification : IRequestSpecification
{
public bool IsSatisfiedBy(object request)
{
var t = request as Type;
if (t == null)
return false;
if (!typeof(BaseEntity).IsAssignableFrom(t))
return false;
return true;
}
}
As you can see, this isn't a simple one-liner, which is indicative of AutoFixture being a rather opinionated library. In this case, AutoFixture's opinion is:
Favor object composition over class inheritance.
-Design Patterns, p. 20
AutoFixture is first and foremost a TDD tool, and one of the main advantages of TDD is that it provides feedback about class design. In this case, the feedback is: Inheritance is awkward and troublesome. Reconsider the design.

wicket persistent object between panels

In wicket without saving to the session how can i have a persistent object for example a list which can be set in one panel and accessed from another. Iv done a lot of googleing and im not entirely sure how this would work. Any help would be appreciated greatly! Thank you.
Related to the comments above, I will try and explain what I was thinking.
Disclaimer: It's been more than a year since I worked with Wicket, so the following should be read as an overall proof-of-concept. I cannot guarantee that it will compile (actually, I can almost certainly guarantee that it will not.)
public class MyPage extends ... {
...
MyPageModel pm = new MyPageModel();
add(new MyPanel1(pm));
add(new MyPanel2(pm));
...
}
public class MyPageModel implements Serializable {
private IModel<List<MyDataObject>> dataObjects;
public MyPageModel() {
this.dataObjects = // Load list from somewhere
}
public IModel<List<MyDataObject>> getDataObjects() {
return this.dataObjects;
}
}
public class MyPanel1 extends ... {
private MyPageModel pageModel;
public MyPanel1(MyPageModel pageModel) {
this.pageModel = pageModel;
...
add(new ListSomethingComponent<MyDataObject>(pageModel.getDataObjects)); // Some list renderer component which takes a IModel<List<MyDataObject>> as data
}
}
public class MyPanel2 extends ... {
private MyPageModel pageModel;
public MyPanel2(MyPageModel pageModel) {
// Same as MyPanel1...
}
}