-
1. Re: Component Inheritance
thejavafreak May 23, 2008 9:34 AM (in response to fijaicairo)Why not use interface instead of abstract class for this case?
best regards,
-
2. Re: Component Inheritance
brackxm May 23, 2008 12:05 PM (in response to fijaicairo)You can use a Factory for this
@Factory("widget") public Widget createWidget() { if(isType1Transaction) return new WidgetType1(); if(isType2Transaction) return new WidgetType2(); ... }
-
3. Re: Component Inheritance
fijaicairo May 23, 2008 9:31 PM (in response to fijaicairo)Thanks. So WidgetType1 and WidgetType2 don't even have to be annotated with @Name? Does that limit their usefulness?
Thanks -
4. Re: Component Inheritance
fijaicairo May 23, 2008 9:33 PM (in response to fijaicairo)Thanks. Well i have a fair bit of default functionality that I'd like to inherit.
-
5. Re: Component Inheritance
jnusaira May 23, 2008 11:25 PM (in response to fijaicairo)Michael:
I was curious on your example. Have you tried that out? Just seems like it wouldn't work.
I understand the concept of the factory. However if you are returning a
new WidgetType1()
... then will any Seam components inside it be injected? I would think you'd need Seam to instantiate it for you for that to happen?Maybe i am wrong here. But instead of that couldnt you do something like the following:
Make Widget1 and Widget2 Seam components directly.
Then inject them into whatever class that factory is in and then use your factory to return the injected component.
Btw to the OP your abstract class should still implement an interface. you dont really want to do the servicing on a concrete class.
-
6. Re: Component Inheritance
mdragoon48 Sep 10, 2009 8:49 AM (in response to fijaicairo)So did Joseph's proposed solution work for you Fijai Cairo?
-
7. Re: Component Inheritance
mdragoon48 Sep 11, 2009 4:29 AM (in response to fijaicairo)I'm experiencing a similar problem to Fijai.
I tried Joseph's suggested solution of injecting all the different 'WidgetType' into a factory class. Then call the factory class for the correct WidgetType for the specific instance.public abstract class Widget{ public Widget(){ System.out.println("new Widget"); //1 } ... } @Name("widgetType1") public class WidgetType1 extends Widget... @Name("widgetType2") public class WidgetType2 extends Widget...
@Name("WidgetFactory") @Scope(ScopeType.APPLICATION) public class WidgetFactory { @In private Widget widgetType1; @In private Widget widgetType2; @Out(scope=ScopeType.CONVERSATION) private Widget widget; @Factory("widget") public Widget loadWidget(){ if(isType1Transaction) return widgetType1; if(isType2Transaction) return widgetType2; } ... }
It all worked. But I noticed, when I call
#{widget}
in my xhtml file in a new conversation, all the constructors on all the WidgetTypes defined to be injected gets called - Even if the Widget is not being used. Is there a way to optimize this? -
8. Re: Component Inheritance
swd847 Sep 11, 2009 8:41 AM (in response to fijaicairo)Use Component.getInstance() rather than injection.
-
9. Re: Component Inheritance
swd847 Sep 11, 2009 8:43 AM (in response to fijaicairo)Also why do you have the @Out? Is there more to the class that what you have shown us? Also widget will be outjected to the application scope, is that really what you are after?
-
10. Re: Component Inheritance
fijaicairo Sep 11, 2009 4:49 PM (in response to fijaicairo)Hi All,
Sorry for the late response. I actually never got to try Joseph's suggestion. I must have missed the email or something. What I ended doing is illustrated below. I'm writing this from memory so bear with me.@In(required=false) @Out(required=false) Widget1 widget1; @In(required=false) @Out(required=false) Widget2 widget2; @In(required=false) @Out(required=false) CommonWidgetStuff commonWidgetStuff; //BaseWidget isn't a seam component BaseWidget widget = (isType1Transaction) ? widget1 : widget2; widget.initialize() widget.doStuff(); commonWidgetStuff.doStuff();
Note that widget isn't a seam component so on my views I use {widget1.xxx} and {commonWidgetStuff.xxx}.
Both widget1 and widget2 get constructed when actions are invoked but I do the meaningful initialization explicitly with a method call.
-
11. Re: Component Inheritance
fijaicairo Sep 11, 2009 5:13 PM (in response to fijaicairo)I think my post needs clearing up...
//Isn't a Seam component but still has annotations for bijection public class BaseWidget{ @In(required = false) @Out(required = false, scope = CONVERSATION) protected OrderDisplayHelper orderDisplayHelper; // Common stuff and hooks } @Name("widget1") public class Widget1 extends BaseWidget{ //custom overrides } @Name("widget2") public class Widget2 extends BaseWidget{ //custom overrides }
@In(required=false) @Out(required=false) Widget1 widget1; @In(required=false) @Out(required=false) Widget2 widget2; //The commonWidgetStuff makes it easy to use fragments/includes. @In(required=false) @Out(required=false) CommonWidgetStuff commonWidgetStuff; //BaseWidget isn't a seam component BaseWidget widget; public string doSomeAction(){ widget = (isType1Transaction) ? widget1 : widget2; widget.initialize() widget.doStuff(); commonWidgetStuff.doStuff(); return widget.someActionView(); } public string doAnotherAction(){ widget = (isType1Transaction) ? widget1 : widget2; widget.initialize() widget.doStuff(); commonWidgetStuff.doStuff(); return widget.someOtherView(); }
-
12. Re: Component Inheritance
mdragoon48 Sep 16, 2009 4:04 AM (in response to fijaicairo)Thanks Stuart. I haven't tried with Component.getInstance (will let you all know when I do). I ended up using:
Expressions.instance().createValueExpression(expression)
. i.e: Expressions.instance().createValueExpression(#{widget2}
). Will explain the how I did it shortly.Stuart, why will: @Out(scope ScopeType.CONVERSATION) private Widget widget; be outjected to APPLICATION scope? I was hoping for it to outject to CONVERSATION scope.
Fijai, thanks for getting back to us. :)
In your case, I believe both Widget1 and Widget2 will be injected on each method call, even if it's not been used. It probably suited your application, but since I had more than 2 'widgets' I thought it'll be too inefficient? -
13. Re: Component Inheritance
mdragoon48 Sep 16, 2009 4:04 AM (in response to fijaicairo)Ok, here's my current implementation (open to improvements):
public abstract class Widget{ public Widget(){ System.out.println("new Widget"); //1 } ... } @Name("widgetType1") public class WidgetType1 extends Widget... @Name("widgetType2") public class WidgetType2 extends Widget...
@Name("WidgetFactory") @Scope(ScopeType.APPLICATION) public class WidgetFactory { @Out(scope=CONVERSATION) private Widget widget; @Factory("widget") public Widget loadWidget(){ if(isType1Transaction) widget = (Widget)Expressions.instance().createValueExpression(\"\#{widget1}\"); if(isType2Transaction) widget = (Widget)Expressions.instance().createValueExpression(\"\#{widget2}\"); } ... }
The good thing is it doesn't inject all WidgetType(s). And the seam annotations work on the WidgetType classes.
-
14. Re: Component Inheritance
fijaicairo Sep 16, 2009 4:13 AM (in response to fijaicairo)I remember trying a factory method as well but used
widget = (isType1Transaction)? new Widget1() : new Widget2();
but that didn't work. I'll try using the value expression.