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.
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;
}
}
}
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§ion=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



