JingDAO Tutorial: Context Configuration
In this example we'll look at how to add configuration information
to your DAO's. Each DaoManager has a
context
which is essentially
a map of key and value pairs. Your DAO's can access the context information
via one of three methods:
Avalon Context Lifecycle
,
JavaBean methods
,
Constructor Parameter
. The following
examples show three implementations of a
package org.jadetower.dao.test.daos; import java.io.File; public interface ContextDao { public String getName(); public File getFile(); }
You can use the
Avalon Contextualize
lifecycle method
to access context configuration values. To do this, implement
package org.jadetower.dao.test.daos.impl; import org.jadetower.dao.test.daos.ContextDao; import java.io.File; import java.util.Map; import org.apache.avalon.framework.context.Context; import org.apache.avalon.framework.context.Contextualizable; import org.apache.avalon.framework.context.ContextException; public class ContextDaoAvalonImpl implements ContextDao, Contextualizable{ String m_name = null; File m_file = null; public ContextDaoAvalonImpl(){ } public void contextualize(Context context) throws ContextException { m_name = (String) context.get("name"); m_file = (File) context.get("file"); } public String getName() { return m_name; } public File getFile() { return m_file; } } To use the JavaBean setter method, make sure that all configurable fields have getters and setters and ensure that the context contains keys which match your field names. package org.jadetower.dao.test.daos.impl; import org.jadetower.dao.test.daos.ContextDao; import java.io.File; public class ContextDaoBeanImpl implements ContextDao { protected String m_name = null; protected File m_file = null; public ContextDaoBeanImpl(){ }; public String getName() { return m_name; } public File getFile() { return m_file; } public void setName(String name){ m_name = name; } public void setFile(File file){ m_file = file; } }
To use the
Constructor Parameter
method, include a
package org.jadetower.dao.test.daos.impl; import org.jadetower.dao.test.daos.ContextDao; import java.io.File; import java.util.Map; public class ContextDaoMapImpl implements ContextDao { Map m_context = null; public ContextDaoMapImpl(Map context){ m_context = context; } public String getName() { return (String) m_context.get("name"); } public File getFile() { return (File) m_context.get("file"); } } Context ConfigurationNow that we know how to access this context configuration information, let's look at how to set it. Again, we have several options: programmatic configuration , XML configuation , and BeanShell scripts .
In the first example, we can pass in a Map to the DaoContainer to intialize
the context values. The following code section comes from the
public void testProgrammaticContext() throws Exception { String[] configuration = new String[] { "src/conf/parent-context-example.xconf"}; HashMap context = new HashMap(); context.put("name", expectedName); context.put("file", new File("src/conf/parent-context-example.xconf")); DaoContainer daoContainer = new DaoContainer(configuration, context, null); DaoManager manager = daoContainer.getManager("programmatic"); ContextDao dao = (ContextDao) manager.getDao("context"); String name = dao.getName(); String file = dao.getFile().getName(); boolean pass = name.equalsIgnoreCase(expectedName) && file.equalsIgnoreCase(expectedFile); assertTrue(pass); } In this code snippet, we can see that we can create a map and pass it as a constructor parameter to the DaoContainer. Context maps passed in this way are referred to as the parent context. We still need some configuration information that tells the DaoManager what to pass from the parent context to the DAOs: <?xml version="1.0" encoding="ISO-8859-1"?> <container> <manager id="programmatic"> <context> <entry name="name" uri="parent://name"/> <entry name="file" uri="parent://file"/> </context> <daos> <dao name="context" uri="class://org.jadetower.dao.test.daos.impl.ContextDaoMapImpl" /> </daos> </manager> </container>
Notice the
To use the other configuration methods, we don't need to do anything special during container setup. Everything is handled in the configuration file where you can directly specify context entries: <manager id="bean"> <context> <entry name="name" value="org.jadetower.dao.test.daos.ContextDao" /> <entry name="fileName" value="src/conf/context-example.xconf"/> <entry name="file" uri="class://java.io.File"> <parameter type="java.lang.String" value="${fileName}"/> </entry> </context> <daos> <dao name="context" uri="class://org.jadetower.dao.test.daos.impl.ContextDaoBeanImpl" /> </daos> </manager>
In this configuration we specify three context values:
The
Any valid Resolver URI scheme can be used in the uri attribute. For more information on URI Resolvers, see the Resolvers section of the tutorial.
Another interesting feature of context configuration is that previously
defined entries can be reused to define new entries. This helps for
objects which have complicated constructors. For example, to create the
However, if you're using many complicated objects in your context and you don't want to hard code that information in your application, it may be much easier to use BeanShell to script your context values. The following is a simple BeanShell script that creates a context equivalent to those we've already seen: import java.util.HashMap; import java.io.File; HashMap context = new HashMap(); context.put("name","org.jadetower.dao.test.daos.ContextDao"); File file = new File("src/conf/context-example.xconf"); context.put("file",file); return context;
The only requirement of such scripts is that the script returns a
<manager id="scripted" extends="bean"> <context> <script file="src/conf/context.bsh"/> </context> </manager> <manager id="embedded" extends="bean"> <context> <script> import java.util.HashMap; import java.io.File; HashMap context = new HashMap(); context.put("name","org.jadetower.dao.test.daos.ContextDao"); File file = new File("src/conf/context-example.xconf"); context.put("file",file); return context; </script> </context>
One final note about this configuration. Notice the
|