Friday, April 06, 2007

New plugin for Intellij IDEA: translate text from one language to another (translate.google.com)

This plugin performs translations in Intellij IDEA Editor Window from one language to another (e.g. from Russian to Spain). It uses "http://translate.google.com" service behind the scene.

Plugin is especially convenient when you are trying to translate long i18n property files in your project for different languages.

Plugin adds "Translate" item into popup menu for the editor (also, in "Code" menu and "Generate" group). It also have separate configuration screen for selecting "from" and "to" languages.

How to use

1. Select the part to be translated;
2. Select "Translate" item from popup menu;
3. "translate.google.com" web site will perform actual translation;
4. Response from the service will be inserted in place of selection.

The project is located here.

Wednesday, April 04, 2007

How to build java presistence example with maven2

Here I will show how to build a very simple example that uses java persistence API. In order to simplify the build process I use maven 2. As the result, example archive is very short in size and all required libraries will be downloaded automatically only when it's really required.

1. Create new Java class, where you map java class/properties to database table/fields. Java persistence annotations will do this job for us:


import javax.persistence.*;

@Entity
@Table(name = "MESSAGES")
public class Message {

  @Id @GeneratedValue @Column(name = "MESSAGE_ID")
  private Long id;

  @Column(name = "MESSAGE_TEXT")
  private String text;

  @ManyToOne(cascade = CascadeType.ALL) @JoinColumn(name = "NEXT_MESSAGE_ID")
  private Message nextMessage;

  public Message() {}

  public Message(String text) {
    this.text = text;
  }

  // getter and setter methods for java properties
  ...
}


As you can see, "Message" class is mapped to "MESSAGES" table, "id", "text" and "nextMessage" properties - to "MESSAGE_ID", "MESSAGE_TEXT" and "NEXT_MESSAGE_ID" fields.

2. Now we can create simple program that uses persistent "Message" object:


import java.util.*;
import javax.persistence.*;

public class HelloWorld {

  public static void main(String[] args) {

    // Start EntityManagerFactory
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("helloworld");

    // First unit of work
    EntityManager em = emf.createEntityManager();
    EntityTransaction tx = em.getTransaction();
    tx.begin();

    Message message = new Message("Hello World with JPA");
    em.persist(message);

    tx.commit();
    em.close();

    // Second unit of work
    EntityManager newEm = emf.createEntityManager();
    EntityTransaction newTx = newEm.getTransaction();
    newTx.begin();

    List messages =
        newEm.createQuery("select m from Message m order by m.text asc").getResultList();

    System.out.println( messages.size() + " message(s) found:" );

    for (Object m : messages) {
      Message loadedMsg = (Message) m;
      System.out.println(loadedMsg.getText());
    }

    newTx.commit();
    newEm.close();

    // Shutting down the application
    emf.close();
  }

}


This example does not refer to any persistent framework directly. Instead, it uses symvolic names to get access to the framework in indirect way. In the abovementioned example we have "helloworld" name to refer to.

So, who is doing the persistence work here? We can use various frameworks here, but they should comply with java persistence API. For example, Hibernate or Toplink.

