New Project: JAXB4GWT

I was tired of seeing all of the XML parsing code in one of my GWT applications.  Because if the way the application was structured, it was impossible to do the xml parsing on the server and return a serialized bean back to the client.  So my approach was to emulate jaxb for the GWT client side.

My approach uses a generator, so all the parsers are created at compile time and linked into the application.

Project Home: http://code.google.com/p/gwtjaxb/

I have gone through several iterations of development, and am pleased to release version 1.0.0.  I am currently using this library in some of my own projects that are in production, and parsing some XML that is found in the wild.



The ol’ two light bulb, tall building problem

Question: You have two light bulbs and a 100-story building. You want to find the floor at which the bulbs will break when dropped. Find the floor using the least number of drops.

Hopefully your mind has immediately kicked into gear … and you start thinking of solutions and estimating the Big-O. Good for you these are the kinds of problems that I just can’t resist.

In this article I’ll take a look at several different solutions to this problem.

Linear Search:Linear Search

Of course we are going to start with linear search, and why not it is the most obvious solution. Start at the first floor and just start dropping bulbs.

How does this algorithm perform? Well as you might expect pretty poorly. In the worst case you have to go all the way up to the top floor in order to find out that the bulbs break … however using this solution you can determine the breaking floor using only one bulb.

Additionally this algorithm has a pretty good travel time. Considering how much time you will spend traveling between floors, this algorithm is pretty good, in the sense that the number of trips up and down the stairs is equal to the number of floors in the building in the worst case.

public void getNumberOfDrops(DropScenerio dropManager) {
for (int i = dropManager.getCurrentFloor();
i <= dropManager.getNumFloors(); i++) {
dropManager.setCurrentFloor(i);
if (dropManager.dropTest()) {
return;
}
}
}

linearperformance

Worst Case # of Drops = n (where n = the height of the building)

Average Case # of Drops = n/2 (where n = the height of the building)

Worst Case Travel Time = n (where n = the height of the building)

Average Case Travel Time = n/2 (where n = the height of the building)

This is a pretty standard linear function and we can use this as a baseline for analyzing other searching methods.



GWT ScrollPanel for Touch Screens


Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 2039

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 2039

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 2411

Warning: implode() [function.implode]: Argument must be an array in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3365

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3388

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3388

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3429

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3481

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3481

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3626

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3626

Getting this working is easier than you think. Basically the only tricky bit is that the touch object allows for multiple fingers they are represented in the array ‘touches[]‘. Since we are only scrolling we only need to worry about the first finger which is why I use touches[0].screenY. Enjoy.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package com.peterfranza.gwt.mobileui.client.widgets;
 
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.user.client.ui.ScrollPanel;
 
/**
 * 
 * @author peter.franza
 *
 */
public class TouchScrollPanel extends ScrollPanel {
 
	private int initialTouchX = -1;
	private int initialTouchY = -1;
	private int initialHorizontalOffset;
	private int initialVerticalOffset;
	private boolean moved = false;
 
	{
		attachTouch(getElement());
	}
 
	public TouchScrollPanel(VerticalPanel body) {
		super(body);
	}
 
	private native void attachTouch(JavaScriptObject ele) /*-{	
		var ref = this;
		ele.ontouchstart = function(evt){
	  		evt.preventDefault();	
	  		ref.@com.peterfranza.gwt.mobileui.client.widgets.TouchScrollPanel::setInitialTouch(II)(evt.touches[0].screenX, evt.touches[0].screenY);
		}	
		ele.ontouchmove = function(evt){
	  		evt.preventDefault();	
	  		ref.@com.peterfranza.gwt.mobileui.client.widgets.TouchScrollPanel::doScroll(II)(evt.touches[0].screenX, evt.touches[0].screenY);
		}		
		ele.ontouchend = function(evt){
			evt.preventDefault();
			ref.@com.peterfranza.gwt.mobileui.client.widgets.TouchScrollPanel::setEndTouch(II)(evt.pageX, evt.pageY);
		}		
	}-*/;
 
	private native void fireClick(int x, int y) /*-{	
		var theTarget = $doc.elementFromPoint(x, y);
		if (theTarget.nodeType == 3) theTarget = theTarget.parentNode;
 
		var theEvent = $doc.createEvent('MouseEvents');
		theEvent.initEvent('click', true, true);
		theTarget.dispatchEvent(theEvent);
	}-*/;
 
 
	@SuppressWarnings("unused")
	private void setInitialTouch(int x, int y) {
		initialVerticalOffset = getScrollPosition();
		initialHorizontalOffset = getHorizontalScrollPosition();
 
		initialTouchX = x;
		initialTouchY = y;
		moved = false;
 
	}
 
	@SuppressWarnings("unused")
	private void doScroll(int x, int y) {
		if (initialTouchY != -1) {
			moved = true;
			int vDelta = initialTouchY - y;
			int hDelta = initialTouchX - x;
			setScrollPosition(vDelta + initialVerticalOffset);
			setHorizontalScrollPosition(hDelta + initialHorizontalOffset);
		}
	}
 
	@SuppressWarnings("unused")
	private void setEndTouch(int x, int y) {
		if (!moved) {
			fireClick(x, y);
		}
		initialTouchX = -1;
		initialTouchY = -1;
	} 
}


