GWT.create vs new operator alternative - gwt

I have to use parametric constructor of my class in GWT.create, but GWT only calls default constructor. I was thinking to replace call of GWT.create with call to new Class(arguments list). Is it the right way to code in GWT deferred binding.
Code is below:
public interface ProductSelectorMetaFactory extends BeanFactory.MetaFactory {
BeanFactory<ProductSelectorTile> getProductSelectorTileFactory();
}
public CustomTileGrid(DataSource cardViewDataSource, ProductSelectorTile tileType, String fieldState,
List<DetailViewerField> list) {
setDataSource(cardViewDataSource);
setAutoFetchData(true);
GWT.create(ProductSelectorMetaFactory.class);
setTileConstructor(tileType.getClass().getName());
}
Here I want to use parameter constructor of ProductSelectorTile class. How can I use this.
Any help is appreciated.
I might be not good in explaining my current problem but feel free if you have any doubt to understand this question.

I would use a helper class with no parameters that can be created by GWT.create(). That helper class can have different implementations - the same as your original class (with parameters). Now, each implementation of helper class can create a proper instance of the original class.
Let's assume that you need different implementations for each user agent. In <module>.gwt.xml you would have this (see documentation):
<replace-with class="<module.path>.MyClassHelperGecko">
<when-type-is class="<module.path>.MyClassHelper" />
<when-property-is name="user.agent" value="gecko1_8" />
</replace-with>
<replace-with class="<module.path>.MyClassHelperSafari">
<when-type-is class="<module.path>.MyClassHelper" />
<when-property-is name="user.agent" value="safari" />
</replace-with>
...
The helper class and its implementations:
public class MyClassHelper {
MyClassInterface getInstance(String param) {
return null;
};
}
public class MyClassHelperGecko extends MyClassHelper {
#Override
public MyClassInterface getInstance(String param) {
return new MyClassGecko(param);
}
}
public class MyClassHelperSafari extends MyClassHelper {
#Override
public MyClassInterface getInstance(String param) {
return new MyClassSafari(param);
}
}
...
And finally implementations of the base class:
public interface MyClassInterface {
// ...
}
public class MyClassGecko implements MyClassInterface {
public MyClassGecko(String param) {
Window.alert("Gecko implementation; param = " + param);
// ...
}
}
public class MyClassSafari implements MyClassInterface {
public MyClassSafari(String param) {
Window.alert("Safari implementation; param = " + param);
// ...
}
}
...
Use it like this and you will see different alerts for different user-agents:
MyClassHelper helper = GWT.create(MyClassHelper.class);
helper.getInstance("abc");
This is a general Deferred Binding Using Replacement solution. There is also Deferred Binding using Generators method. Once you get the idea you can choose the method that is best for you.

Related

Autofac - One interface, multiple implementations

Single interface: IDoSomething {...}
Two classes implement that interface:
ClassA : IDoSomething {...}
ClassB : IDoSomething {...}
One class uses any of those classes.
public class DummyClass(IDoSomething doSomething) {...}
code without Autofac:
{
....
IDoSomething myProperty;
if (type == "A")
myProperty = new DummyClass (new ClassA());
else
myProperty = new DummyClass (new ClassB());
myProperty.CallSomeMethod();
....
}
Is it possible to implement something like that using Autofac?
Thanks in advance,
What you are looking for is, as I remember, the Strategy Pattern. You may have N implementations of a single interface. As long you register them all, Autofac or any other DI framework should provide them all.
One of the options would be to create a declaration of the property with private setter or only getter inside Interface then implement that property in each of the class. In the class where you need to select the correct implementation, the constructor should have the parameter IEnumerable<ICommon>.
Autofac or any other DI frameworks should inject all possible implementation. After that, you could spin foreach and search for the desired property.
It may look something like this.
public interface ICommon{
string Identifier{get;}
void commonAction();
}
public class A: ICommon{
public string Identifier { get{return "ClassA";} }
public void commonAction()
{
Console.WriteLine("ClassA");
}
}
public class A: ICommon{
public string Identifier { get{return "ClassB";} }
public void commonAction()
{
Console.WriteLine("ClassA");
}
}
public class Action{
private IEnumerable<ICommon> _common;
public Action(IEnumerable<ICommon> common){
_common = common;
}
public void SelectorMethod(){
foreach(var classes in _common){
if(classes.Identifier == "ClassA"){
classes.commonAction();
}
}
}
}

