blob: 4926ce857d5a66680f7c27313fc852d05d995c01 [file] [log] [blame]
The factory pattern is useful, but nevertheless not suitable for Wicket components.
*Listing 15:*
{code}
public class CmsFactory {
public Label getCmsLabel(String markupId, final String url) {
IModel<String> fragment = new AbstractReadOnlyModel<String>() {
@Override
public String getObject() {
return loadSomeContent(url);
}
};
Label result = new Label(markupId, fragment);
result.setRenderBodyOnly(true);
result.setEscapeModelStrings(false);
return result;
}
public String loadContent(String url) {
// load some content
}
}
// create the component within the page:
public class MyPage extends WebPage {
@SpringBean
CmsFactory cmsFactory;
public MyPage() {
add(cmsFactory.getCmsLabel("id", "http://url.to.load.from"));
}
}
{code}
This approach for adding a label from the @CmsFactory@ to a page seems to be okay at first glance, but it comes with some disadvantages. There is no possibility to use inheritance anymore. Furthermore, there is no possibility to override @isVisible()@ and @isEnabled()@. The factory could also be a Spring service which instanciates the component. A better solution is to create a @CmsLabel@.
*Listing 16:*
{code}
public class CmsLabel extends Label {
@SpringBean
CmsResource cmsResource;
public CmsLabel(String id, IModel<String> urlModel) {
super(id, urlModel);
IModel<String> fragment = new AbstractReadOnlyModel<String>(){
@Override
public String getObject() {
return cmsResource.loadSomeContent(urlModel.getObject());
}
};
setRenderBodyOnly(true);
setEscapeModelStrings(false);
}
}
// create the component within a page
public class MyPage extends WebPage {
public MyPage() {
add(new CmsLabel("id", Model.of("http://url.to.load.from")));
}
}
{code}
The label in listing 16 is clearly encapsulated in a component without using a factory. Now you can easily create inline implementations and override @isVisible()@ or other stuff. Naturally, you might claim "I need a factory to initialize some values in the component, e.g. a Spring service.". For this you can create a implementation of @IComponentInstantiationListener@. This listener gets called on the super-constructor of every component. The most popular implementation of this interface is the @SpringComponentInjector@ which injects Spring beans in components when the fields are annotated with @\@SpringBean@. You can easliy write and add your own implementation of @IComponentInstantiationListener@. So there is no reason for using a factory anymore. More information about the instanciation listener is located in Wicket's JavaDoc.