Author: ngn
Date: Mon Jul 14 14:05:03 2008
New Revision: 676733
URL: http://svn.apache.org/viewvc?rev=676733&view=rev
Log:
Moving deprecated classes to the server module and renaming to to
ftpserver-deprecated. These will be dropped in M3
Added:
mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/Bean.java
(with props)
mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/ComponentBean.java
(with props)
mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/ConfigurableFtpServerContext.java
(with props)
mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/PojoBean.java
(with props)
mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/ftplet/EmptyConfiguration.java
(with props)
mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/util/
mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/util/ConfigurationClassUtils.java
(with props)
Added: mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/Bean.java
URL:
http://svn.apache.org/viewvc/mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/Bean.java?rev=676733&view=auto
==============================================================================
--- mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/Bean.java
(added)
+++ mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/Bean.java
Mon Jul 14 14:05:03 2008
@@ -0,0 +1,48 @@
+/*
+ * 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 org.apache.ftpserver.ftplet.Component;
+import org.apache.ftpserver.ftplet.Configuration;
+
+public abstract class Bean {
+
+ @SuppressWarnings("unchecked")
+ public static Bean createBean(Configuration config, String defaultClass)
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, (Class<Component>) clazz);
+ } else {
+ return new PojoBean(config, (Class<Object>) clazz);
+ }
+ }
+
+ public abstract Object initBean() throws Exception;
+
+ public abstract void destroyBean();
+
+ public abstract Object getBean();
+
+}
Propchange:
mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/Bean.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added:
mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/ComponentBean.java
URL:
http://svn.apache.org/viewvc/mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/ComponentBean.java?rev=676733&view=auto
==============================================================================
---
mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/ComponentBean.java
(added)
+++
mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/ComponentBean.java
Mon Jul 14 14:05:03 2008
@@ -0,0 +1,52 @@
+/*
+ * 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 org.apache.ftpserver.ftplet.Component;
+import org.apache.ftpserver.ftplet.Configuration;
+
+public class ComponentBean extends Bean {
+
+ private Configuration config;
+ private Component component;
+ private Class<Component> clazz;
+
+ public ComponentBean(Configuration config, Class<Component> clazz) {
+ this.clazz = clazz;
+ this.config = config;
+ }
+
+ public Object initBean() throws Exception {
+ component = clazz.newInstance();
+
+ component.configure(config);
+ return component;
+ }
+
+ public Object getBean() {
+ return component;
+ }
+
+ public void destroyBean() {
+ component.dispose();
+ component = null;
+ }
+
+}
Propchange:
mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/ComponentBean.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added:
mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/ConfigurableFtpServerContext.java
URL:
http://svn.apache.org/viewvc/mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/ConfigurableFtpServerContext.java?rev=676733&view=auto
==============================================================================
---
mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/ConfigurableFtpServerContext.java
(added)
+++
mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/ConfigurableFtpServerContext.java
Mon Jul 14 14:05:03 2008
@@ -0,0 +1,336 @@
+/*
+ * 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.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.Map.Entry;
+
+import org.apache.ftpserver.filesystem.NativeFileSystemManager;
+import org.apache.ftpserver.ftplet.Authority;
+import org.apache.ftpserver.ftplet.Configuration;
+import org.apache.ftpserver.ftplet.DefaultFtplet;
+import org.apache.ftpserver.ftplet.DefaultFtpletContainer;
+import org.apache.ftpserver.ftplet.FileSystemManager;
+import org.apache.ftpserver.ftplet.FtpException;
+import org.apache.ftpserver.ftplet.FtpStatistics;
+import org.apache.ftpserver.ftplet.Ftplet;
+import org.apache.ftpserver.ftplet.FtpletContainer;
+import org.apache.ftpserver.ftplet.UserManager;
+import org.apache.ftpserver.interfaces.CommandFactory;
+import org.apache.ftpserver.interfaces.FtpServerContext;
+import org.apache.ftpserver.interfaces.MessageResource;
+import org.apache.ftpserver.listener.Listener;
+import org.apache.ftpserver.listener.nio.NioListener;
+import org.apache.ftpserver.message.MessageResourceImpl;
+import org.apache.ftpserver.usermanager.BaseUser;
+import org.apache.ftpserver.usermanager.ConcurrentLoginPermission;
+import org.apache.ftpserver.usermanager.PropertiesUserManager;
+import org.apache.ftpserver.usermanager.TransferRatePermission;
+import org.apache.ftpserver.usermanager.WritePermission;
+import org.apache.ftpserver.util.ConfigurationClassUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * FTP server configuration implementation. It holds all
+ * the components used.
+ */
+public class ConfigurableFtpServerContext implements FtpServerContext {
+
+ private final Logger LOG =
LoggerFactory.getLogger(ConfigurableFtpServerContext.class);
+
+ private Bean messageResourceBean;
+ private Bean userManagerBean;
+ private Bean fileSystemManagerBean;
+ private Bean ftpletContainerBean;
+ private Bean statisticsBean;
+ private Bean commandFactoryBean;
+ private Bean connectionConfigBean;
+
+ private Map<String, Bean> listeners = new HashMap<String, Bean>();
+
+
+ private static final Authority[] ADMIN_AUTHORITIES = new Authority[]{
+ new WritePermission()
+ };
+
+ private static final Authority[] ANON_AUTHORITIES = new Authority[]{
+ new ConcurrentLoginPermission(20, 2),
+ new TransferRatePermission(4800, 4800)
+ };
+
+ /**
+ * Constructor - set the root configuration.
+ */
+ public ConfigurableFtpServerContext(Configuration conf) throws Exception {
+
+ try {
+
+ listeners = createListeners(conf, "listeners");
+
+ // create all the components
+ messageResourceBean = createComponent(conf, "message",
MessageResourceImpl.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());
+ connectionConfigBean = createComponent(conf,
"connection-config", DefaultConnectionConfig.class.getName());
+
+ // create user if necessary
+ boolean userCreate = conf.getBoolean("create-default-user", true);
+ if(userCreate) {
+ createDefaultUsers();
+ }
+
+ ftpletContainerBean = createComponent(conf, "ftplet-container",
DefaultFtpletContainer.class.getName());
+
+ initFtplets((FtpletContainer) ftpletContainerBean.getBean(), conf);
+ }
+ catch(Exception ex) {
+ dispose();
+ throw ex;
+ }
+ }
+
+ private Map<String, Bean> createListeners(Configuration conf, String
prefix) throws Exception {
+ Map<String, Bean> map = new HashMap<String, Bean>();
+
+ Configuration listenersConfig = conf.subset(prefix);
+ if(listenersConfig.isEmpty()) {
+ // create default listener
+ Bean listenerBean = createComponent(listenersConfig, "default",
NioListener.class.getName());
+
+ map.put("default", listenerBean);
+ } else {
+
+ Iterator<String> keys = listenersConfig.getKeys();
+
+ while (keys.hasNext()) {
+ String key = (String) keys.next();
+
+ Bean listenerBean = createComponent(listenersConfig, key,
NioListener.class.getName());
+
+ map.put(key, listenerBean);
+ }
+ }
+
+
+ return map;
+ }
+
+ /**
+ * create and initialize ftlets
+ * @param container
+ * @param conf
+ * @throws FtpException
+ */
+ private void initFtplets(FtpletContainer container, Configuration conf)
throws FtpException {
+ String ftpletNames = conf.getString("ftplets", null);
+ Configuration ftpletConf = conf.subset("ftplet");
+
+ if(ftpletNames == null) {
+ return;
+ }
+
+ //log = ftpConfig.getLogFactory().getInstance(getClass());
+ StringTokenizer st = new StringTokenizer(ftpletNames, " ,;\r\n\t");
+ try {
+ while(st.hasMoreTokens()) {
+ String ftpletName = st.nextToken();
+ LOG.info("Configuring ftplet : " + ftpletName);
+
+ // get ftplet specific configuration
+ Configuration subConfig = ftpletConf.subset(ftpletName);
+
+ Ftplet ftplet = (Ftplet)
ConfigurationClassUtils.createBean(subConfig, DefaultFtplet.class.getName());
+ ftplet.init(this);
+ container.addFtplet(ftpletName, ftplet);
+ }
+ }
+ catch(FtpException ex) {
+ container.destroy();
+ throw ex;
+ }
+ catch(Exception ex) {
+ container.destroy();
+ LOG.error("FtpletContainer.init()", ex);
+ throw new FtpException("FtpletContainer.init()", ex);
+ }
+ }
+
+ /**
+ * Create component.
+ */
+ private Bean createComponent(Configuration parentConfig, String
configName, String defaultClass) throws Exception {
+
+ // get configuration subset
+ Configuration conf = parentConfig.subset(configName);
+
+ Bean bean = Bean.createBean(conf, defaultClass);
+ bean.initBean();
+ return bean;
+ }
+
+ /**
+ * Create default users.
+ */
+ private void createDefaultUsers() throws Exception {
+ UserManager userManager = getUserManager();
+
+ // create admin user
+ String adminName = userManager.getAdminName();
+ if(!userManager.doesExist(adminName)) {
+ LOG.info("Creating user : " + adminName);
+ BaseUser adminUser = new BaseUser();
+ adminUser.setName(adminName);
+ adminUser.setPassword(adminName);
+ adminUser.setEnabled(true);
+
+ adminUser.setAuthorities(ADMIN_AUTHORITIES);
+
+ adminUser.setHomeDirectory("./res/home");
+ adminUser.setMaxIdleTime(0);
+ userManager.save(adminUser);
+ }
+
+ // create anonymous user
+ if(!userManager.doesExist("anonymous")) {
+ LOG.info("Creating user : anonymous");
+ BaseUser anonUser = new BaseUser();
+ anonUser.setName("anonymous");
+ anonUser.setPassword("");
+
+ anonUser.setAuthorities(ANON_AUTHORITIES);
+
+ anonUser.setEnabled(true);
+
+ anonUser.setHomeDirectory("./res/home");
+ anonUser.setMaxIdleTime(300);
+ userManager.save(anonUser);
+ }
+ }
+
+ /**
+ * Get user manager.
+ */
+ public UserManager getUserManager() {
+ return (UserManager) userManagerBean.getBean();
+ }
+
+ /**
+ * Get file system manager.
+ */
+ public FileSystemManager getFileSystemManager() {
+ return (FileSystemManager) fileSystemManagerBean.getBean();
+ }
+
+ /**
+ * Get message resource.
+ */
+ public MessageResource getMessageResource() {
+ return (MessageResource) messageResourceBean.getBean();
+ }
+
+ /**
+ * Get ftp statistics.
+ */
+ public FtpStatistics getFtpStatistics() {
+ return (FtpStatistics) statisticsBean.getBean();
+ }
+
+ /**
+ * Get ftplet handler.
+ */
+ public FtpletContainer getFtpletContainer() {
+ return (FtpletContainer) ftpletContainerBean.getBean();
+ }
+
+ /**
+ * Get the command factory.
+ */
+ public CommandFactory getCommandFactory() {
+ return (CommandFactory) commandFactoryBean.getBean();
+ }
+
+ /**
+ * Get Ftplet.
+ */
+ public Ftplet getFtplet(String name) {
+ return ((FtpletContainer)
ftpletContainerBean.getBean()).getFtplet(name);
+ }
+
+ /**
+ * Close all the components.
+ */
+ public void dispose() {
+
+ Iterator<Bean> listenerIter = listeners.values().iterator();
+ while (listenerIter.hasNext()) {
+ Bean listenerBean = listenerIter.next();
+ listenerBean.destroyBean();
+ }
+
+ if(ftpletContainerBean != null && ftpletContainerBean.getBean() !=
null) {
+ ftpletContainerBean.destroyBean();
+ }
+
+ if(userManagerBean != null && userManagerBean.getBean() != null) {
+ userManagerBean.destroyBean();
+ }
+
+ if(fileSystemManagerBean != null && fileSystemManagerBean.getBean() !=
null) {
+ fileSystemManagerBean.destroyBean();
+ }
+
+ if(statisticsBean != null && statisticsBean.getBean() != null) {
+ statisticsBean.destroyBean();
+ }
+
+ if(messageResourceBean != null && messageResourceBean.getBean() !=
null) {
+ messageResourceBean.destroyBean();
+ }
+ }
+
+ public Listener getListener(String name) {
+ Bean listenerBean = listeners.get(name);
+
+ if(listenerBean != null) {
+ return (Listener) listenerBean.getBean();
+ } else {
+ return null;
+ }
+ }
+
+ public ConnectionConfig getConnectionConfig() {
+ return (ConnectionConfig) connectionConfigBean.getBean();
+ }
+
+ public Map<String, Listener> getListeners() {
+ Map<String, Listener> result = new HashMap<String, Listener>();
+
+ for(Entry<String, Bean> entry : listeners.entrySet()) {
+ result.put(entry.getKey(), (Listener) entry.getValue().getBean());
+ }
+ return result;
+ }
+}
Propchange:
mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/ConfigurableFtpServerContext.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added:
mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/PojoBean.java
URL:
http://svn.apache.org/viewvc/mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/PojoBean.java?rev=676733&view=auto
==============================================================================
---
mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/PojoBean.java
(added)
+++
mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/PojoBean.java
Mon Jul 14 14:05:03 2008
@@ -0,0 +1,72 @@
+/*
+ * 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 org.apache.ftpserver.ftplet.Configuration;
+import org.apache.ftpserver.util.ConfigurationClassUtils;
+
+public class PojoBean extends Bean {
+
+ private Configuration config;
+ private Object pojo;
+ private Class<Object> clazz;
+
+ public PojoBean(Configuration config, Class<Object> clazz) {
+ this.clazz = clazz;
+ this.config = config;
+ }
+
+ public Object initBean() throws Exception {
+ pojo = ConfigurationClassUtils.createBean(config, clazz.getName());
+
+ configure();
+
+ return pojo;
+
+ }
+
+ private void configure() throws Exception {
+ String configureMethodName = config.getString("configure-method",
"configure");
+
+ try {
+ ConfigurationClassUtils.invokeMethod(pojo, configureMethodName);
+ } catch(RuntimeException e) {
+ // ignore
+ }
+ }
+
+ public void destroyBean() {
+ String disposeMethodName = config.getString("dispose-method",
"dispose");
+
+ try {
+ ConfigurationClassUtils.invokeMethod(pojo, disposeMethodName);
+
+ pojo = null;
+ } catch(Exception e) {
+ // TODO log!
+ }
+ }
+
+ public Object getBean() {
+ return pojo;
+ }
+
+}
Propchange:
mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/PojoBean.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added:
mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/ftplet/EmptyConfiguration.java
URL:
http://svn.apache.org/viewvc/mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/ftplet/EmptyConfiguration.java?rev=676733&view=auto
==============================================================================
---
mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/ftplet/EmptyConfiguration.java
(added)
+++
mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/ftplet/EmptyConfiguration.java
Mon Jul 14 14:05:03 2008
@@ -0,0 +1,131 @@
+/*
+ * 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.ftplet;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+
+/**
+ * Empty configuration - always returns the default values.
+ */
+public
+class EmptyConfiguration implements Configuration {
+
+ public final static EmptyConfiguration INSTANCE = new EmptyConfiguration();
+
+ /**
+ * Private constructor - use INSTANCE static variable.
+ */
+ private EmptyConfiguration() {
+ }
+
+ /**
+ * Is empty?
+ */
+ public boolean isEmpty() {
+ return true;
+ }
+
+ /**
+ * Throw exception.
+ */
+ public String getString(String param) throws FtpException {
+ throw new FtpException();
+ }
+
+ /**
+ * Return default value.
+ */
+ public String getString(String patram, String defaultVal) {
+ return defaultVal;
+ }
+
+ /**
+ * Throw exception.
+ */
+ public int getInt(String patram) throws FtpException {
+ throw new FtpException();
+ }
+
+ /**
+ * Return default value.
+ */
+ public int getInt(String patram, int defaultVal) {
+ return defaultVal;
+ }
+
+ /**
+ * Throw exception.
+ */
+ public long getLong(String param) throws FtpException {
+ throw new FtpException();
+ }
+
+ /**
+ * Return default value.
+ */
+ public long getLong(String param, long defaultVal) {
+ return defaultVal;
+ }
+
+ /**
+ * Throw exception.
+ */
+ public boolean getBoolean(String patram) throws FtpException {
+ throw new FtpException();
+ }
+
+ /**
+ * Return default value.
+ */
+ public boolean getBoolean(String patram, boolean defaultVal) {
+ return defaultVal;
+ }
+
+ /**
+ * Throw exception.
+ */
+ public double getDouble(String patram) throws FtpException {
+ throw new FtpException();
+ }
+
+ /**
+ * Get default value.
+ */
+ public double getDouble(String patram, double defaultVal) {
+ return defaultVal;
+ }
+
+ /**
+ * Throw exception.
+ */
+ public Configuration subset(String param) {
+ return this;
+ }
+
+ /**
+ * Get the keys.
+ */
+ public Iterator<String> getKeys() {
+ return new ArrayList<String>(1).iterator();
+ }
+
+}
Propchange:
mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/ftplet/EmptyConfiguration.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added:
mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/util/ConfigurationClassUtils.java
URL:
http://svn.apache.org/viewvc/mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/util/ConfigurationClassUtils.java?rev=676733&view=auto
==============================================================================
---
mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/util/ConfigurationClassUtils.java
(added)
+++
mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/util/ConfigurationClassUtils.java
Mon Jul 14 14:05:03 2008
@@ -0,0 +1,281 @@
+/*
+ * 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.PropertyDescriptor;
+import java.io.File;
+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.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.ftpserver.FtpServerConfigurationException;
+import org.apache.ftpserver.ftplet.Configuration;
+
+
+
+public class ConfigurationClassUtils {
+
+ private static Object createObject(Class<?> clazz, Configuration config,
String propValue) {
+ Object value;
+
+ if(config.isEmpty()) {
+ // regular property
+ value = cast(clazz, propValue);
+ } else {
+ if(clazz == null) {
+ String className = config.getString("class", null);
+ if(className != null) {
+ try {
+ clazz = Class.forName(className);
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException("Class not found: " +
className, e);
+ }
+ } else {
+ // TODO improve error message
+ throw new RuntimeException("Can not resolve class");
+ }
+ }
+
+ if(Map.class.isAssignableFrom(clazz)) {
+ Map<String, Object> map = new HashMap<String, Object>();
+
+ Iterator<String> mapKeys =
ClassUtils.getKeysInOrder(config.getKeys());
+
+ while (mapKeys.hasNext()) {
+ String mapKey = mapKeys.next();
+ String mapValue = config.getString(mapKey, null);
+ Configuration mapConfig = config.subset(mapKey);
+
+ map.put(mapKey, createObject(String.class, mapConfig,
mapValue));
+ }
+
+ value = map;
+ } else if(Collection.class.isAssignableFrom(clazz)) {
+ List<Object> list = new ArrayList<Object>();
+
+ Iterator<String> mapKeys =
ClassUtils.getKeysInOrder(config.getKeys());
+
+ while (mapKeys.hasNext()) {
+ String mapKey = mapKeys.next();
+
+ String listValue = config.getString(mapKey, null);
+
+ list.add(createObject(null, config.subset(mapKey),
listValue));
+ }
+
+ value = list;
+ } else if(clazz.isArray()) {
+ List<Object> list = new ArrayList<Object>();
+
+ Iterator<String> mapKeys =
ClassUtils.getKeysInOrder(config.getKeys());
+
+ while (mapKeys.hasNext()) {
+ String mapKey = mapKeys.next();
+
+ String listValue = config.getString(mapKey, null);
+
+ list.add(createObject(clazz.getComponentType(),
config.subset(mapKey), listValue));
+ }
+
+ Object castArray = Array.newInstance(clazz.getComponentType(),
list.size());
+
+ for (int i = 0; i < list.size(); i++) {
+ Array.set(castArray, i, list.get(i));
+ }
+
+
+ value = castArray;
+ } else {
+ // create new bean
+
+ value = createBean(config, clazz.getName());
+ }
+
+ }
+
+ return value;
+ }
+
+ public static Map<?, ?> createMap(Configuration config) {
+ return (Map<?, ?>) createObject(Map.class, config, 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<String> keys = config.getKeys();
+
+ while (keys.hasNext()) {
+ String key = keys.next();
+
+ if(key.equals("class")) {
+ continue;
+ }
+
+ Configuration subConfig = config.subset(key);
+
+ String propValue = config.getString(key, null);
+
+ PropertyDescriptor descriptor = ClassUtils.getDescriptor(clazz,
key);
+
+ if(descriptor == null) {
+ throw new FtpServerConfigurationException("Unknown property
\"" + key + "\" on class " + className);
+ }
+
+ Object value = createObject(descriptor.getPropertyType(),
subConfig, propValue);
+
+ ClassUtils.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<String> list = new ArrayList<String>();
+ String[] values = value.split(",");
+
+ for (int i = 0; i < values.length; i++) {
+ list.add(values[i].trim());
+ }
+
+ castValue = list;
+ } else if (clazz == File.class) {
+ castValue = new File(value);
+ } 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;
+ }
+
+ /**
+ * Checks if a class is a subclass of a class with the specified name.
+ * Used as an instanceOf without having to load the class, useful when
+ * trying to check for classes that might not be available in the runtime
+ * JRE.
+ * @param clazz The class to check
+ * @param className The class name to look for in the super classes
+ * @return true if the class extends a class by the specified name.
+ */
+ public static boolean extendsClass(final Class<?> clazz, String className)
{
+ Class<?> superClass = clazz.getSuperclass();
+
+ while(superClass != null) {
+ if(superClass.getName().equals(className)) {
+ return true;
+ }
+ superClass = superClass.getSuperclass();
+
+ }
+ return false;
+ }
+}
Propchange:
mina/ftpserver/trunk/server/src/main/java/org/apache/ftpserver/util/ConfigurationClassUtils.java
------------------------------------------------------------------------------
svn:mime-type = text/plain