Setup multiple data sources in Grails 2.0

Hi there,

lately I was trying to use multiple data sources with a Grails application. It took me some time to figure out how to do that, therefore I thought it would be something worth sharing. The approach described here will only work for applications written in Grails 2.0 and above since the usage of multiple data sources is a feature which was added into Grails starting with version 2.0.

So here is how you do it. Unsurprisingly you can add your additional data sources within your DataSources.groovy configuration file. You simply add them to the appropriate subsection (development, test, production etc.) within the environments section of your configuration file. That should look some like this:

environments {
    development {
        dataSource {
        //This is your DEFAULT data source
	//Add the configuration parameters for your DEFAULT data source here.
        }

	dataSource_monsters {
	//This is thefirst of your additional data sources, put the configuration
        //parameters  corresponding to the first data source here.
        }

	dataSource_aliens {
	//This is the second of your additional data sources, put the configuration
        //parameters  corresponding to the second data source here.
        }
    }
    test {
	//You can specify other data sources in your test environment as usual.
        dataSource {

	}
	dataSource_monsters {

        }
	dataSource_aliens {

        }
    }
    production {
	//You can specify other data sources in your production environment as usual.
        dataSource {

	}
	dataSource_monsters {

        }
	dataSource_aliens {

        }
    }
}

As you may have noticed, there is a convention on how to specify additional data sources. The convention is to name the section “datasource_[your choosen name]”. So in the example file there are two different data sources, “datasource_monsters” and “datasource_aliens”. The name you choose after the the underscore is totally up to you. Another thing to notice is that you specify your default data source for a specific environment by using the “dataSource” clause without the additional underscore part.

So for each environment – development, test and production we have defined three different data sources. One default data source, and two additional data sources (‘monsters’ and ‘aliens’).

But how do you decide which data source a specific class should use?

The answer is by defining a mapping section within your class. Let’s see how that looks with some domain classes:

class Lair{

}

class Monster{
    static mapping = {
        datasource 'monsters'
    }
}

class Alien{
    static mapping = {
        datasource 'aliens'
    }
}

If a class does not specify a mapping section it will use the default data source defined in your section. So the Lair class would use the default data source for persisting itself. The other two classes (‘Monster’ and ‘Alien’) each define a mapping section with a data source that they would like to use. So the Monster class would be mapped to a monsters table in the ‘monsters’ data source and the Aliens class would be mapped to an aliens table in the ‘aliens’ data source.

I hope you enjoyed the read an everything worked for you. Drop me a comment if you experience any issues or if you think I should add some information to this article.

Howto Install Sun’s Java 6 on Debain

This article is a short Tutorial on how to install Java 6 on a Machine running Debian (Lenny) OS. I will try to keep the Installation process as simple as possible so let’s get started…

Step 1: Add “non-free” parameter

If you haven’t already done so, you have to add the “non-free” parameter to your apt “sources.list”. So open up your sources.list normallly located in /etc/apt/sources.list like so

nano /etc/apt/sources.list

…if you did not modify your “sources.list” up to now it might look something like this…

# deb cdrom:[Debian GNU/Linux 5.0.4 _Lenny_ - Official i386 NETINST Binary-1 20100201-16:45]/ lenny main
# deb cdrom:[Debian GNU/Linux 5.0.4 _Lenny_ - Official i386 NETINST Binary-1 20100201-16:45]/ lenny main

deb http://ftp.de.debian.org/debian/ lenny main
deb-src http://ftp.de.debian.org/debian/ lenny main

deb http://security.debian.org/ lenny/updates main
deb-src http://security.debian.org/ lenny/updates main

…now you have to add the “non-free” parameter to the end of the deb and deb-src lines. After that your “sources.list” should look like:

# deb cdrom:[Debian GNU/Linux 5.0.4 _Lenny_ - Official i386 NETINST Binary-1 20100201-16:45]/ lenny main
# deb cdrom:[Debian GNU/Linux 5.0.4 _Lenny_ - Official i386 NETINST Binary-1 20100201-16:45]/ lenny main

