I solved the problem *exactly* as I wanted originally, and as I
promised I'd post my solution, here it is. Let me just summarize:

I'm building a large open source J2EE app. I'm building it off of
PostgreSQL backend, but I want the app to be completely unaware of the
DAO implementation, so in the future somebody can develop MySQL or any
other backend without changing a single line of code in the
application.

Entire application uses DAO interfaces only, and Hivemind dependency
injection is used to provide the DAO provider (which in turn provides
references to DAOs). The DAO provider itself can be further enhanced
via Hivemind to inject specific DAO implementations (currently not
needed).

Anyway, the beauty as I see it is that DAOs are now like a 3rd party
library from the application standpoind. If somebody develops MySQL
database for the app, they would provide DAO JAR, configure it an the
app is happy.

Each DAO itself is a special kind of a singleton. Constructor is
private - nothing special, but getInstance() method has a package
scope. This is elegant because if an application developer will try to
incorrectly use specific DAO rather than the interface, he/she would
not even be able to instantiate one because getInstance() is only
visible from the package, and only the DAO provider object which lives
in the same package as all DAOs can instantiate it. Then, Hivemind
injects the provider...

hivemodule.xml

        <service-point id="daoProvider"
interface="org.opendating.data.dao.IApplicationDAOProvider"/>

        <implementation service-id="daoProvider">
                <create-instance
class="org.opendating.data.dao.postgres.PostgresDAOProvider"
model="singleton"/>
        </implementation>

/*
 * Created on Mar 18, 2006, 9:42:05 AM CST
 * Created by Adam Zimowski
 *
 * Copyright (C) 2005-present OpenDating.org
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * or visit http://www.fsf.org
 */
package org.opendating.data.dao;


/**
 * Defines all DAO components used by the application. The application uses
 * this interface to lookup every DAO it needs, without consideration for a
 * particullar implementation. The actual implementation of this provider is
 * wired through Hivemind configuration microkernel. This approach allows to
 * easily replace entire database back end, without changing a single line of
 * application code. For instance, one could port the database to MySQL without
 * writing a single stored procedure, and along with the new database could
 * provide a JARred DAO library with a provider implementing this interface,
 * and a series of DAOs conforming to their respective interfaces. A simple
 * change in Hivemind configuration would then wire the application to MySQL.
 *
 * @author Adam Zimowski
 * @since 0.1
 * @.file [EMAIL PROTECTED] }
 */
public interface IApplicationDAOProvider {

        public abstract ILoginDAO getLoginDAO();

        public abstract IDateDAO getDateDAO();
        
        public abstract IMemberDAO getMemberDAO();
        
        public abstract IPostalCodeDAO getPostalCodeDAO();
        
        public abstract IProfileOptionsDAO getProfileOptionsDAO();

        public abstract ISessionDAO getSessionDAO();
        
        public abstract ISimpleProfileDAO getSimpleProfileDAO();
        
        public abstract IStatsDAO getStatsDAO();
}


/*
 * Created on Mar 18, 2006, 9:39:09 AM CST
 * Created by Adam Zimowski
 *
 * Copyright (C) 2005-present OpenDating.org
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * or visit http://www.fsf.org
 */
package org.opendating.data.dao.postgres;

import org.apache.log4j.Logger;
import org.opendating.data.dao.IApplicationDAOProvider;
import org.opendating.data.dao.IDateDAO;
import org.opendating.data.dao.ILoginDAO;
import org.opendating.data.dao.IMemberDAO;
import org.opendating.data.dao.IPostalCodeDAO;
import org.opendating.data.dao.IProfileOptionsDAO;
import org.opendating.data.dao.ISessionDAO;
import org.opendating.data.dao.ISimpleProfileDAO;
import org.opendating.data.dao.IStatsDAO;
import org.opendating.util.log.LogEngine;

public class PostgresDAOProvider implements IApplicationDAOProvider {

        private Logger _aLog = LogEngine.getAppLogger();
        
        public PostgresDAOProvider() {
                if(_aLog.isDebugEnabled())
                        _aLog.debug("Creating PostgreSQL DAO Provider...");
        }
        
        /* (non-Javadoc)
         * @see org.opendating.data.dao.db.main.IMainDAOProvider#getLoginDAO()
         */
        public ILoginDAO getLoginDAO() {
                return LoginPgDAO.getInstance();
        }
        
