Tuesday, August 25, 2009

JavaFX onKeyTyped for a Scene [Update]

[Update]
Since javaFX 1.2 nodes have to set the "focusTraversable" property to "true" in order the receive key events.
[/Update]

keyTyped events are easy to use in JavaFX. Just add a function to onKeyTyped on a node and this node will be notified if a key is typed.

But what if you start with an empty scene. There are no nodes which can receive the event. And there is no onKeyTyped for a scene or stage.

I found two solutions for this problem. Both are some kind of a hack but they work:

1. Create a CustomNode without any graphics and just a onKeyTyped and add this to the scene content.

2. (my preferred solution) Use a Group which is empty at the beginning and later contains the scenes nodes. Groups do have onKeyTyped.

Here is an example:

var stage = Stage {
title: "Application title"
fullScreen: true
scene: Scene {
content: [
Group {
focusTraversable: true
content: [
]
onKeyTyped: function( e: KeyEvent) : Void {
System.out.println("Hello");
}
}
]
}
}

Monday, August 24, 2009

Restful AtomPub Services with HTTP Basic Authentication in Azure

Implementing a service with an AtomPub interface on Azure is quite easy. As a starting point I used the PictureRestService example from:

http://code.msdn.microsoft.com/wcfazure/Wiki/View.aspx?title=PictureRestService

Next step is to restrict the access to the interface methods to a set of authorized users.

As a starting point for this I used:

http://msdn.microsoft.com/en-us/library/dd203052.aspx

As mentioned in this guide the first thing to do is to check if the request contains an user authentication. For this the HTTP request has to contain an "Authorization" header. For a basic user name password authentication the value of this header has to be the string "basic" followed by the user name a ":" and the password. User name, ":" and password are stored in a Base64 encoded string.

Here is an example which checks if the user is "eggeral" or "sven":

private bool AuthenticateUser(out string userName)
{
userName = null;
WebOperationContext ctx = WebOperationContext.Current;
string authHeader = ctx.IncomingRequest.
Headers[HttpRequestHeader.Authorization];
if (authHeader == null)
{
return false;
}
if (!string.IsNullOrEmpty(authHeader))
{
if (authHeader.StartsWith("basic ",
StringComparison.InvariantCultureIgnoreCase))
{

string userNameAndPassword = Encoding.Default.GetString(
Convert.FromBase64String(authHeader.Substring(6)));
string[] parts = userNameAndPassword.Split(':');
userName = parts[0];
string password = parts[1];

if (userName == "eggeral" && password == "secret")
{
return true;
}
if (userName == "sven" && password == "sven")
{
return true;
}

}

}
return false;
}


If the request does not contain an "Authorization" header we have to request one from the client (for example Firefox or Internet Explorer). This is done be answering the request with the status 401 Unauthorized and a "WwwAuthenticate" header which specifies the authentication mechanism. The client will then prompt the user for user name and password and resend the request to the service.

Here is the code which handles this for the "PutEntry" method:

protected override SyndicationItem PutEntry(string collection,
string id,
SyndicationItem entry)
{
string userName;
if (!AuthenticateUser(out userName))
{
WebOperationContext.Current.OutgoingResponse.StatusCode =
HttpStatusCode.Unauthorized;
WebOperationContext.Current.OutgoingResponse.
Headers.Add(
HttpResponseHeader.WwwAuthenticate,
"Basic realm=\"Task Management\"");
return null;
}
// Do some stuff and return an entry.

}


Of course basic authentication is not secure, but its an easy way to get started. For production systems implement a more secure method as described in Microsofts guide for Restful web services (link above).

Tuesday, August 11, 2009

Using devenv.exe in MSBuild Files and TFS

I need to run devenv.exe on our team build (TFS) in order to compile certain projects (for example: setups).

If, like in our case, the tfsbuld.proj file is not only used on the TFS but also for local builds you have to find out here devenv.exe actually is (it depends on your Windows version an language).

The trick is that MSBuild can read registry information. So you can get the install directory for Visual Studio from the registry and then use an Exec task to run devenv.exe.

Here is how this works:


<Exec Command="&quot;$(Registry:HKEY_LOCAL_MACHINE\\Software\Microsoft\VisualStudio\9.0@InstallDir)\Common7\IDE\devenv&quot; &quot;$(SolutionRoot)\mysolution.sln&quot; /Build Release /project &quot;setupdir\setupproj.vdproj" /projectconfig Release"/>