/**//* * 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] */ publicclass 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 */ publicvoid 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) */ publicvoid 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; } elseif (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; } elseif (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 */ privatevoid 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$ } } thrownew 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 */ privatestaticfinal Logger log = Logger.getLogger(DefaultContainer.class); publicstaticvoid main(String args[]) throws InstantiationException, IllegalAccessException...{ DefaultContainer container =new DefaultContainer(); container.addParameter(AccessControl.class.getName(), "uk.ltd.getahead.dwr.impl.DefaultAccessControl"); container.configurationFinished(); } }
/**//* * 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 t