private boolean searchAndInvoke()

in tapestry-framework/src/java/org/apache/tapestry/listener/ListenerMethodInvokerImpl.java [87:211]


    private boolean searchAndInvoke(Object target, IRequestCycle cycle, Object[] listenerParameters)
    {
        BrowserEvent event = null;
        if (listenerParameters.length > 0 
                && BrowserEvent.class.isInstance(listenerParameters[listenerParameters.length - 1]))
            event = (BrowserEvent)listenerParameters[listenerParameters.length - 1];
        
        List invokeParms = new ArrayList();

        Method possibleMethod = null;

        methods:
            for (int i = 0; i < _methods.length; i++, invokeParms.clear()) {
                
                if (!_methods[i].getName().equals(_name))
                   continue;
                
                Class[] parms = _methods[i].getParameterTypes();
                
                // impossible to call this
                
                if (parms.length > (listenerParameters.length + 1) ) {
                    
                    if (possibleMethod == null)
                        possibleMethod = _methods[i];
                    else if (parms.length < possibleMethod.getParameterTypes().length)
                        possibleMethod = _methods[i];
                    
                    continue;
                }
                
                int listenerIndex = 0;
                for (int p = 0; p < parms.length && listenerIndex < (listenerParameters.length + 1); p++) {
                    
                    // special case for BrowserEvent
                    if (BrowserEvent.class.isAssignableFrom(parms[p])) {
                        if (event == null)
                            continue methods;
                        
                        if (!invokeParms.contains(event))
                            invokeParms.add(event);
                        
                        continue;
                    }
                    
                    // special case for request cycle
                    if (IRequestCycle.class.isAssignableFrom(parms[p])) {
                        invokeParms.add(cycle);
                        continue;
                    }
                    
                    if (event != null && listenerIndex < (listenerParameters.length + 1)
                            || listenerIndex < listenerParameters.length) {
                        invokeParms.add(listenerParameters[listenerIndex]);
                        listenerIndex++;
                    }
                }
                
                if (invokeParms.size() != parms.length) {

                    // set possible method just in case
                    
                    if (possibleMethod == null)
                        possibleMethod = _methods[i];
                    else if (parms.length < possibleMethod.getParameterTypes().length)
                        possibleMethod = _methods[i];

                    continue;
                }
                
                invokeListenerMethod(_methods[i], target, cycle, invokeParms.toArray(new Object[invokeParms.size()]));
                
                return true;
            }

        // if we didn't have enough parameters but still found a matching method name go ahead
        // and do your best to fill in the parameters and invoke it

        if (possibleMethod != null) {

            Class[] parms = possibleMethod.getParameterTypes();
            Object[] args = new Object[parms.length];
            
            for (int p=0; p < parms.length; p++) {

                // setup primitive defaults
                
                if (parms[p].isPrimitive()) {

                    if (parms[p] == Boolean.TYPE) {

                        args[p] = Boolean.FALSE;
                    } else if (parms[p] == Byte.TYPE) {

                        args[p] = new Byte(DEFAULT_BYTE);
                    } else if (parms[p] == Short.TYPE) {

                        args[p] = new Short(DEFAULT_SHORT);
                    } else if (parms[p] == Integer.TYPE) {

                        args[p] = new Integer(-1);
                    } else if (parms[p] == Long.TYPE) {

                        args[p] = new Long(-1);
                    } else if (parms[p] == Float.TYPE) {

                        args[p] = new Float(-1);
                    } else if (parms[p] == Double.TYPE) {

                        args[p] = new Double(-1);
                    }
                }

                if (IRequestCycle.class.isAssignableFrom(parms[p])) {
                    args[p] = cycle;
                }
            }
            
            invokeListenerMethod(possibleMethod, target, cycle, args);
            
            return true;
        }

        return false;
    }