GWT loading remote JSONP XSS


Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 2039

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 2039

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 2411

Warning: implode() [function.implode]: Argument must be an array in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3365

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3388

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3388

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3429

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3481

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3481

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3626

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3626

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 2039

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 2039

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 2411

Warning: implode() [function.implode]: Argument must be an array in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3365

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3388

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3388

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3429

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3481

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3481

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3626

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3626

In almost all browsers there is one thing that everybody wants to do, but you just can’t, Load cross site data. That is you can’t unless you are using JSONP. Basically you load the data into its own script tag tell the server you are loading it from to wrap the data in a callback that you have defined. This will fire an event after the data has loaded. Perfect.

I wanted to use it in GWT … now I can.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package com.peterfranza.gwt.cle.client;
 
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.RootPanel;
 
public class JSONPLoader {
 
	private LoaderCallback callback;
 
	public void load(String jsonUrl, LoaderCallback callback) {
		this.callback = callback;
		String callbackString = "jsonLoad_" + 
			DOM.createUniqueId().replace("-", "_") + "_callback";
		String url = jsonUrl + (jsonUrl.contains("?") ? "&" : "?") 
			+ "_callback=" + callbackString;
		publishCallbackMethod(callbackString);
		Element fr1 = DOM.createElement("script");		
		fr1.setAttribute("src", url);
		RootPanel.get().getElement().appendChild(fr1);
 
	}
 
	private native void publishCallbackMethod(String callback) /*-{
		var ptr = this;
  		$wnd[callback] = function(obj) {
  			ptr.@com.peterfranza.gwt.cle.client.JSONPLoader::loadremotedata(Ljava/lang/String;Lcom/google/gwt/core/client/JavaScriptObject;)(callback, obj);
  		};
	}-*/;
 
	@SuppressWarnings("unused")
	private void loadremotedata(String cbp, JavaScriptObject obj) {
	  callback.onLoad(new JSONObject(obj));
	}
 
	public interface LoaderCallback {
		void onLoad(JSONObject object);
	}
 
}

Usage:

1
2
3
4
5
6
7
8
JSONPLoader loader = new JSONPLoader();
loader.load("http://pipes.yahoo.com/pipes/pipe.run?_id=CPreCvz42xG4eaOWouNLYQ&_render=json&location=madison&section=mcy", new LoaderCallback() {
 
	@Override
	public void onLoad(JSONObject object) {
		Window.alert("loaded " + object.size());
	}
});

Notice that the json url does not specify the _callback parameter, this is because it is added by the JSONPLoader class.



Connecting Apache (httpd) To Active Directory


Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 2039

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 2039

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 2411

Warning: implode() [function.implode]: Argument must be an array in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3365

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3388

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3388

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3429

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3481

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3481

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3626

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3626

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 2039

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 2039

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 2411

Warning: implode() [function.implode]: Argument must be an array in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3365

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3388

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3388

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3429

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3481

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3481

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3626

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3626

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 2039

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 2039

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 2411

Warning: implode() [function.implode]: Argument must be an array in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3365

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3388

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3388

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3429

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3481

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3481

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3626

Warning: Invalid argument supplied for foreach() in /home/pfranza/peterfranza.com/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3626

Recently I went through a small effort to connect a subversion repository to active directory. This is a good thing because it means that you no longer will need to manage the usernames and password using the old htpasswd format. The htpasswd is fine for very controlled environments but the passwords it allows you to use are pretty weak and the encryption of the passwords is fairly weak also, so allowing the connection to happen using active directory as the authority is a good thing. Also it keeps you from having to maintain more passwords, and I like that idea.

In your /etc/httpd/conf.d/filename.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
LoadModule dav_svn_module modules/mod_dav_svn.so
LoadModule authz_svn_module modules/mod_authz_svn.so
 
LDAPConnectionTimeout 15
 
LDAPSharedCacheSize 200000
LDAPCacheEntries 1024
LDAPCacheTTL 600
LDAPOpCacheEntries 1024
LDAPOpCacheTTL 600
 
  <Location /server/cache-info>
   SetHandler ldap-status
  </Location>
 
  <Location /svn>
    DAV svn
    SVNPath /subversion/repos
    SVNListParentPath on
 
    AuthzSVNAccessFile /subversion/svnauthorz
    Satisfy Any
    AuthType Basic
    AuthName "Members Only"
    AuthzLDAPAuthoritative off
    AuthBasicProvider ldap
    AuthLDAPBindDN "svn.user@domain.com"
    AuthLDAPBindPassword "svn.user.password"
    AuthLDAPURL "ldap://<ldapserverip>/DC=domain,DC=com?sAMAccountName?sub?(objectClass=user)"
    Require valid-user
 </Location>

However every couple of transactions I would get an error and this message would appear in my error log

/var/log/httpd/error_log

1
[Fri Apr 30 09:21:46 2010] [warn] [client 192.168.100.105] [22578] auth_ldap authenticate: user peter.franza authentication failed; URI /svnad/projects/ [ldap_search_ext_s() for user failed][Operations error], referer: http://svn/svnad/projects/

The solution was to disable following referers

/etc/openldap/ldap.conf

1
REFERRALS off

*Note this is in /etc/openldap/ not the ldap.conf in /etc that file is used from pam authentication and not for mod_ldap