29 Jan 2009

Fomatting messages

I always found formatting Strings was painful in Java. Especially since I learn Ruby where you can do:
some = 'foobar'
my_string = "Here are #{some} value"

In Java, a basic example would be:
String searchPolygon = "POLYGON((" + lowerLeft + ", " + 
lowerRight + ", " + upperRight + ", "
+ upperLeft + ", " + lowerLeft + "))";

If you have too many parameters or you are looking for more efficiency, you can do something like (you can use StringBuffer instead of StringBuilder see javadoc):
StringBuilder searchPolygon = new StringBuilder();
searchPolygon.append("POLYGON((");
searchPolygon.append(lowerLeft);
searchPolygon.append(", ");
searchPolygon.append(lowerRight);
searchPolygon.append(", ");
searchPolygon.append(upperRight);
searchPolygon.append(", ");
searchPolygon.append(upperLeft);
searchPolygon.append(", ");
searchPolygon.append(lowerLeft);
searchPolygon.append("))");
searchPolygon.toString();

But still, it's ugly :(


Or you can use MessageFormat wich make the code more much readable in my opinion ;)

MessageFormat polygonFormatter =
new MessageFormat("POLYGON(({0}, {1}, {2}, {3}, {4}))");
Object[] values = new Object[] {
lowerLeft, lowerRight, upperRight, upperLeft, lowerLeft };
String searchPolygon = polygonFormatter.format(values);


It could have even be better if we could have use a map with key/value instead of indexes... but I didn't found anyting in the java language itself that does this :(

3 Dec 2008

Insert Polygon into Postgis

I was trying to insert a polygon (I think it's the same as a bbox but not sure yet) into a postgis table. But I only found scaterred examples where the columns declaration was missing... So here's a concret example.
The SQL:

SELECT AddGeometryColumn( 'my_table', 'geo_bbox', 4326, 'POLYGON', 2);
UPDATE my_table
SET geo_bbox=GeomFromText('POLYGON((0 0,4 0,4 4,0 4,0 0))',4326)
WHERE id='my_pk';

Where '4326' is the standard/normal/usual coordinnates system: longitude/latitude. You can do the following to get more info about '4326':
select * from spatial_ref_sys where SRID=4326;


To check if everything is working you can do:

SELECT ST_Contains(geo_bbox, GeomFromText('POINT(2 2)',4326))
FROM my_table
WHERE clef='my_pk';

It should return 't' for 'true'.

Errors I've bumped into and their "gotchas":
  • parse error - invalid geometry
    UPDATE my_table 
    SET geo_bbox=GeomFromText('POLYGON(0 0,4 0,4 4,0 4,0 0)',4326)
    WHERE clef='my_pk';
    ERROR: parse error - invalid geometry
    CONTEXT: SQL function "geomfromtext" statement 1

    You forget the double '((' and '))'. There is a double '((' because Polygon can be describe like this: POLYGON((first_shape), (second_shape))
  • geometry contains non-closed rings
    UPDATE my_table 
    SET geo_bbox=GeomFromText('POLYGON((0 0,4 0,4 4,0 4))',4326)
    WHERE clef='my_pk';
    ERROR: geometry contains non-closed rings
    CONTEXT: SQL function "geomfromtext" statement 1
    You forget the last coordinates, you need to repeate the first point twice:
    POLYGON((down_left, down_right, up_right, up_left, down_left))
  • geometry contains non-closed rings
    UPDATE my_table 
    SET geo_bbox=GeomFromText('POLYGON((0 0,4 0,4 4,0 4,0 10))',4326)
    WHERE clef='my_pk';
    ERROR: geometry contains non-closed rings
    CONTEXT: SQL function "geomfromtext" statement 1
    That's because the finishing point (0,10) is not the same as the starting point (0,0)
  • other: invalid geometry
    I also got an other way to get an "invalid geometry" but I don't remember how to reproduce it... postgis does some validation if your coordinates are not valid.


Postgis official documentation: Creating object syntaxe

Technorati tags:

2 Dec 2008

ohloh la!

I just discovered ohloh.net after reading Marting Fowler latest post.

Ohloh display informations about open source projects: commits, timelines, contributors, languages etc...

Amazing how they managed to extract valuable informations for internet/svn/projects and how they presented it in a meaningful way!

I had lots of fun finding people I know:

Or project I've worked with:

This can help see if a project is under active development or not and who is really working on, not just claiming to be a contributor ;)

27 Nov 2008

Insert big data chunk into MySQL