deb http://ftp.de.debian.org/debian/ lenny main non-free
deb-src http://ftp.de.debian.org/debian/ lenny main  non-free

deb http://security.debian.org/ lenny/updates main
deb-src http://security.debian.org/ lenny/updates main

…save your modified “sources.list” file.

Step 2: Install Java

Before you can install the sun-java packages you have to update your package repository…

apt-get update

now you can install the java packages…

apt-get install sun-java6-jdk sun-java6-jre

Step 3: Make Sun Java the preferred Java runtime

You can make the installed Java distribution the preferred Java runtime by using the “update-java-alternatives” command like so:

update-java-alternatives -s java-6-sun

This will make the newly installed Java runtime the standard Java runtime for your system.

Step 4: Set JAVA_HOME

Before we do anything else we set the JAVA_HOME environment variable so that other applications can find your java distribution. To to that you have to edit your “.bashrc” file located in your home directory. So open up your “.bashrc” file:

nano ~/.bashrc

…and add the following line to the end of your file

export JAVA_HOME=/usr/lib/jvm/java-6-sun

at this point I’m assuming that your distribution installed java in /usr/lib/jvm/java-6-sun which is the default behaviour. If that is not the case you have to replace the path with your installation path. Now you can try to log out and log in again to check if the JAVA_HOME is correctly set. After logging in again you just type…

echo $JAVA_HOME

if everything went right you should see the path that you set in your “.bashrc” earlier.

/usr/lib/jvm/java-6-sun

The approach discussed above will set the JAVA_HOME environment variable for your user only! So other users on the system cannot make use of your JAVA_HOME variable. To set the JAVA_HOME variable on a systemwide scale you have to edit the /etc/profile file. Setting the JAVA_HOME variable in the /etc/profile file will make it available to every user of the current system. The process of setting the JAVA_HOME variable is the same as described above, except that you use the /etc/profile file instead of the ~/.bashrc file in your users home directory.

Step 5: Check your Java Installation

If everything went right the command

java -version

…should yield the following output:

java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) Client VM (build 16.3-b01, mixed mode, sharing)

… so that’s that…hope it helps…cya

Adding XML namespaces via Dom4j

Hello everyone,

today’s article is about adding namespaces to your XML document using Java and Dom4j, so let’s get started…

First of all we need an instance of the Dom4j factory, here is how we do it…

//Get an instance of the dom4j document factory
DocumentFactory factory = DocumentFactory.getInstance();

…next we create an element which is going to serve as the root element as well as a new xml document using the factory object.

//use the factory to create a root element
Element rootElement = factory.createElement("RootElement");
//use the factory to create a new document with the previously created root element
Document doc = factory.createDocument(rootElement);

Now we are ready to create our namespaces.

//create some dom4j namespaces that we like to add to our new document
Namespace namespace1 = new Namespace("xsd","http://www.w3.org/2001/XMLSchema#");
Namespace namespace2 = new Namespace("rdfs","http://www.w3.org/2000/01/rdf-schema#");
Namespace namespace3 = new Namespace("rdf","http://www.w3.org/1999/02/22-rdf-syntax-ns#");
Namespace namespace4 = new Namespace("owl","http://www.w3.org/2002/07/owl#");
Namespace namespace5 = new Namespace("some","http://some/other/namespace:-)#");

The last step we have to take is to add all the namespaces to the XML document.

//add the created namespaces to the document</span>
doc.getRootElement().add(namespace1);
doc.getRootElement().add(namespace2);
doc.getRootElement().add(namespace3);
doc.getRootElement().add(namespace4);
doc.getRootElement().add(namespace5);

Finished! To check if everything worked as intended we’re going to write the document to an XML file…

try{
  //write the created document to an arbitrary file
  FileOutputStream fos = new FileOutputStream( "files/output.xml" );

  OutputFormat outformat = OutputFormat.createPrettyPrint();
  XMLWriter writer = new XMLWriter(fos, outformat);
  writer.write(doc);
  writer.flush();

}catch(FileNotFoundException e) {
  // catch exception
  e.printStackTrace();
}catch(UnsupportedEncodingException e) {
  // catch exception
  e.printStackTrace();
}catch (IOException e) {
  // catch exception
  e.printStackTrace();
}