        /* (non-Javadoc)
         * @see org.opendating.data.dao.IApplicationDAOProvider#getDateDAO()
         */
        public IDateDAO getDateDAO() {
                return DatePgDAO.getInstance();
        }
        
        /* (non-Javadoc)
         * @see org.opendating.data.dao.IApplicationDAOProvider#getMemberDAO()
         */
        public IMemberDAO getMemberDAO() {
                return MemberPgDAO.getInstance();
        }

        /* (non-Javadoc)
         * @see 
org.opendating.data.dao.IApplicationDAOProvider#getPostalCodeDAO()
         */
        public IPostalCodeDAO getPostalCodeDAO() {
                return PostalCodePgDAO.getInstance();
        }

        /* (non-Javadoc)
         * @see 
org.opendating.data.dao.IApplicationDAOProvider#getProfileOptionsDAO()
         */
        public IProfileOptionsDAO getProfileOptionsDAO() {
                return ProfileOptionsPgDAO.getInstance();
        }

        /* (non-Javadoc)
         * @see org.opendating.data.dao.IApplicationDAOProvider#getSessionDAO()
         */
        public ISessionDAO getSessionDAO() {
                return SessionPgDAO.getInstance();
        }

        /* (non-Javadoc)
         * @see 
org.opendating.data.dao.IApplicationDAOProvider#getSimpleProfileDAO()
         */
        public ISimpleProfileDAO getSimpleProfileDAO() {
                return SimpleProfilePgDAO.getInstance();
        }

        /* (non-Javadoc)
         * @see org.opendating.data.dao.IApplicationDAOProvider#getStatsDAO()
         */
        public IStatsDAO getStatsDAO() {
                return StatsPgDAO.getInstance();
        }
}

--------------- one of the dao's -------------------------

/*
 * Created on Aug 24, 2005, 8:29:00 PM
 * Created by Adam Zimowski
 *
 * Copyright (C) 2005-present OpenDating.org
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * or visit http://www.fsf.org
 */
package org.opendating.data.dao.postgres;

import java.util.List;

import org.opendating.data.SimpleEntity;
import org.opendating.data.dao.IDateDAO;


/**
 * Provides data access to all the date-related information.
 *
 * @author Adam Zimowski
 * @since 0.1
 * @.file [EMAIL PROTECTED] }
 */
public final class DatePgDAO extends SimpleEntityPgDAO implements IDateDAO {

        private static DatePgDAO _instance = null;
        
        /**
         * Default constructor; instantiates this class, and calls the 
underlying
         * base.
         *
         * @since 0.1
         */
        private DatePgDAO() {
                super();
        }
        
        static DatePgDAO getInstance() {
                if(_instance == null) _instance = new DatePgDAO();
                return _instance;
        }

        /* (non-Javadoc)
         * @see org.opendating.data.dao.IDateDAO#getMonths()
         */
        public List<SimpleEntity> getMonths() {
                return getSimpleEntityList("f_get_qtn_months");
        }
}

----- Then, Tapestry objects simply implement this: ----------

/*
 * Created on Mar 18, 2006, 2:31:06 PM CST
 * Created by Adam Zimowski
 *
 * Copyright (C) 2005-present OpenDating.org
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * or visit http://www.fsf.org
 */
package org.opendating.tapestry;

import org.apache.tapestry.annotations.InjectObject;
import org.opendating.data.dao.IApplicationDAOProvider;

/**
 * Provides easy access to the DAO provider for Tapestry based objects. Since
 * Tapestry is tightly integrated with Hivemind, it provides convinient
 * annotations which can be used instead of plain registry lookup. Therefore
 * for Tapestry pages and comonents it is easiest to simply implement this
 * interface (without implementing the method), and call the getter to grab
 * the provider. Tapestry and Hivemind will do the rest of the magic, and
 * deliver a valid reference...
 *
 * @author Adam Zimowski
 * @since 0.1
 * @.file [EMAIL PROTECTED] }
 */
public interface ITapestryDAOProvider {

        @InjectObject("service:org.opendating.daoProvider")
        public abstract IApplicationDAOProvider getDAO();
}

Regards,
Adam

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to