DJ Native Swing javascript command problems - java

Using DJ Native Swing it is possible to show a web page within a java application. When you do this it is also possible to communicate from the browser to the java runtime environment using the "command" protocol. The documentation has a code snippet which demonstrates it's usage:
function sendCommand( command ){
var s = 'command://' + encodeURIComponent( command );
for( var i = 1; i < arguments.length; s+= '&' + encodeURIComponent( arguments[i++] ) );
window.location = s;
}
As it looks here it seems to be a regular GET request to an url using the command protocol instead of http. Although when I create and image, script tag or just and ajax get request there is no response and the breakpoint in the java runtime isn't triggered.
I don't want to set the window.location because I don't want to navigate away from the page I am currently at. Using the link to navigate to a command url does work though but it also navigates away from the current page. The page uses OpenLayers and dojo. (I have also tried dojo.io.script)

After some work I have found a neat way to communicate with the java runtime which doesn't trigger a refresh of the page every time there is communication. It is inspired on the way JSONP works to get around the cross domain restriction in most browsers these days. Because an iFrame will also trigger a command:// url it possible to do a JSONP like action using this technique. The code on the client side (browser):
dojo.provide( "nmpo.io.java" );
dojo.require( "dojo.io.script" );
nmpo.io.java = dojo.delegate( dojo.io.script, {
attach: function(/*String*/id, /*String*/url, /*Document?*/frameDocument){
// summary:
// creates a new tag pointing to the specified URL and
// adds it to the document.
// description:
// Attaches the script element to the DOM. Use this method if you
// just want to attach a script to the DOM and do not care when or
// if it loads.
var frame = dojo.create( "iframe", {
id: id,
frameborder: 0,
framespacing: 0
}, dojo.body( ) );
dojo.style( frame, { display: "none" } );
dojo.attr( frame, { src: url } );
return frame;
},
_makeScriptDeferred: function(/*Object*/args){
//summary:
// sets up a Deferred object for an IO request.
var dfd = dojo._ioSetArgs(args, this._deferredCancel, this._deferredOk, this._deferredError);
var ioArgs = dfd.ioArgs;
ioArgs.id = dojo._scopeName + "IoScript" + (this._counter++);
ioArgs.canDelete = false;
//Special setup for jsonp case
ioArgs.jsonp = args.callbackParamName || args.jsonp;
if(ioArgs.jsonp){
//Add the jsonp parameter.
ioArgs.query = ioArgs.query || "";
if(ioArgs.query.length > 0){
ioArgs.query += "&";
}
ioArgs.query += ioArgs.jsonp
+ "="
+ (args.frameDoc ? "parent." : "")
+ "nmpo.io.java.jsonp_" + ioArgs.id + "._jsonpCallback";
ioArgs.frameDoc = args.frameDoc;
//Setup the Deferred to have the jsonp callback.
ioArgs.canDelete = true;
dfd._jsonpCallback = this._jsonpCallback;
this["jsonp_" + ioArgs.id] = dfd;
}
return dfd; // dojo.Deferred
}
});
When a request is sent to the java runtime a callback argument will be supplied and a webBrowser.executeJavascript( callbackName + "(" + json + ");" ); action can be executed to trigger the callback in the browser.
Usage example client:
dojo.require( "nmpo.io.java" );
nmpo.io.java.get({
// For some reason the first paramater (the one after the '?') is never in the
// paramater array in the java runtime. As a work around we stick in a dummy.
url: "command://sum?_",
callbackParamName: "callback",
content: {
numbers: [ 1, 2, 3, 4, 5 ].join( "," )
},
load: function( result ){
console.log( "A result was returned, the sum was [ " + result.result + " ]" );
}
});
Usage example java:
webBrowser.addWebBrowserListener(new WebBrowserAdapter() {
#Override
public void commandReceived(WebBrowserCommandEvent e) {
// Check if you have the right command here, left out for the example
// Parse the paramaters into a Hashtable or something, also left out for the example
int sum = 0;
for( String number : arguments.get( "numbers" ).split( "," ) ){
sum += Integer.parseInt( number );
}
// Execute the javascript callback like would happen with a regular JSONP call.
webBrowser.executeJavascript( arguments.get( "callback" ) + "({ result: " + sum + " });" );
}
});
Also with IE in the frame I can highly recommend using firebug lite, the dev tools for IE are not available.

