Stuff I Wrote

Nexus One

in Uncategorized - 1 min read



I just saw on engadget the exclusive photos of the Nexus One and I must say it seems rather sweet. The interface seems very clean and the screen also. What are the internal specs however, CPU, GPU, who knows? We'll just have to wait to find out.
Hmm.... I know what I want for New Year's :)))

Search and Replace in ODT using AODL

in Uncategorized - 8 min read
Recently I needed to create a way to search and replace a word in a OpenOffice OpenDocument ODT. It would seem the project itself already has a library AODL (take care, at least two other project pages but with older code) that exposes the format model but I didn't find any utility methods like search and replace functionality. I've created two versions of the method, one a old-style, imperative approach, and the other, a LINQ version. As I'm still new to LINQ it would seem that the classical approach produces a more efficient code. Anyone care to chip in and make a faster algorithm? In this particular version I'm just going for simple string equality, I didn't want to go with other StringComparison methods (just look at the Equals overload method).


public static void SearchAndReplaceString(TextDocument document, string searchText, string replaceText)
{
var content = document.Content;

foreach (var item in content)
{
if (item is Paragraph)
{
foreach (var textContent in ((Paragraph)item).TextContent)
{
if (textContent.Text == searchText)
{
textContent.Text = replaceText;
}
}
}
}
}


public static void SearchAndReplaceStringLINQ(TextDocument document, string searchText, string replaceText)
{
var content = document.Content;

IEnumerable<Paragraph> paragraphs =
from item in content
where item is Paragraph
select (Paragraph)item;


foreach (var paragraph in paragraphs)
{
var paragraphText = paragraph.TextContent.Where<IText>(t => t.Text == searchText);
foreach (var textItem in paragraphText)
{
textItem.Text = replaceText;
}
}
}


I should point out this method matches only single words.

Fix 1. Replace text if under table structure, doesn't work if the Cell is in the header.

public static void SearchAndReplaceString(TextDocument document, string searchText, string replaceText)
{
var content = document.Content;
ReplaceInContent(searchText, replaceText, content);
}

private static void ReplaceInContent(string searchText, string replaceText, ContentCollection content)
{
foreach (var item in content)
{
if (item is Paragraph)
{
foreach (var textContent in ((Paragraph)item).TextContent)
{
if (textContent.Text == searchText)
{
textContent.Text = replaceText;
}
}
}
else if (item is Table)
{
foreach (var row in ((Table)item).Rows)
{
foreach (var cell in row.Cells)
{
var cellContent = cell.Content;
ReplaceInContent(searchText, replaceText, cellContent);
}
}
}
}
}

Relaxing SSL validation for JaxWS

