GWT AsyncCallback Does Not Populate Static Member - java

I have an AsyncCallback call that contacts my GWT-RPC service and retrieves some data. I am trying to store that data into a class which has a static method to store the results of the query. However, I noticed that the data is not being populated in the static data member. If I "slow down" the AsyncCallback call by putting an SC.logWarn(...) in the AsyncCallback call, then the static data member gets populated properly.
final AsyncCallback<Set<MyData>> dataCallback =
new AsyncCallback<Set<MyData>>()
{
#Override
public void onSuccess(Set<MyData> aDataType)
{
for (MyData data : aDataType)
{
String someData = aDataType.getData();
Record rec = new Record();
rec.setAttribute("data", someData);
getDataSource().addData(rec);
}
LocalUiCache.setLocalCache(new ResultSet(getDataSource()));
}
};
MyDataService.RPC.getInstance().getData(dataCallback);
...
public class LocalUiCache
{
private static ResultSet localCache;
/**
* #return the localCache
*/
public static ResultSet getLocalCache()
{
return localCache;
}
/**
* #param aLocalCache the localCache to set
*/
public static void setLocalCache(ResultSet aLocalCache)
{
localCache = aLocalCache;
}
}

I'm not sure at this, but I suppose that SmartGWT doesn't reloads your changes fast.
You can try to tweak dataSource cache or call explicitly invalidate method.
Other suggestion will surely work, but it's 'dirty hack'. You can put in async callback scheduled call:
new Timer() {
public void run() {
LocalUiCache.setLocalCache(new ResultSet(getDataSource()));
}
}.schedule(50);

Related

How to make a Callback function for webservice in Java?

I'm using a Odoo service to get my data of web. In main class I have a method to read a data:
public void OdooRead() {
OdooService.getCustomers(odoo, "myCallbackFunction");
}
So, I did create a other class to make this service:
public class OdooService {
public static final String[] odooAllFields = {"id","name","customer_account_number","customer_group_id","segment_id","subsegment_id","economic_group_id","type_stablishment_id","street","street2","final_user","final_taxpayer","cnpj_cpf","inscr_est","ccm","cnae","phone","phone_extension","mobile","fax","email","email_extra","website","lang"};
public static List<Customer> getCustomers(OdooClient client, "myCallbackFunction") {
List<Customer> list = new ArrayList<>();
ODomain domain = new ODomain();
OdooFields odooFields = new OdooFields();
odooFields.addAll(odooAllFields);
String sorting = "id ASC";
int offset = 0;
int limit = 0;
client.searchRead("res.partner", domain, odooFields, offset, limit, sorting, new IOdooResponse() {
#Override
public void onResult(OdooResult result) {
// HERE I WANTS CALL THE CALLBACK FUNCTION TO MAIN!
}
});
return list;
}
}
So, when the method returns the result of search on web, I wants send a callback function to main, with the list of results as parameter. And while this, the main class runs normally, and when method finish I refresh user interface.

How to get inserted row id after inserting row in room to the main thread