Related

Play change Language dynamallicy

Fairly new to Play trying to change the language dynamically.
route
GET /language/:lang controllers.Index.setLanguage(lang: String)
Tried so far (but none of them work)
Lang.apply(language);
Lang.change(language); // <-- doesn't even compile
Lang.apply(language);
ctx().changeLang(language);
view
#import play.i18n.Messages
...
#Messages.get("message")
#messages.at("message")
...
Both not working..
application.config
messages
Method with some logging
public Result setLanguage(String language) {
Http.Context context = Http.Context.current();
String langFromHttpContext = context.lang().language();
String langFromCtx = ctx().lang().language();
String playLangCookieVal = request().cookies().get("PLAY_LANG").value();
boolean changed = ctx().changeLang(language);
Logger.info("Request param: " + language);
Logger.info("Http context language: " + langFromHttpContext);
Logger.info("ctx language: " + langFromHttpContext);
Logger.info("PLAY_LANG cookie value: " + langFromCtx);
Logger.info("Changed: " + changed);
return ok(index.render("Index"));
}
Result
application - Request param: en
application - Http context language: nl
application - ctx language: nl
application - PLAY_LANG cookie value: nl
application - Changed: false
You need to delete the application.langs="nl" from the configuration. It's deprecated and replaced by the play.i18n.langs.
You must leave only play.i18n.langs=["en","nl"]
You code does not work because Play reads the application.langs="nl" and ignore play.i18n.langs=["en","nl"] (because langs already read from the application.langs), so it suggest your application use only "nl" language and, of course could not set it to "en", so ctx().changeLang(language) method return false
Try this:
ctx().changeLang(language);

Accessing PowerDesigner Repository Models via COM

I have been trying to get live models directly from the PowerDesigner repository using the COM API without success. Here's what I've been trying in VBA:
Set pd = CreateObject("PowerDesigner.Application")
Set conn = pd.RepositoryConnection
conn.Open "", "", "ShhMahPW"
Set model = conn.FindChildByPath("Program/Project/Logical Models/MahLOM", PdOOM_Classes.cls_Model)
MsgBox model.ShortDescription 'This fails because model is null!
Similarly, I've been trying the same thing in Eclipse with the Java COM bridge:
Application pd = this.getApplicationHook();
//Make live connection to proxy repository
RepositoryConnection conn = new RepositoryConnection( pd.GetRepositoryConnection() );
conn.Open( "", "", ConnectionParams.PASSWORD );
BaseObject model = conn.FindChildByPath( "Program/Project/Logical Models/MahLOM",
PdOOM_Classes.cls_Model );
//Null model, COMException: "Action can not be performed. result = -2147467259"
System.out.println( model.GetShortDescription() )
Can someone please suggest a good way of diving into the repository? I have been able to confirm that I have a connection to the repo and then list the children at that top level. I am struggling to dig into folders beyond the root level. Thanks!
I knew that the model I was looking to pull down from the repo already existed in my local workspace. Really this was a refresh of the local workspaces models. To perform this, the method UpdateFromRepository() can be used!
So what I can do then is get a handle to the local PowerDesigner model and then call for an update before retrieving children. Note the casting from BaseObject to BaseModel for the sake of the refresh...
private BaseObject getModel(){
Application pd = this.getApplicationHook();
model = pd.OpenModel(this.basePath + this.modelName);
System.out.println( "Retrieving model updates from repository... ");
RepositoryConnection conn = new RepositoryConnection( pd.GetRepositoryConnection() );
conn.Open( "", "", ConnectionParams.PASSWORD);
boolean success = new BaseModel(model).UpdateFromRepository();
if( success )
System.out.println( "Update successful!" );
else
System.out.println( "Update failed. Check PowerDesigner settings." );
return this.model;
}
Your main problem is that the search ChildKind should be Cls_RepositoryModel, instead of PdOOM_Class.cls_Model.
option explicit
' assuming we're already connected
if RepositoryConnection.Connected then
Descent RepositoryConnection,""
end if
dim c
set c = RepositoryConnection.FindChildByPath("Folder_7/ConceptualDataModel_1", Cls_RepositoryModel)
if not c is nothing then
output "*** found object " & c.classname
end if
sub Descent(obj,ofs)
output ofs & obj.name & " - " & obj.ObjectType & " - " & obj.ClassName
if obj.ObjectType = "RepositoryModel" then exit sub
if obj.PermanentID = 3 then exit sub ' to save time, don't enter Library
if not obj.HasCollection("ChildObjects") then exit sub
dim c
for each c in obj.ChildObjects
Descent c,ofs & " "
next
end sub