in Uncategorized - 17 min read
I've recently had the need to access a web service developed in .Net and signed with a self signed certificate. I've decided to use the JaxWS and the Metro stack to develop the client and run it on Java6. As a plus, the service was protected with username and password. The service was exposed on an IP address and I repetedly had problems in establishing a connection. In the end, thanks to this article, it was obvious that the certificate was not created with the alternative name attribute but it was not an option to change the certificate as the web service was already used by other consumers (.net clients don't suffer by this issue).
So, on my quest to relax the validation, I've found out this article and code snippet, which did not compile at first (I guess package names were changed in JDK6) so I've did some trivial refactoring and now, after invoking the static methods in the client code, the SSL connection gets validated with no problems. Hope it helps and thanks to the original authors.


/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package adhocclient2;

/**
*
* @author schrepfler
*/
import java.security.GeneralSecurityException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

/**
* This class provide various static methods that relax X509 certificate and
* hostname verification while using the SSL over the HTTP protocol.
*
* @author Francis Labrie
*/
public final class SSLUtilities {

/**
* Hostname verifier for the Sun's deprecated API.
*
* @deprecated see {@link #_hostnameVerifier}.
*/
private static HostnameVerifier __hostnameVerifier;
/**
* Thrust managers for the Sun's deprecated API.
*
* @deprecated see {@link #_trustManagers}.
*/
private static TrustManager[] __trustManagers;
/**
* Hostname verifier.
*/
private static HostnameVerifier _hostnameVerifier;
/**
* Thrust managers.
*/
private static TrustManager[] _trustManagers;

/**
* Set the default Hostname Verifier to an instance of a fake class that
* trust all hostnames. This method uses the old deprecated API from the
* com.sun.ssl package.
*
* @deprecated see {@link #_trustAllHostnames()}.
*/
private static void __trustAllHostnames() {
// Create a trust manager that does not validate certificate chains
if (__hostnameVerifier == null) {
__hostnameVerifier = new _FakeHostnameVerifier();
} // if
// Install the all-trusting host name verifier
HttpsURLConnection.setDefaultHostnameVerifier(__hostnameVerifier);
} // __trustAllHttpsCertificates

/**
* Set the default X509 Trust Manager to an instance of a fake class that
* trust all certificates, even the self-signed ones. This method uses the
* old deprecated API from the com.sun.ssl package.
*
* @deprecated see {@link #_trustAllHttpsCertificates()}.
*/
private static void __trustAllHttpsCertificates() {
SSLContext context;

// Create a trust manager that does not validate certificate chains
if (__trustManagers == null) {
__trustManagers = new TrustManager[]{new _FakeX509TrustManager()};
} // if
// Install the all-trusting trust manager
try {
context = SSLContext.getInstance("SSL");
context.init(null, __trustManagers, new SecureRandom());
} catch (GeneralSecurityException gse) {
throw new IllegalStateException(gse.getMessage());
} // catch
HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
} // __trustAllHttpsCertificates

/**
* Return true if the protocol handler property java.
* protocol.handler.pkgs is set to the Sun's com.sun.net.ssl.
* internal.www.protocol deprecated one, false
* otherwise.
*
* @return true if the protocol handler
* property is set to the Sun's deprecated one, false
* otherwise.
*/
private static boolean isDeprecatedSSLProtocol() {
return ("com.sun.net.ssl.internal.www.protocol".equals(System.getProperty("java.protocol.handler.pkgs")));
} // isDeprecatedSSLProtocol

/**
* Set the default Hostname Verifier to an instance of a fake class that
* trust all hostnames.
*/
private static void _trustAllHostnames() {
// Create a trust manager that does not validate certificate chains
if (_hostnameVerifier == null) {
_hostnameVerifier = new FakeHostnameVerifier();
} // if
// Install the all-trusting host name verifier:
HttpsURLConnection.setDefaultHostnameVerifier(_hostnameVerifier);
} // _trustAllHttpsCertificates

/**
* Set the default X509 Trust Manager to an instance of a fake class that
* trust all certificates, even the self-signed ones.
*/
private static void _trustAllHttpsCertificates() {
SSLContext context;

// Create a trust manager that does not validate certificate chains
if (_trustManagers == null) {
_trustManagers = new TrustManager[]{new FakeX509TrustManager()};
} // if
// Install the all-trusting trust manager:
try {
context = SSLContext.getInstance("SSL");
context.init(null, _trustManagers, new SecureRandom());
} catch (GeneralSecurityException gse) {
throw new IllegalStateException(gse.getMessage());
} // catch
HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
} // _trustAllHttpsCertificates

/**
* Set the default Hostname Verifier to an instance of a fake class that
* trust all hostnames.
*/
public static void trustAllHostnames() {
// Is the deprecated protocol setted?
if (isDeprecatedSSLProtocol()) {
__trustAllHostnames();
} else {
_trustAllHostnames();
} // else
} // trustAllHostnames

/**
* Set the default X509 Trust Manager to an instance of a fake class that
* trust all certificates, even the self-signed ones.
*/
public static void trustAllHttpsCertificates() {
// Is the deprecated protocol setted?
if (isDeprecatedSSLProtocol()) {
__trustAllHttpsCertificates();
} else {
_trustAllHttpsCertificates();
} // else
} // trustAllHttpsCertificates

/**
* This class implements a fake hostname verificator, trusting any host
* name. This class uses the old deprecated API from the com.sun.
* ssl package.
*
* @author Francis Labrie
*
* @deprecated see {@link SSLUtilities.FakeHostnameVerifier}.
*/
public static class _FakeHostnameVerifier
implements HostnameVerifier {

/**
* Always return true, indicating that the host name is an
* acceptable match with the server's authentication scheme.
*
* @param hostname the host name.
* @param session the SSL session used on the connection to
* host.
* @return the true boolean value
* indicating the host name is trusted.
*/
public boolean verify(String hostname, SSLSession session) {
return (true);
}
} // _FakeHostnameVerifier

/**
* This class allow any X509 certificates to be used to authenticate the
* remote side of a secure socket, including self-signed certificates. This
* class uses the old deprecated API from the com.sun.ssl
* package.
*
* @author Francis Labrie
*
* @deprecated see {@link SSLUtilities.FakeX509TrustManager}.
*/
public static class _FakeX509TrustManager
implements X509TrustManager {

/**
* Empty array of certificate authority certificates.
*/
private static final X509Certificate[] _AcceptedIssuers =
new X509Certificate[]{};

/**
* Always return true, trusting for client SSL
* chain peer certificate chain.
*
* @param chain the peer certificate chain.
* @return the true boolean value
* indicating the chain is trusted.
*/
public boolean isClientTrusted(X509Certificate[] chain) {
return (true);
} // checkClientTrusted

/**
* Always return true, trusting for server SSL
* chain peer certificate chain.
*
* @param chain the peer certificate chain.
* @return the true boolean value
* indicating the chain is trusted.
*/
public boolean isServerTrusted(X509Certificate[] chain) {
return (true);
} // checkServerTrusted

/**
* Return an empty array of certificate authority certificates which
* are trusted for authenticating peers.
*
* @return a empty array of issuer certificates.
*/
public X509Certificate[] getAcceptedIssuers() {
return (_AcceptedIssuers);
} // getAcceptedIssuers

public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
throw new UnsupportedOperationException("Not supported yet.");
}

public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
throw new UnsupportedOperationException("Not supported yet.");
}
} // _FakeX509TrustManager

