How is AbstractTestCase linked to UiTestBase<D> in QAF 2.18 version? - qaf

I am new to QAF 2.18 & trying to understand how an AbstractTestCase is able to accept a type parameter using Generic's in below case.
public abstract class AbstractTestCase<D, B extends UiTestBase<D>>
The WebDriverTestCase extends AbstractTestCase<D, B extends UiTestBase<D>> that said, the AbstractTestCase must and should make a use of Interface UiTestBase or the classes that have the implementation of the interface UiTestBase<D>. I tried to drill down more & couldn't find that QAFExtendedWebDriver and WebDriverTestBase classes don't implement UiTestBase in any way. Could anyone help me understand how is this working? Thanks in advance.
public class WebDriverTestCase extends AbstractTestCase<QAFExtendedWebDriver, WebDriverTestBase>

Related

Creating objects with AssistedInject Factory in Guice

I have a class that should be injected in two different ways:
for general purpose as singleton
customized version as RequestScoped.
Example:
public class TaskProcessorService implements TaskProcessor {
private final TaskRegistry taskRegistry;
#Inject
public TaskProcessorService(TaskRegistry taskRegistry){
this(taskRegistry, null);
}
#AssistedInject
public TaskProcessorService(TaskRegistry taskRegistry, #Assisted String userId) {...}
public synchronized void performTask(){...}
}
Let's say everybody can use general purpose object and compete for performTask operation (since it's synchronized), or they can invest and create it's own instance/instances.
For general purpose i've created interface
public interface TaskProcessor{
void performTask();
}
and binding:
bind(TaskProcessor.class).to(TaskProcessorService .class).in(Singleton.class);
and for customized version i've created factory
public interface TaskProcessorFactory{
public TaskProcessor(#Assisted String userId);
}
and installed it:
install(new FactoryModuleBuilder()
.implement(TaskProcessorService.class, TaskProcessorService.class)
.build(TaskProcessorFactory.class));
I've tried it and it worked in runtime(I hope that I didnt make mistakes writing above pieces of code by hand), hovewer I'm not sure if it works fully as I wanted since I just wrote it and doesnt had time to fully test it yet.
But then i realized that i don't know how the factory works.
For different users ('userId') it should create different instances, but what about same userId? Let's say some John Doe want to create 3 instances of TaskProcessorService, will the factory create 3 different instances for each call (assuming parameter will be same - john doe's ID)?
That's the main question, does the factory always create new objects even for calls with the same parameters? Couldn't find any proof about it in docs, and i'm not 100% sure if some caching mechanism was not created.
And second issue, is it optimal solution for the problem?
Answer to your first question is yes. In your case it will always create different objects. For second question continue reading.
It is incorrect to have 2 bindings referring to the same interface. In case of of an object with 2 constructors, you annotate them both with #AssistedInject and in the factory, you need 2 methods reflecting those constructors. Then just install it using the FactoryModuleBuilder.

How can we prdecit inject object will be created from so many modules in my project?

Suppose I have 3 modeules in OpenGraph. i.e for example
ObjectGraph og = new ObjectGraph.create(
new moduleA();
new moduleB();
new moduleC();
);
#module
public class moduleA{
#Provides #Singleton Log providerLog(){
return log;
}
}
till now it seems to be okay. But I have a class named
publi class BaseActivity extends Activity {
#Inject
Log log;
}
Here i am not specifiying any module in the #Injection. But Log object will be created in the class. I know this log object will be created from that moduleA module like injects{#moduleA}. How it will create Log module without specifying any module.
Anything wrong with my understanding or coding please suggest me. Thx in advance.
You have specified moduleA in the object graph. You will be injecting your BaseActivity class using the object graph, which is configured using moduleA.

CDI and HK2 Not working together

I am not sure whether I understood the exact way of how these two does the injection using #Inject,but I recently developed an app where during the first phase of development I used Dependency Injection using #inject of HK2 and binded the resources using abstract binder,it worked fine.Then I wanted to inject one more value. I needed to inject a basic String values using #Inject and the value for this was got form a method annotated with #Produces.But when I do that I get this error.
org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at Injectee(requiredType=String
I read in many places and many suggest CDI and HK2 have some issues working together.I am not able to resolve the issue.
When I try the above scenario in two different standalone programs they run fine.But when I integrate them I get the above error message.
This is what I found in java's jira:
https://java.net/jira/browse/GLASSFISH-20597
My example is:
public ClassA{
#Inject
ClassBInter b;
}
I binded the class b in the abstract binder
new AbstractBinder(){
#Override
protected void configure() {
//Binding the implementation to the interface
bind(ClassBImpl.class).to(ClassBInter.class);
}
}
this worked fine.
but when I tried the below concept of adding an #Inject to a String in the same system,it crashes with the above exception
public ClassC{
#Inject
String name;
}
Producer Class
public ProducerClass{
#Produces
public String getName(){
return "henry Ford";
}
}
String injection is generally not supported, across the board. You can use qualifiers, which should help with resolution.
Do you have a beans.xml file in your deployment?

#Inject a Controller

We're actually trying to inject different Controller-Classes to implement a trimmed version and a full version.
we take a look on spring and guice and all the documentation is just about to inject variables like
#inject
static MyBean bean;
but is it possible to make the inject-declaration for a class like this
#Inject
public class MyRealBean implement MyBean
?
i think not, but perhaps... ;)
So the question is, where to put the inject-annotion for the controller in the play framework.
i figure out kind of a hack, but I'm not lucky with that.
i created a wrapper controller, who owns the bean-controller and send all message to it.
public Wrapper extends Controller {
#Inject
static MyBean bean;
public static void index() {
bean.index();
}
perhaps somebody knows a better way or we're on the wrong way...
thanks
Put the #Inject annotation before constructor.

Is it posssible to extend/override component class, that "cc.myFunc" will be available in facelet?

I've already asked here two questions about the subject, but the answers was uninformative. May be I did not explain well, what I want. Now, I will be more specific. I know that "Composite components are a Facelets feature, not a JSF feature", I know that "Facelets is that Facelets is a view technology which is designed with JSF in mind". I don't know exactly, but I guess that abbreviations "cc.attrs" and "cc.clientId" assume, that there is some java class for component, behind the scene. I want to know, if it is possible to override/extend it in such way that "cc.myFunc" will be available?
You can provide a custom class for a composite component. The requirement is that the class has to be an UIComponent and implement the interface NamingContainer. There is a base class UINamingContainer that you can extend.
To declare it in your composite use something like:
<cc:interface componentType="my.CustomComponent">
</cc:interface>
The class could be something like:
#FacesComponent("my.CustomComponent") //Component type in the composite
public class AComponent extends UINamingContainer{
private int a;
//setter and getter for a
public void sayHello(){
System.out.println("Hello");
}
}
Note that the value of componentType attribute is the value of FacesComponent annotation.
In the implementation of your composite component, you would use #{cc.sayHello()}. The parentheses are required because without them the Facelets ELResolver would try to look for an attribute sayHello.

Resources