The browser console doesn't recognize js vars that were injected with selenium webdriver

I try to bowser to a page with selenium web-driver.
I then inject and execute some js via selenium web-driver.
I try to access these vars in this opened browser console,
but it seems they were not created. How come?
I have this code:
public void foo (){
String script =
"var aLocation = {};" +
"var aOffer = {};" +
"var aAdData = " +
"{ " +
"location: aLocation, " +
"offer: aOffer " +
" };" +
"var aClientEnv = " +
" { " +
" sessionid: \"\", " +
" cookie: \"\", " +
" lon: 34.847, " +
" lat: 32.123, " +
" venue: \"\", " +
" venue_context: \"\", " +
" source: \"\"," + // One of the following (string) values: ADS_PIN_INFO,
// ADS_0SPEED_INFO, ADS_LINE_SEARCH_INFO,
// ADS_ARROW_NEARBY_INFO, ADS_CATEGORY_AUTOCOMPLETE_INFO,
// ADS_HISTORY_LIST_INFO
// (this field is also called "channel")
" locale: \"\"" + // ISO639-1 language code (2-5 characters), supported formats:
" };" +
"W.setOffer(aAdData, aClientEnv);";
javascriptExecutor.executeScript(script);
}
which yields:
script =
var aLocation = {};
var aOffer = {};
var aAdData = {
location: aLocation,
offer: aOffer
};
var aClientEnv = {
sessionid: "",
cookie: "",
rtserver - id: 1,
lon: 34.847,
lat: 32.123,
venue: "",
venue_context: "",
source: "",
locale: ""
};
W.setOffer(aAdData, aClientEnv);
I evaluate aLocation in this browser console and get "variable not defined". How can this be?
It is important to know how Selenium executes the JavaScript that is executed in the browser.
Contrarily to what nilesh's answer implies slapping a var in front of a variable declaration does not take it out of the global space. For instance if var foo = 1 is executed outside of a function scope, it will declare a global variable named foo.
The key is how Selenium executes the script. It would be possible for Selenium to execute the script passed to executeScript in the global space. (There are ways.) However, it does not. What it does is wrap the script in a new function so any var that appears in the code passed to executeScript is going to declare a local variable.
Just dropping the var would work but I prefer to be explicit when I want to manipulate the global space. I explicitly access the window object (e.g. window.foo = 1). Dropping var looks like it could be a mistake, whereas using window. looks deliberate.
Because your variables are NOT global. As soon as you declare them with var they are scoped. If you want to test something out, just put nemo=100; in your script above and try printing out in console, it should work.
Edit #1
By the way, by no means I'm advocating global variables here. I'm just trying to explain what happened to your variables in JS executed by WebDriver. If you want to use global variables then more explicit declaration like window.foo makes more sense like others have suggested. However overall try to avoid using them. Moreover try to avoid executing JavaScript using WebDriver in the first place
unless you have no other choice. WebDriver is supposed to simulate a real user for you and your user is less likely to execute a JavaScript to interact with your web app.

JavaScript Cookie Creation Issue