/**
* This class implements a fake hostname verificator, trusting any host
* name.
*
* @author Francis Labrie
*/
public static class FakeHostnameVerifier implements HostnameVerifier {

/**
* Always return true, indicating that the host name is
* an acceptable match with the server's authentication scheme.
*
* @param hostname the host name.
* @param session the SSL session used on the connection to
* host.
* @return the true boolean value
* indicating the host name is trusted.
*/
public boolean verify(String hostname,
SSLSession session) {
return (true);
} // verify
} // FakeHostnameVerifier

/**
* This class allow any X509 certificates to be used to authenticate the
* remote side of a secure socket, including self-signed certificates.
*
* @author Francis Labrie
*/
public static class FakeX509TrustManager implements X509TrustManager {

/**
* Empty array of certificate authority certificates.
*/
private static final X509Certificate[] _AcceptedIssuers =
new X509Certificate[]{};

/**
* Always trust for client SSL chain peer certificate
* chain with any authType authentication types.
*
* @param chain the peer certificate chain.
* @param authType the authentication type based on the client
* certificate.
*/
public void checkClientTrusted(X509Certificate[] chain,
String authType) {
} // checkClientTrusted

/**
* Always trust for server SSL chain peer certificate
* chain with any authType exchange algorithm types.
*
* @param chain the peer certificate chain.
* @param authType the key exchange algorithm used.
*/
public void checkServerTrusted(X509Certificate[] chain,
String authType) {
} // checkServerTrusted

/**
* Return an empty array of certificate authority certificates which
* are trusted for authenticating peers.
*
* @return a empty array of issuer certificates.
*/
public X509Certificate[] getAcceptedIssuers() {
return (_AcceptedIssuers);
} // getAcceptedIssuers
} // FakeX509TrustManager
} // SSLUtilities


GWT SuggestBoxReloaded