…if everything went fine we should end up with an XML file that looks like this:

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

<RootElement xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:some="http://some/other/namespace:-)#">

</RootElement>

So this is how you add namespaces to your xml document via Dom4j…have a nice day and stay tuned for more face-melting articles :)…

XPath Expressions Dom4j vs XMLSpy

Hello,

this is my first real article so I hope I get things right…

This article is about a “Problem” I recently encountered while using XPath expressions in Dom4j and XMLSpy. The main objective was to select certain nodes in an XML File. Just to give you a better understanding of what I wanted to select, here the related snippet of the XML File:

   <!-- Individual:http://www.co-ode.org/ontologies/pizza/pizza.owl#Germany -->
   <owl:Thing rdf:about="#Germany">
       <rdf:type rdf:resource="#Country"/>
   </owl:Thing>

   <!-- Individual: http://www.co-ode.org/ontologies/pizza/pizza.owl#Italy -->
   <owl:Thing rdf:about="#Italy">
      <rdf:type rdf:resource="#Country"/>
   </owl:Thing>

   <owl:Thing rdf:about="#AmeriCunt">
       <rdf:type rdf:resource="#American"/>
   </owl:Thing>

   <American rdf:ID="Lappland"/>

   <AmericanHot rdf:ID="Toska"></AmericanHot>

   <AnchoviesTopping rdf:ID="Lappland"/>;

   <ArtichokeTopping rdf:ID="Lappland"/></span>

   <AsparagusTopping rdf:ID="Lappland"/>

I wanted to select the elements in the lines 17 – 25 via XPath expressions. So I tried to select the first Element with the expression “//American”. In XMLSpy and everything worked just fine. Therefore I took my java code and tried to run the same XPath expression with Dom4j (see code below):

Document doc = null;
try {
      doc = new SAXReader(  ).read(
              new FileInputStream("files/pizza.owl"));

      XPath xpathSelector =
      DocumentHelper.createXPath("//American");

      List<Element> elements = xpathSelector.selectNodes(doc);
      for(Element e: elements){
          System.out.println("Found");
      }

} catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (DocumentException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

That didn’t work so well and I ended up with an empty result set. After hours I finally came up with a solution to this problem (even though I am not quite sure that the explanation why the problem occurred with Dom4j and not with XMLSpy is accurate or not…..so it’s just a guess ).

I figured out that the elements I tried to select don’t belong to any namespace (in fact they do, they belong to the standard namespace of the XML file, if defined). The elements which I wanted to select existed one level below the actual root element of the XML file.

My guess is that XMLSpy figures out the namespaces of given document on its own and therefore can select elements based on an expression like “//American”. Dom4j on the other hand doesn’t figure out namespaces on its own an therefore is incapable of correctly evaluating the expression. That is why I ended up with an empty result set on my first try.

What I did is I took the namespace (line 1 in the XML file below) which all elements belong to if they have no prefix assigned to them and made it known to Dom4j:

<rdf:RDF xmlns="http://www.co-ode.org/ontologies/pizza/pizza.owl#"
     xml:base="http://www.co-ode.org/ontologies/pizza/pizza.owl"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
     xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
     xmlns:owl="http://www.w3.org/2002/07/owl#">

Java Code (the relevant changes are lokated in lines 4,5 and 8):

           try {
               doc = new SAXReader(  ).read(new FileInputStream("files/pizza.owl"));

               Map map = new HashMap();
               map.put("standard", "http://www.co-ode.org/ontologies/pizza/pizza.owl#");

               XPath xpathSelector  = DocumentHelper.createXPath("//standard:American");
               xpathSelector.setNamespaceContext(new SimpleNamespaceContext(map));

                List<Element> elements = xpathSelector.selectNodes(doc);
                for(Element e: elements){
                    System.out.println("Found");
                }

            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (DocumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

Now everything was working fine and I got my desired elements…