I want to return the inserted row Id to use it to update some value in the same row
#Entity(tableName = "course")
public class Course {
#PrimaryKey(autoGenerate = true)
private int id;
private String firebaseId;
}
#Dao
public interface CourseDao {
#Insert(onConflict = REPLACE)
long insertCourse(Course course);
#Query("UPDATE course SET firebaseId = :firebaseId WHERE id = :id")
void updateFirebaseId(int id, String firebaseId);
}
the problem is I cant return the Id to the main thread
public class Repository {
private static final Object LOCK= new Object();
private static Repository sInstance;
private final CourseDao mCourseDao;
private final AppExecutors mAppExecutors;
public void insertCourse(final Course course) {
mAppExecutors.diskIO().execute(new Runnable() {
#Override
public void run() {
mCourseDao.insertCourse(course);
}
});
}
public void updateCourse(final Course course) {
mAppExecutors.diskIO().execute(new Runnable() {
#Override
public void run() {
mCourseDao.updateCourse(course);
}
});
}
}
I tried to use liveData but its not supported on insert
Error:(34, 20) error: Methods annotated with #Insert can return either void, long, Long, long[], Long[] or List<Long>.
Is it possible to return the id of Course once the insertion is completed without writing a separate select query?
LiveData is not supported for insert.
I feel there are 2 approaches to do insert operation in the background thread and send the result (long) back to Activity:
Using LiveData, I personally like this approach:
public class Repository {
private LiveData<Long> insertedId = MutableLiveData()
public void insertCourse(final Course course) {
mAppExecutors.diskIO().execute(new Runnable() {
#Override
public void run() {
Long id = mCourseDao.insertCourse(course);
insertId.setValue(id);
}
});
}
}
Using Rx:
return Single.fromCallable(() -> mCourseDao.insertCourse(course));
Here, you'll get Single<Long> which you can observe in your Activity
Note: Repository will return Long to ViewModel and in your ViewModel will have the LiveData and setValue stuff.
I did it like this in Java
In the environment where you want the id:
public class MyIdClass {
ArrayList<Integer> someIds = new ArrayList<>(); //this could be a primitive it doesn't matter
constructor with repository....{}
#FunctionalInterface //desugaring... normal interfaces are ok I guess?
public interface GetIdFromDao {
void getId(long id);
}
public void insertSomething(
Something something
) {
someRepository.insertSomething(
something,
id -> someIds.add((int)id) //lambda replacement, I think method reference cannot be done because of (int) casting, but if Array is type long it could be done.
);
}
}
In abstract class MyDao...: (something that I cannot stress enough..., work with ABSTRACT CLASS DAO, its more flexible)
#Insert(onConflict = OnConflictStrategy.IGNORE)
protected abstract long protectedInsertSomething(Something something);
public void insert(
Something something,
MyIdClass.GetIdFromDao getIdFromDao
) {
//get long id with insert method type long
long newSomethingId = protectedInsertSomething(something);
getIdFromDao.getId(newSomethingId);
}
Inside Repository, If you use AsyncTask<X, Y, Z>, you can actually pass everything through VarAgrs, even listeners, but be sure to recast them in the order which they get inserted, and use type Object or a common ancestor.
(Something) object[0];
(MyIdClass.GetIdFromDao) object[1];
new InsertAsyncTask<>(dao).execute(
something, //0
getIdFromDao //1
)
Also use #SupressWarnings("unchecked"), nothing happens
Now If you want even further interaction, you can connect a LiveData to the listener, or construct a Factory ViewModel...
an abstract factory ViewModel... that would be interesting.
But I believe DataBinding has an Observable view Model which I guess can be used(?)... I really don't know.

Refresh the TableViewer table every time add a new item to list

I created a TableViewer table to display data from an ArrayList. I want to refresh the table every time I add a new item to my list. But now the table waits until all my data has been added to the list then the table will display all the data at once. Can some one help me with this problem? I got stuck at here for a long time... Here is some code
private void buildPerformanceTable(
IPerformanceDataRetriever performanceDataRetriever) {
tableViewer.setContentProvider(new JobProfileContentProvider());
tableViewer.setLabelProvider(new JobProfileLabelProvider());
tableViewer.setComparator(new JobProfileViewerComparator());
Table table = tableViewer.getTable();
for (ColumnType columnType : ColumnType.values()) {
buildTableColumn(columnType.getColumnName(),
columnType.getColumnIndex());
}
tableViewer.setInput(performanceDataRetriever);
for (int i = 0; i < table.getColumnCount(); i++) {
table.getColumn(i).pack();
}
table.setHeaderVisible(true);
table.setLinesVisible(true);
}
public class JobProfileContentProvider implements IStructuredContentProvider{
private static final long SERIAL_VERSION_UID = 6452458171326245659L;
/**
* {#inheritDoc}
*/
#Override
public Object[] getElements(Object object) {
return ((IPerformanceDataRetriever) object).providePerformanceData()
.toArray();
}
/**
* <b>This method is not implemented.</b> <br>
*
* {#inheritDoc}
*/
#Override
public void dispose() {
}
/**
* <b>This method is not implemented.</b> <br>
*
* {#inheritDoc}
*/
#Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
}
public class JobProfileInfoMock implements IPerformanceDataRetriever {
/**
* Creates an instance of list containing active JobProfile.
*
* #return List contains JobProfile.
*/
public static List<JobProfile> getJobProfileWithAllActiveJobs(){
List<JobProfile> JobProfiles = new ArrayList<JobProfile>();
for(int i=1;i<=6;i++){
JobProfile profile = new JobProfile.ProfileBuilder().jobId(i)
.cpuUsage(80+i).memoryUsage(40+i).ipAddress("192.1.12.4"+i).isActive(true)
.build();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
JobProfiles.add(profile);
System.out.println(JobProfiles.size());
}
return JobProfiles;
}
}
Call tableViewer.refresh() each time you add to the table.
You must make one call to tableViewer.setInput before you can call refresh.
If you are running in a background thread you must use Display.asyncExec to run the refresh call in the UI thread.
Add this bunch of code in your create part control method enter code here this will may be help you
ResourcesPlugin.getWorkspace().addResourceChangeListener(new IResourceChangeListener() {
#Override
public void resourceChanged(IResourceChangeEvent event) {
treeViewer.refresh();
}
});