in gwt - 5 min read
This article will present how to implement a GWT 1.6 (RC2) SuggestBox with backing hidden fields, RPC calls and not query the server on every character event.
While integrating GWT on work, I needed to implement a SuggestBox with a backend RPC service but I had some requirements that the default SuggestBox didn't fulfill. Namely, I needed that the suggestion sets hidden fields (ex. displaying a human readable name for the user and setting a hidden id field). The solution presented in GWT SuggestBox backed by DTO Model and the Using the GWT SuggestBox with RPC were very helpful in creating this example project. I advise you to read/implement them before reading further in order to understand the issues.
The first article hit the sweet point on how to pass hidden values using the DTO pattern, you can either wrap your hidden fields (Hidden.wrap) or as in this example we'll instantiate them using GWT and add them to the panel. The next issues were following, 1. You need to be able to clear the value either by a button or by deleting the text in the TextBox, 2. The Lombardi solution presented an issue as it sent out every query string, 3. Enable some sort of reusability of the generated javascript client.
First of all I created three basic Suggestion classes, IdEnabledSuggestion, TextEnabledSuggestion and SimpleSuggestion. These three probably cover 90% of the cases (actually, the TextEnabledSuggestion can replace IdEnabledSuggestion just as well), otherwise you can add a DTO with the data you need, just remember that you must put the DTO class in the /client package, in my first trials I had it outside which led to problems.
 
public class IdEnabledSuggestion implements IsSerializable, Suggestion {

private String displayString, replacementString;
private Long id;

public IdEnabledSuggestion(){

}

public IdEnabledSuggestion(String displayString, String replacementString, Long id){
this.displayString = displayString;
this.replacementString = replacementString;
this.id = id;
}

public String getDisplayString() {
return displayString;
}

public String getReplacementString() {
return replacementString;
}

public Long getId() {
return id;
}
}

Then you extend the RemoteService interface and also the Async version. In order to achieve reusability, I've added an enum that acts as a switch, that way I can group all suggestion methods under the same servlet. A even more flexible solution would be to add a text parameter to the javascript client that would switch the endpoint ending on separate url's, probably using ServiceDefTarget.setServiceEntryPoint(String), but as I don't really like declaring a servlet for each endpoint I would recommend that solution with some kind of rest/mvc framework, I would love to see someone extending this example with struts2 and spring mvc endpoints :)
 
@RemoteServiceRelativePath("oracle")
public interface OracleService extends RemoteService {

public SuggestOracle.Response getSuggestions(SuggestOracle.Request search, Oracles oracle);

public static class Util {
public static OracleServiceAsync getInstance() {
OracleServiceAsync instance = (OracleServiceAsync) GWT.create(OracleService.class);
return instance;
}
}
}

In order to solve the second issue, and avoid sending queries on every key event, I have extracted a SuggestOracle.Request and SuggestOracle.Callback on a instance level. When a user inserts a query, I temporarily set the variables and schedule the timer, this way, even if new events come, they overwrite the instance variables effectively caching them for later so when the time passes the service gets invoked once and only once with the last query.
It's a simple trick that produces the expected actions and I hope I'm not missing some threading, timer or leakage issue?
I've added also setters so that you can set your delay and minimum number of characters needed to send the query.
I then wrap the Hidden, the SuggestBox and a widget that implements HasClickHandlers in a object that adds the various handlers to manage form state and you are good to go. :)
 
public class HiddenSuggestBox {

private SuggestBox suggestBox;
private Hidden hidden;
private HasClickHandlers clearWidget;

public HiddenSuggestBox(SuggestBox suggestBox, Hidden hidden, HasClickHandlers clearWidget) {
super();
this.suggestBox = suggestBox;
this.hidden = hidden;
this.clearWidget = clearWidget;
this.suggestBox.addSelectionHandler(new MySelectionHandler());
this.suggestBox.getTextBox().addValueChangeHandler(new ClearTextBox());
this.clearWidget.addClickHandler(new ClearValueHandler());
}

private class MySelectionHandler implements SelectionHandler<suggestion> {
public void onSelection(SelectionEvent<suggestion> event) {
if(event.getSelectedItem() instanceof TextEnabledSuggestion){
TextEnabledSuggestion suggestion = (TextEnabledSuggestion)event.getSelectedItem();
hidden.setValue(suggestion.getText());
} else if(event.getSelectedItem() instanceof IdEnabledSuggestion){
IdEnabledSuggestion suggestion = (IdEnabledSuggestion)event.getSelectedItem();
hidden.setValue(suggestion.getId()+"");
} else {
hidden.setValue(event.getSelectedItem().getReplacementString());
}

}
}

private class ClearTextBox implements ValueChangeHandler<string> {
public void onValueChange(ValueChangeEvent<string> event) {
if(event.getValue().trim().equals("")){
suggestBox.getTextBox().setValue("");
hidden.setValue("");
}
}
}
private class ClearValueHandler implements ClickHandler {
public void onClick(ClickEvent event) {
hidden.setValue("");
suggestBox.setValue("");
}
}
}

