DWR的小型IOC容器类DefaultContainer

/*
 * Copyright 2005 Joe Walker
 *
 * Licensed 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  uk.ltd.getahead.dwr.impl;

import  java.lang.reflect.InvocationTargetException;
import  java.lang.reflect.Method;
import  java.util.Iterator;
import  java.util.Map;
import  java.util.TreeMap;

import  uk.ltd.getahead.dwr.AccessControl;
import  uk.ltd.getahead.dwr.Container;
import  uk.ltd.getahead.dwr.util.Logger;

/**
 * DefaultContainer is like a mini-IoC container for DWR.
 * At least it is an IoC container by interface (check: no params that have
 * anything to do with DWR), but it is hard coded specifically for DWR. If we
 * want to make more of it we can later, but this is certainly not going to
 * become a full blown IoC container.
 * 
@author Joe Walker [joe at getahead dot ltd dot uk]
 
*/

public   class  DefaultContainer  implements  Container
{
    
/**
     * Set the class that should be used to implement the given interface
     * 
@param askFor The interface to implement
     * 
@param value The new implementation
     * 
@throws IllegalAccessException If the specified beans could not be accessed
     * 
@throws InstantiationException If the specified beans could not be created 
     
*/

    
public void addParameter(Object askFor, Object value) throws InstantiationException, IllegalAccessException
    
{
        
// Maybe the value is a classname that needs instansiating
        if (value instanceof String)
        
{
            
try
            
{
                Class impl 
= Class.forName((String) value);
                value 
= impl.newInstance();
            }

            
catch (ClassNotFoundException ex)
            
{
                
// it's not a classname, leave it
            }

        }


        
// If we have an instansiated value object and askFor is an interface
        
// then we can check that one implements the other
        if (!(value instanceof String) && askFor instanceof String)
        
{
            
try
            
{
                Class iface 
= Class.forName((String) askFor);
                
if (!iface.isAssignableFrom(value.getClass()))
                
{
                    log.error(
"Can't cast: " + value + " to " + askFor); //$NON-NLS-1$ //$NON-NLS-2$
                }

            }

            
catch (ClassNotFoundException ex)
            
{
                
// it's not a classname, leave it
            }

        }


        
if (value instanceof String && log.isDebugEnabled())
        
{
            log.debug(
"Adding IoC setting: " + askFor + "=" + value); //$NON-NLS-1$ //$NON-NLS-2$
        }

        
else
        
{
            log.debug(
"Adding IoC implementation: " + askFor + "=" + value.getClass().getName()); //$NON-NLS-1$ //$NON-NLS-2$
        }


        beans.put(askFor, value);
    }


    
/**
     * Called to indicate that we finished called setImplementation.
     * 
@see DefaultContainer#addParameter(Object, Object)
     
*/

    
public void configurationFinished()
    
{
        
// We try to autowire each bean in turn
        for (Iterator it = beans.entrySet().iterator(); it.hasNext();)
        
{
            Map.Entry entry 
= (Map.Entry) it.next();
            
// Class type = (Class) entry.getKey();
            Object ovalue = entry.getValue();

            
if (!(ovalue instanceof String))
            
{
                log.debug(
"Trying to autowire: " + ovalue.getClass().getName()); //$NON-NLS-1$
    
                Method[] methods 
= ovalue.getClass().getMethods();
                methods:
                
for (int i = 0; i < methods.length; i++)
                
{
                    Method setter 
= methods[i];
    
                    
if (setter.getName().startsWith("set"&& //$NON-NLS-1$
                        setter.getName().length() > 3 &&
                        setter.getParameterTypes().length 
== 1)
                    
{
                        String name 
= Character.toLowerCase(setter.getName().charAt(3)) + setter.getName().substring(4);
                        Class propertyType 
= setter.getParameterTypes()[0];

                        
// First we try auto-wire by name
                        Object setting = beans.get(name);
                        
if (setting != null)
                        
{
                            
if (propertyType.isAssignableFrom(setting.getClass()))
                            
{
                                log.debug(
"- autowire-by-name: " + name + "=" + setting); //$NON-NLS-1$ //$NON-NLS-2$
                                invoke(setter, ovalue, setting);

                                
continue methods;
                            }

                            
else if (propertyType == Boolean.TYPE && setting.getClass() == String.class)
                            
{
                                Boolean bool 
= Boolean.valueOf((String) setting);
                                log.debug(
"- autowire-by-name: " + name + "=" + bool); //$NON-NLS-1$ //$NON-NLS-2$
                                invoke(setter, ovalue, bool);

                                
continue methods;
                            }

                            
else if (propertyType == Integer.TYPE && setting.getClass() == String.class)
                            
{
                                Integer integer 
= Integer.valueOf((String) setting);
                                log.debug(
"- autowire-by-name: " + name + "=" + integer); //$NON-NLS-1$ //$NON-NLS-2$
                                invoke(setter, ovalue, integer);

                                
continue methods;
                            }

                        }


                        
// Next we try autowire-by-type
                        Object value = beans.get(propertyType.getName());
                        
if (value != null)
                        
{
                            log.debug(
"- autowire-by-type: " + name + "=" + value.getClass().getName()); //$NON-NLS-1$ //$NON-NLS-2$
                            invoke(setter, ovalue, value);

                            
continue methods;
                        }


                        log.debug(
"- skipped autowire: " + name); //$NON-NLS-1$
                    }

                }

            }

        }

    }


    
/**
     * A helper to do the reflection
     * 
@param setter The method to invoke
     * 
@param bean The object to invoke the method on
     * 
@param value The value to assign to the property using the setter method
     
*/

    
private void invoke(Method setter, Object bean, Object value)
    
{
        
try
        
{
            setter.invoke(bean, 
new Object[] { value });
        }

        
catch (IllegalArgumentException ex)
        
{
            log.error(
"- Internal error: " + ex.getMessage()); //$NON-NLS-1$
        }

        
catch (IllegalAccessException ex)
        
{
            log.error(
"- Permission error: " + ex.getMessage()); //$NON-NLS-1$
        }

        
catch (InvocationTargetException ex)
        
{
            log.error(
"- Exception during auto-wire", ex.getTargetException()); //$NON-NLS-1$
        }

    }


    
/* (non-Javadoc)
     * @see uk.ltd.getahead.dwr.Container#getBean(java.lang.String)
     
*/

    
public Object getBean(String id)
    
{
        Object reply 
= beans.get(id);
        
if (reply == null)
        
{
            
if (log.isDebugEnabled())
            
{
                
for (Iterator it = beans.keySet().iterator(); it.hasNext();)
                
{
                    log.debug(
"- known bean: " + it.next()); //$NON-NLS-1$
                }

            }


            
throw new IllegalArgumentException("DefaultContainer can't find a " + id); //$NON-NLS-1$
        }


        
return reply;
    }


    
/**
     * The beans that we know of indexed by type
     
*/

    
protected Map beans = new TreeMap();

    
/**
     * The log stream
     
*/

    
private static final Logger log = Logger.getLogger(DefaultContainer.class);
    
    
public static void main(String args[]) throws InstantiationException, IllegalAccessException{
        
        DefaultContainer container 
= new DefaultContainer();
        container.addParameter(AccessControl.
class.getName(), 
            
"uk.ltd.getahead.dwr.impl.DefaultAccessControl"); 
        container.configurationFinished();
        
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值