wicket persistent object between panels - list

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...
}
}

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;
}

Mocking HystrixObservableCommand results in real .toObservable() getting called

I have a HystrixObservableCommand that I'd like to mock using Mockito:
public class LoginWithEmailCommand extends HystrixObservableCommand<Boolean> {
// stuff...
}
With a test that looks like this:
#RunWith(MockitoJUnitRunner.class)
public class ExampleTest {
#Mock
Observable<Result> mockObs;
#Test
public void mockwtf() {
LoginWithEmailCommand cmd = mock(LoginWithEmailCommand.class);
when(cmd.toObservable()).thenReturn(mockObs);
cmd.toObservable();
}
}
However, running this test results in a NullPointerException:
java.lang.NullPointerException
at com.netflix.hystrix.AbstractCommand.toObservable(AbstractCommand.java:342)
at com.netflix.hystrix.HystrixObservableCommand.toObservable(HystrixObservableCommand.java:35)
Why does the real .toObservable() keep getting called? Setting a breakpoint shows that the LoginWithEmailCommand object being created is a generated, proxied object...
ANOTHER CLUE: If I add this override into the ObservableCommand, mocking works:
#Override
public Observable<Boolean> toObservable() {
return super.toObservable();
}
...is there a cleaner way to make this work than having to put unused toObservable overrides in?
This is my solution for this, so far -- perhaps there is a cleaner way...
Step 1: Create a new BaseCommand in my package:
public abstract class BaseCommand<T> extends HystrixObservableCommand<T> {
// protected ctors go here
#Override
public Observable<T> toObservable() {
return super.toObservable();
}
}
Step 2: Extend my commands from this base instead.
public class LoginWithEmailCommand extends BaseCommand<Boolean> {
// stuff...
}
and now the mocks work correctly.

Need to sort a list using Wicket

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.)

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.

How to make AfterBeanDiscovery get triggered in JUnit

I have the following four classes: DataConsumer, DataProducer, SomeQualifier, a META-INF/beans.xml and a test. The class files are coded as follows:
public class DataConsumer {
private boolean loaded = false;
#Inject
#SomeQualifier
private String someString;
public void afterBeanDiscovery(
#Observes final AfterBeanDiscovery afterBeanDiscovery,
final BeanManager manager) {
loaded = true;
}
public boolean getLoaded() {
return loaded;
}
public String sayHello() {
return someString;
}
}
public class DataProducer {
#Produces
#SomeQualifier
private final String sample = "sample";
}
public #interface SomeQualifier {
}
The unit test looks like this.
public class WeldTest {
#Test
public void testHelloWorld() {
final WeldContainer weld = new Weld().initialize();
final DataConsumer consumer = weld.instance()
.select(DataConsumer.class).get();
Assert.assertEquals("sample", consumer.sayHello());
Assert.assertTrue(consumer.getLoaded());
}
}
However, it is failing on the assertTrue with getLoaded() it appears that the #Observes does not get fired.
Take a look at arquillian: www.arquillian.org. It'll take care of all of this for you.
I found a similar question that had answered my question
CDI - Observing Container Events
Although I am unable to use DataConsumer as both an Extension and a CDI managed bean. So it needs a third class just to be the Extension. However, because Extension have no access to managed beans since they are not created yet, I conclude that is no possible solution to use an #Observes AfterBeanDiscovery to modify the bean data. Even the BeanManager that gets passed in cannot find any of the beans.