Author: eric Date: Fri Sep 3 07:44:00 2010 New Revision: 992226 URL: http://svn.apache.org/viewvc?rev=992226&view=rev Log: DomainList is now also JPA (JAMES-1037)
Added: james/server/trunk/core-function/src/main/java/org/apache/james/domain/JPADomain.java james/server/trunk/core-function/src/main/java/org/apache/james/domain/JPADomainList.java james/server/trunk/core-function/src/test/java/org/apache/james/domain/JPADomainListTest.java Modified: james/server/trunk/core-function/pom.xml james/server/trunk/core-function/src/main/java/org/apache/james/domain/JDBCDomainList.java james/server/trunk/spring-deployment/src/main/config/james/META-INF/persistence.xml james/server/trunk/spring-deployment/src/main/config/james/spring-beans.xml Modified: james/server/trunk/core-function/pom.xml URL: http://svn.apache.org/viewvc/james/server/trunk/core-function/pom.xml?rev=992226&r1=992225&r2=992226&view=diff ============================================================================== --- james/server/trunk/core-function/pom.xml (original) +++ james/server/trunk/core-function/pom.xml Fri Sep 3 07:44:00 2010 @@ -112,6 +112,14 @@ <scope>test</scope> </dependency> <dependency> + <groupId>org.apache.openjpa</groupId> + <artifactId>openjpa</artifactId> + </dependency> + <dependency> + <groupId>javax.persistence</groupId> + <artifactId>persistence-api</artifactId> + </dependency> + <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> @@ -123,4 +131,39 @@ <type>test-jar</type> </dependency> </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>openjpa-maven-plugin</artifactId> + <version>1.0</version> + <configuration> + <includes>org/apache/james/domain/JPADomain.class</includes> + <addDefaultConstructor>true</addDefaultConstructor> + <enforcePropertyRestrictions>true</enforcePropertyRestrictions> + <toolProperties> + <property> + <name>log</name> + <value>TOOL=TRACE</value> + </property> + <property> + <name>metaDataFactory</name> + <value>jpa(Types=org.apache.james.domain.JPADomain)</value> + </property> + </toolProperties> + </configuration> + <executions> + <execution> + <id>enhancer</id> + <phase>process-classes</phase> + <goals> + <goal>enhance</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + </project> Modified: james/server/trunk/core-function/src/main/java/org/apache/james/domain/JDBCDomainList.java URL: http://svn.apache.org/viewvc/james/server/trunk/core-function/src/main/java/org/apache/james/domain/JDBCDomainList.java?rev=992226&r1=992225&r2=992226&view=diff ============================================================================== --- james/server/trunk/core-function/src/main/java/org/apache/james/domain/JDBCDomainList.java (original) +++ james/server/trunk/core-function/src/main/java/org/apache/james/domain/JDBCDomainList.java Fri Sep 3 07:44:00 2010 @@ -45,7 +45,9 @@ import org.apache.james.util.sql.JDBCUti import org.apache.james.util.sql.SqlResources; /** - * Allow to query a costum table for domains + * Allow to query a custom table for domains + * + * @deprecated use the JPA */ public class JDBCDomainList extends AbstractDomainList implements Configurable{ Added: james/server/trunk/core-function/src/main/java/org/apache/james/domain/JPADomain.java URL: http://svn.apache.org/viewvc/james/server/trunk/core-function/src/main/java/org/apache/james/domain/JPADomain.java?rev=992226&view=auto ============================================================================== --- james/server/trunk/core-function/src/main/java/org/apache/james/domain/JPADomain.java (added) +++ james/server/trunk/core-function/src/main/java/org/apache/james/domain/JPADomain.java Fri Sep 3 07:44:00 2010 @@ -0,0 +1,58 @@ +/**************************************************************** + * 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 javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; +import javax.persistence.Table; + +/** + * Domain class for the James Domain to be used for JPA persistence. + * + */ +...@entity(name = "JamesDomain") +...@table(name = "DOMAIN") +...@namedqueries( { + @NamedQuery(name = "findDomainByName", query = "SELECT domain FROM JamesDomain domain WHERE domain.name=:name"), + @NamedQuery(name = "containsDomain", query = "SELECT COUNT(domain) FROM JamesDomain domain WHERE domain.name=:name") , + @NamedQuery(name = "listDomainNames", query = "SELECT domain.name FROM JamesDomain domain"), + @NamedQuery(name = "deleteDomainByName", query = "DELETE FROM JamesDomain domain WHERE domain.name=:name") +}) +public class JPADomain { + + /** + * The name of the domain. column name is chosen to be compatible with the JDBCDomainList. + */ + @Id + @Column(name = "DOMAIN", nullable = false, length = 100) + private String name; + + /** + * Use this simple constructor to create a new Domain. + * + * @param name the name of the Domain + */ + public JPADomain (String name) { + this.name = name; + } + +} Added: james/server/trunk/core-function/src/main/java/org/apache/james/domain/JPADomainList.java URL: http://svn.apache.org/viewvc/james/server/trunk/core-function/src/main/java/org/apache/james/domain/JPADomainList.java?rev=992226&view=auto ============================================================================== --- james/server/trunk/core-function/src/main/java/org/apache/james/domain/JPADomainList.java (added) +++ james/server/trunk/core-function/src/main/java/org/apache/james/domain/JPADomainList.java Fri Sep 3 07:44:00 2010 @@ -0,0 +1,146 @@ +/**************************************************************** + * 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; + } + +} Added: james/server/trunk/core-function/src/test/java/org/apache/james/domain/JPADomainListTest.java URL: http://svn.apache.org/viewvc/james/server/trunk/core-function/src/test/java/org/apache/james/domain/JPADomainListTest.java?rev=992226&view=auto ============================================================================== --- james/server/trunk/core-function/src/test/java/org/apache/james/domain/JPADomainListTest.java (added) +++ james/server/trunk/core-function/src/test/java/org/apache/james/domain/JPADomainListTest.java Fri Sep 3 07:44:00 2010 @@ -0,0 +1,162 @@ +/**************************************************************** + * 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.net.InetAddress; +import java.net.UnknownHostException; +import java.util.HashMap; + +import junit.framework.TestCase; + +import org.apache.commons.logging.impl.SimpleLog; +import org.apache.james.api.dnsservice.AbstractDNSServer; +import org.apache.james.api.dnsservice.DNSService; +import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory; +import org.apache.openjpa.persistence.OpenJPAPersistence; + +/** + * Test the JPA implementation of the DomainList. + */ +public class JPADomainListTest extends TestCase { + + // Domains we will play with. + private final String DOMAIN_1 = "domain1.tld"; + private final String DOMAIN_2 = "domain2.tld"; + private final String DOMAIN_3 = "domain3.tld"; + private final String DOMAIN_4 = "domain4.tld"; + private final String DOMAIN_5 = "domain5.tld"; + + /** + * The OpenJPA Entity Manager used for the tests. + */ + private OpenJPAEntityManagerFactory factory; + + /** + * The properties for the OpenJPA Entity Manager. + */ + private HashMap<String, String> properties; + + /** + * The JPA DomainList service. + */ + private JPADomainList jpaDomainList; + + @Override + protected void setUp() throws Exception { + + super.setUp(); + + // Use a memory database. + properties = new HashMap<String, String>(); + properties.put("openjpa.ConnectionDriverName", org.apache.derby.jdbc.EmbeddedDriver.class.getName()); + properties.put("openjpa.ConnectionURL", "jdbc:derby:memory:JPADomainListTestDB;create=true"); + properties.put("openjpa.Log", "JDBC=WARN, SQL=TRACE, Runtime=WARN"); + properties.put("openjpa.ConnectionFactoryProperties", "PrettyPrint=true, PrettyPrintLineLength=72"); + properties.put("openjpa.jdbc.SynchronizeMappings", "buildSchema(ForeignKeys=true)"); + properties.put("openjpa.MetaDataFactory", "jpa(Types=" + JPADomain.class.getName() +")"); + factory = OpenJPAPersistence.getEntityManagerFactory(properties); + + // Initialize the JPADomainList (no autodetect,...). + jpaDomainList = new JPADomainList(); + jpaDomainList.setLog(new SimpleLog("JPADomainListMockLog")); + jpaDomainList.setDNSService(setUpDNSServer("localhost")); + jpaDomainList.setAutoDetect(false); + jpaDomainList.setAutoDetectIP(false); + jpaDomainList.setEntityManagerFactory(factory); + + // Always delete everything before running any tests. + deleteAll(); + + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + } + + /** + * Add 3 domains and list them. + */ + public void createListDomains() { + assertEquals(true, jpaDomainList.addDomain(DOMAIN_3)); + assertEquals(true, jpaDomainList.addDomain(DOMAIN_4)); + assertEquals(true, jpaDomainList.addDomain(DOMAIN_5)); + assertEquals(3, jpaDomainList.getDomains().size()); + } + + /** + * Add a domain and check it is present. + */ + public void testAddContainsDomain() { + assertEquals(true, jpaDomainList.addDomain(DOMAIN_2)); + assertEquals(true, jpaDomainList.containsDomain(DOMAIN_2)); + } + + /** + * Add and remove a domain, and check database is empty. + */ + public void testAddRemoveContainsSameDomain() { + assertEquals(true, jpaDomainList.addDomain(DOMAIN_1)); + assertEquals(true, jpaDomainList.removeDomain(DOMAIN_1)); + assertEquals(null, jpaDomainList.getDomains()); + } + + /** + * Add a domain and remove another domain, and check first domain is still present. + */ + public void testAddRemoveContainsDifferentDomain() { + assertEquals(true, jpaDomainList.addDomain(DOMAIN_1)); + assertEquals(true, jpaDomainList.removeDomain(DOMAIN_2)); + assertEquals(1, jpaDomainList.getDomains().size()); + assertEquals(true, jpaDomainList.containsDomain(DOMAIN_1)); + } + + /** + * Delete all possible domains from database. + */ + private void deleteAll() { + assertEquals(true, jpaDomainList.removeDomain(DOMAIN_1)); + assertEquals(true, jpaDomainList.removeDomain(DOMAIN_2)); + assertEquals(true, jpaDomainList.removeDomain(DOMAIN_3)); + assertEquals(true, jpaDomainList.removeDomain(DOMAIN_4)); + assertEquals(true, jpaDomainList.removeDomain(DOMAIN_5)); + } + + /** + * Return a fake DNSServer. + * + * @param hostName + * @return + */ + private DNSService setUpDNSServer(final String hostName) { + DNSService dns = new AbstractDNSServer() { + public String getHostName(InetAddress inet) { + return hostName; + } + public InetAddress[] getAllByName(String name) throws UnknownHostException { + return new InetAddress[] { InetAddress.getByName("127.0.0.1")}; + } + public InetAddress getLocalHost() throws UnknownHostException { + return InetAddress.getLocalHost(); + } + }; + return dns; + } + +} Modified: james/server/trunk/spring-deployment/src/main/config/james/META-INF/persistence.xml URL: http://svn.apache.org/viewvc/james/server/trunk/spring-deployment/src/main/config/james/META-INF/persistence.xml?rev=992226&r1=992225&r2=992226&view=diff ============================================================================== --- james/server/trunk/spring-deployment/src/main/config/james/META-INF/persistence.xml (original) +++ james/server/trunk/spring-deployment/src/main/config/james/META-INF/persistence.xml Fri Sep 3 07:44:00 2010 @@ -30,6 +30,10 @@ <!-- UsersRepository --> <class>org.apache.james.userrepository.JPAUser</class> + + <!-- DomainList --> + <class>org.apache.james.domain.JPADomain</class> + <properties> <!-- Create tables on startup --> <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/> Modified: james/server/trunk/spring-deployment/src/main/config/james/spring-beans.xml URL: http://svn.apache.org/viewvc/james/server/trunk/spring-deployment/src/main/config/james/spring-beans.xml?rev=992226&r1=992225&r2=992226&view=diff ============================================================================== --- james/server/trunk/spring-deployment/src/main/config/james/spring-beans.xml (original) +++ james/server/trunk/spring-deployment/src/main/config/james/spring-beans.xml Fri Sep 3 07:44:00 2010 @@ -267,7 +267,14 @@ <!-- The context domainlist implementation --> <bean id="domainlist" class="org.apache.james.domain.XMLDomainList" /> - <!-- JDBC implementation of the domainlist service--> + <!-- JPA implementation of the domainlist service --> + <!-- + <bean id="domainlist" class="org.apache.james.domain.JPADomainList"> + <property name="entityManagerFactory" ref="entityManagerFactory" /> + </bean> + --> + + <!-- JDBC implementation of the domainlist service - deprecated, use the JPADomainList --> <!-- <bean id="domainlist" class="org.apache.james.domain.JDBCDomainList"/> --> --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org