You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ftpserver-commits@incubator.apache.org by ng...@apache.org on 2007/02/03 21:53:11 UTC
svn commit: r503318 - in /incubator/ftpserver/trunk/core/src:
java/org/apache/ftpserver/ java/org/apache/ftpserver/util/
test/org/apache/ftpserver/ test/org/apache/ftpserver/util/
Author: ngn
Date: Sat Feb 3 13:53:11 2007
New Revision: 503318
URL: http://svn.apache.org/viewvc?view=rev&rev=503318
Log:
Adding minimal implementation for supporting POJOs as components.
Added:
incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/Bean.java (with props)
incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/ComponentBean.java (with props)
incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/PojoBean.java (with props)
incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/util/ClassUtils.java (with props)
incubator/ftpserver/trunk/core/src/test/org/apache/ftpserver/ComponentBeanTest.java (with props)
incubator/ftpserver/trunk/core/src/test/org/apache/ftpserver/PojoBeanTest.java (with props)
incubator/ftpserver/trunk/core/src/test/org/apache/ftpserver/util/ClassUtilsTest.java (with props)
Modified:
incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/ConfigurableFtpServerContext.java
Added: incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/Bean.java
URL: http://svn.apache.org/viewvc/incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/Bean.java?view=auto&rev=503318
==============================================================================
--- incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/Bean.java (added)
+++ incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/Bean.java Sat Feb 3 13:53:11 2007
@@ -0,0 +1,31 @@
+package org.apache.ftpserver;
+
+import org.apache.commons.logging.LogFactory;
+import org.apache.ftpserver.ftplet.Component;
+import org.apache.ftpserver.ftplet.Configuration;
+
+public abstract class Bean {
+
+ public static Bean createBean(Configuration config, String defaultClass, LogFactory logFactory) throws Exception {
+ String className = config.getString("class", defaultClass);
+
+ Class clazz = Class.forName(className);
+
+ boolean isComponent = Component.class.isAssignableFrom(clazz);
+
+ if(isComponent) {
+ return new ComponentBean(config, clazz, logFactory);
+ } else {
+ return new PojoBean(config, clazz, logFactory);
+ }
+ }
+
+ public abstract Object initBean() throws Exception;
+
+ public abstract void destroyBean();
+
+ public abstract Object getBean();
+
+
+
+}
Propchange: incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/Bean.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/ComponentBean.java
URL: http://svn.apache.org/viewvc/incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/ComponentBean.java?view=auto&rev=503318
==============================================================================
--- incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/ComponentBean.java (added)
+++ incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/ComponentBean.java Sat Feb 3 13:53:11 2007
@@ -0,0 +1,37 @@
+package org.apache.ftpserver;
+
+import org.apache.commons.logging.LogFactory;
+import org.apache.ftpserver.ftplet.Component;
+import org.apache.ftpserver.ftplet.Configuration;
+
+public class ComponentBean extends Bean {
+
+ private Configuration config;
+ private Component component;
+ private LogFactory logFactory;
+ private Class clazz;
+
+ public ComponentBean(Configuration config, Class clazz, LogFactory logFactory) {
+ this.clazz = clazz;
+ this.logFactory = logFactory;
+ this.config = config;
+ }
+
+ public Object initBean() throws Exception {
+ component = (Component) clazz.newInstance();
+
+ component.setLogFactory(logFactory);
+ component.configure(config);
+ return component;
+ }
+
+ public Object getBean() {
+ return component;
+ }
+
+ public void destroyBean() {
+ component.dispose();
+ component = null;
+ }
+
+}
Propchange: incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/ComponentBean.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/ConfigurableFtpServerContext.java
URL: http://svn.apache.org/viewvc/incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/ConfigurableFtpServerContext.java?view=diff&rev=503318&r1=503317&r2=503318
==============================================================================
--- incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/ConfigurableFtpServerContext.java (original)
+++ incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/ConfigurableFtpServerContext.java Sat Feb 3 13:53:11 2007
@@ -26,7 +26,6 @@
import org.apache.commons.logging.LogFactory;
import org.apache.ftpserver.filesystem.NativeFileSystemManager;
import org.apache.ftpserver.ftplet.Authority;
-import org.apache.ftpserver.ftplet.Component;
import org.apache.ftpserver.ftplet.Configuration;
import org.apache.ftpserver.ftplet.DefaultFtpletContainer;
import org.apache.ftpserver.ftplet.FileSystemManager;
@@ -40,7 +39,6 @@
import org.apache.ftpserver.interfaces.FtpServerContext;
import org.apache.ftpserver.interfaces.IpRestrictor;
import org.apache.ftpserver.interfaces.MessageResource;
-import org.apache.ftpserver.interfaces.ServerFtpStatistics;
import org.apache.ftpserver.interfaces.SocketFactory;
import org.apache.ftpserver.iprestrictor.FileIpRestrictor;
import org.apache.ftpserver.listener.ConnectionManager;
@@ -61,16 +59,16 @@
class ConfigurableFtpServerContext implements FtpServerContext {
private LogFactory logFactory;
- private SocketFactory socketFactory;
- private DataConnectionConfig dataConConfig;
- private MessageResource messageResource;
- private ConnectionManager connectionManager;
- private IpRestrictor ipRestrictor;
- private UserManager userManager;
- private FileSystemManager fileSystemManager;
- private FtpletContainer ftpletContainer;
- private ServerFtpStatistics statistics;
- private CommandFactory commandFactory;
+ private Bean socketFactoryBean;
+ private Bean dataConConfigBean;
+ private Bean messageResourceBean;
+ private Bean connectionManagerBean;
+ private Bean ipRestrictorBean;
+ private Bean userManagerBean;
+ private Bean fileSystemManagerBean;
+ private Bean ftpletContainerBean;
+ private Bean statisticsBean;
+ private Bean commandFactoryBean;
private Log log;
@@ -96,15 +94,15 @@
log = logFactory.getInstance(ConfigurableFtpServerContext.class);
// create all the components
- socketFactory = (SocketFactory) createComponent(conf, "socket-factory", FtpSocketFactory.class.getName());
- dataConConfig = (DataConnectionConfig) createComponent(conf, "data-connection", DefaultDataConnectionConfig.class.getName());
- messageResource = (MessageResource) createComponent(conf, "message", MessageResourceImpl.class.getName());
- connectionManager = (ConnectionManager) createComponent(conf, "connection-manager", ConnectionManagerImpl.class.getName());
- ipRestrictor = (IpRestrictor) createComponent(conf, "ip-restrictor", FileIpRestrictor.class.getName());
- userManager = (UserManager) createComponent(conf, "user-manager", PropertiesUserManager.class.getName());
- fileSystemManager = (FileSystemManager) createComponent(conf, "file-system-manager", NativeFileSystemManager.class.getName());
- statistics = (ServerFtpStatistics) createComponent(conf, "statistics", FtpStatisticsImpl.class.getName());
- commandFactory = (CommandFactory) createComponent(conf, "command-factory", DefaultCommandFactory.class.getName());
+ socketFactoryBean = createComponent(conf, "socket-factory", FtpSocketFactory.class.getName());
+ dataConConfigBean = createComponent(conf, "data-connection", DefaultDataConnectionConfig.class.getName());
+ messageResourceBean = createComponent(conf, "message", MessageResourceImpl.class.getName());
+ connectionManagerBean = createComponent(conf, "connection-manager", ConnectionManagerImpl.class.getName());
+ ipRestrictorBean = createComponent(conf, "ip-restrictor", FileIpRestrictor.class.getName());
+ userManagerBean = createComponent(conf, "user-manager", PropertiesUserManager.class.getName());
+ fileSystemManagerBean = createComponent(conf, "file-system-manager", NativeFileSystemManager.class.getName());
+ statisticsBean = createComponent(conf, "statistics", FtpStatisticsImpl.class.getName());
+ commandFactoryBean = createComponent(conf, "command-factory", DefaultCommandFactory.class.getName());
// create user if necessary
boolean userCreate = conf.getBoolean("create-default-user", true);
@@ -112,9 +110,9 @@
createDefaultUsers();
}
- ftpletContainer = (FtpletContainer) createComponent(conf, "ftplet-container", DefaultFtpletContainer.class.getName());
+ ftpletContainerBean = createComponent(conf, "ftplet-container", DefaultFtpletContainer.class.getName());
- initFtplets(ftpletContainer, conf);
+ initFtplets((FtpletContainer) ftpletContainerBean.getBean(), conf);
}
catch(Exception ex) {
dispose();
@@ -168,17 +166,14 @@
/**
* Create component.
*/
- private Component createComponent(Configuration parentConfig, String configName, String defaultClass) throws Exception {
+ private Bean createComponent(Configuration parentConfig, String configName, String defaultClass) throws Exception {
// get configuration subset
Configuration conf = parentConfig.subset(configName);
- // create and configure component
- String className = conf.getString("class", defaultClass);
- Component comp = (Component)Class.forName(className).newInstance();
- comp.setLogFactory(logFactory);
- comp.configure(conf);
- return comp;
+ Bean bean = Bean.createBean(conf, defaultClass, logFactory);
+ bean.initBean();
+ return bean;
}
/**
@@ -231,91 +226,91 @@
* Get socket factory.
*/
public SocketFactory getSocketFactory() {
- return socketFactory;
+ return (SocketFactory) socketFactoryBean.getBean();
}
/**
* Get user manager.
*/
public UserManager getUserManager() {
- return userManager;
+ return (UserManager) userManagerBean.getBean();
}
/**
* Get IP restrictor.
*/
public IpRestrictor getIpRestrictor() {
- return ipRestrictor;
+ return (IpRestrictor) ipRestrictorBean.getBean();
}
/**
* Get connection manager.
*/
public ConnectionManager getConnectionManager() {
- return connectionManager;
+ return (ConnectionManager) connectionManagerBean.getBean();
}
/**
* Get file system manager.
*/
public FileSystemManager getFileSystemManager() {
- return fileSystemManager;
+ return (FileSystemManager) fileSystemManagerBean.getBean();
}
/**
* Get message resource.
*/
public MessageResource getMessageResource() {
- return messageResource;
+ return (MessageResource) messageResourceBean.getBean();
}
/**
* Get ftp statistics.
*/
public FtpStatistics getFtpStatistics() {
- return statistics;
+ return (FtpStatistics) statisticsBean.getBean();
}
/**
* Get ftplet handler.
*/
public Ftplet getFtpletContainer() {
- return ftpletContainer;
+ return (Ftplet) ftpletContainerBean.getBean();
}
/**
* Get data connection config.
*/
public DataConnectionConfig getDataConnectionConfig() {
- return dataConConfig;
+ return (DataConnectionConfig) dataConConfigBean.getBean();
}
/**
* Get the command factory.
*/
public CommandFactory getCommandFactory() {
- return commandFactory;
+ return (CommandFactory) commandFactoryBean.getBean();
}
/**
* Get server address.
*/
public InetAddress getServerAddress() {
- return socketFactory.getServerAddress();
+ return ((SocketFactory) socketFactoryBean.getBean()).getServerAddress();
}
/**
* Get server port.
*/
public int getServerPort() {
- return socketFactory.getPort();
+ return ((SocketFactory) socketFactoryBean.getBean()).getPort();
}
/**
* Get Ftplet.
*/
public Ftplet getFtplet(String name) {
- return ftpletContainer.getFtplet(name);
+ return ((FtpletContainer) ftpletContainerBean.getBean()).getFtplet(name);
}
/**
@@ -323,46 +318,36 @@
*/
public void dispose() {
- if(connectionManager != null) {
- connectionManager.dispose();
- connectionManager = null;
+ if(connectionManagerBean.getBean() != null) {
+ connectionManagerBean.destroyBean();
}
- if(dataConConfig != null) {
- dataConConfig.dispose();
- dataConConfig = null;
+ if(dataConConfigBean.getBean() != null) {
+ dataConConfigBean.destroyBean();
}
- if(ftpletContainer != null) {
- if(ftpletContainer instanceof Component) {
- ((Component)ftpletContainer).dispose();
- }
- ftpletContainer = null;
+ if(ftpletContainerBean.getBean() != null) {
+ ftpletContainerBean.destroyBean();
}
- if(userManager != null) {
- userManager.dispose();
- userManager = null;
+ if(userManagerBean.getBean() != null) {
+ userManagerBean.destroyBean();
}
- if(ipRestrictor != null) {
- ipRestrictor.dispose();
- ipRestrictor = null;
+ if(ipRestrictorBean.getBean() != null) {
+ ipRestrictorBean.destroyBean();
}
- if(fileSystemManager != null) {
- fileSystemManager.dispose();
- fileSystemManager = null;
+ if(fileSystemManagerBean.getBean() != null) {
+ fileSystemManagerBean.destroyBean();
}
- if(statistics != null) {
- statistics.dispose();
- statistics = null;
+ if(statisticsBean.getBean() != null) {
+ statisticsBean.destroyBean();
}
- if(messageResource != null) {
- messageResource.dispose();
- messageResource = null;
+ if(messageResourceBean.getBean() != null) {
+ messageResourceBean.destroyBean();
}
if(logFactory != null) {
Added: incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/PojoBean.java
URL: http://svn.apache.org/viewvc/incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/PojoBean.java?view=auto&rev=503318
==============================================================================
--- incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/PojoBean.java (added)
+++ incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/PojoBean.java Sat Feb 3 13:53:11 2007
@@ -0,0 +1,71 @@
+package org.apache.ftpserver;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.commons.logging.LogFactory;
+import org.apache.ftpserver.ftplet.Configuration;
+import org.apache.ftpserver.util.ClassUtils;
+
+public class PojoBean extends Bean {
+
+ private Configuration config;
+ private Object pojo;
+ private LogFactory logFactory;
+ private Class clazz;
+
+ public PojoBean(Configuration config, Class clazz, LogFactory logFactory) {
+ this.clazz = clazz;
+ this.logFactory = logFactory;
+ this.config = config;
+ }
+
+ public Object initBean() throws Exception {
+ pojo = ClassUtils.createBean(config, clazz.getName());
+
+ setLogFactory();
+
+ configure();
+
+ return pojo;
+
+ }
+
+ /**
+ * @throws IllegalAccessException
+ * @throws InvocationTargetException
+ */
+ private void setLogFactory() throws Exception {
+ if(logFactory == null) {
+ return;
+ }
+
+ ClassUtils.setProperty(pojo, "logFactory", logFactory);
+ }
+
+ private void configure() throws Exception {
+ String configureMethodName = config.getString("configure-method", "configure");
+
+ try {
+ ClassUtils.invokeMethod(pojo, configureMethodName);
+ } catch(RuntimeException e) {
+ // ignore
+ }
+ }
+
+ public void destroyBean() {
+ String disposeMethodName = config.getString("dispose-method", "dispose");
+
+ try {
+ ClassUtils.invokeMethod(pojo, disposeMethodName);
+
+ pojo = null;
+ } catch(Exception e) {
+ // TODO log!
+ }
+ }
+
+ public Object getBean() {
+ return pojo;
+ }
+
+}
Propchange: incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/PojoBean.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/util/ClassUtils.java
URL: http://svn.apache.org/viewvc/incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/util/ClassUtils.java?view=auto&rev=503318
==============================================================================
--- incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/util/ClassUtils.java (added)
+++ incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/util/ClassUtils.java Sat Feb 3 13:53:11 2007
@@ -0,0 +1,240 @@
+/*
+ * 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.ftpserver.util;
+
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.ftpserver.ftplet.Configuration;
+
+
+
+public class ClassUtils {
+
+ public static void setProperty(Object target, String propertyName, String propertyValue) {
+ PropertyDescriptor setter = getDescriptor(target.getClass(), propertyName);
+
+ setProperty(target, setter, propertyValue);
+ }
+
+ public static void setProperty(Object target, String propertyName, Object propertyValue) {
+ PropertyDescriptor setter = getDescriptor(target.getClass(), propertyName);
+
+ setProperty(target, setter, propertyValue);
+ }
+
+ private static void setProperty(Object target, PropertyDescriptor setter, Object castValue) {
+ Method setterMethod = setter.getWriteMethod();
+
+ if(setter != null && setterMethod != null) {
+ try {
+ setterMethod.invoke(target, new Object[]{castValue});
+ } catch (Exception e) {
+ throw new RuntimeException("Failed invoking setter " + setter.getDisplayName() + " on " + target, e);
+ }
+ } else {
+ throw new RuntimeException("Property \"" + setter.getDisplayName() + "\" is not settable on class "+ target.getClass());
+ }
+
+ }
+
+ private static void setProperty(Object target, PropertyDescriptor setter, String propertyValue) {
+ Object castValue = ClassUtils.cast(setter.getPropertyType(), propertyValue);
+
+ setProperty(target, setter, castValue);
+ }
+
+ private static PropertyDescriptor getDescriptor(Class clazz, String propertyName) {
+ BeanInfo beanInfo;
+ try {
+ beanInfo = Introspector.getBeanInfo(clazz);
+ } catch (IntrospectionException e) {
+ throw new RuntimeException("Failed to introspect class: " + clazz);
+ }
+ PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
+
+ for (int i = 0; i < propertyDescriptors.length; i++) {
+ PropertyDescriptor propertyDescriptor = propertyDescriptors[i];
+ if(propertyDescriptor.getName().equals(propertyName)) {
+ return propertyDescriptor;
+ }
+ }
+
+ return null;
+ }
+
+ public static Object createBean(Configuration config, String defaultClass) {
+ String className = config.getString("class", defaultClass);
+
+ Class clazz;
+ Object bean;
+ try {
+ clazz = Class.forName(className);
+ bean = clazz.newInstance();
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to create instance of class " + className, e);
+ }
+
+
+ Iterator keys = config.getKeys();
+
+ while (keys.hasNext()) {
+ String key = (String) keys.next();
+
+ if(key.equals("class")) {
+ continue;
+ }
+
+ Configuration subConfig = config.subset(key);
+
+ Object value;
+ PropertyDescriptor descriptor = getDescriptor(clazz, key);
+ if(subConfig.isEmpty()) {
+ // regular property
+ value = cast(descriptor.getPropertyType(), config.getString(key, null));
+ } else {
+ if(Map.class.isAssignableFrom(descriptor.getPropertyType())) {
+ Map map = new HashMap();
+
+ Iterator mapKeys = subConfig.getKeys();
+
+ while (mapKeys.hasNext()) {
+ String mapKey = (String) mapKeys.next();
+
+ map.put(mapKey, subConfig.getString(mapKey, null));
+ }
+
+ value = map;
+
+ } else {
+ // create new bean
+
+ value = createBean(subConfig, descriptor.getPropertyType().getName());
+ }
+
+ }
+
+ setProperty(bean, descriptor, value);
+ }
+
+
+ return bean;
+ }
+
+ public static void invokeMethod(Object target, String methodName) {
+ try {
+ Method destroyMethod = target.getClass().getMethod(methodName, new Class[0]);
+ destroyMethod.invoke(target, new Object[0]);
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to invoke method " + methodName + " on " + target);
+ }
+ }
+
+ public static Object cast(Class clazz, String value) {
+
+ Object castValue = null;
+ int pos;
+
+ if (clazz == String.class) {
+ castValue = value;
+ } else if (clazz == Boolean.TYPE || clazz == Boolean.class) {
+ castValue = new Boolean(value);
+ } else if (clazz == Byte.TYPE || clazz == Byte.class) {
+ castValue = new Byte(value);
+ } else if (
+ (clazz == Character.TYPE || clazz == Character.class)
+ && value.length() == 1) {
+ castValue = new Character(value.charAt(0));
+ } else if (clazz == Double.TYPE || clazz == Double.class) {
+ castValue = new Double(value);
+ } else if (clazz == Float.TYPE || clazz == Float.class) {
+ castValue = new Float(value);
+ } else if (clazz == Integer.TYPE || clazz == Integer.class) {
+ castValue = new Integer(value);
+ } else if (clazz == Long.TYPE || clazz == Long.class) {
+ castValue = new Long(value);
+ } else if (clazz == Short.TYPE || clazz == Short.class) {
+ castValue = new Short(value);
+ } else if (clazz == BigDecimal.class) {
+ castValue = new BigDecimal(value);
+ } else if (clazz == BigInteger.class) {
+ castValue = new BigInteger(value);
+ } else if(clazz.isArray()) {
+ String[] values = value.split(",");
+ Object castArray = Array.newInstance(clazz.getComponentType(), values.length);
+
+ for (int i = 0; i < values.length; i++) {
+ Array.set(castArray, i, cast(clazz.getComponentType(), values[i].trim()));
+ }
+
+ castValue = castArray;
+ } else if(clazz == List.class) {
+ List list = new ArrayList();
+ String[] values = value.split(",");
+
+ for (int i = 0; i < values.length; i++) {
+ list.add(values[i].trim());
+ }
+
+ castValue = list;
+ } else if (clazz == URL.class) {
+ try {
+ castValue = new URL(value);
+ } catch (MalformedURLException e) {
+ throw new RuntimeException("Malformed URL: " + value, e);
+ }
+ } else if (clazz == InetAddress.class) {
+ try {
+ castValue = InetAddress.getByName(value);
+ } catch (UnknownHostException e) {
+ throw new RuntimeException("Unknown host: " + value, e);
+ }
+ } else if((pos = value.lastIndexOf('.')) != -1) {
+ try {
+ Class c = Class.forName(value.substring(0, pos));
+ Field f = c.getDeclaredField(value.substring(pos+1));
+
+ castValue = f.get(null);
+ } catch (Exception ex) {
+ throw new RuntimeException("Failed to get static field value for " + value, ex);
+ }
+ } else {
+ throw new RuntimeException("Unable to cast \""+value+"\" as a "+clazz.getName());
+ }
+
+ return castValue;
+ }
+}
Propchange: incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/util/ClassUtils.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/ftpserver/trunk/core/src/test/org/apache/ftpserver/ComponentBeanTest.java
URL: http://svn.apache.org/viewvc/incubator/ftpserver/trunk/core/src/test/org/apache/ftpserver/ComponentBeanTest.java?view=auto&rev=503318
==============================================================================
--- incubator/ftpserver/trunk/core/src/test/org/apache/ftpserver/ComponentBeanTest.java (added)
+++ incubator/ftpserver/trunk/core/src/test/org/apache/ftpserver/ComponentBeanTest.java Sat Feb 3 13:53:11 2007
@@ -0,0 +1,91 @@
+/*
+ * 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.ftpserver;
+
+import java.util.Properties;
+
+import org.apache.commons.logging.LogFactory;
+import org.apache.ftpserver.config.PropertiesConfiguration;
+import org.apache.ftpserver.ftplet.Component;
+import org.apache.ftpserver.ftplet.Configuration;
+import org.apache.ftpserver.ftplet.FtpException;
+
+import junit.framework.TestCase;
+
+
+public class ComponentBeanTest extends TestCase {
+
+ public static class MockComponent implements Component {
+
+ public Configuration config;
+ public boolean disposed = false;
+ public LogFactory logFactory;
+
+ public void configure(Configuration config) throws FtpException {
+ this.config = config;
+ }
+
+ public void dispose() {
+ disposed = true;
+ }
+
+ public void setLogFactory(LogFactory logFactory) {
+ this.logFactory = logFactory;
+ }
+
+ }
+
+ public void testLifecycle() throws Exception {
+ Properties props = new Properties();
+ props.setProperty("config.class", MockComponent.class.getName());
+ props.setProperty("config.foo", "bar");
+ PropertiesConfiguration config = new PropertiesConfiguration(props);
+
+ ComponentBean bean = (ComponentBean) Bean.createBean(config, null, null);
+
+ MockComponent component = (MockComponent) bean.initBean();
+ assertEquals("bar", component.config.getString("foo"));
+ assertFalse(component.disposed);
+
+ bean.destroyBean();
+ assertTrue(component.disposed);
+ assertNull(bean.getBean());
+
+ }
+
+ public void testLifecycleDefaultClass() throws Exception {
+ Properties props = new Properties();
+ props.setProperty("config.foo", "bar");
+ PropertiesConfiguration config = new PropertiesConfiguration(props);
+
+
+ ComponentBean bean = (ComponentBean) Bean.createBean(config, MockComponent.class.getName(), null);
+
+ MockComponent component = (MockComponent) bean.initBean();
+ assertEquals("bar", component.config.getString("foo"));
+ assertFalse(component.disposed);
+
+ bean.destroyBean();
+ assertTrue(component.disposed);
+ assertNull(bean.getBean());
+
+ }
+
+}
Propchange: incubator/ftpserver/trunk/core/src/test/org/apache/ftpserver/ComponentBeanTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/ftpserver/trunk/core/src/test/org/apache/ftpserver/PojoBeanTest.java
URL: http://svn.apache.org/viewvc/incubator/ftpserver/trunk/core/src/test/org/apache/ftpserver/PojoBeanTest.java?view=auto&rev=503318
==============================================================================
--- incubator/ftpserver/trunk/core/src/test/org/apache/ftpserver/PojoBeanTest.java (added)
+++ incubator/ftpserver/trunk/core/src/test/org/apache/ftpserver/PojoBeanTest.java Sat Feb 3 13:53:11 2007
@@ -0,0 +1,107 @@
+/*
+ * 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.ftpserver;
+
+import java.util.Properties;
+
+import junit.framework.TestCase;
+
+import org.apache.commons.logging.LogFactory;
+import org.apache.ftpserver.config.PropertiesConfiguration;
+import org.apache.ftpserver.ftplet.Configuration;
+import org.apache.ftpserver.ftplet.FtpException;
+
+
+public class PojoBeanTest extends TestCase {
+
+ public static class MockPojo {
+
+ public Configuration config;
+ public boolean configured = false;
+ public boolean disposed = false;
+ public LogFactory logFactory;
+
+ public String foo;
+ public int bar;
+
+ public void setBar(int bar) {
+ this.bar = bar;
+ }
+
+ public void setFoo(String foo) {
+ this.foo = foo;
+ }
+
+ public void configure() throws FtpException {
+ logFactory.getInstance(MockPojo.class).debug("test");
+
+ configured = true;
+ }
+
+ public void dispose() {
+ disposed = true;
+ }
+
+ public void setLogFactory(LogFactory logFactory) {
+ this.logFactory = logFactory;
+ }
+ }
+
+ public void testLifecycle() throws Exception {
+ Properties props = new Properties();
+ props.setProperty("config.class", MockPojo.class.getName());
+ props.setProperty("config.foo", "hello");
+ props.setProperty("config.bar", "123");
+
+ PropertiesConfiguration config = new PropertiesConfiguration(props);
+
+ LogFactory logFactory = LogFactory.getFactory();
+
+ PojoBean bean = (PojoBean) Bean.createBean(config, null, logFactory);
+
+ MockPojo pojo = (MockPojo) bean.initBean();
+ assertEquals("hello", pojo.foo);
+ assertEquals(123, pojo.bar);
+ assertFalse(pojo.disposed);
+ assertTrue(pojo.configured);
+ assertSame(logFactory, pojo.logFactory);
+
+ bean.destroyBean();
+ assertTrue(pojo.disposed);
+ assertNull(bean.getBean());
+ }
+
+ /*public void testLifecycleDefaultClass() throws Exception {
+ Properties props = new Properties();
+ props.setProperty("config.foo", "bar");
+ PropertiesConfiguration config = new PropertiesConfiguration(props);
+
+
+ ComponentBean bean = (ComponentBean) Bean.createBean(config, MockComponent.class.getName(), null);
+
+ MockComponent component = (MockComponent) bean.initBean();
+ assertEquals("bar", component.config.getString("foo"));
+ assertFalse(component.disposed);
+
+ bean.destroyBean();
+ assertTrue(component.disposed);
+ }*/
+
+}
Propchange: incubator/ftpserver/trunk/core/src/test/org/apache/ftpserver/PojoBeanTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/ftpserver/trunk/core/src/test/org/apache/ftpserver/util/ClassUtilsTest.java
URL: http://svn.apache.org/viewvc/incubator/ftpserver/trunk/core/src/test/org/apache/ftpserver/util/ClassUtilsTest.java?view=auto&rev=503318
==============================================================================
--- incubator/ftpserver/trunk/core/src/test/org/apache/ftpserver/util/ClassUtilsTest.java (added)
+++ incubator/ftpserver/trunk/core/src/test/org/apache/ftpserver/util/ClassUtilsTest.java Sat Feb 3 13:53:11 2007
@@ -0,0 +1,379 @@
+/*
+ * 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.ftpserver.util;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.URL;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import junit.framework.TestCase;
+
+import org.apache.ftpserver.config.PropertiesConfiguration;
+import org.apache.ftpserver.ftplet.Configuration;
+
+public class ClassUtilsTest extends TestCase {
+
+ public void testSetProperty() {
+ MyBean bean = new MyBean();
+
+ ClassUtils.setProperty(bean, "foo", "flopp");
+ assertEquals("flopp", bean.getFoo());
+
+ ClassUtils.setProperty(bean, "foo", "flipp");
+ assertEquals("flipp", bean.getFoo());
+
+ ClassUtils.setProperty(bean, "bar", "123");
+
+ assertEquals(123, bean.getBar());
+ }
+
+ public void testSetPropertyWrongCast() {
+ MyBean bean = new MyBean();
+
+ try{
+ ClassUtils.setProperty(bean, "bar", "flopp");
+ fail("Must throw exception");
+ } catch(RuntimeException e) {
+ // ok
+ }
+ }
+
+ public void testSetPropertyUnknownProperty() {
+ MyBean bean = new MyBean();
+
+ try{
+ ClassUtils.setProperty(bean, "dummy", "flopp");
+ fail("Must throw exception");
+ } catch(RuntimeException e) {
+ // ok
+ }
+ }
+
+ public void testCreateSimpleBean() {
+ Properties props = new Properties();
+ props.setProperty("config.class", MyBean.class.getName());
+ props.setProperty("config.foo", "flopp");
+ props.setProperty("config.bar", "123");
+
+ Configuration config = new PropertiesConfiguration(props);
+
+ MyBean bean = (MyBean) ClassUtils.createBean(config, null);
+ assertEquals("flopp", bean.getFoo());
+ assertEquals(123, bean.getBar());
+ }
+
+ public void testCreateComplexBean() throws Exception {
+ Properties props = new Properties();
+ props.setProperty("config.class", MyOtherBean.class.getName());
+ props.setProperty("config.baz", "1.2.3.4");
+ props.setProperty("config.myBean.class", MyBean.class.getName());
+ props.setProperty("config.myBean.foo", "flopp");
+ props.setProperty("config.myBean.bar", "123");
+
+ Configuration config = new PropertiesConfiguration(props);
+
+ MyOtherBean otherBean = (MyOtherBean) ClassUtils.createBean(config, null);
+ assertEquals(InetAddress.getByName("1.2.3.4"), otherBean.getBaz());
+
+ MyBean bean = otherBean.getMyBean();
+
+ assertEquals("flopp", bean.getFoo());
+ assertEquals(123, bean.getBar());
+ }
+
+ public void testCreateComplexBeanNoClassForSubBean() throws Exception {
+ Properties props = new Properties();
+ props.setProperty("config.class", MyOtherBean.class.getName());
+ props.setProperty("config.baz", "1.2.3.4");
+ props.setProperty("config.myBean.foo", "flopp");
+ props.setProperty("config.myBean.bar", "123");
+
+ Configuration config = new PropertiesConfiguration(props);
+
+ MyOtherBean otherBean = (MyOtherBean) ClassUtils.createBean(config, null);
+ assertEquals(InetAddress.getByName("1.2.3.4"), otherBean.getBaz());
+
+ MyBean bean = otherBean.getMyBean();
+
+ assertEquals("flopp", bean.getFoo());
+ assertEquals(123, bean.getBar());
+ }
+
+ public void testCreateListBean() {
+ Properties props = new Properties();
+ props.setProperty("config.class", MyCollectionBean.class.getName());
+ props.setProperty("config.list", "foo,bar, bar, flopp ");
+
+ Configuration config = new PropertiesConfiguration(props);
+
+ MyCollectionBean bean = (MyCollectionBean) ClassUtils.createBean(config, null);
+
+ Iterator iter = bean.getList().iterator();
+
+ assertEquals("foo", iter.next());
+ assertEquals("bar", iter.next());
+ assertEquals("bar", iter.next());
+ assertEquals("flopp", iter.next());
+ assertFalse(iter.hasNext());
+ }
+
+ public void testCreateArrayBean() {
+ Properties props = new Properties();
+ props.setProperty("config.class", MyCollectionBean.class.getName());
+ props.setProperty("config.array", "1,12, 123, 1234 ");
+
+ Configuration config = new PropertiesConfiguration(props);
+
+ MyCollectionBean bean = (MyCollectionBean) ClassUtils.createBean(config, null);
+
+ int[] array = bean.getArray();
+
+ assertEquals(4, array.length);
+ assertEquals(1, array[0]);
+ assertEquals(12, array[1]);
+ assertEquals(123, array[2]);
+ assertEquals(1234, array[3]);
+ }
+
+ public void testCreateMapBean() {
+ Properties props = new Properties();
+ props.setProperty("config.class", MyMapBean.class.getName());
+ props.setProperty("config.map.foo1", "bar1");
+ props.setProperty("config.map.foo2", "bar2");
+ props.setProperty("config.map.foo3", "bar3");
+ props.setProperty("config.map.foo4", "bar4");
+
+ Configuration config = new PropertiesConfiguration(props);
+
+ MyMapBean bean = (MyMapBean) ClassUtils.createBean(config, null);
+
+ Map map = bean.getMap();
+
+ assertEquals(4, map.size());
+ assertEquals("bar1", map.get("foo1"));
+ assertEquals("bar2", map.get("foo2"));
+ assertEquals("bar3", map.get("foo3"));
+ assertEquals("bar4", map.get("foo4"));
+ }
+
+
+ /////////////////////////////////
+ // Test cast method
+ public void testCastToInt() {
+ assertEquals(new Integer(123), ClassUtils.cast(Integer.TYPE, "123"));
+ assertEquals(new Integer(123), ClassUtils.cast(Integer.class, "123"));
+
+ try {
+ ClassUtils.cast(Integer.class, "foo");
+ fail("Must throw exception");
+ } catch(NumberFormatException e) {
+ // ok
+ }
+ }
+
+ public void testCastToLong() {
+ assertEquals(new Long(123), ClassUtils.cast(Long.TYPE, "123"));
+ assertEquals(new Long(123), ClassUtils.cast(Long.class, "123"));
+
+ try {
+ ClassUtils.cast(Long.class, "foo");
+ fail("Must throw exception");
+ } catch(NumberFormatException e) {
+ // ok
+ }
+ }
+
+ public void testCastToFloat() {
+ assertEquals(new Float(123), ClassUtils.cast(Float.TYPE, "123"));
+ assertEquals(new Float(123), ClassUtils.cast(Float.class, "123"));
+ assertEquals(new Float(1.23), ClassUtils.cast(Float.TYPE, "1.23"));
+ assertEquals(new Float(1.23), ClassUtils.cast(Float.class, "1.23"));
+
+ try {
+ ClassUtils.cast(Float.class, "foo");
+ fail("Must throw exception");
+ } catch(NumberFormatException e) {
+ // ok
+ }
+ }
+
+ public void testCastToDouble() {
+ assertEquals(new Double(123), ClassUtils.cast(Double.TYPE, "123"));
+ assertEquals(new Double(123), ClassUtils.cast(Double.class, "123"));
+ assertEquals(new Double(1.23), ClassUtils.cast(Double.TYPE, "1.23"));
+ assertEquals(new Double(1.23), ClassUtils.cast(Double.class, "1.23"));
+
+ try {
+ ClassUtils.cast(Double.class, "foo");
+ fail("Must throw exception");
+ } catch(NumberFormatException e) {
+ // ok
+ }
+ }
+
+ public void testCastToByte() {
+ assertEquals(new Byte("3"), ClassUtils.cast(Byte.TYPE, "3"));
+ assertEquals(new Byte("3"), ClassUtils.cast(Byte.class, "3"));
+
+ try {
+ ClassUtils.cast(Byte.class, "foo");
+ fail("Must throw exception");
+ } catch(NumberFormatException e) {
+ // ok
+ }
+ }
+
+ public void testCastToBigDecimal() {
+ assertEquals(new BigDecimal("1.23"), ClassUtils.cast(BigDecimal.class, "1.23"));
+
+ try {
+ ClassUtils.cast(BigDecimal.class, "foo");
+ fail("Must throw exception");
+ } catch(NumberFormatException e) {
+ // ok
+ }
+ }
+
+ public void testCastToBigInteger() {
+ assertEquals(new BigInteger("123"), ClassUtils.cast(BigInteger.class, "123"));
+
+ try {
+ ClassUtils.cast(BigInteger.class, "foo");
+ fail("Must throw exception");
+ } catch(NumberFormatException e) {
+ // ok
+ }
+ }
+
+ public void testCastToChar() {
+ assertEquals(new Character('a'), ClassUtils.cast(Character.TYPE, "a"));
+ assertEquals(new Character('a'), ClassUtils.cast(Character.class, "a"));
+
+ try {
+ ClassUtils.cast(Character.class, "foo");
+ fail("Must throw exception");
+ } catch(RuntimeException e) {
+ // ok
+ }
+ }
+
+ public void testCastToBoolean() {
+ assertEquals(Boolean.TRUE, ClassUtils.cast(Boolean.TYPE, "true"));
+ assertEquals(Boolean.TRUE, ClassUtils.cast(Boolean.class, "true"));
+ assertEquals(Boolean.FALSE, ClassUtils.cast(Boolean.TYPE, "false"));
+ assertEquals(Boolean.FALSE, ClassUtils.cast(Boolean.class, "false"));
+ assertEquals(Boolean.FALSE, ClassUtils.cast(Boolean.class, "foo"));
+ }
+
+ public void testCastToURL() throws Exception {
+ assertEquals(new URL("http://localhost"), ClassUtils.cast(URL.class, "http://localhost"));
+
+ try {
+ ClassUtils.cast(URL.class, "foo://foo://foo");
+ fail("Must throw exception");
+ } catch(RuntimeException e) {
+ // ok
+ }
+ }
+
+ public void testCastToInetAddress() throws Exception {
+ assertEquals(InetAddress.getByName("localhost"), ClassUtils.cast(InetAddress.class, "localhost"));
+ assertEquals(InetAddress.getByName("1.2.3.4"), ClassUtils.cast(InetAddress.class, "1.2.3.4"));
+
+ try {
+ ClassUtils.cast(InetAddress.class, "1.2.3.4.5");
+ fail("Must throw exception");
+ } catch(RuntimeException e) {
+ // ok
+ }
+ }
+
+ public static class MyCollectionBean {
+ private List list;
+ private int[] array;
+
+ public int[] getArray() {
+ return array;
+ }
+ public void setArray(int[] array) {
+ this.array = array;
+ }
+ public List getList() {
+ return list;
+ }
+ public void setList(List list) {
+ this.list = list;
+ }
+ }
+
+ public static class MyMapBean {
+ private Map map;
+
+ public Map getMap() {
+ return map;
+ }
+
+ public void setMap(Map map) {
+ this.map = map;
+ }
+
+ }
+
+ public static class MyBean {
+ private String foo;
+ private int bar;
+
+ public int getBar() {
+ return bar;
+ }
+ public void setBar(int bar) {
+ this.bar = bar;
+ }
+ public String getFoo() {
+ return foo;
+ }
+ public void setFoo(String foo) {
+ this.foo = foo;
+ }
+ }
+
+ public static class MyOtherBean {
+ private MyBean myBean;
+ private InetAddress baz;
+ public InetAddress getBaz() {
+ return baz;
+ }
+ public void setBaz(InetAddress baz) {
+ this.baz = baz;
+ }
+ public MyBean getMyBean() {
+ return myBean;
+ }
+ public void setMyBean(MyBean myBean) {
+ this.myBean = myBean;
+ }
+ }
+
+}
\ No newline at end of file
Propchange: incubator/ftpserver/trunk/core/src/test/org/apache/ftpserver/util/ClassUtilsTest.java
------------------------------------------------------------------------------
svn:eol-style = native