eclipse project archive
You might need to set JVM in launcher and ant script.

No row with the given identifier exists

in Uncategorized - 1 min read
I've recently gotten this infamous Exception while doing a HQL query.
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [it.linksystem.csai.model.Operator#3]

This was rather strange as the system worked quite well and it successfully retrieved selects on that entity using the Criteria API.
Looking on the net, most suggestions and FAQ's point to a different direction. My issue was rather simple mapping error. The entity on which I was doing selects, was referencing an Operator. In my (java) model, Admin inherits from Operator, and both inherit from User. In fact persisting the entities was no problem no matter if the entity persisted was referencing an Admin or Operator. If however there was an instance that referenced an Admin hibernate would launch the Exception if one executed a HQL query (I guess Criteria queries follow a different path to create the select and are immune to this issue).
My mistake was that I didn't know you can nest a subclass tag in another subclass tag in the hbm file so I've put all subclasses directly under User. Once I've moved Admin under Operator the HQL works fine.
I hope this will help somebody.

Turning off Asus M50S light sensor

in asus, notebook - 1 min read
As I've recently gotten this nice laptop, I've found that the light sensor really makes more problems then it solves so I'm shutting it down in both Windows (Fn+A) and in Linux.
Under linux all you need to do is:
echo 0 > /sys/devices/platform/asus-laptop/ls_switch

This fix is valid only for the current session, to persist the settings just install sysfsutils and then in /etc/sysfs.conf put
devices/platform/asus-laptop/ls_switch=0

JBuilder 2008 and Windows Vista problems

in jbuilder, uml - 1 min read
So let's say you try to install JBuilder 2008 under Windows Vista (32bit). Did all went smoothly? A friend of mine got a nice JVM terminated Exit code=-1 error. It would seem that if you modify the JBuilder.ini -Xmx parameter (initially over 800M) to 700M or 600M and if you run reset_JBuilder.bat it might finish the installation. An alternative is to modify JBuilder.ini the moment it gets created so you don't have to wait twice.
Also it would seem sometimes class diagrams won't show classes. My friend deleted all com.ibm.icu* packages and jars under JBuilder and put com.ibm.icu_3.8.1.v20080530.jar from eclipse 3.4 to the jbuilder 2088 plugins directory.
For the moment things seem to function.

On HC

in Uncategorized - 1 min read
As often things go, you sometimes don't notice things that are integral part of your life. Yesterday I was in company with my cousin and his girlfriend and we noticed this weird thing we decided to call HC which stands for hardcore. Basically, its stands for compulsive-obsessive attention to "details" like water drops after washing the dishes, having things clean at all times, not allowing other people to slip up and often venting on them if they make a mistake. Of course like any good HC person I don't consider this things minor details :)
The point is, is it a virtue, or is it a problem? Should we vent on other people when they make a mistake, how should we do it? Is it only a symptoms of something much deeper or a better capacity to adapt to harsher conditions of life?
Anyhow, on this bright note, if I don't manage to concoct one more blog post for the holidays, I wish you all the best for the New Year 2008 and may all your wishes come true!
PS. It won't happen if you leave all your clothes around all the time ;)

27 and counting

in Uncategorized - 1 min read
One more year has passed. My life had some drammatic ups and downs than this year. I can't say I'm full out in the clear, but I've closed some things from the past and can look with hope to the future. I can't be happier for having so many good friends and I know things are going to get better.
As it's wishing time, I'd like for java to have verbatim literals, that means you could omit the backslash in front of special characters (like the backslash itself) ex:
"Backslash: \\" <==> @"Backslash: \"

I think this would allow us to much easier copy/paste regex code from existing regex expressions.

Tose Proeski 1981-2007

in Uncategorized - 1 min read
In a tragic accident between his VW Tuareg and a truck on the Zagreb - Lipovac highway (Croatia), the best Macedonian pop artist Tose Proevski was killed in an instant.
He followed my generation with his beautiful voice and gave us truly splendid memories that we will share forever. A truly wonderful person, humanitarian and ambassador of goodwill that will be missed by all.