/****************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one   *
 * or more contributor license agreements.  See the NOTICE file *
 * distributed with this work for additional information        *
 * regarding copyright ownership.  The ASF licenses this file   *
 * to you under the Apache License, Version 2.0 (the            *
 * "License"); you may not use this file except in compliance   *
 * with the License.  You may obtain a copy of the License at   *
 *                                                              *
 *   http://www.apache.org/licenses/LICENSE-2.0                 *
 *                                                              *
 * Unless required by applicable law or agreed to in writing,   *
 * software distributed under the License is distributed on an  *
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
 * KIND, either express or implied.  See the License for the    *
 * specific language governing permissions and limitations      *
 * under the License.                                           *
 ****************************************************************/
package org.apache.james.domain;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.PersistenceException;

import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.HierarchicalConfiguration;
import org.apache.james.lifecycle.Configurable;

/**
 * JPA implementation of the DomainList.
 * This implementation is compatible with the JDBCDomainList, meaning same database schema can be reused.
 *
 */
public class JPADomainList extends AbstractDomainList implements Configurable {
    
    /**
     * The entity manager to access the database.
     */
    private EntityManagerFactory entityManagerFactory;

    /*
     * (non-Javadoc)
     * @see org.apache.james.lifecycle.Configurable#configure(org.apache.commons.configuration.HierarchicalConfiguration)
     */
    @SuppressWarnings("unchecked")
    public void configure(HierarchicalConfiguration config) throws ConfigurationException {
        // TODO The common configuration could be migrated to AbstractDomainList (should it implement Configurable?)
        setAutoDetect(config.getBoolean("autodetect", true));    
        setAutoDetectIP(config.getBoolean("autodetectIP", true));    
    }
   
    /**
     * @see org.apache.james.domain.AbstractDomainList#getDomainListInternal()
     */
    protected List<String> getDomainListInternal() {
        List<String> domains = new ArrayList<String>();
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        try {
            domains = entityManager.createNamedQuery("listDomainNames").getResultList();
        } catch (PersistenceException e) {
            getLogger().debug("Failed to list domains", e);
        } finally {
            entityManager.close();
        }
        if (domains.size() == 0) {
            return null;
        } else {
            return new ArrayList<String>(domains);
        }
    }

    /**
     * @see org.apache.james.api.domainlist.DomainList#containsDomain(java.lang.String)
     */
    public boolean containsDomain(String domain) {
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        try {
            JPADomain jpaDomain = (JPADomain) entityManager.createNamedQuery("findDomainByName").setParameter("name", domain).getSingleResult();
            return (jpaDomain != null) ? true : false;
        } catch (PersistenceException e) {
            getLogger().debug("Failed to find domain", e);
        } finally {
            entityManager.close();
        }    
        return false;
    }

    /**
     * @see org.apache.james.domain.AbstractDomainList#addDomainInternal(java.lang.String)
     */
    protected boolean addDomainInternal(String domain) {
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        final EntityTransaction transaction = entityManager.getTransaction();
        try {
            transaction.begin();
            JPADomain jpaDomain = new JPADomain(domain);
            entityManager.persist(jpaDomain);
            transaction.commit();
            return true;
        } catch (PersistenceException e) {
            getLogger().debug("Failed to save domain", e);
            if (transaction.isActive()) {
                transaction.rollback();
            }
        } finally {
            entityManager.close();
        }
        return false;
    }

    /**
     * @see org.apache.james.domain.AbstractDomainList#removeDomainInternal(java.lang.String)
     */
    protected boolean removeDomainInternal(String domain) {
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        final EntityTransaction transaction = entityManager.getTransaction();
        try {
            transaction.begin();
            entityManager.createNamedQuery("deleteDomainByName").setParameter("name", domain).executeUpdate();
            transaction.commit();
            return true;
        } catch (PersistenceException e) {
            getLogger().debug("Failed to remove domain", e);
            if (transaction.isActive()) {
                transaction.rollback();
            }
        } finally {
            entityManager.close();
        }
        return false;
    }

    /**
     * Set the entity manager to use.
     * 
     * @param entityManagerFactory
     */
    public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
        this.entityManagerFactory = entityManagerFactory;
    }

}

@@ -1472,16 +1472,59 @@
 eption;%0D
+%0Aimport javax.persistence.PersistenceUnit;%0D
 %0A%0D%0Aimpor
@@ -5832,32 +5832,54 @@
 ctory%0D%0A     */%0D%0A
+    @PersistenceUnit%0D%0A
     public void 

Use @PersistenceUnit annotation