Author: norman
Date: Thu Oct 1 14:06:57 2009
New Revision: 820664
URL: http://svn.apache.org/viewvc?rev=820664&view=rev
Log:
Massiv refactoring:
* use loaderservice for pop3server to inject stuff
* Share code between SMTPServer and POP3Server (packaging is sub-optimal atm)
* use same pattern in pop3server as in smtpserver
Added:
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/AbstractCommandDispatcher.java
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/AbstractHandlerChain.java
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/CommonCommandHandler.java
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/ExtensibleHandler.java
- copied, changed from r819454,
james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/ExtensibleHandler.java
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/HandlersPackage.java
- copied, changed from r819454,
james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/HandlersPackage.java
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/WiringException.java
- copied, changed from r819454,
james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/WiringException.java
Added:
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/AbstractCommandDispatcher.java
URL:
http://svn.apache.org/viewvc/james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/AbstractCommandDispatcher.java?rev=820664&view=auto
==============================================================================
---
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/AbstractCommandDispatcher.java
(added)
+++
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/AbstractCommandDispatcher.java
Thu Oct 1 14:06:57 2009
@@ -0,0 +1,115 @@
+package org.apache.james.socket;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+
+import org.apache.commons.logging.Log;
+
+public abstract class AbstractCommandDispatcher<CommandHandler extends
CommonCommandHandler> implements ExtensibleHandler {
+ /**
+ * The list of available command handlers
+ */
+ private HashMap<String, List<CommandHandler>> commandHandlerMap = new
HashMap<String, List<CommandHandler>>();
+
+ /**
+ * Add it to map (key as command name, value is an array list of
CommandHandlers)
+ *
+ * @param commandName the command name which will be key
+ * @param cmdHandler The CommandHandler object
+ */
+ protected void addToMap(String commandName, CommandHandler cmdHandler) {
+ List<CommandHandler> handlers = commandHandlerMap.get(commandName);
+ if(handlers == null) {
+ handlers = new ArrayList<CommandHandler>();
+ commandHandlerMap.put(commandName, handlers);
+ }
+ handlers.add(cmdHandler);
+ }
+
+
+ /**
+ * Returns all the configured CommandHandlers for the specified command
+ *
+ * @param command the command name which will be key
+ * @param session not null
+ * @return List of CommandHandlers
+ */
+ protected List<CommandHandler> getCommandHandlers(String command,
TLSSupportedSession session) {
+ if (command == null) {
+ return null;
+ }
+ if (session.getLogger().isDebugEnabled()) {
+ session.getLogger().debug("Lookup command handler for command: " +
command);
+ }
+ List<CommandHandler> handlers = commandHandlerMap.get(command);
+ if(handlers == null) {
+ handlers =
commandHandlerMap.get(getUnknownCommandHandlerIdentifier());
+ }
+
+ return handlers;
+ }
+
+ /**
+ * @throws WiringException
+ * @see
org.apache.james.socket.ExtensibleHandler#wireExtensions(java.lang.Class,
java.util.List)
+ */
+ @SuppressWarnings("unchecked")
+ public void wireExtensions(Class interfaceName, List extension) throws
WiringException {
+ this.commandHandlerMap = new HashMap<String, List<CommandHandler>>();
+
+ for (Iterator it = extension.iterator(); it.hasNext(); ) {
+ CommandHandler handler = (CommandHandler) it.next();
+ Collection implCmds = handler.getImplCommands();
+
+ for (Iterator i = implCmds.iterator(); i.hasNext(); ) {
+ String commandName = ((String)
i.next()).trim().toUpperCase(Locale.US);
+ /*
+ if (getLog().isInfoEnabled()) {
+ getLog().info(
+ "Added Commandhandler: " + handler.getClass() + "
for command "+commandName);
+ }
+ */
+ addToMap(commandName, (CommandHandler) handler);
+ }
+ }
+
+ addToMap(getUnknownCommandHandlerIdentifier(),
getUnknownCommandHandler());
+
+ if (commandHandlerMap.size() < 2) {
+ if (getLog().isErrorEnabled()) {
+ getLog().error("No commandhandlers configured");
+ }
+ throw new WiringException("No commandhandlers configured");
+ } else {
+ boolean found = true;
+ List<String> mandatoryCommands = getMandatoryCommands();
+ for (int i = 0; i < mandatoryCommands.size(); i++) {
+ if (!commandHandlerMap.containsKey(mandatoryCommands.get(i))) {
+ if (getLog().isErrorEnabled()) {
+ getLog().error(
+ "No commandhandlers configured for the
command:"
+ + mandatoryCommands.get(i));
+ }
+ found = false;
+ break;
+ }
+ }
+
+ if (!found) {
+ throw new WiringException(
+ "No commandhandlers configured for mandatory
commands");
+ }
+
+
+ }
+
+ }
+ protected abstract Log getLog();
+ protected abstract List<String> getMandatoryCommands();
+ protected abstract String getUnknownCommandHandlerIdentifier();
+ protected abstract CommandHandler getUnknownCommandHandler();
+}
Added:
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/AbstractHandlerChain.java
URL:
http://svn.apache.org/viewvc/james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/AbstractHandlerChain.java?rev=820664&view=auto
==============================================================================
---
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/AbstractHandlerChain.java
(added)
+++
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/AbstractHandlerChain.java
Thu Oct 1 14:06:57 2009
@@ -0,0 +1,211 @@
+/****************************************************************
+ * 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.socket;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.annotation.Resource;
+
+import org.apache.commons.configuration.BaseConfiguration;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.HierarchicalConfiguration;
+import org.apache.commons.logging.Log;
+import org.apache.james.api.kernel.LoaderService;
+
+public abstract class AbstractHandlerChain {
+ protected final List<Object> handlers = new LinkedList<Object>();
+
+ /** Loads instances */
+ private LoaderService loader;
+
+ protected HierarchicalConfiguration commonsConf;
+
+
+ /**
+ * Gets the current instance loader.
+ * @return the loader
+ */
+ public final LoaderService getLoader() {
+ return loader;
+ }
+
+ /**
+ * Sets the loader to be used for instances.
+ * @param loader the loader to set, not null
+ */
+ @Resource(name="org.apache.james.LoaderService")
+ public final void setLoader(LoaderService loader) {
+ this.loader = loader;
+ }
+
+
+ /**
+ * ExtensibleHandler wiring
+ *
+ * @throws WiringException
+ */
+ protected void wireExtensibleHandlers() throws WiringException {
+ for (Iterator<?> h = handlers.iterator(); h.hasNext(); ) {
+ Object handler = h.next();
+ if (handler instanceof ExtensibleHandler) {
+ final ExtensibleHandler extensibleHandler =
(ExtensibleHandler) handler;
+ final List<Class<?>> markerInterfaces =
extensibleHandler.getMarkerInterfaces();
+ for (int i= 0;i < markerInterfaces.size(); i++) {
+ final Class<?> markerInterface = markerInterfaces.get(i);
+ final List<?> extensions = getHandlers(markerInterface);
+
extensibleHandler.wireExtensions(markerInterface,extensions);
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Load and add the classes to the handler map
+ *
+ * @param classLoader The classLoader to use
+ * @param className The class name
+ * @param config The configuration
+ * @throws ConfigurationException Get thrown on error
+ */
+ protected void loadClass(ClassLoader classLoader, String className,
+ org.apache.commons.configuration.Configuration config) throws
Exception {
+ final Class<?> handlerClass = classLoader.loadClass(className);
+ Object handler = loader.load(handlerClass);
+
+ // enable logging
+ if (handler instanceof LogEnabled) {
+ ((LogEnabled) handler).setLog(getLog());
+ }
+
+ // configure the handler
+ if (handler instanceof
org.apache.james.socket.configuration.Configurable) {
+ org.apache.james.socket.configuration.Configurable
configurableHandler = (org.apache.james.socket.configuration.Configurable)
handler;
+ configurableHandler.configure(config);
+ }
+
+ // if it is a commands handler add it to the map with key as command
+ // name
+ if (handler instanceof HandlersPackage) {
+ List<String> c = ((HandlersPackage) handler).getHandlers();
+
+ for (Iterator<String> i = c.iterator(); i.hasNext(); ) {
+ String cName = i.next();
+
+ Configuration cmdConf = addHandler(cName);
+
+ loadClass(classLoader, cName, cmdConf);
+ }
+
+ }
+
+ if (getLog().isInfoEnabled()) {
+ getLog().info("Added Handler: " + className);
+ }
+
+ // fill the big handler table
+ handlers.add(handler);
+ }
+
+ /**
+ * Return a DefaultConfiguration build on the given command name and
classname
+ *
+ * @param cmdName The command name
+ * @param className The class name
+ * @return DefaultConfiguration
+ * @throws ConfigurationException
+ */
+ protected Configuration addHandler(String className) throws
ConfigurationException {
+ Configuration hConf = new BaseConfiguration();
+ hConf.addProperty("handler/@class", className);
+ return hConf;
+ }
+
+
+ /**
+ * Returns a list of handler of the requested type.
+ * @param <T>
+ *
+ * @param type the type of handler we're interested in
+ * @return a List of handlers
+ */
+ @SuppressWarnings("unchecked")
+ public <T> LinkedList<T> getHandlers(Class<T> type) {
+ LinkedList<T> result = new LinkedList<T>();
+ for (Iterator<?> i = handlers.iterator(); i.hasNext(); ) {
+ Object handler = i.next();
+ if (type.isInstance(handler)) {
+ result.add((T)handler);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * loads the various handlers from the configuration
+ *
+ * @param configuration
+ * configuration under handlerchain node
+ */
+ @SuppressWarnings("unchecked")
+ protected void loadHandlers() throws Exception {
+ if (commonsConf != null) {
+ List<org.apache.commons.configuration.Configuration> children =
commonsConf.configurationsAt("handler");
+ ClassLoader classLoader =
Thread.currentThread().getContextClassLoader();
+
+ // load the configured handlers
+ if (children != null && children.isEmpty() == false) {
+
+ String coreCmdName = getCoreCmdHandlerLoader().getName();
+ // load the core handlers
+ loadClass(classLoader, coreCmdName,
+ addHandler(coreCmdName));
+
+ for (int i = 0; i < children.size(); i++) {
+ org.apache.commons.configuration.Configuration hConf =
children.get(i);
+ String className = hConf.getString("@class");
+
+ if (className != null) {
+ // ignore base handlers.
+ if (!className.equals(coreCmdName)) {
+
+ // load the handler
+ loadClass(classLoader, className, hConf);
+ }
+ }
+ }
+
+ }
+ }
+ }
+ public void configure(HierarchicalConfiguration commonsConf) throws
Exception {
+ this.commonsConf = commonsConf;
+ loadHandlers();
+ wireExtensibleHandlers();
+ }
+
+ protected abstract Class<?> getCoreCmdHandlerLoader();
+
+ protected abstract Log getLog();
+}
Added:
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/CommonCommandHandler.java
URL:
http://svn.apache.org/viewvc/james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/CommonCommandHandler.java?rev=820664&view=auto
==============================================================================
---
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/CommonCommandHandler.java
(added)
+++
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/CommonCommandHandler.java
Thu Oct 1 14:06:57 2009
@@ -0,0 +1,32 @@
+/****************************************************************
+ * 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.socket;
+
+import java.util.Collection;
+
+public interface CommonCommandHandler {
+
+ /**
+ * Return a Collection of implemented commands
+ *
+ * @return Collection which contains implemented commands
+ */
+ Collection<String> getImplCommands();
+}
Copied:
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/ExtensibleHandler.java
(from r819454,
james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/ExtensibleHandler.java)
URL:
http://svn.apache.org/viewvc/james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/ExtensibleHandler.java?p2=james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/ExtensibleHandler.java&p1=james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/ExtensibleHandler.java&r1=819454&r2=820664&rev=820664&view=diff
==============================================================================
---
james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/ExtensibleHandler.java
(original)
+++
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/ExtensibleHandler.java
Thu Oct 1 14:06:57 2009
@@ -17,10 +17,11 @@
* under the License. *
****************************************************************/
-package org.apache.james.smtpserver;
+package org.apache.james.socket;
import java.util.List;
+
/**
* Handlers extends this interface to be notified of available
* extensions of the given type.
Copied:
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/HandlersPackage.java
(from r819454,
james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/HandlersPackage.java)
URL:
http://svn.apache.org/viewvc/james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/HandlersPackage.java?p2=james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/HandlersPackage.java&p1=james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/HandlersPackage.java&r1=819454&r2=820664&rev=820664&view=diff
==============================================================================
---
james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/HandlersPackage.java
(original)
+++
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/HandlersPackage.java
Thu Oct 1 14:06:57 2009
@@ -19,7 +19,7 @@
-package org.apache.james.smtpserver;
+package org.apache.james.socket;
import java.util.List;
@@ -31,7 +31,7 @@
public interface HandlersPackage {
/**
- * Return a Map which contains a set of CommandHandlers
+ * Return a List which contains a set of CommandHandlers
*
* @return Map
*/
Copied:
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/WiringException.java
(from r819454,
james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/WiringException.java)
URL:
http://svn.apache.org/viewvc/james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/WiringException.java?p2=james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/WiringException.java&p1=james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/WiringException.java&r1=819454&r2=820664&rev=820664&view=diff
==============================================================================
---
james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/WiringException.java
(original)
+++
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/WiringException.java
Thu Oct 1 14:06:57 2009
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
-package org.apache.james.smtpserver;
+package org.apache.james.socket;
/**
* Indicates an issue prevent the successful wiring of the components
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]