Infinite recursion when using subcomponent for encapsulation

I'm trying to achieve encapsulation by using subcomponent which is described here, but I got infinite recursion.
Here is my code:
//tried adding #ScopeA, still the same.
public class A {
#Inject
A(B b) {
}
}
#ScopeA
public class B {
#Inject
B() {
}
}
#Component(modules = AModule.class)
#Singleton
public interface AComponent {
public A a();
}
#Module(subcomponents = SComponent.class)
class AModule {
#Provides
#Singleton
A a(SComponent.Factory factory) {
return factory.component().a();
}
}
#Subcomponent
#ScopeA
interface SComponent {
#ScopeA
A a();
#Subcomponent.Factory
interface Factory {
SComponent component();
}
}
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerAComponent.create().a();
}
}
After checking generated dagger code, I found this:
private final class SComponentImpl implements SComponent {
private SComponentImpl() {}
#Override
public A a() {
return DaggerAComponent.this.aProvider.get();
}
}
It seeems that SComponent are getting A from parent component, which is not what I wanted, where is the problem of my code?
Note that the example from the Subcomponents for Encapsulation page uses a qualifier annotation, #PrivateToDatabase, which is not a scoping annotation and which distinguishes the binding of Database from the binding of #PrivateToDatabase Database.
Subcomponents inherit all of the bindings from their parent components, so you currently do have A available from the parent component and also A available from the subcomponent. This is especially tricky if anything in your subcomponent needs to inject A, if it weren't marked #Singleton: Do you want the A from the parent component, or the A from the subcomponent?
Another tricky part of this situation is that you can't use qualifier annotations on classes that use #Inject constructors.
I'd recommend that you do the following:
Extract an interface from A, so then you have A and AImpl.
Keep your #Provides method that gets an A instance from the subcomponent.
Have the subcomponent expose AImpl, and (to best avoid ambiguity) only inject AImpl in the classes in your subcomponent, not A.
If you'd rather not extract an interface, you could also work around this problem by removing #Inject from A and writing a #Provides method in a module in the subcomponent that returns a qualified A, so the unqualified A goes through the top-level component and the qualified A is only available within the subcomponent.

How to call default implementation in overriden spring-data method

First of all, this is not a duplicate of Spring Data: Override save method. I want to override the save method, and I know where to find the documentation, but my question is how to call the original implementation in my custom code.
To override save() method in spring-data-*, you do something like below:
interface CustomizedSave<T> {
<S extends T> S save(S entity);
}
class CustomizedSaveImpl<T> implements CustomizedSave<T> {
public <S extends T> S save(S entity) {
// Your custom implementation
}
}
interface UserRepository extends CrudRepository<User, Long>, CustomizedSave<User> {
}
interface PersonRepository extends CrudRepository<Person, Long>, CustomizedSave<Person> {
}
My question is how to call the "super" implementation of save()? In spring-data-elasticsearch, the default save() implementation is not so simple to set up (basically I need to copy AbstractElasticsearchRepository source code), so I would rather not do this.
#Autowired
private EntityManager em;
#Override
public User save(User entity) {
JpaRepositoryFactory jrf = new JpaRepositoryFactory(em);
UserRepositories repoWithoutCustom = jrf.getRepository(UserRepositories.class);
do somth....
}
Where repoWithoutCustom what you need, your UserRepository without any customized methods. Just use required RepositoryFactory, in your case Elastic as i understood

Dagger2 Android subcomponent injection in nonAndroid classes

