From ftpserver-commits-return-114-apmail-incubator-ftpserver-commits-archive=incubator.apache.org@incubator.apache.org Sat Feb 03 21:54:04 2007 Return-Path: Delivered-To: apmail-incubator-ftpserver-commits-archive@www.apache.org Received: (qmail 71493 invoked from network); 3 Feb 2007 21:54:04 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 3 Feb 2007 21:54:04 -0000 Received: (qmail 44592 invoked by uid 500); 3 Feb 2007 21:54:10 -0000 Delivered-To: apmail-incubator-ftpserver-commits-archive@incubator.apache.org Received: (qmail 44577 invoked by uid 500); 3 Feb 2007 21:54:10 -0000 Mailing-List: contact ftpserver-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: ftpserver-dev@incubator.apache.org Delivered-To: mailing list ftpserver-commits@incubator.apache.org Received: (qmail 44565 invoked by uid 99); 3 Feb 2007 21:54:10 -0000 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 03 Feb 2007 13:54:09 -0800 Received: by eris.apache.org (Postfix, from userid 65534) id 537E31A981C; Sat, 3 Feb 2007 13:53:12 -0800 (PST) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: 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/ Date: Sat, 03 Feb 2007 21:53:11 -0000 To: ftpserver-commits@incubator.apache.org From: ngn@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20070203215312.537E31A981C@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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