Happy new year 2010
For me, year 2010 will be a big switch in my life... hopefully for the best !
So, I wish you all the best things for this last year of the first third millennium's decade !
Happy new year !
Personal stuff. Obviously.
For me, year 2010 will be a big switch in my life... hopefully for the best !
So, I wish you all the best things for this last year of the first third millennium's decade !
Happy new year !
Posted by Fanf at 18:43 1 comments
I'm setting up a boostrap project for GWT 2 witch would use maven 2, UiBinder and i18n.
The idea is to centralize resources about UiBinder and test GWT 2, the result being used as a template project for real GWT 2 projects.
I'm quite new to GWT (2 days old...), so it is also a learning project. If it could be of any use for you, don't hesitate to use it - or enhance it, or make comments :)
For now, it's based on GWT 2.0.0-ms2, and some configuration may be specific to my environment (Linux&Firefox 3.5).
It's available here: http://github.com/fanf/gwt2-mvn-bootstrap
Posted by Fanf at 11:41 1 comments
Each time I start a new Java project with Maven 2, I need to write the same dependencies again and again: SLF4J and no commons-logging because it's evil (and SpringFramework seems to want to keep it), Joda Time by default, some properties, etc.
So, that's the template pom.xml I use for the bootstrap, if it may help anybody here (it uses logback for logging, as it's more efficient than Log4j with SLF4J, but feel free to use what you want):
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.test</groupId>
<artifactId>test</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<properties>
<!-- UTF-8 for everyone -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<slf4j-version>1.5.8</slf4j-version>
<logback-version>0.9.17</logback-version>
</properties>
<description>Template for project without Commons-logging</description>
<repositories>
<repository>
<id>no-commons-logging</id>
<name>No-commons-logging Maven Repository</name>
<layout>default</layout>
<url>http://no-commons-logging.zapto.org/mvn2</url>
<snapshots><enabled>false</enabled></snapshots>
</repository>
</repositories>
<pluginRepositories>
</pluginRepositories>
<build>
<plugins>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>1.6</version>
</dependency>
<!-- test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
<!--
All the following is related to our will to NOT use Commong-logging. Never.
And framework we depend on won't bring commons-loggin nether (I'm looking at
you, stringframework).
-->
<!-- use no-commons-logging -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>99.0-does-not-exist</version>
</dependency>
<!-- no-commons-logging-api, if you need it -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging-api</artifactId>
<version>99.0-does-not-exist</version>
</dependency>
<!-- slf4j commons-logging replacement -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j-version}</version>
</dependency>
<!-- other slf4j jars -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j-version}</version>
</dependency>
<!-- using slf4j native backend -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback-version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback-version}</version>
</dependency>
</dependencies>
</project>
Posted by Fanf at 14:44 2 comments
Labels: no-commons-logging, pom, slf4j
I'm actively looking for best practices and patterns about how to create clone objects in Scala, with the possibility to change some values of the cloned object along the way.
I have the usual concern of the Java world on that topic: I would like to avoid Java "clone", I want to be able to use the pattern in a class hierarchy, I want to have the minimum amount of code (or at least, the simplest possible) to write in domain class to support my cloning API.
And as I'm in Scala, I want to deal with both vars and vals, if possible in the same consistent way.
Actually, I want to provide to my libraries consumer an effective way to do things like that (where *Child* extends *Parent* class):
val p = new Parent("some value")
// simple cloning
val p2 = p.copy
//clone, and change a val and a var along the way
val p3 = p.copy(p_val1 = "new value for val", p_var1 = "new value for var")
//and same things apply for children of Parent:
val c = new Child("some parent value", "some child value")
//override child val/var and/or parent val/var in the same fashion
val c1 = c.copy(p_val1 = "new value for val defined in Parent class",
c_val1 = "new value for val defined in Child class",
p_var1 = "new value for var defined in Parent class",
c_var1 = "new value for var defined in Child class" )
class A(val val_a:String) {
var var_a = ""
}
object A {
def merge[T](t:T)
(
var_a : String
) : T = {
t match {
case x:A => x.var_a = var_a
case _ => error("")
}
t
}
def copy(source:A)
(
val_a : String = source.val_a,
var_a : String = source.var_a
) : A = merge(new A(val_a))(var_a)
}
class B(override val val_a:String, val val_b : Int) extends A(val_a) {
var var_b = 0
}
object B {
def merge[T](t:T)
(
var_a : String,
var_b : Int
) : T = {
A.merge(t)(var_a) match {
case x:B => x.var_b = var_b
case _ => error("")
}
t
}
def copy(source:B)
(
val_a : String = source.val_a,
var_a : String = source.var_a,
val_b : Int = source.val_b,
var_b : Int = source.var_b
) : B = merge(new B(val_a,val_b))(var_a,var_b)
}
class C(override val val_a : String) extends A(val_a)
// *****************
// Example of use
// *****************
object TestCloning {
def main(args:Array[String]) {
val a1 = new A("la_init")
a1.var_a = "ra_init"
val b1 = new B("lb_init",1)
b1.var_a = "rb_init"
b1.var_b = 10
//example with A
val a2 = A.copy(a1)()
assert(!(a1 eq a2))
assert(a2.var_a == a1.var_a)
assert(a2.val_a == a1.val_a)
val a3 = A.copy(a1)(val_a = "la_mod")
assert(a3.var_a == a1.var_a)
assert(a3.val_a == "la_mod")
val a4 = A.copy(a1)(val_a = "la_mod", var_a = "ra_mod")
assert(a4.val_a == "la_mod")
assert(a4.var_a == "ra_mod")
val a5 = A.copy(new C("foo"))()
assert(a5.var_a == "")
assert(a5.val_a == "foo")
val a6 = A.copy(b1)()
assert(a6.val_a == "lb_init")
assert(a6.var_a == "rb_init")
//with B
val b2 = B.copy(b1)()
assert(b2.val_a == "lb_init")
assert(b2.var_a == "rb_init")
assert(b2.val_b == 1)
assert(b2.var_b == 10)
val b3 = B.copy(b1)(var_b = 5, val_a = "lb_mod")
assert(b3.val_a == "lb_mod")
assert(b3.var_a == "rb_init")
assert(b3.val_b == 1)
assert(b3.var_b == 5)
}
def copyWith(source:A)( ... ) : A = merge(...)(...)
def copy(source:A) = copyWith(source)()
3/ and 4/ are just feelings, and so could be shut up for now.Posted by Fanf at 18:32 3 comments
Update: typos only
Until a really recent time, LDAP in the JVM, trougth JNDI API, was a nightmare of usability. Just connecting to an LDAP directory with a simple login/pass was worth a dozen lines of really unatural code (and I'm almost not exagering)
Hopefully, the situation is evolving, and there is several projects willing to provide a better LDAP SDK on the JVM.
Among them, there is UnboundId's one. I started to play with it, and it's quite delighting to be able to use a good API to do your work !
So it gives me an idea : how this SDK could be pimped thanks to Scala to be used in command lines, in a ruby ActiveLDAP fashion ?
And things are coming along really well. It's just a start, but this is an example of a Scala REPL session with my version of Scala ActiveLDAP :
scala> import test.activeldap._
import test.activeldap._
scala> import LdapFilter._
import LdapFilter._
scala> val p = new SimpleAuthLCP(baseDn = "dc=example,dc=org",authDn =
"cn=admin", authPw = "secret pass")
p: test.activeldap.SimpleAuthLCP = [cn=admin@localhost:389 (base:
dc=example,dc=org) by password authentication]
scala> val users = new MetaActiveEntry(prefix = "ou=people",
rdn = "uid" , classes = Set("top","person","organizationalPerson","inetOrgPerson"),
provider = p )
users: test.activeldap.MetaActiveEntry = test.activeldap.MetaActiveEntry@c85a33
scala> val user = users.find()(0)
user: test.activeldap.ActiveEntry = uid=42,ou=people,dc=example,dc=org
scala> user.details
res28: java.lang.String = Entry(dn='uid=42,ou=people,dc=example,dc=org',
attributes={Attribute(name=objectClass, values={'inetOrgPerson',
'organizationalPerson', 'person', 'top'}),
Attribute(name=sn, values={'Bar'}), Attribute(name=cn, values={'Foo'}),
Attribute(name=mail, values={'foo@bar.com'}), Attribute(name=uid, values={'42'})})
scala> user("uid") = "43"
scala> user.save
scala> users.find()
res31: Seq[test.activeldap.ActiveEntry] = ArrayBuffer(uid=42,ou=people,dc=example,dc=org,
uid=43,ou=people,dc=example,dc=org)
scala> user("mail") = Seq("foo@bar.com","foo_bar@bar.com")
scala> user.save
scala> users.find(EQ("uid","43"))(0).details
res34: java.lang.String = Entry(dn='uid=43,ou=people,dc=example,dc=org',
attributes={Attribute(name=objectClass, values={'inetOrgPerson',
'organizationalPerson', 'person', 'top'}), Attribute(name=sn, values={'Bar'}),
Attribute(name=cn, values={'Foo'}), Attribute(name=mail, values={'foo@bar.com',
'foo_bar@bar.com'}), Attribute(name=uid, values={'43'})})
scala> user.delete
scala> users.find(EQ("uid","43"))
res36: Seq[test.activeldap.ActiveEntry] = ArrayBuffer()
scala>
scala> val p = new SimpleAuthLCP( | authDn = "cn=manager", | authPw = "secret password", | host = "an.other.host.com", | port = "1389", | baseDn = "dc=company,dc=com" | )
Posted by Fanf at 21:42 3 comments
Labels: activeldap, ldap, scala
© Blogger template 'Minimalist G' by Ourblogtemplates.com 2008
Back to TOP