You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by no...@apache.org on 2006/10/20 14:59:27 UTC
svn commit: r466098 - in /james/server/trunk/src: conf/
java/org/apache/james/domain/ java/org/apache/james/vut/
test/org/apache/james/domain/
Author: norman
Date: Fri Oct 20 05:59:26 2006
New Revision: 466098
URL: http://svn.apache.org/viewvc?view=rev&rev=466098
Log:
Add JDBCDomainList to allow costum queries for DOMAINS. See JAMES-426
Fix a nullpointer
Added:
james/server/trunk/src/java/org/apache/james/domain/JDBCDomainList.java (with props)
james/server/trunk/src/java/org/apache/james/domain/JDBCDomainList.xinfo
james/server/trunk/src/test/org/apache/james/domain/JDBCDomainListTest.java (with props)
Modified:
james/server/trunk/src/conf/sqlResources.xml
james/server/trunk/src/java/org/apache/james/domain/AbstractDomainList.java
james/server/trunk/src/java/org/apache/james/vut/JDBCVirtualUserTable.java
james/server/trunk/src/test/org/apache/james/domain/XMLDomainListTest.java
Modified: james/server/trunk/src/conf/sqlResources.xml
URL: http://svn.apache.org/viewvc/james/server/trunk/src/conf/sqlResources.xml?view=diff&rev=466098&r1=466097&r2=466098
==============================================================================
--- james/server/trunk/src/conf/sqlResources.xml (original)
+++ james/server/trunk/src/conf/sqlResources.xml Fri Oct 20 05:59:26 2006
@@ -1091,5 +1091,12 @@
)
</sql>
</sqlDefs>
+
+<!-- SQL statements for the JDBCDomainList -->
+<sqlDefs name="org.apache.james.domain.JDBCDomainList">
+ <sql name="selectDomains">select distinct domain from ${table} </sql>
+
+ <sql name="selectDomain">select distinct domain from ${table} where domain = ? </sql>
+</sqlDefs>
</sqlResources>
Modified: james/server/trunk/src/java/org/apache/james/domain/AbstractDomainList.java
URL: http://svn.apache.org/viewvc/james/server/trunk/src/java/org/apache/james/domain/AbstractDomainList.java?view=diff&rev=466098&r1=466097&r2=466098
==============================================================================
--- james/server/trunk/src/java/org/apache/james/domain/AbstractDomainList.java (original)
+++ james/server/trunk/src/java/org/apache/james/domain/AbstractDomainList.java Fri Oct 20 05:59:26 2006
@@ -34,6 +34,9 @@
import org.apache.james.services.DNSServer;
import org.apache.james.services.DomainList;
+/**
+ * All implementations of the DomainList interface should extends this abstract class
+ */
public abstract class AbstractDomainList extends AbstractLogEnabled implements Serviceable, DomainList {
DNSServer dns;
@@ -50,12 +53,16 @@
*/
public List getDomains() {
List domains = getInternalDomainList();
- if (getLogger().isInfoEnabled()) {
- for (Iterator i = domains.iterator(); i.hasNext(); ) {
- getLogger().info("Handling mail for: " + i.next());
- }
- }
- return domains;
+ if (domains != null) {
+ if (getLogger().isInfoEnabled()) {
+ for (Iterator i = domains.iterator(); i.hasNext(); ) {
+ getLogger().info("Handling mail for: " + i.next());
+ }
+ }
+ return domains;
+ } else {
+ return null;
+ }
}
/**
Added: james/server/trunk/src/java/org/apache/james/domain/JDBCDomainList.java
URL: http://svn.apache.org/viewvc/james/server/trunk/src/java/org/apache/james/domain/JDBCDomainList.java?view=auto&rev=466098
==============================================================================
--- james/server/trunk/src/java/org/apache/james/domain/JDBCDomainList.java (added)
+++ james/server/trunk/src/java/org/apache/james/domain/JDBCDomainList.java Fri Oct 20 05:59:26 2006
@@ -0,0 +1,306 @@
+/****************************************************************
+ * 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.io.File;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.avalon.cornerstone.services.datasources.DataSourceSelector;
+import org.apache.avalon.excalibur.datasource.DataSourceComponent;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.james.services.FileSystem;
+import org.apache.james.util.JDBCUtil;
+import org.apache.james.util.SqlResources;
+
+/**
+ * Allow to query a costum table for domains
+ */
+public class JDBCDomainList extends AbstractDomainList implements Serviceable,Configurable,Initializable {
+
+ private DataSourceSelector datasources;
+ private DataSourceComponent dataSourceComponent;
+ private FileSystem fileSystem;
+
+ private String tableName = null;
+ private String dataSourceName = null;
+
+ /**
+ * Contains all of the sql strings for this component.
+ */
+ protected SqlResources sqlQueries;
+
+ /**
+ * The name of the SQL configuration file to be used to configure this repository.
+ */
+ private String sqlFileName;
+
+ protected String datasourceName;
+
+ /**
+ * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+ */
+ public void service(ServiceManager arg0) throws ServiceException {
+ super.service(arg0);
+ datasources = (DataSourceSelector)arg0.lookup(DataSourceSelector.ROLE);
+ setFileSystem((FileSystem) arg0.lookup(FileSystem.ROLE));
+ }
+
+ /**
+ * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
+ */
+ public void configure(Configuration arg0) throws ConfigurationException {
+ Configuration config = arg0.getChild("repositoryPath");
+
+ if (config == null) {
+ throw new ConfigurationException("RepositoryPath must configured");
+ }
+
+ String destination = config.getValue();
+ // normalize the destination, to simplify processing.
+ if ( ! destination.endsWith("/") ) {
+ destination += "/";
+ }
+ // Parse the DestinationURL for the name of the datasource,
+ // the table to use, and the (optional) repository Key.
+ // Split on "/", starting after "db://"
+ List urlParams = new ArrayList();
+ int start = 5;
+
+ int end = destination.indexOf('/', start);
+ while ( end > -1 ) {
+ urlParams.add(destination.substring(start, end));
+ start = end + 1;
+ end = destination.indexOf('/', start);
+ }
+ System.err.println("SIZE; " + urlParams.size());
+
+ // Build SqlParameters and get datasource name from URL parameters
+ if (urlParams.size() != 2) {
+ StringBuffer exceptionBuffer =
+ new StringBuffer(256)
+ .append("Malformed destinationURL - Must be of the format '")
+ .append("db://<data-source>/<table>'. Was passed ")
+ .append(arg0.getAttribute("repositoryPath"));
+ throw new ConfigurationException(exceptionBuffer.toString());
+ }
+ dataSourceName = (String)urlParams.get(0);
+ tableName = (String)urlParams.get(1);
+
+
+ if (getLogger().isDebugEnabled()) {
+ StringBuffer logBuffer =
+ new StringBuffer(128)
+ .append("Parsed URL: table = '")
+ .append(tableName)
+ .append("'");
+ getLogger().debug(logBuffer.toString());
+ }
+
+ sqlFileName = arg0.getChild("sqlFile").getValue();
+ if (!sqlFileName.startsWith("file://")) {
+ throw new ConfigurationException
+ ("Malformed sqlFile - Must be of the format 'file://<filename>'.");
+ }
+ }
+
+ /**
+ * @see org.apache.avalon.framework.activity.Initializable#initialize()
+ */
+ public void initialize() throws Exception {
+
+ setDataSourceComponent((DataSourceComponent) datasources.select(dataSourceName));
+
+ StringBuffer logBuffer = null;
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug(this.getClass().getName() + ".initialize()");
+ }
+
+ // Test the connection to the database, by getting the DatabaseMetaData.
+ Connection conn = dataSourceComponent.getConnection();
+ PreparedStatement createStatement = null;
+
+ try {
+ // Initialise the sql strings.
+
+ File sqlFile = null;
+ try {
+ sqlFile = fileSystem.getFile(sqlFileName);
+ sqlFileName = null;
+ } catch (Exception e) {
+ getLogger().fatalError(e.getMessage(), e);
+ throw e;
+ }
+
+ if (getLogger().isDebugEnabled()) {
+ logBuffer =
+ new StringBuffer(128)
+ .append("Reading SQL resources from file: ")
+ .append(sqlFile.getAbsolutePath())
+ .append(", section ")
+ .append(this.getClass().getName())
+ .append(".");
+ getLogger().debug(logBuffer.toString());
+ }
+
+ // Build the statement parameters
+ Map sqlParameters = new HashMap();
+ if (tableName != null) {
+ sqlParameters.put("table", tableName);
+ }
+
+ sqlQueries = new SqlResources();
+ sqlQueries.init(sqlFile, this.getClass().getName(),
+ conn, sqlParameters);
+
+ // Check if the required table exists. If not, create it.
+ DatabaseMetaData dbMetaData = conn.getMetaData();
+ // Need to ask in the case that identifiers are stored, ask the DatabaseMetaInfo.
+ // Try UPPER, lower, and MixedCase, to see if the table is there.
+
+ if (!(theJDBCUtil.tableExists(dbMetaData, tableName))) {
+
+ // Users table doesn't exist - create it.
+ createStatement =
+ conn.prepareStatement(sqlQueries.getSqlString("createTable", true));
+ createStatement.execute();
+
+ if (getLogger().isInfoEnabled()) {
+ logBuffer =
+ new StringBuffer(64)
+ .append("JdbcVirtalUserTable: Created table '")
+ .append(tableName)
+ .append("'.");
+ getLogger().info(logBuffer.toString());
+ }
+ }
+
+
+ } finally {
+ theJDBCUtil.closeJDBCStatement(createStatement);
+ theJDBCUtil.closeJDBCConnection(conn);
+ }
+ }
+
+ /**
+ * The JDBCUtil helper class
+ */
+ private final JDBCUtil theJDBCUtil = new JDBCUtil() {
+ protected void delegatedLog(String logString) {
+ getLogger().debug("JDBCVirtualUserTable: " + logString);
+ }
+ };
+
+ public void setDataSourceComponent(DataSourceComponent dataSourceComponent) {
+ this.dataSourceComponent = dataSourceComponent;
+ }
+
+
+ public void setFileSystem(FileSystem fileSystem) {
+ this.fileSystem = fileSystem;
+ }
+
+
+
+
+ /**
+ * @see org.apache.james.domain.AbstractDomainList#getInternalDomainList()
+ */
+ protected List getInternalDomainList() {
+ List domains = new ArrayList();
+ Connection conn = null;
+ PreparedStatement mappingStmt = null;
+
+ try {
+ conn = dataSourceComponent.getConnection();
+ mappingStmt = conn.prepareStatement(sqlQueries.getSqlString("selectDomains", true));
+
+ ResultSet mappingRS = null;
+ try {
+ mappingRS = mappingStmt.executeQuery();
+ while (mappingRS.next()) {
+ String domain = mappingRS.getString(1).toLowerCase();
+ if(domains.contains(domains) == false) {
+ domains.add(domain);
+ }
+ }
+ } finally {
+ theJDBCUtil.closeJDBCResultSet(mappingRS);
+ }
+
+ } catch (SQLException sqle) {
+ getLogger().error("Error accessing database", sqle);
+ } finally {
+ theJDBCUtil.closeJDBCStatement(mappingStmt);
+ theJDBCUtil.closeJDBCConnection(conn);
+ }
+ if (domains.size() == 0) {
+ return null;
+ } else {
+ return domains;
+ }
+ }
+
+ /**
+ * @see org.apache.james.services.DomainList#containsDomain(java.lang.String)
+ */
+ public boolean containsDomain(String domain) {
+ Connection conn = null;
+ PreparedStatement mappingStmt = null;
+
+ try {
+ conn = dataSourceComponent.getConnection();
+ mappingStmt = conn.prepareStatement(sqlQueries.getSqlString("selectDomain", true));
+
+ ResultSet mappingRS = null;
+ try {
+ mappingStmt.setString(1, domain);
+ mappingRS = mappingStmt.executeQuery();
+ if (mappingRS.next()) {
+ return true;
+ }
+ } finally {
+ theJDBCUtil.closeJDBCResultSet(mappingRS);
+ }
+
+ } catch (SQLException sqle) {
+ getLogger().error("Error accessing database", sqle);
+ } finally {
+ theJDBCUtil.closeJDBCStatement(mappingStmt);
+ theJDBCUtil.closeJDBCConnection(conn);
+ }
+ return false;
+ }
+}
Propchange: james/server/trunk/src/java/org/apache/james/domain/JDBCDomainList.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: james/server/trunk/src/java/org/apache/james/domain/JDBCDomainList.xinfo
URL: http://svn.apache.org/viewvc/james/server/trunk/src/java/org/apache/james/domain/JDBCDomainList.xinfo?view=auto&rev=466098
==============================================================================
--- james/server/trunk/src/java/org/apache/james/domain/JDBCDomainList.xinfo (added)
+++ james/server/trunk/src/java/org/apache/james/domain/JDBCDomainList.xinfo Fri Oct 20 05:59:26 2006
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+
+<blockinfo>
+
+ <!-- section to describe block -->
+ <block>
+ <version>1.0</version>
+ </block>
+
+ <services>
+ <service name="org.apache.james.services.DomainList" version="1.0" />
+ </services>
+
+ <dependencies>
+ <dependency>
+ <service name="org.apache.james.services.DNSServer" version="1.0"/>
+ </dependency>
+ <dependency>
+ <service name="org.apache.avalon.cornerstone.services.datasources.DataSourceSelector" version="1.0"/>
+ </dependency>
+ <dependency>
+ <service name="org.apache.james.services.FileSystem" version="1.0"/>
+ </dependency>
+ </dependencies>
+</blockinfo>
Modified: james/server/trunk/src/java/org/apache/james/vut/JDBCVirtualUserTable.java
URL: http://svn.apache.org/viewvc/james/server/trunk/src/java/org/apache/james/vut/JDBCVirtualUserTable.java?view=diff&rev=466098&r1=466097&r2=466098
==============================================================================
--- james/server/trunk/src/java/org/apache/james/vut/JDBCVirtualUserTable.java (original)
+++ james/server/trunk/src/java/org/apache/james/vut/JDBCVirtualUserTable.java Fri Oct 20 05:59:26 2006
@@ -117,7 +117,7 @@
new StringBuffer(256)
.append("Malformed destinationURL - Must be of the format '")
.append("db://<data-source>'. Was passed ")
- .append(arg0.getAttribute("destinationURL"));
+ .append(arg0.getAttribute("repositoryPath"));
throw new ConfigurationException(exceptionBuffer.toString());
}
if (urlParams.size() >= 1) {
@@ -199,7 +199,7 @@
// Try UPPER, lower, and MixedCase, to see if the table is there.
if (!(theJDBCUtil.tableExists(dbMetaData, tableName))) {
-
+
// Users table doesn't exist - create it.
createStatement =
conn.prepareStatement(sqlQueries.getSqlString("createTable", true));
Added: james/server/trunk/src/test/org/apache/james/domain/JDBCDomainListTest.java
URL: http://svn.apache.org/viewvc/james/server/trunk/src/test/org/apache/james/domain/JDBCDomainListTest.java?view=auto&rev=466098
==============================================================================
--- james/server/trunk/src/test/org/apache/james/domain/JDBCDomainListTest.java (added)
+++ james/server/trunk/src/test/org/apache/james/domain/JDBCDomainListTest.java Fri Oct 20 05:59:26 2006
@@ -0,0 +1,176 @@
+/****************************************************************
+ * 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.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import junit.framework.TestCase;
+
+import org.apache.avalon.cornerstone.services.datasources.DataSourceSelector;
+import org.apache.avalon.excalibur.datasource.DataSourceComponent;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.configuration.DefaultConfiguration;
+import org.apache.avalon.framework.container.ContainerUtil;
+import org.apache.avalon.framework.service.DefaultServiceManager;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.james.services.AbstractDNSServer;
+import org.apache.james.services.DNSServer;
+import org.apache.james.services.FileSystem;
+import org.apache.james.test.mock.avalon.MockLogger;
+import org.apache.james.test.mock.avalon.MockServiceManager;
+import org.apache.james.test.mock.james.MockFileSystem;
+import org.apache.james.test.mock.util.AttrValConfiguration;
+import org.apache.james.test.util.Util;
+import org.apache.james.util.JDBCUtil;
+
+public class JDBCDomainListTest extends TestCase {
+ private String repos = "db://maildb/";
+ private String table = "costumTable";
+ private DataSourceSelector dataSource;
+ private DataSourceComponent data;
+
+ public void setUp() throws Exception {
+ dataSource = Util.getDataSourceSelector();
+ data = (DataSourceComponent) dataSource.select("maildb");
+
+ sqlQuery("create table " + table + " (domain VARCHAR (255))");
+ }
+
+ public void tearDown() throws Exception {
+ sqlQuery("drop table " + table);
+ }
+
+ private boolean sqlQuery(String query){
+ Connection conn = null;
+ PreparedStatement mappingStmt = null;
+
+ try {
+ conn = data.getConnection();
+ mappingStmt = conn.prepareStatement(query);
+
+ ResultSet mappingRS = null;
+ try {
+
+ if(mappingStmt.executeUpdate() >0) {
+ return true;
+ }
+ } finally {
+ theJDBCUtil.closeJDBCResultSet(mappingRS);
+ }
+ } catch (SQLException e) {
+ System.err.println(e.getMessage());
+ } finally {
+ theJDBCUtil.closeJDBCStatement(mappingStmt);
+ theJDBCUtil.closeJDBCConnection(conn);
+ }
+ return false;
+ }
+
+
+ private boolean addDomain(String domain) {
+ return sqlQuery("insert into " + table + " values ('" +domain + "')");
+ }
+
+ /**
+ * The JDBCUtil helper class
+ */
+ private final JDBCUtil theJDBCUtil = new JDBCUtil() {
+ protected void delegatedLog(String logString) {}
+ };
+
+ private Configuration setUpConfiguration(String url) {
+ DefaultConfiguration configuration = new DefaultConfiguration("test");
+ DefaultConfiguration reposConf = new DefaultConfiguration("repositoryPath");
+ reposConf.setValue(url);
+ configuration.addChild(reposConf);
+
+ DefaultConfiguration sqlConf = new DefaultConfiguration("sqlFile");
+ sqlConf.setValue("file://conf/sqlResources.xml");
+ configuration.addChild(sqlConf);
+
+ return configuration;
+ }
+
+ private DNSServer setUpDNSServer(final String hostName) {
+ DNSServer 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")};
+ }
+ };
+ return dns;
+ }
+
+ private MockServiceManager setUpServiceManager(DNSServer dns) throws Exception {
+ MockServiceManager service = new MockServiceManager();
+ service.put(DNSServer.ROLE, dns);
+ service.put(FileSystem.ROLE, new MockFileSystem());
+ service.put(DataSourceSelector.ROLE, dataSource);
+ return service;
+ }
+
+ public void testGetDomains() throws Exception {
+ addDomain("domain1.");
+
+ JDBCDomainList dom = new JDBCDomainList();
+ ContainerUtil.enableLogging(dom,new MockLogger());
+ dom.service(setUpServiceManager(setUpDNSServer("localhost")));
+ dom.configure(setUpConfiguration(repos + table));
+ dom.initialize();
+
+ assertTrue("One domain found",dom.getDomains().size() ==1);
+ }
+
+
+ public void testThrowConfigurationException() throws Exception {
+ boolean exception = false;
+ boolean exception2 = false;
+ JDBCDomainList dom = new JDBCDomainList();
+ ContainerUtil.enableLogging(dom,new MockLogger());
+ dom.service(setUpServiceManager(setUpDNSServer("localhost")));
+ try {
+ dom.configure(new DefaultConfiguration("invalid"));
+ dom.initialize();
+ } catch (ConfigurationException e) {
+ exception = true;
+ }
+
+ assertTrue("Exception thrown",exception);
+
+ try {
+ dom.configure(setUpConfiguration(null));
+ } catch (ConfigurationException e) {
+ exception2 = true;
+ }
+
+ assertTrue("Exception thrown",exception2);
+ }
+}
Propchange: james/server/trunk/src/test/org/apache/james/domain/JDBCDomainListTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: james/server/trunk/src/test/org/apache/james/domain/XMLDomainListTest.java
URL: http://svn.apache.org/viewvc/james/server/trunk/src/test/org/apache/james/domain/XMLDomainListTest.java?view=diff&rev=466098&r1=466097&r2=466098
==============================================================================
--- james/server/trunk/src/test/org/apache/james/domain/XMLDomainListTest.java (original)
+++ james/server/trunk/src/test/org/apache/james/domain/XMLDomainListTest.java Fri Oct 20 05:59:26 2006
@@ -64,8 +64,7 @@
}
public InetAddress[] getAllByName(String name) throws UnknownHostException {
- return new InetAddress[] { InetAddress.getByName("127.0.0.1")};
-
+ return new InetAddress[] { InetAddress.getByName("127.0.0.1")};
}
};
return dns;
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org