I've done this for years.

    <context-param>
      <param-name>com.xyz.cayenne.DOMAIN_FILE_NAME</param-name>
      
<param-value>name-of-my-cayenne-for-some-particular-database-connection.xml</param-value>
      <description>file name of cayenne.xml - leave blank for
"cayenne.xml"</description>
    </context-param>

   <listener>
      <listener-class>com.xyz.cayenne.CustomConfiguration</listener-class>
    </listener>

There was a lot of extra stuff in here you don't probably need since
this application not only can have different databases, but other
differences in application configuration, but this sanitized file
should give you the starting point you need.

All of the various cayenne.xml files you might want to support would
be stored in the com/xyz/cayenne/model/app package although you can
change that.   Each cayenne.xml file points to the same <map> but has
different database connectivity defined in the <node> definitions
[datasource, adapter,  factory].

Note that this is a Cayenne 1.1 project so you may have to update some
code to use it with more modern versions.

package com.xyz.cayenne;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.Iterator;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.Logger;
import org.objectstyle.cayenne.access.DataDomain;
import org.objectstyle.cayenne.access.DataNode;
import org.objectstyle.cayenne.access.QueryLogger;
import org.objectstyle.cayenne.conf.Configuration;
import org.objectstyle.cayenne.conf.DefaultConfiguration;
import org.objectstyle.cayenne.conf.WebApplicationListener;

/**
 * Special subclass of ServletConfiguration that enables
 * logging of Cayenne queries and can also perform some
 * custom tasks on servlet container startup.
 */
public class CustomConfiguration extends WebApplicationListener
{
    private static final String CAYENNE_DOMAIN_FILE_NAME =
"com.xyz.cayenne.DOMAIN_FILE_NAME";

    protected static Log log = LogFactory.getLog(CustomConfiguration.class);

        public CustomConfiguration()
        {
                super();
                
        if (log.isTraceEnabled())  log.trace("in CustomConfiguration()");

                this.configureLogging();
        }

        protected void configureLogging() {
                // debug configuration
                // Configuration.setLoggingLevel(Level.ALL);
        }

    /** Establishes a Cayenne shared Configuration object that can
later be obtained by calling
      * <code>Configuration.getSharedConfiguration()</code>.
      * This method is a part of ServletContextListener interface and is called
      * on application startup. */
    public void contextInitialized(ServletContextEvent sce) {
        if (log.isTraceEnabled())  log.trace("in
CustomConfiguration.contextInitialized(ServletContextEvent)");


        try
        {
            super.contextInitialized(sce);

            DataDomain dataDomain = getConfiguration().getDomain();
            dataDomain.setSharedCacheEnabled(false);

            // Ignore errors generated by the driver id logging
            try
            {
                Iterator dataNodeIterator =
dataDomain.getDataNodes().iterator();
                while (dataNodeIterator.hasNext())
                {
                    DataNode dataNode = (DataNode) dataNodeIterator.next();

                    Connection connection = null;
                                try
                                {
                                    connection = 
dataNode.getDataSource().getConnection();
                        
                                    DatabaseMetaData meta = 
connection.getMetaData ();
                                    Logger cayenneLogger = 
Logger.getLogger(QueryLogger.class);
                                    cayenneLogger.debug("Database Product Name 
is ... " +
meta.getDatabaseProductName());
                                    cayenneLogger.debug("Database Product 
Version is  " +
meta.getDatabaseProductVersion());
                                    cayenneLogger.debug("JDBC Driver Name is 
........ " +
meta.getDriverName());
                                    cayenneLogger.debug("JDBC Driver Version is 
..... " +
meta.getDriverVersion());
                                    cayenneLogger.debug("JDBC Driver Major 
Version is " +
meta.getDriverMajorVersion());
                                    cayenneLogger.debug("JDBC Driver Minor 
Version is " +
meta.getDriverMinorVersion());
                                }
                                catch (SQLException e)
                                {
                                    e.printStackTrace();
                                    log.debug(e);
                                }
                                finally
                                {
                                    try
                        {
                            connection.close();
                        }
                        catch (SQLException exception)
                        {
                            exception.printStackTrace();
                        }
                                }
                }
            }
            catch (RuntimeException e1)
            {
                e1.printStackTrace();
                log.debug(e1);
            }
        }
        catch (RuntimeException e)
        {
            e.printStackTrace();
            log.debug(e);
        }
    }

    /** Currently does nothing. <i>In the future it should close down
      * any database connections if they wheren't obtained via JNDI.</i>
      * This method is a part of ServletContextListener interface and is called
      * on application shutdown. */
    public void contextDestroyed(ServletContextEvent sce) {
        if (log.isTraceEnabled())  log.trace("in
CustomConfiguration.contextDestroyed(ServletContextEvent)");

        super.contextDestroyed(sce);
   }

    protected Configuration newConfiguration(ServletContext sc) {
        String domainFileName = sc.getInitParameter(CAYENNE_DOMAIN_FILE_NAME);
        return newConfiguration(domainFileName);
    }

    protected Configuration newConfiguration(String cayenneDomainFileName) {
        DefaultConfiguration conf;
        if (null == cayenneDomainFileName)
        {
            conf = new CustomBasicServletConfiguration();
        }
        else
        {
            conf = new CustomBasicServletConfiguration(cayenneDomainFileName);
        }
        conf.addClassPath("com/xyz/cayenne/model/app");
        return conf;
    }

}



On Tue, May 15, 2012 at 5:59 PM, Tony Giaccone <t...@giaccone.org> wrote:
>
>
> So here's my situation. I'm building a framework, where I'd like to let my 
> development team choose to use either sql light or postgres on a shared 
> server as the persistent store.
>
> Using SQLite  lets them do development locally with out having to install 
> Postgress on each workstation and or be dependent on a central shared 
> postgres server.
>
> My first thought was to create two different models and then pick one in the 
> web.xml file. I'm sure this would work, but the model name would have to be 
> different for each model, so as to avoid file name collision. I'm not really 
> keen on that idea, because the models are the same and vary only in the 
> values in the data node.  And then I thought I could put them in different 
> folders, which represented the datanode file.
>
> resources/sqlite/myCayenneModel.xml
> resources/postgres/myCayenneModel.xml
>
> But it's not clear to me, how that is handled in the web.xml file.  The 
> filter name is the name of the model, no? How do you manage that if the model 
> is not at the top level of the classpath?
>
> After thinking about it, it seems to me the best solution is to ask you all.
>
> Just to be pedantic here's the problem.
>
> I have two different data models which essentially different only in the 
> value of the  data node.
> I want to be able to choose one model at compile time.
> I don't want to have to change any java code to make the choice. I'd prefer 
> to just edit the web.xml file.
>
>
> Anyone have a solution?
>
>
> Tony Giaccone

Reply via email to