Inserting 370 000 records in a mysql table was taking ages!
Found this little trick:
LOAD DATA CONCURRENT LOCAL INFILE 'C:\\my\\path\\to\\folder\\records.sql' INTO TABLE FOO;

Useful under Windows and MySQLQueryBrowser ;)

MySQL funny command line option

While searching for help for mysql ubuntu command line tool:

$ mysql --help
Usage: mysql [OPTIONS] [database]
-?, --help Display this help and exit.
...
-U, --i-am-a-dummy Synonym for option --safe-updates, -U.
...

19 Nov 2008

Flag a blog post as deprecated

While looking for some info on capistrano I stumbled on this post: "Ant sucks for FTP deployment - What alternatives do we have?".

The funny thing is the deprecated notice:


I often use @deprecated for the code but I never though of using it for my old blog posts... good idea :)

And it's also a good way to always keep url even if they display wrong or inaccurate info, just like describe in this w3c document "Cool URIs don't change."

Simple Jdbc

I wanted to use spring JdbcTemplate to simplify my jdbc code but I had to add 3 jars just to use it !
  • spring-jdbc.jar
  • spring-tx.jar
  • spring-core.jar


spring-tx.jar because I got this error:
The type org.springframework.dao.DataAccessException cannot be resolved. 
It is indirectly referenced from required .class files
TestSpring.java

spring-core.jar because I got this error:
The type org.springframework.core.NestedRuntimeException 
cannot be resolved. It is indirectly referenced from required .class files
TestSpring.java

And I wasn't even sure about the transaction part, did I need to include spring-beans.jar and spring-context.jar; start to use a TransactionTemplate and configure a PlatformTransactionManager with tons of xml configuration, services and dao(s) :(

So I decided to make a small but simple project doing exactly what I wanted: jdbcTemplate and I made it public on sourceforge.

Don't expect any documentation or support for this, it's just that I don't want to redo this code on my next jdbc project (if that ever happens).




You can also take a look at DbUtils at http://commons.apache.org that does just the same ;)


 

12 Nov 2008

Why you should use JUnit4

I've been using JUnit 4 from time to time but never really understood the benefit moving from version 3 to version 4.

That's because I never took time to take a look at new features :o

Don't be like me ;) Just take a look at this article: "Junit 4 in 60 seconds"

You will discover annotations like:
  • Better Exception Handling with @Test(expected = ArithmeticException.class)
  • @Ignore("Not Ready to Run")
  • @Test(timeout = 1000)

Small enhancements making testing easier and clearer!

5 Nov 2008

New Java Date Time Api

This is a good news: Date and Time API: Round 3. Date and Time parsing is always a mess... if they could just remove the old api (and not be backward compatible) that would be even better but it takes courage.

Come on almost all java.util.Date methods are deprecated since Jdk version 1.1... It's time to change!

27 Oct 2008

Fixing log4j email notification under ubuntu

I had a problem under ubuntu to use log4j email notification through SMTPAppender.

The problem:

java.lang.NoClassDefFoundError: gnu/inet/util/GetSystemPropertyAction
at javax.mail.internet.ParameterList.(ParameterList.java:72)
at javax.mail.internet.ContentType.(ContentType.java:104)
at gnu.mail.handler.Text.getJavaCharset(Text.java:160)
at gnu.mail.handler.Text.writeTo(Text.java:140)
at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:868)
...


Solution:

I think :
apt-get remove libgnuinet-java

is enough but this is the exact command I had to run:
apt-get remove libgnuinet-java libgnujaf-java libgnumail-java-doc


Env:
Jetty 6, java 6, log4j 1.2.15 + commons-logging 1.1

Log4j conf:

log4j.rootLogger=INFO, CONSOLE, FILE, EMAIL
# EMAIL
log4j.appender.EMAIL=org.apache.log4j.net.SMTPAppender
log4j.appender.EMAIL.SMTPHost=xxx
log4j.appender.EMAIL.From=xxx@xx.com
log4j.appender.EMAIL.To=xxx@xx.com
# log4j.appender.EMAIL.SMTPUsername=xxx
# log4j.appender.EMAIL.SMTPPassword=xxx
log4j.appender.EMAIL.Subject=[MyApp] Application Error
log4j.appender.EMAIL.layout=org.apache.log4j.PatternLayout
log4j.appender.EMAIL.layout.ConversionPattern=[%d] [%t] %-5p %c %x - %m%n
log4j.appender.EMAIL.Threshold=ERROR
log4j.appender.EMAIL.BufferSize=1
# log4j.appender.EMAIL.SMTPDebug=true


I'm also using sun jvm using this command:
update-java-alternatives --set java-6-sun