I am currently trying to create a cookie in JavaScript. The idea is that when the user clicks the extension icon whilst watching a YouTube video it gets the tab name and saves it as a cookie. This is so that I can then access the cookie from my Java program.
I am using chrome and I can't see the cookie in the list when I have pressed it even though the alert successfully displays so I am wondering if anyone can see an issue with my code.
Also if anyone has a better idea of how to get the tab name to my Java program I would be happy to hear your ideas.
Thanks everyone, here's my code:
chrome.browserAction.onClicked.addListener(run);
function run()
{
var cookieName, cookieValue;
cookieName = "Tab";
chrome.tabs.getSelected(null, function(tab)
{
cookieValue = tab.title;
createCookie(cookieName, cookieValue);
});
}
function createCookie(name, value)
{
var expires = new Date().getTime() + (1000 * 3600);
var domain = ";domain=.youtube.com";
document.cookie = name + "=" + value + ";expires=" + expires + domain + ";path=/";
alert(name + " = " + value + ". Date = " + expires);
}
EDIT: I have changed my code to use the chrome API's provided by Google, great success!
If anyone has the same problem I have used the Google API's for chrome concerning cookies.
My new code is the following:
chrome.browserAction.onClicked.addListener(run);
function run()
{
var cookieName, cookieValue, cookieURL;
cookieName = "Tab";
chrome.tabs.getSelected(null, function(tab)
{
cookieValue = tab.title;
cookieURL = tab.url;
createCookie(cookieName, cookieValue, cookieURL);
});
}
function createCookie(cookieName, cookieValue, cookieURL)
{
chrome.cookies.set({name: cookieName, value: cookieValue, domain: ".youtube.com", url: cookieURL});
}
Note: In the manifest file you will need permissions for tabs, cookies and the website domain. Furthermore I have not stated when the cookie expires thus it expires when the session is closed.

Convert Permission Mask to Roles for GetPermissionCollection

We have a requirement where we need to check if a user has "Upload" access to a folder in Sharepoint document library. For that, I am using the "GetPermissionCollection" method of Permissions webservice on the document library. The response I get is of below format:
I am not able to convert the Permission mask to role. I am doing this in Java and I dont have SPBasePermissions class.
Is there a way in Java to convert the Mask into role?
Thanks in advance
Yes, you just need to do bitwise operations against it. You will need to hardwire the bitmask for the permissions you care about, but this should be safe enough since these do not change in SharePoint 2010.
I found this link:
Permission/Deny Mask in SharePoint
which says something about this bitwise AND.
You should also use this link:
http://msdn.microsoft.com/en-us/library/dd304243%28PROT.13%29.aspx
which Enums the Masks for the permissions.
I also made an javascript example that can help you...
however you will have to convert it into java
I used JQuery, SPServices js (http://spservices.codeplex.com/)
and this link for the masks codes
http://msdn.microsoft.com/en-us/library/dd304243%28PROT.13%29.aspx
I Hope this helps you, I did this because I was needing it also, however it may also help others.
You need to replace the LIST NAME HERE with the name of the list, and find out which is the mask for upload.
The script will spit everyone that has access to a list, and say if they can read, add, change and delete things. Hopes this helps you.
$('#divid').html('Working...').SPServices({
operation: "GetPermissionCollection",
objectName: 'LIST NAME HERE',
objectType: "List",
completefunc: function (xData, Status) {
var out = "<ul>";
$(xData.responseXML).find("Permission").each(function () {
if ($(this).attr("MemberIsUser") === "True") {
out += "<li>User: " + $(this).attr("UserLogin") + "</li>";
} else {
out += "<li>Group: " + $(this).attr("GroupName") + "</li>";
}
var readmask = 0x0000000000000001;
var addmask = 0x0000000000000002;
var editmask = 0x0000000000000004;
var deletemask = 0x0000000000000008;
out += "<li>Mask: " + $(this).attr("Mask") + "</li>";
var canread = readmask & $(this).attr("Mask").toString(16) > 0 ? "Yes" : "No";
var canadd = addmask & $(this).attr("Mask").toString(16) > 0 ? "Yes" : "No";
var canedit = editmask & $(this).attr("Mask").toString(16) > 0 ? "Yes" : "No";
var candelete = deletemask & $(this).attr("Mask").toString(16) > 0 ? "Yes" : "No";
out += "<li>Can Read: " + canread + "</li>";
out += "<li>Can Add: " + canadd + "</li>";
out += "<li>Can Edit: " + canedit + "</li>";
out += "<li>Can Delete: " + candelete + "</li>";
});
out += "</ul>";
$('divid').html(out);
}
});

Categories