mandag 15. desember 2008

Regexp for logging of method calls

BeanShell macros (May be run in jEdit)
Copy and paste auto-generated method signature, and run this macro

// rid of tabs, newlines and double spaces
strippSpace( String text ) {
text = text.replaceAll( "\\t" , " " );
text = text.replaceAll( "\\n?" , "" );
do {
text = text.replaceAll( " " , " " );
} while ( text.indexOf( " " ) > -1 );
return text;
}

// tidy up method call
cleanCall( String text ) {
text = text.replaceAll( "\\(\\s*" , "(\n\t" );
text = text.replaceAll( ",\\s*" , ",\n\t" );
text = text.replaceAll( "\\s*\\)\\s*" , "\n)" );
return text;
}

convertMethodSignature2SuperCall( String text ){
// 2 strings before )
text = text.replaceAll( "\\w*\\W?(\\w*)\\W*\\)\\W*" , "$1 );" );
// 2 strings before comma
text = text.replaceAll( "\\w*\\W?(\\w*)\\W*,\\W*" , "$1, " );
// 3 strings before (
text = text.replaceAll( "\\A\\s*\\w*\\s?void\\s?(\\w*)\\s*\\(" , "super.$1(" );
text = text.replaceAll( "\\A\\s*\\w*\\s?\\w*\\s?(\\w*)\\s*\\(" , "return super.$1(" );
return text;
}

convertMethodSignature2SillyReturn( String text ){
// 2 strings before )
text = text.replaceAll( "\\w*\\W?(\\w*)\\W*\\)\\W*" , "$1 );" );
// 2 strings before comma
text = text.replaceAll( "\\w*\\W?(\\w*)\\W*,\\W*" , "$1, " );
// 3 strings before (
text = text.replaceAll( "\\A\\s*\\w*\\s?void\\s?(\\w*)\\s*\\(" , "" );
text = text.replaceAll( "\\A\\s*\\w*\\s?(\\w*)\\s?(\\w*)\\s*\\(" , "return new $1();" );
return text;
}

convertMethodSignature2LogStatement( String text ){
// 2 strings before )
text = text.replaceAll( "\\w*\\W?(\\w*)\\W*\\)\\W*" , "\n\t\tSEMAFOR_CALL \"$1\" SEMAFOR_COMMA $1 )\n\t);" );
// 2 strings before comma
text = text.replaceAll( "\\w*\\W?(\\w*)\\W*,\\W*" , "\n\t\tSEMAFOR_CALL \"$1\" SEMAFOR_COMMA $1 )," );
// 3 strings before parenthesis
text = text.replaceAll( "\\A\\s*\\w*\\s?\\w*\\s?(\\w*)\\(" , "\tSEMAFOR_CALL \"$1\" ," );
// semafors
text = text.replaceAll( "SEMAFOR_COMMA" , "," );
text = text.replaceAll( "SEMAFOR_CALL" , "toXml(" );
return text;
}

String text = Macros.input(view,"Method call:");
if(text == null || "".equals(text))
return;

String text = strippSpace( text );
String superCall = convertMethodSignature2SuperCall( text );
String logCall = convertMethodSignature2LogStatement( text );
String call = cleanCall( text );
String res = call + "{\n" + logCall + "\n\t" + superCall + "\n}";