Learning Dagger2 and maybe going off the rails here. I have a class - MapRoute that may or may not be needed in a Fragment. If MapRoute is needed, I want to create it and when the MapRoute is instantiated I want to inject it with dependencies created at the application level. I am also using Builder pattern to populate MapRouter.
Perhaps the generic question is when you are in nonAndroid classes (not Activity/Fragment/...) how can you inject dependencies from above? How to you construct the nonAndroid injector in place of AndroidInjection.inject(this)?
So my fragment is:
public class ActivityMapFragment extends DaggerFragment ... {
#Inject
MapRoute.Builder mapRouteBuilder;
private void plotRouteForMap(Cursor csr){
MapRoute.Builder builder = new MapRoute.Builder();
builder.setSupportMapFragment(supportMapFragment)
.setLocationExerciseRecord(ler)
.setMapType(mapType)
.setUseCurrentLocationLabel(useCurrentLocationLabel)
.setCursor(csr)
.setTitle(activityTitle)
.setActivityPhotosCallback(this);
mapRoute = builder.build();
mapRoute.plotGpsRoute();
}
...
MapRoute is: (Edit) added Builder code snippet
public class MapRoute ... {
#Inject
public DisplayUnits displayUnits; <<< Created at app level
#Inject
public PhotoUtils photoUtils; <<<< Create at app level
public MapRoute() {
// Use subcomponent builder
MapRouteSubcomponent component =
DaggerMapRouteSubComponent.builder().build(); <<< Want to do this
component.inject(this);
}
public static class Builder {
SupportMapFragment supportMapFragment;
LocationExerciseRecord ler;
boolean useCurrentLocationLabel;
int mapType;
Cursor cursor;
ActivityPhotosCallback activityPhotosCallback;
String title;
#Inject
public Builder() {
}
public Builder setSupportMapFragment(SupportMapFragment supportMapFragment){
this.supportMapFragment = supportMapFragment;
return this;
}
....
MapRouteSubcomponent best guess:
#Subcomponent(modules = {MapRouteModule.class, ApplicationModule.class})
public interface MapRouteSubcomponent {
// allow to inject into our MapRoute class
void inject(MapRoute mapRoute);
#Subcomponent.Builder
interface Builder extends SubComponentBuilder<MapRouteSubcomponent> {
Builder mapRouteModule(MapRouteModule mapRouteModule);
}
#Module
public class MapRouteModule {
// What to put here?
}
And finally a subcomponent builder:
// from https://github.com/Zorail/SubComponent/blob/master/app/src/main/java/zorail/rohan/com/subcomponent/SubComponentBuilder.java
public interface SubComponentBuilder<V> {
V build();
}
At this point I am at a stand on where to go from here.

Intercepting Async Proxy Service exceptions for GWT RPC

My app has many RPC calls, and they all have a .onFailure(Throwable caught) method. I have a class shared between the client and the server code NotLoggedInException. This is thrown by the server, if the user doesn't have the relevant permissions based on sessions/cookies/permissions etc.
Ideally I would like to handle this exception in one place BEFORE others are passed to the .onFailure() code, given how ubiquitous this handling is and needs to be for security. There is a GWT.setUncaughtExceptionHandler() but this appears to get called after the handling which isn't ideal (in case an .onFailure accidentally consumes too much).
Does anybody have an elegant solution to this? An ugly solution is to wrap the deferred binded .create() proxy in the same aggregated class implementing the async interface.
Sidenote: The server was issuing a redirect before, but I don't like this paradigm, and would prefer it to be handled by the eventbus of the app.
Update: ugly answer referred to above
public abstract class CustomAsyncCallback implements AsyncCallback{
#Override
public CustomAsyncCallback(AsyncCallback<T> callback)
{
this.wrap = callback ;
}
AsyncCallback<T> wrap ;
#Override
public void onFailure(Throwable caught) {
if (!handleException())
{
wrap.onFailure(caught) ;
}
}
#Override
public void onSuccess(T t) {
wrap.onSuccess(t) ;
}
}
public class WrapDeferredBinding implements RpcInterfaceAsync
{
RpcInterfaceAsync service = GWT.create(RpcInterface.class);
public void method1(int arg1, AsyncCallback<Boolean> callback)
{
service.method1(arg1, new CustomAsyncCallback<Boolean>(callback)) ;
}
public void method2 ....
public void method3 ....
}
In order to wrap every AsynCallback<T> that is passed to any RemoteService you need to override RemoteServiceProxy#doCreateRequestCallback() because every AsynCallback<T> is handed in here before an RPC call happens.
Here are the steps to do so:
To begin you need to define your own Proxy Generator to step in every time a RemoteService proxy gets generated. Start by extending ServiceInterfaceProxyGenerator and overriding #createProxyCreator().
/**
* This Generator extends the default GWT {#link ServiceInterfaceProxyGenerator} and replaces it in the
* co.company.MyModule GWT module for all types that are assignable to
* {#link com.google.gwt.user.client.rpc.RemoteService}. Instead of the default GWT {#link ProxyCreator} it provides the
* {#link MyProxyCreator}.
*/
public class MyServiceInterfaceProxyGenerator extends ServiceInterfaceProxyGenerator {
#Override
protected ProxyCreator createProxyCreator(JClassType remoteService) {
return new MyProxyCreator(remoteService);
}
}
In your MyModule.gwt.xml make use of deferred binding to instruct GWT to compile using your Proxy Generator whenever it generates something of the type RemoteService:
<generate-with
class="com.company.ourapp.rebind.rpc.MyServiceInterfaceProxyGenerator">
<when-type-assignable class="com.google.gwt.user.client.rpc.RemoteService"/>
</generate-with>
Extend ProxyCreator and override #getProxySupertype(). Use it in MyServiceInterfaceProxyGenerator#createProxyCreator() so that you can define the base class for all the generated RemoteServiceProxies.
/**
* This proxy creator extends the default GWT {#link ProxyCreator} and replaces {#link RemoteServiceProxy} as base class
* of proxies with {#link MyRemoteServiceProxy}.
*/
public class MyProxyCreator extends ProxyCreator {
public MyProxyCreator(JClassType serviceIntf) {
super(serviceIntf);
}
#Override
protected Class<? extends RemoteServiceProxy> getProxySupertype() {
return MyRemoteServiceProxy.class;
}
}
Make sure both your MyProxyCreator and your MyServiceInterfaceProxyGenerator are located in a package that will not get cross-compiled by GWT into javascript. Otherwise you will see an error like this:
[ERROR] Line XX: No source code is available for type com.google.gwt.user.rebind.rpc.ProxyCreator; did you forget to inherit a required module?
You are now ready to extend RemoteServiceProxy and override #doCreateRequestCallback()! Here you can do anything you like and apply it to every callback that goes to your server. Make sure that you add this class, and any other class you use here, in my case AsyncCallbackProxy, to your client package to be cross-compiled.
/**
* The remote service proxy extends default GWT {#link RemoteServiceProxy} and proxies the {#link AsyncCallback} with
* the {#link AsyncCallbackProxy}.
*/
public class MyRemoteServiceProxy extends RemoteServiceProxy {
public MyRemoteServiceProxy(String moduleBaseURL, String remoteServiceRelativePath, String serializationPolicyName,
Serializer serializer) {
super(moduleBaseURL, remoteServiceRelativePath, serializationPolicyName, serializer);
}
#Override
protected <T> RequestCallback doCreateRequestCallback(RequestCallbackAdapter.ResponseReader responseReader,
String methodName, RpcStatsContext statsContext,
AsyncCallback<T> callback) {
return super.doCreateRequestCallback(responseReader, methodName, statsContext, new AsyncCallbackProxy<T>(callback));
}
}
Now, your AsyncCallbackProxy can look something like this:
public class AsyncCallbackProxy<T> implements AsyncCallback<T> {
private AsyncCallback<T> delegate;
public AsyncCallbackProxy(AsyncCallback<T> delegate) {
this.delegate = delegate;
}
#Override
public final void onFailure(Throwable caught) {
GWT.log("AsyncCallbackProxy#onFailure() : " + caught.getMessage(), caught);
if (caught instanceof NotLoggedInException) {
// Handle it here
}
delegate.onFailure(proxy);
}
#Override
public final void onSuccess(T result) {
delegate.onSuccess(result);
}
}
References:
DevGuideCodingBasicsDeferred.html
An example applied to performance tracking
You can wrap AsyncCallback class with an abstract class:
public abstract class CustomAsyncCallback<T> implements AsyncCallback<T>{
#Override
public void onFailure(Throwable caught) {
GWT.log(caught.getMessage());
handleException();
this.customOnFailure(yourDesireParam);
}
/**
* this method is optional
*/
public abstract void customOnFailure(Param yourDesireParam);
}
And then send a CustomAsyncCallback object to your RPC asynch methods.