Scope management - Stateful IO Monad?

I am playing with functional programming and in particular with Functional Java. I have implemented with success my version of the IO Monad and I am writing IO actions for my core. It is basically serializing objects to Xml files (the object type extends the custom XmlWritable interface).
Unfortunately, in order to do that, an instance of OutputStream AND one instance of XmlSerializer needs to be created. The scope of the OutputStream is wider than XmlSerializer's, which means that the only way I can see to be able to correctly handle both lifecycles within my IO monad is to carry both of them with me in a tuple, closing OutputStream after having written using XmlSerializer.
This leads to heavy and ugly code (Java 6 is definitely not the best for this):
public abstract class IO<R> {
[...]
}
public class IOActions {
public final F<String, IO<OutputStream>> openFileFn() {
return new F<String, IO<OutputStream>>() {
#Override
public IO<OutputStream> f(String fileName) {
[...]
}
};
}
/* This will be partially applied, encoding will be fixed */
public static final F<OutputStream, IO<P2<OutputStream, XmlSerializer>>> initSerializer() {
return new F<OutputStream, IO<P2<OutputStream, XmlSerializer>>>() {
#Override
public IO<P2<OutputStream, XmlSerializer>> f(OutputStream os) {
XmlSerializer = new ...
[...]
}
};
}
/* This will be partially applied as well */
public static final F2<XmlWritable, P2<OutputStream, XmlSerializer>, IO<P2<OutputStream, XmlSerializer>>> writeObjectFn() {
return new F2<XmlWritable, P2<OutputStream, XmlSerializer>, IO<P2<OutputStream, XmlSerializer>>>() {
#Override
public IO<P2<OutputStream, XmlSerializer>> f(XmlWritable object, P2<OutputStream, XmlSerializer> p) {
[...]
}
};
}
Is there a more idiomatic why to handle my use case in functional programming?
Lurking, I discovered the State Monad...but I am kind of scared to see what it is going to happen if I apply a State Monad on top of a IO Monad in Functional Java.
I actually took great inspiration from Functional-Java's DB combinators to solve similar problems. I made my very own "XML combinators" (and more) from this pattern, so its worth learning.
You might find this discussion on google groups useful.
edit - replying to the comment:
follow the code:
notice how you start a new connection using the StateDb, see that you have a few options to start a connection, one that eventually commits, and one that eventually rollback. these are just two examples of things you can "carry" with the computation. Essentially, every computation that you bind (a plain modaic bind), could potentially carry information.
here is an example i gave in the discussion above:
DB<PreparedStatement> prepareStatement(final String sql) {
return new DB<PreparedStatement>() {
public PreparedStatement run(Connection c) throws SQLException {
return c.prepareStatement(sql);
}}}
// for a query that a reader might perform, i might have a function like this:
F<PreparedStatement, DB<ResultSet>> runStatement() {
public DB<ResultSet> f(final PreparedStatement s) {
return new DB<ResultSet>() {
public ResultSet run (Connection c) throws SQLException {
return s.executeQuery();
}}}
So in this example, you can pass extra information, namely the sql query as a parameter to the function that gets bound. you could just as well had more parameters to runStatement.
to put it all together, you get something like:
ResultSet rs = DbState.reader("conn-url").run(prepareStatement("select * from table").bind(runStatement());
Hope this helps!
Here is what I have come up with. Feedback is very appreciated.
I followed the answer above, taking inspiration from the linked discussion:
public class IOXml<T extends XmlWritable> implements DataWriter<T>{
private final XmlSerializer mXmlSerializer;
private final Option<String> mXmlEncoding;
private final IO<OutputStream> ioCreateStream;
private final F<OutputStream, IO<Unit>> ioCloseStream;
#Inject
IOXml(IO<OutputStream> createStream, F<OutputStream, IO<Unit>> closeStream, XmlSerializer xmlSerializer, Option<String> xmlEncoding) {
mXmlSerializer = xmlSerializer;
mXmlEncoding = xmlEncoding;
ioCreateStream = createStream;
ioCloseStream = closeStream;
}
/**
* Write a T object which is XmlWritable.
* #param osAndSer The tuple containing OutputStream and XmlSerializer.
* #param object The object to write.
* #return IO monad object.
*/
protected IO<Unit> writeObject(final T object) {
return new IO<Unit>() {
#Override
public Unit performIO() throws IOException {
object.writeXml(mXmlSerializer);
return Unit.unit();
}
};
}
protected final F<Unit, IO<Unit>> writeObjectFn(final T object) {
return new F<Unit, IO<Unit>>() {
#Override
public IO<Unit> f(Unit a) {
return writeObject(object);
}
};
}
/**
* Initialize the XmlSerializer before using it.
* #param os An OutputStream.
* #param encoding The encoding of the xml file.
* #return An IO action returning nothing.
*/
protected IO<Unit> initXml(final OutputStream os) {
return new IO<Unit>() {
#Override
public Unit performIO() throws IOException {
mXmlSerializer.setOutput(os, mXmlEncoding.toNull());
mXmlSerializer.startDocument(mXmlEncoding.toNull(), true);
return Unit.unit();
}
};
}
/**
* Close the XmlSerializer after.
* #return An IO action returning nothing.
*/
protected IO<Unit> closeXml() {
return new IO<Unit>() {
#Override
public Unit performIO() throws IOException {
mXmlSerializer.endDocument();
return Unit.unit();
}
};
}
protected final F<Unit, IO<Unit>> closeXmlFn() {
return new F<Unit, IO<Unit>>() {
#Override
public IO<Unit> f(Unit a) {
return closeXml();
}
};
}
#Override
public void close() throws IOException {
closeXml().performIO();
}
#Override
public void write(T object) {
throw new UnsupportedOperationException("Are you sure? IOXml is a functional class. Use the function returned by liftIO instead.");
}
/**
* Curried function to write XML objects, given the object itself and an OutputStream.
* #return The curried function.
*/
protected F<OutputStream, F<T, IO<Unit>>> writeFn() {
// returning the outer
return new F<OutputStream, F<T, IO<Unit>>>() {
#Override
public F<T, IO<Unit>> f(final OutputStream os) {
// Returning the inner
return new F<T, IO<Unit>>() {
#Override
public IO<Unit> f(T object) {
return initXml(os).bind(writeObjectFn(object)).bind(closeXmlFn());
}
};
}
};
}
#Override
public IO<Unit> writeIO(final T object) {
return IOImpl.bracket(ioCreateStream, // init
ioCloseStream, // close
Function.partialApply2(writeFn(), object)); // body
}
}

Automatically opening and closing connection

NOTE: Please ignore my use of MultivaluedMap instead of multiple vargs String...args.
Is there a standard way in java of doing this?
What I have is a resource, that is returned from a remote server. But before each query, the remote connection must be open, and after the returns are returned - it must be closed.
So a natural way of doing this is something like:
Connection c = config.configureConnection();
c.open(); //open
List<Car> cars;
try{
cars = c.getCars();
}finally{
c.close(); //close
}
Now I want to implement something that operates on the level of the resources themselves, without worrying about connection, for example:
List<Car> cars = new CarResource().all(); //opens and closes connection
The way I am currently doing it is by having one abstract class, AbstractQueriable call abstract methods query(String ...args) and query(int id), which any class extending it must implement.
The AbstractQuerieable implements the Queriable interface, which makes it expose the three public methods filter(String ...args), all() and get(int id) - which are the public facing methods.
Here is the Queriable interface:
public interface Queriable <T>{
public T get(String id);
/** Simply returns all resources */
public Collection<T> all();
public Collection<T> filter(MultivaluedMap<String, String> args);
}
here is the AbstractQueriable class that implements it:
public abstract class AbstractQueriable<T> implements Queriable<T> {
#Override
public final T get(String id) {
setup();
try {
return query(id);
} finally {
cleanup();
}
}
#Override
public final Collection<T> filter(MultivaluedMap<String, String> args) {
setup();
try {
return query(args);
} finally {
cleanup();
}
}
/**
* Returns all resources.
*
* This is a convenience method that is equivalent to passing an empty
* arguments list to the filter function.
*
* #return The collection of all resources if possible
*/
#Override
public final Collection<T> all() {
return filter(null);
}
/**
* Queries for a resource by id.
*
* #param id
* id of the resource to return
* #return
*/
protected abstract T query(String id);
/**
* Queries for a resource by given arguments.
*
* #param args
* Map of arguments, where each key is the argument name, and the
* corresponing values are the values
* #return The collection of resources found
*/
protected abstract Collection<T> query(MultivaluedMap<String, String> args);
private void cleanup() {
Repository.close();
}
private void setup() {
Repository.open();
}
and finally my resource, which I want to use in the code, must extend the AbstractQueriable class, for example (please note that the details of these methods are not important):
public class CarRepositoryResource extends AbstractQueriable<Car> {
#Override
protected Car query(String id) {
MultivaluedMap<String, String> params = new MultivaluedMapImpl();
params.add("CarID", id);
// Delegate the query to the parametarized version
Collection<cars> cars = query(params);
if (cars == null || cars.size() == 0) {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
if (cars.size() > 1) {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
return cars.iterator().next();
}
#Override
protected Collection<Car> query(MultivaluedMap<String, String> params) {
Collection<Car> cars = new ArrayList<Car>();
Response response = Repository.getConnection().doQuery("Car");
while (response.next()) {
Returned returned = response.getResult();
if (returned != null) {
cars.add(returned);
}
}
return cars;
}
}
which finally, I can use in my code:
Collection<Car> cars = new CarRepositoryResource().all();
//... display cars to the client etc...
There are a few things I don't like about this kind of setup:
I must instantiate a new instance of my "CarRepositoryResource" every time I do a query.
The method names "query", while internal and private, are still confusing and clunky.
I am not sure if there is a better pattern or framework out there.
The connection that I am using does not support/implement the JDBC api and is not sql-based.
You could use a variation of the (in)famous Open session in view pattern.
Basically it comes down to this:
Define a "context" in which connections are available
(usually the request in web applications)
Handle (possibly lazy) initialization and release of a connection when entering/exiting the context
Code your methods taking for granted they will only be used inside such a context
It is not difficult to implement (storing the connection in a static ThreadLocal to make it thread safe) and will definitely spare a few open/close calls (performance-wise that could be a big gain, depending on how heavy your connection is).
The context class could look something like (consider this pseudo-code);
public class MyContext{
private static final
ThreadLocal<Connection> connection = new ThreadLocal<Connection>();
public static void enter() {
connection.set(initializeConnection());
// this is eager initialization
// if you think it will often the case that no connection is actually
// required inside a context, you can defer the actual initialization
// until the first call to get()
}
public static void exit() {
try { connection.close(); }
catch(Throwable t) { /* panic! */ }
finally { connection.set(null); }
}
public static Connection get() {
Connection c = connection.get();
if (c == null) throw new IllegalStateException("blah blah");
return c;
}
}
Then you would use connections like this:
MyContext.enter();
try {
// connections are available here:
// anything that calls MyContext.get()
// gets (the same) valid connection instance
} finally {
MyContext.exit();
}
This block can be put wherever you want (in webapps it usually wraps the processing of each request) - from the main method if you are coding a simple case when you want a single connection available for the whole lifespan of your application, to the finest methods in your API.
You might want to take a look at fluent interfaces (with an interesting example here) and its "Builder" pattern.
You would query like this:
cars().in(DB).where(id().isEqualTo(1234));
This way you can hide the connection/disconnection code in the outermost cars() method, for example.

Categories