|
Re: Simple non-UI object example [message #846697 is a reply to message #846346] |
Mon, 16 April 2012 09:52 |
|
Hi Michael,
there is no recipe to follow yet for non-widget components. Many of the
parts involved are still under development. For RAP 2.0, we'll have a
tutorial on that topic available. Until then, here's how you can issue a
request from the client:
var isReady = ThirdPary.isSomethingReady();
var request = org.eclipse.swt.Request.getInstance();
request.addParameter( "ThirdPary.ready", isReady );
If you want to inform the server immediately, you can also call
request.send(). If you omit this call, the parameter will be transmitted
with the next request.
On the server side, you'll have to read and process this parameter.
Check out the GeolocationSynchronizer for an example.
Hope this helps,
Ralf
--
Ralf Sternberg
Twitter: @EclipseRAP
Blog: http://eclipsesource.com/blogs/
Professional services for RAP and RCP?
http://eclipsesource.com/services/rap/
|
|
|
|
Re: Simple non-UI object example [message #847589 is a reply to message #846808] |
Tue, 17 April 2012 12:56 |
|
Hi Leone,
please note that a phase listener has application scope, not session
scope. You have to compare the current display with the session display
to make your code behave correctly in a multi-user environment. See the
class AbstractObjectSynchronizer as an example.
As long as you're in the UI thread (and you are during request
processing), you can always store attributes in the session store
`RWT.getSessionStore()` or the application store
`RWT.getApplicationStore()`.
Best regards, Ralf
--
Ralf Sternberg
Twitter: @EclipseRAP
Blog: http://eclipsesource.com/blogs/
Professional services for RAP and RCP?
http://eclipsesource.com/services/rap/
|
|
|
|
Re: Simple non-UI object example [message #849880 is a reply to message #847912] |
Thu, 19 April 2012 14:31 |
Michael Ihde Messages: 10 Registered: July 2009 |
Junior Member |
|
|
Ralf/Mark,
Thanks for the help. I've included a full example below for others who run across this thread...however, I struggled to find a way to do exactly what I was trying to accomplish. My goal was to provide a synchronous API...something like this:
public class MyWidget implements IEntryPoint {
public int createUI() {
Display display = new Display();
if (isThirdPartyReady()) {
// Do one thing
} else {
// Do another thing
}
}
public boolean isThirdPartyReady(IProgressMonitor monitor) {
// add life cycle listener
// execute JS
// while !monitor.isCanceled()
// check for response
// return response
}
}
This, of course, will produce a deadlock because isThirdPartyReady was called in the UIThread and the LifeCycleListeners are also called in the UIThread. I tried using a custom ServiceHandler and qx.io.request.Xhr() but I was unable to get that to work (should I continue to try down this path?). Fundamentally I'm attempting to execute client-side code and receive the response while blocking the UI thread...perhaps this is a naive goal.
In my particular case, I want to build my UI differently based off results of client-side execution. For example:
public int createUI() {
if (detectedSomethingAboutClientSide()) {
// series of SWT widget creation
} else {
// alternate series of SWT widget creation
}
}
I can accomplish this through asynchronous callbacks (like below), it just makes the code a bit more obtuse. In my particular case, it would suffice if I could contribute client-side code into rwt-index.html initialization. I'm thinking something like IEarlyStartupJS. Javascript from this extension-point would be executed in rwt-index.html and be able to contribute parameters to the "rwt_initialize" message. The LifeCycleServiceHandler would store these in RWT.getSessionStore() or some other location. Is this a useful idea? If so, I will happily make the changes and provide a patch.
Anyways here is the complete final solution:
public interface IAsyncCallback<T> {
public void onSuccess(T result);
public void onFailure(Throwable t);
}
...
public static void isThirdPartyReady(final Display display, final IAsyncCallback<Boolean> callback) {
RWT.getLifeCycle().addPhaseListener(new PhaseListener() {
@Override
public PhaseId getPhaseId() {
return PhaseId.READ_DATA;
}
@Override
public void beforePhase(PhaseEvent event) {
}
@Override
public void afterPhase(PhaseEvent event) {
if (display != LifeCycleUtil.getSessionDisplay()) return;
HttpServletRequest req = RWT.getRequest();
String isThirdPartyReadyStr = req.getParameter("isThirdPartyReady");
if ((req != null) && (isThirdPartyReadyStr!= null)) {
final boolean isThirdPartyReady = Boolean.parseBoolean(isThirdPartyReadyStr);
if (callback != null) {
SafeRunner.run(new ISafeRunnable() {
@Override
public void run() throws Exception {
callback.onSuccess(isThirdPartyReady);
}
@Override
public void handleException(Throwable exception) {
}
});
}
RWT.getSessionStore().setAttribute("isThirdPartyReady", isThirdPartyReady );
RWT.getLifeCycle().removePhaseListener(this);
}
}
});
StringBuilder code = new StringBuilder();
code.append("var req = org.eclipse.swt.Request.getInstance();\n");
code.append("req.addParameter(\"isThirdPartyReady\", ThirdParty.util.isReady());\n");
code.append("req.send();\n");
JSExecutor.executeJS(code.toString());
}
Thanks again for all the help.
~Michael
|
|
|
Re: Simple non-UI object example [message #851866 is a reply to message #849880] |
Sat, 21 April 2012 11:55 |
|
Hi Michael,
Do you have to *wait* for your third-party library to become ready or do
you just *check* if it's available? In the latter case, it would be
ideal to pass this information to the server in the first request already.
For the mobile RAP clients, we've been thinking about a new Java API to
identify the client and access some client properties. Maybe such an API
could be extensible to provide for your case, too. If this sounds like a
solution, you could open an enhancement request and describe your use case.
As a workaround, you could also register your JavaScript code as a
resource to have it delivered to the client right on startup. The code
could attach a send listener to the request that adds your custom
parameter to every single Ajax request.
Regards, Ralf
--
Ralf Sternberg
Twitter: @EclipseRAP
Blog: http://eclipsesource.com/blogs/
Professional services for RAP and RCP?
http://eclipsesource.com/services/rap/
|
|
|
Re: Simple non-UI object example [message #853152 is a reply to message #851866] |
Sun, 22 April 2012 19:26 |
Michael Ihde Messages: 10 Registered: July 2009 |
Junior Member |
|
|
Ralf,
Coincidentally I had just figured out the workaround approach you suggested. Here are the details of what ended up working for me for other's who want to repeat it.
A) Contribute my JavaScript via org.eclipse.rap.ui.resources
B) Contribute a phase listener org.eclipse.rap.ui.phaselistener
In the Javascript code I do this
...
org.eclipse.swt.Request.getInstance().addEventListener( "send", this._onSWTRequestSend, this );
...
function _onSWTRequestSend( evt ) {
var req = org.eclipse.swt.Request.getInstance();
var is_rwt_initialize = req.getParameter( "rwt_initialize");
if (is_rwt_initialize === "true") {
req.addParameter("isThirdPartyReady", ThirdParty.util.isReady());
}
}
My phase listener check for the parameter in the beforePhase() callback. This allows it to set the session store before createUI is called.
public void beforePhase(PhaseEvent event) {
...
RWT.getSessionStore().setAttribute(...);
...
}
I'll have to think about the use-case for the mobile RAP client.
Thanks for the help and patience. RAP and the RAP developers are both awesome
~Michael
[Updated on: Sun, 22 April 2012 20:04] Report message to a moderator
|
|
|
Powered by
FUDForum. Page generated in 0.04079 seconds