3. In this example we use Hibernate (http://hibernate.org) as persistence framework and hsqldb (http://hsqldb.org) as database. Let's take a look ad the hibernate configuration file (persistence.xml) where we describe "helloworld" factory:


<persistence xmlns="http://java.sun.com/xml/ns/persistence"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
   http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
   version="1.0">

  <!-- persistence.xml -->

  <persistence-unit name="helloworld">

    <!-- The provider only needs to be set if you use several JPA providers -->
    <provider>org.hibernate.ejb.HibernatePersistence</provider>

    <properties>
      <!-- Scan for annotated classes and Hibernate mapping XML files -->
      <property name="hibernate.archive.autodetection" value="class, hbm"/>

      <!-- SQL stdout logging -->
      <property name="hibernate.show_sql" value="true"/>
      <property name="hibernate.format_sql" value="true"/>
      <property name="use_sql_comments" value="true"/>

      <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>

      <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/>
      <property name="hibernate.connection.url" value="jdbc:hsqldb:file:persistence-db/test"/>
      <property name="hibernate.connection.username" value="sa"/>
      <property name="hibernate.hbm2ddl.auto" value="create"/>

      <property name="hibernate.c3p0.min_size" value="5"/>
      <property name="hibernate.c3p0.max_size" value="20"/>
      <property name="hibernate.c3p0.timeout" value="300"/>
      <property name="hibernate.c3p0.max_statements" value="50"/>
      <property name="hibernate.c3p0.idle_test_period" value="3000"/>
    </properties>
  </persistence-unit>

</persistence>


This file should be located on your CLASSPATH within META-INF directory. "hibernate.hbm2ddl.auto" property will take care of creating database table automatically.

4. Maven 2 file is responsible of downloading all dependent libraries, building correct CLASSPATH for the project and running the example (we use "exec:java" plugin for it):


<?xml version="1.0" encoding="UTF-8"?>

<project>
  <modelVersion>4.0.0</modelVersion>

  <groupId>persistence-deps</groupId>
  <artifactId>persistence-deps</artifactId>
  <version>1.0</version>

  <dependencies>
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.0.4</version>
    </dependency>

    <dependency>
      <groupId>hsqldb</groupId>
      <artifactId>hsqldb</artifactId>
      <version>1.8.0.7</version>
    </dependency>

    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate</artifactId>
      <version>3.2.2.ga</version>
    </dependency>

    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-annotations</artifactId>
      <version>3.2.1.ga</version>
    </dependency>

    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-entitymanager</artifactId>
      <version>3.2.1.ga</version>
    </dependency>

    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-tools</artifactId>
      <version>3.2.0.beta9a</version>
    </dependency>

    <dependency>
      <groupId>c3p0</groupId>
      <artifactId>c3p0</artifactId>
      <version>0.9.1</version>
    </dependency>
  </dependencies>

  <build>
    <defaultGoal>compile</defaultGoal>

    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.5</source>
          <target>1.5</target>
        </configuration>
      </plugin>

      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>exec-maven-plugin</artifactId>
        <executions>
          <execution>
            <goals>
              <goal>java</goal>
            </goals>
          </execution>
        </executions>

        <configuration>
          <mainClass>hello.HelloWorld</mainClass>
        </configuration>
      </plugin>
    </plugins>
  </build>

  <repositories>
    <repository>
      <id>scriptlandia-repo</id>
      <name>Scriptlandia Maven2 repository</name>
      <url>http://scriptlandia-repository.googlecode.com/svn/trunk/tools</url>
    </repository>
  </repositories>
</project>


5. Now, you can run compete example in one line:


>mvn compile exec:java


Complete example is located here.

Tuesday, April 03, 2007

How to compile and run Scala program with Ant and Maven 2

We have small scala program:


// HelloWorld.scala

object HelloWorld {

  def main(args: Array[String]) = {
    Console.println("Hello, world!")
  }

}


and want to compile/run it. In order to do it, we have to perform some additional steps.



    Compile/run with Ant


a). Scala is preinstalled

You need to have "scala-library" and "scala compiler" libraries in order to compile Scala programs.
You can download them from Scala web site (http://scala-lang.org).

Your ant script will start with the following lines:


<!-- 1. Define common properties. -->

<property name="src.dir" value="src/main/scala"/>
<property name="build.dir" value="target/classes"/>

<property name="repository.home" value="c:/maven-repository"/>
<property name="scala-compiler.jar" value="${repository.home}/scala/scala-compiler/2.4.0/scala-compiler-2.4.0.jar"/>
<property name="scala-library.jar" value="${repository.home}/scala/scala-library/2.4.0/scala-library-2.4.0.jar"/>

<!-- 2. Define Scala CLASSPATH. -->

<path id="scala.classpath">
  <pathelement location="${scala-compiler.jar}"/>
  <pathelement location="${scala-library.jar}"/>
</path>

<!-- 3. Define project CLASSPATH. -->

<path id="project.classpath">
  <path refid="scala.classpath"/>

  <pathelement location="${build.dir}"/>
</path>

<!-- 4. Define scala compiler command. -->

<taskdef resource="scala/tools/ant/antlib.xml">
  <classpath refid="scala.classpath"/>
</taskdef>


Now you can compile sources by using "scalac" command:


<!-- 5. Compiles sources by using "scalac" command. -->

<target name="compile">
  <mkdir dir="${build.dir}"/>

  <scalac srcdir="${src.dir}" destdir="${build.dir}" classpathref="project.classpath" force="changed">
    <include name="**/*.scala"/>
  </scalac>
</target>


Once compiled, you can run scala program:


<!-- 6. Runs scala executable. -->

<target name="run" depends="compile">
  <java classname="scala.tools.nsc.MainGenericRunner" fork="true">
    <classpath>
      <path refid="project.classpath"/>
    </classpath>

    <arg line="HelloWorld"/>
  </java>
</target>


Run this command:


>ant run


It will compile and then run scala example.


b). scala is being installed by maven 2