Registers.setRegister('HistoryModel.getModel("clipboard").addItem(res);
view.getStatus().setMessageAndClear("OK - result on clipboard");


Logging methods

public static String toXml( String name, Object value ) {
// FixMe: escape xml special characters
if ( value == null )
value = "";
return "\t<" + name + ">" + value.toString() + "";
}
/** */
public static String toXml( String method, String... items ) {
String msg = "";
if ( items != null && 0 < msg = "<">" + msg + "";
System.out.println( msg );
return msg;
},res);
HistoryModel.getModel("clipboard").addItem(res);
view.getStatus().setMessageAndClear("OK - result on clipboard");

Logging methods
public static String toXml( String name, Object value ) {
// FixMe: escape xml special characters
if ( value == null )
value = "";
return "\t<" + name + ">" + value.toString() + "";
}
/** */
public static String toXml( String method, String... items ) {
String msg = "";
if ( items != null && 0 < msg = "<">" + msg + "";
System.out.println( msg );
return msg;
}

fredag 17. oktober 2008

GeoCoding and maps in Swing

Maps


Started with article from java.net., which details how to use the JxMapViewer from SwingLabs.

Web-based maps
Use OpenLayers to wrap service provider.
For Ajax-maps, check this article, or Tap into the Google Geocoder Web service. or even Overlay data on maps using XSLT, KML, and the Google Maps API, Part 2.

GeoCoding

Første søk var oppløftende, sjekk irb.no : Postnummer => geodata.
Statkart er grei å sjekke, men dataene nås først og fremst gjennom NorKart, Ugland IT...
Ugland IT, FlexiMap Online, FlexiMap Locator.
Foretrekker GeoData. (ESRI-baserte tjenester)
NorKart: FixMe.
geoNorge: FixMe.

Coordinate conversion

This article explains the works. Try libraries: GeoTools, JCoord (cf. this message).

EPSG:32633 = WGS_1984_UTM_Zone_33N: 6648970N 255101E
EPSG:4326 = Lat/lon (GCS_WGS_1984): 59.90530N 10.61976E
900913 = Google special projection (is Mercator): 8378684N 1182185E
epsg:54004 = Mercator (World_Mercator)

A degree of longitude at the equator is 111.2 kilometers. A minute is 1853 meters.
A second is 30.9 meters. For other latitudes multiply by cos(lat).
cos((2 * PI * 66) / 360) = 0.406736643

For reference systems / epsg codes, see: GIServer or spatialreference.
http://www.radicalcartography.net

Gratis-tjenester:

Norsk openstreetmap prosjekt, men det ser ut til å være mangelfullt.

Posten sin nedlastingsside (gir kommunenr fra postnr, 1 skritt til for posisjon, men det blir veldig unøyaktig).

Geonames funker sånn noenlunde med postnummer, de har webservice og egen norge-side. Mulig vi må betale for tjenesten.

Google: read this chapter in the Google Maps Hack book. Adding a Google Map to the Sample JSF Catalog Application + How to Use the Map Viewer and GeoCoder Components. Best match: Lightweight Google Geocoder with Java?
Freebase har tripleter (subjekt+verb+objekt) som mapper postnumre til geolokasjoner, ikke mange norske. eksempel.

Google laget en liste med Geocoders.


fredag 26. september 2008

Groovy stuff

Groovy is:

  • Ruby for Java developers and JVM

  • What Java should be (groovy extends Java)
    • Native Beans (auto-generated get'ers and set'ers)
    • Lots of small and big improvements to language and libraries
    • Meta-programming provides method injection, interception and supports dsl-generation

Or, according to themselves (Gloss over)

is an agile and dynamic language for the Java Virtual Machine
  • Dynamic = kall til fx writeToFile() feiler først runtime => må teste all kode. Polymorfisme ikke bundet til arv
builds upon the strengths of Java but has additional power features inspired by languages like Python, Ruby and Smalltalk
  • Mange tilegg til collections, xml-support, db-dsl-features
makes modern programming features available to Java developers with almost-zero learning curve
  • Closures and Meta-programming (method intercept, inject, synthesize
supports Domain-Specific Languages and other compact syntax so your code becomes easy to read and maintain
  • Via meta-programming: 5.times { println "Hello world" }
makes writing shell and build scripts easy with its powerful processing primitives, OO abilities and an Ant DSL
  • GAnt = ant-script skrevet i Groovy (ikke xml)
increases developer productivity by reducing scaffolding code when developing web, GUI, database or console applications

simplifies testing by supporting unit testing and mocking out-of-the-box

seamlessly integrates with all existing Java objects and libraries
  • Kan kalle frem & tilbake
  • Joint compiler
compiles straight to Java bytecode so you can use it anywhere you can use Java

Hands dirty, now!


/**
cd C:\Pirate\my_projects\HobbyCode\Groovy\HelloEclipse
set CP=target\classes;%GROOVY_HOME%\embeddable\groovy-all-1.5.6.jar
java -cp %CP% AllCode

* @author tsk
*/
String message = "\n\n\n\n******** Velkommen! ********";

System.out.println( message )

System.out.println 'This is a "Hello World" application'

def duckTypedString = "You have already seen such Groovy stuff as:"

println duckTypedString

println(
'''klasse og main() er implisitt definert hvis ikke du gidder
Heredocs (""" eller \''')
May use " or ', whatever suits you best
Valgfritt:
* semikolon
* parentes
* datatype (duck typed)
* exception handling

'''
)

println "Ingen primitive datatyper: " + 1.getClass()

println "\n\n******** GString and non-default class / main ********"

// java -cp %CP% org.dotme.learn.groovy.AutomaticallyCreatedAbove
public class AutomaticallyCreatedAbove {
public static void main( String[] args ) {
String input = "GString demo"
if ( args ) { // Groovy truth...
input = args[0]
println "cmd /c groovy -h".execute().text
}
println "$input ${input.length()}"
}
}


println "\n\n******** Calling Java, and back ********"
org.dotme.learn.groovy.JavaClass javaClass = new org.dotme.learn.groovy.JavaClass();
println javaClass.message();

println "java -cp %CP% org.dotme.learn.groovy.JavaClass"

String messageToJava() {
"Hello from Groovy"
}








println "\n\n******** Metodepeker, Closure, operator overloading, automatic imports ********"

def demoMethodPointer = AllCode.&main
if ( ! args )
demoMethodPointer( "peker til main-metoden" )

File outFile = new File( "TEXTFILE.txt" )

def println = { text -> // parameter in
outFile << a ="=">>

"""
println = System.out.&println







println "\n\n******** Groovy beans ********"
class ClassWithGeneratedGetSet {
def exposedProperty
private String privateSupressGetSet
final String readOnly

ClassWithGeneratedGetSet( String inProperty , String inReadOnly = "Tommy" ) {
exposedProperty = inProperty
readOnly = inReadOnly
}
}


ClassWithGeneratedGetSet obj = new ClassWithGeneratedGetSet( "Programming" );
println obj.getReadOnly()
println obj.exposedProperty

obj.setProperty "exposedProperty" , "Groovy recipies"
def prop = "exposedProperty"
println obj."${prop}"







println "\n\n******** Dynamically typed ********"

println DynamicTypeTester.getSize( new DynamicType() )
println DynamicTypeTester.getSize( 1 )
println DynamicTypeTester.getSize( null )

class DynamicType {
int size( ) {
1
}
}

class DynamicTypeTester {
static int getSize( Object lst ) {
if ( lst?.metaClass?.respondsTo( lst , 'size' ) )
return lst.size()
0
}
}







println "\n\n******** Meta programming ********"

family.injectedMethod = { entries ->
family.putAll entries
}
family.injectedMethod( [ trickToResolveCallsToMeAndYouAbove : "methodMissing()" ] )

println family.trickToResolveCallsToMeAndYouAbove


Integer.metaClass
Integer.metaClass.ogsåIJava = { println "Kan legge til metoder i Java klasser" }
2.ogsåIJava()


def interceptedMethodObj = new MethodInterceptDemo();
interceptedMethodObj.unsuspectingVictim()
interceptedMethodObj.nonExistingMethod()

class MethodInterceptDemo implements GroovyInterceptable {
def invokeMethod( String methodName , args ) {
System.out.println "before call to $methodName"
def method = MethodInterceptDemo.metaClass.getMetaMethod( methodName , args )
method?.invoke( this , args )
System.out.println "after call to $methodName"
}
def unsuspectingVictim() {
System.out.println "in unsuspectingVictim"
}
}



println "\n\n******** XML ********"
/***
* Excerpted from "Programming Groovy",
* published by The Pragmatic Bookshelf.
* Copyrights apply to this code. It may not be used to create training material,
* courses, books, articles, and the like. Contact us if you are in doubt.
* We make no guarantees that this code is fit for any purpose.
* Visit http://www.pragmaticprogrammer.com/titles/vslg for more book information.
***/
URL u = getClass().getResource( 'languages.xml' )
languages = new XmlParser().parse ( u.toExternalForm() )

println "Languages and authors"

languages.each {
println "${it.@name} authored by ${it.author[0].text()}"
}

def languagesByAuthor = { authorName ->
languages.findAll { it.author[0].text() == authorName }.collect {
it.@name }.join(', ')
}


println "Languages by Wirth:" + languagesByAuthor('Wirth')








println "\n\n******** Mange måter å loope ********"
for(i in 0..2) { println 'ho ' }
1.upto( 3 ) { println "$it gang 1.upto( 3 )" }
3.times { println "$it gang 3.times" }
0.step(10, 2) { println "$it gang 0.step(10, 2)" }



println "\n\n******** Collections ********"
HashSet set = [
"merk at {} er for closures" ,
"hei" ,
"closure som siste parameter..."
] as HashSet

set.each( {println it} )
println set*.toUpperCase() // spread operator

ArrayList list = [ 1 , 2 ]
list <<>
println "på plass $i står $tall"
}

Map family = [
me : "Tarzan" ,
you : "Jane"
]
println family.get( "me" )
println family.you

mandag 22. september 2008

JavaZone 2008

I attended JavaZone 2008 in Oslo Spektrum. I quite enjoyed it, though there was not so much hype stuff this year, I guess that new and emerging languages was supposed to fill that role?

New languages: Groovy
Groovy, the Blue Pill: Writing Next Generation Java Code in Groovy:
seemed to provide most utility reducing lines of code. That seems to be
a good thing until you consider that the biggest shrinkage is
accomplished by creating get'ers and set'ers behind the scene.
Groovy, The Red Pill: The Groovy Way to Blow a Buttoned-Down Java Developer's Mind:
Meta-programming, now we're talking

New languages: Scala
Introducing the Scala Programming Language:
Scala does provide an inclination towards writing immutable objects, and thus thread-safe code.

How to implement a dynamic (web-based) map
Vector-based maps can be bought from Statens kartverk, publishing rights sold separately.
WMS: Web Map Service.
Commersial: Google, Microsoft, Yahoo
Open: ka-map, OpenLayers.
OpenLayers can wrap commercial service for later substitution.
?tilecache.org?

Test smells
Test duplicates code
Too many expectations (should do 1 thing)
Too many dependencies
Confused Object
Exposed implementation
Test setup requires magic

Environment aware spring context:
http://kaare-nilsen.com/
http://projects.kaare-nilsen.com/projects/show/staged-spring/
http://kaare-nilsen.com:8081/nexus/content/repositories/releases


Sure bets

I always enjoy good speakers, among this year's celebrities:

Kevlin Henney (Objects of Desire)

Michael Feathers (Design Sense - Cultivating Deep Software Design Skill)

Robert Cecil Martin (Clean Code III: Functions)

Mary Poppendieck (The Double Paradox of Lean Software Development)
  • focus on throughput not utilization (don't fill schedules).
  • Don't put work in a long queue that won't be processed, say no.


tirsdag 15. juli 2008

UI checklists

Search checklist from adaptivepath.

My own checklist for Matisse

Once a new component is added to UI form, edit its properties:
  • Code-tab: Variable name
  • Code-tab: Serialize to
  • Properties-tab: Name
  • Properties-tab: Label
  • Properties-tab: Accesible name
  • Properties-tab: tooltipText
  • Properties-tab: text
  • Properties-tab: sizing
  • Properties-tab: border
  • Properties-tab: turn off autoCreateColumnsFromModel for JTables
  • When setting Action: remember to hook off "Background task".

torsdag 19. juni 2008

Software maintenance is...

  • Intellectually complex - it requires innovation while placing severe constraints on the innovator
  • Technically difficult - the maintainer must be able to work with a concept and a design and its code all at the same time
  • Unfair - the maintainer never gets all the things the maintainer needs, such as documentation
  • No-win - the maintainer only sees people who have problems
  • Dirty work - the maintainer must work at the grubby level of detailed coding
  • Living in the past - the code was probably written by someone else before they got good at it
  • Conservative - the going motto for maintenance is "if it ain't broke, don't fix it"

Software maintenance is pretty complex, challenging stuff.

tirsdag 20. mai 2008

Architecture: Swing, Maven2, NetBeans etc.

Development setup

  • Maven
  • NetBeans, plugins

Modules: swing-gui (client), service (ejb, ws, xml-dummies), model, parent
  • Unit tests, test-data
  • Code harness
  • Libraries / Frameworks: SWAF, Hibernate

Maven in NetBeans

I use NetBeans (6.1 ) with maven plugin, as described here. should maybe read 10 Steps to Happiness with Maven and the NetBeans Platform.
Maven is found on Apache site.

Swing

I found a host of useful examples on java2s, (with Outline=TreeTable examples) and in "Swing Hacks". I use some stuff from SwingLabs, check documentation.

MVC + Swing

I use Swing Application Framework, note that this Framework is "bleeding edge" according to self, but seeing it was used by Matisse NetBeans plugin, I concluded I might as well try it. (Alternatives: Eclipse RCP, NetBeans Platform, and Spring RCP (cf intro) and JGoodies).
I was pointed to Swing Fuse by this article on DI with Swing Fuse. Worth also to look up Google guice.

SDN has a nice article on Java SE Application Design With MVC.
On undo/redo from JavaWorld, or MVC-alternative.
Check Holub's More on getters and setters.

Unit testing

Unit testing the Swing GUI may not be worthwile, cf. jfcUnit Tests Swing GUIs (sidebar).
Injection of test data can be done with Castor.

More

Check the Capability Pattern.


torsdag 8. mai 2008

JNDI in JUnit tests

Sun har også en provider som kan brukes - se jndi-tutorial.
I ended up using Simple-JNDI - simple-jndi, thanks to:
James Strachan's Weblog
Injecting Constants as Spring Bean Properties | Unicon

My setup for lookup-key "java:comp/env/jdbc/ds":

jndi.properties:
java.naming.factory.initial=org.osjava.sj.SimpleContextFactory
org.osjava.sj.root=${project.build.directory}\\test-classes\\jndi
org.osjava.sj.colon.replace=--
org.osjava.sj.delimiter=/

src/test/resources/jndi/java--comp/env/jdbc/ds.properties:
type=javax.sql.DataSource
driver=oracle.jdbc.OracleDriver
url=${db.url}
user=${db.user}
password=${db.password}



fredag 18. april 2008

Java sql type mapping (Oracle, MySql++)

I found this useful table at the castor site:


Castor TypeJDBC TypeJava Object TypeMySQLPostgreSQLOracleDerbyMSSQLSapDBDB2SybaseHSQLPointBase
BIT BIT java.lang.Boolean TINYINT(1) BOOLEAN BOOLEAN CHAR FOR BIT DATA BIT BOOLEAN
BIT BIT BOOLEAN
TINYINT TINYINT java.lang.Byte TINYINT SMALLINT SMALLINT SMALLINT TINYINT SMALLINT SMALLINT TINYINT TINYINT SMALLINT
SMALLINT SMALLINT java.lang.Short SMALLINT SMALLINT SMALLINT SMALLINT SMALLINT SMALLINT SMALLINT SMALLINT SMALLINT SMALLINT
INTEGER INTEGER java.lang.Integer INTEGER INTEGER INTEGER INTEGER INTEGER INTEGER INTEGER INTEGER INTEGER INTEGER
BIGINT BIGINT java.lang.Long BIGINT BIGINT NUMERIC BIGINT BIGINT INTEGER BIGINT INTEGER BIGINT NUMERIC
FLOAT FLOAT java.lang.Double FLOAT DOUBLE PRECISION FLOAT FLOAT FLOAT FLOAT FLOAT FLOAT FLOAT FLOAT
DOUBLE DOUBLE java.lang.Double DOUBLE DOUBLE PRECISION DOUBLE PRECISION DOUBLE DOUBLE PRECISION DOUBLE PRECISION DOUBLE DOUBLE PRECISION DOUBLE PRECISION DOUBLE PRECISION
REAL REAL java.lang.Float REAL REAL REAL REAL REAL DOUBLE PRECISION REAL REAL REAL REAL
NUMERIC NUMERIC java.math.BigDecimal NUMERIC NUMERIC NUMERIC NUMERIC NUMERIC NUMERIC NUMERIC NUMERIC NUMERIC NUMERIC
DECIMAL DECIMAL java.math.BigDecimal DECIMAL NUMERIC DECIMAL DECIMAL DECIMAL DECIMAL DECIMAL DECIMAL DECIMAL DECIMAL
CHAR CHAR java.lang.String CHAR CHAR CHAR CHAR CHAR CHAR CHAR CHAR CHAR CHAR
VARCHAR VARCHAR java.lang.String VARCHAR VARCHAR VARCHAR2 VARCHAR VARCHAR VARCHAR VARCHAR VARCHAR VARCHAR VARCHAR
DATE DATE java.sql.Date DATE DATE DATE DATE DATETIME DATE DATE DATETIME DATE DATE
TIME TIME java.sql.Time TIME TIME DATE TIME DATETIME TIME TIME DATETIME TIME TIME
TIMESTAMP TIMESTAMP java.sql.Timestamp TIMESTAMP TIMESTAMP TIMESTAMP TIMESTAMP TIMESTAMP TIMESTAMP TIMESTAMP TIMESTAMP TIMESTAMP TIMESTAMP
BINARY BINARY byte[] BINARY BYTEA RAW CHAR [n] FOR BIT DATA BINARY BLOB CHAR [n] FOR BIT DATA BINARY BINARY BLOB
VARBINARY VARBINARY byte[] VARBINARY BYTEA LONG RAW VARCHAR [] FOR BIT DATA VARBINARY BLOB VARCHAR [] FOR BIT DATA VARBINARY VARBINARY BLOB
LONGVARBINARY LONGVARBINARY byte[] VARBINARY BYTEA LONG RAW LONG VARCHAR FOR BIT DATA IMAGE BLOB LONG VARCHAR FOR BIT DATA VARBINARY LONGVARBINARY BLOB
OTHER OTHER java.lang.Object BLOB BYTEA BLOB BLOB IMAGE BLOB BLOB IMAGE OTHER BLOB
JAVA_OBJECT JAVA_OBJECT java.lang.Object BLOB BYTEA BLOB BLOB IMAGE BLOB BLOB IMAGE OBJECT BLOB
BLOB BLOB java.io.InputStream BLOB BYTEA BLOB BLOB IMAGE BLOB BLOB IMAGE OBJECT BLOB
CLOB CLOB java.sql.Clob TEXT TEXT CLOB CLOB TEXT CLOB CLOB TEXT OBJECT CLOB


tirsdag 15. april 2008

Welcome!

This is my blog for stuff that I work, or even play with, mostly computer code. If any of this is useful to anybody but me, that's nice and good with me, but:
  1. be nice - use it for good, not bad.
  2. be responsible - don't blame (or sue) me for any problems arising from such use.
I put out most stuff here for my own sake, so the rest is optional but you're welcome to link to this blog and give me credit (or even money) if you feel that I deserve it.