If you don't want to install scala libraries manually, you can use maven tasks for ant
(see http://maven.apache.org/ant-tasks.html for further details):


<project name="scala-compile-test2" default="compile" basedir="."
         xmlns:artifact="antlib:org.apache.maven.artifact.ant">

  <!-- 1. Define common properties. -->

  <property name="src.dir" value="src/main/scala"/>
  <property name="build.dir" value="target/classes"/>

  <!-- 2. Define Scala CLASSPATH with the help of Maven 2. -->

  <!--property name="repository.home" value="c:/maven-repository"/-->

  <artifact:localRepository id="local.repository" location="${repository.home}" layout="default"/>

  <artifact:pom file="scala-compile-test2.maven" id="maven.project" />

  <artifact:dependencies pathId="scala.classpath" filesetId="compile.fileset" useScope="compile">
    <pom refid="maven.project"/>
  </artifact:dependencies>


Steps 3-6 are the same as in previous example.


    Compile/run with Maven2


There are 2 maven plugings to work with scala sources. First plugin is implemented as
standard extension to the plexus compiler
(http://svn.codehaus.org/plexus/plexus-components/trunk/plexus-compiler/plexus-compilers).

The extension is located in the following repository:
http://scriptlandia-repository.googlecode.com/svn/trunk/languages

Another plugin for scala is implemented as regular maven plugin
(see details here: http://millstone.iodp.tamu.edu/~blambi/maven-scala-plugin).

a). plexus-compiler-scalac

First, you have to specify the location of scala sources. We'll do it with the help of
"build-helper-maven-plugin":


  <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>build-helper-maven-plugin</artifactId>
    <executions>
      <execution>
        <id>add-source</id>
        <phase>generate-sources</phase>
        <goals>
          <goal>add-source</goal>
        </goals>
        <configuration>
          <sources>
            <source>src/main/scala</source>
          </sources>
        </configuration>
      </execution>
    </executions>
  </plugin>


Then you configure "maven-compiler-plugin" plugin:


  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
      <compilerId>scalac</compilerId>

      <includes>
        <include>**</include>
      </includes>
    </configuration>

    <dependencies>
      <dependency>
        <groupId>org.codehaus.plexus</groupId>
        <artifactId>plexus-compiler-scalac</artifactId>
        <version>1.5.3</version>

        <scope>runtime</scope>
      </dependency>
    </dependencies>
  </plugin>


And don't forget about right repository:


  <repositories>
    <repository>
      <id>scriptlandia-repo</id>
      <name>Scriptlandia Maven2 repository</name>
      <url>http://scriptlandia-repository.googlecode.com/svn/trunk/languages</url>
    </repository>
  </repositories>


Now, compilation is easy:


>mvn compile


In order to run compiled code we'll use "exec" maven plugin:


  <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <executions>
      <execution>
        <goals>
          <goal>java</goal>
        </goals>
      </execution>
    </executions>

    <configuration>
      <mainClass>HelloWorld</mainClass>
    </configuration>
  </plugin>


And run it:


>mvn exec:java


b). maven-scala-plugin

This plugin contains 2 parts: compiler and runner. It requires small configuration:


  <plugin>
    <groupId>iodp.usio</groupId>
    <artifactId>maven-scala-plugin</artifactId>

    <configuration>
      <mainClass>HelloWorld</mainClass>
    </configuration>
    <executions>
      <execution>
        <phase>compile</phase>
        <goals>
          <goal>compile</goal>
        </goals>
      </execution>
    </executions>
  </plugin>


You also have to specify the location of this plugin:


  <pluginRepositories>
    <pluginRepository>
      <id>maven2.iodp.usio</id>
      <name>IODP Maven2 Repository</name>
      <url>http://millstone.iodp.tamu.edu/maven2</url>
    </pluginRepository>
  </pluginRepositories>


Now you will be able to compile and run scala code now:


>mvn scala:compile

>mvn scala:run -DmainClass=HelloWorld