Coverage Report - org.apache.tapestry.pageload.EventConnectionVisitor
 
Classes in this File Line Coverage Branch Coverage Complexity
EventConnectionVisitor
57% 
61% 
4.909
 
 1  
 package org.apache.tapestry.pageload;
 2  
 
 3  
 import org.apache.hivemind.ApplicationRuntimeException;
 4  
 import org.apache.hivemind.PoolManageable;
 5  
 import org.apache.tapestry.IComponent;
 6  
 import org.apache.tapestry.IForm;
 7  
 import org.apache.tapestry.IPage;
 8  
 import org.apache.tapestry.IRender;
 9  
 import org.apache.tapestry.form.IFormComponent;
 10  
 import org.apache.tapestry.internal.Component;
 11  
 import org.apache.tapestry.internal.event.ComponentEventProperty;
 12  
 import org.apache.tapestry.internal.event.EventBoundListener;
 13  
 import org.apache.tapestry.internal.event.IComponentEventInvoker;
 14  
 import org.apache.tapestry.spec.IComponentSpecification;
 15  
 
 16  
 import java.util.*;
 17  
 
 18  
 /**
 19  
  * Handles connecting up components and forms targeted with the EventListener annotation.
 20  
  */
 21  3
 public class EventConnectionVisitor implements IComponentVisitor, PoolManageable {
 22  
 
 23  
     IComponentEventInvoker _invoker;
 24  
 
 25  3
     IPage _currentPage = null;
 26  3
     List _forms = new ArrayList();
 27  
 
 28  
     public void visitComponent(IComponent component)
 29  
     {
 30  4
         checkComponentPage(component);
 31  
 
 32  4
         Map events = component.getSpecification().getComponentEvents();
 33  4
         Set keySet = events.keySet();
 34  4
         String[] compIds = (String[]) keySet.toArray(new String[keySet.size()]);
 35  
         
 36  6
         for (int i=0; i < compIds.length; i++)
 37  
         {
 38  2
             String compId = compIds[i];
 39  2
             ComponentEventProperty property = (ComponentEventProperty) events.get(compId);
 40  
 
 41  
             // find the targeted component
 42  
 
 43  2
             IComponent comp = findComponent(compId, component.getPage());
 44  
 
 45  2
             if (comp == null)
 46  0
                 continue;
 47  
 
 48  5
             if (Component.class.isInstance(comp))
 49  0
                 ((Component)comp).setHasEvents(true);
 50  
             
 51  
             // wire up with idPath
 52  
 
 53  2
             String idPath = comp.getExtendedId();
 54  
             
 55  2
             component.getSpecification().rewireComponentId(compId, idPath);
 56  
             
 57  2
             _invoker.addEventListener(idPath, component.getSpecification());
 58  2
             wireFormEvents(comp, component.getSpecification());
 59  
         }
 60  
         
 61  
         // find form element targets for re-mapping with proper idpath && IEventInvoker connection
 62  
 
 63  4
         events = component.getSpecification().getElementEvents();
 64  4
         Iterator it = events.keySet().iterator();
 65  
 
 66  
         // for efficiency later in ComponentEventConnectionWorker
 67  
 
 68  4
         if (events.size() > 0 && Component.class.isInstance(component)) {
 69  0
             ((Component)component).setHasEvents(true);
 70  
         }
 71  
 
 72  6
         while (it.hasNext())
 73  
         {
 74  2
             String elementId = (String) it.next();
 75  2
             ComponentEventProperty property = (ComponentEventProperty) events.get(elementId);
 76  
 
 77  2
             Iterator bindingIt  = property.getFormEvents().iterator();
 78  4
             while (bindingIt.hasNext())
 79  
             {
 80  2
                 String key = (String) bindingIt.next();
 81  2
                 List listeners = property.getFormEventListeners(key);
 82  
 
 83  4
                 for (int i=0; i < listeners.size(); i++) {
 84  
                     
 85  2
                     EventBoundListener listener = (EventBoundListener) listeners.get(i);
 86  2
                     wireElementFormEvents(listener, component, component.getSpecification());
 87  
                 }
 88  2
             }
 89  2
         }
 90  4
     }
 91  
 
 92  
     void wireElementFormEvents(EventBoundListener listener, IComponent component, IComponentSpecification spec)
 93  
     {
 94  2
         if (listener.getFormId() == null)
 95  0
             return;
 96  
 
 97  2
         if (_forms.size() < 1)
 98  1
             discoverPageForms(component.getPage());
 99  
 
 100  2
         IForm form = null;
 101  2
         for (int i=0; i < _forms.size(); i++)
 102  
         {
 103  2
             IForm f = (IForm) _forms.get(i);
 104  2
             if (listener.getFormId().equals(f.getExtendedId()) || listener.getFormId().equals(f.getId()))
 105  
             {
 106  2
                 form = f;
 107  2
                 break;
 108  
             }
 109  
         }
 110  
 
 111  
         // couldn't find the form they specified
 112  
 
 113  2
         if (form == null)
 114  0
             throw new ApplicationRuntimeException(PageloadMessages.componentNotFound(listener.getFormId()),
 115  
                                                   component, component.getLocation(), null);
 116  
 
 117  2
         String idPath = form.getExtendedId();
 118  
         
 119  2
         listener.setFormId(idPath);
 120  2
         _invoker.addFormEventListener(idPath, spec);
 121  2
     }
 122  
 
 123  
     void wireFormEvents(IComponent component, IComponentSpecification listener)
 124  
     {
 125  2
         if (!IFormComponent.class.isInstance(component))
 126  2
             return;
 127  
 
 128  0
         IFormComponent fcomp = (IFormComponent) component;
 129  
 
 130  0
         if (_forms.size() < 1)
 131  0
             discoverPageForms(fcomp.getPage());
 132  
 
 133  0
         IForm form = findComponentForm(fcomp);
 134  0
         if (form == null)
 135  0
             return;
 136  
 
 137  0
         listener.connectAutoSubmitEvents(component, form);
 138  0
         _invoker.addFormEventListener(form.getExtendedId(), listener);
 139  0
     }
 140  
 
 141  
     IComponent findComponent(String id, IComponent target)
 142  
     {
 143  2
         Map components = target.getComponents();
 144  2
         if (components == null)
 145  0
             return null;
 146  
         
 147  2
         IComponent comp = (IComponent) components.get(id);
 148  2
         if (comp != null)
 149  2
             return comp;
 150  
 
 151  0
         Iterator children = components.values().iterator();
 152  
 
 153  0
         while (children.hasNext())
 154  
         {
 155  0
             IComponent child = (IComponent) children.next();
 156  
 
 157  0
             comp = findComponent(id, child);
 158  0
             if (comp != null)
 159  0
                 return comp;
 160  0
         }
 161  
 
 162  0
         return null;
 163  
     }
 164  
 
 165  
     void discoverPageForms(IComponent parent)
 166  
     {
 167  2
         if (IForm.class.isInstance(parent))
 168  1
             _forms.add(parent);
 169  
 
 170  2
         Iterator it = parent.getComponents().values().iterator();
 171  3
         while (it.hasNext())
 172  
         {
 173  1
             IComponent comp = (IComponent)it.next();
 174  
 
 175  1
             discoverPageForms(comp);
 176  1
         }
 177  2
     }
 178  
 
 179  
     IForm findComponentForm(IFormComponent child)
 180  
     {
 181  0
         for (int i = 0; i < _forms.size(); i++) {
 182  
 
 183  0
             IForm form = (IForm) _forms.get(i);
 184  
 
 185  0
             IComponent match = findContainedComponent(child.getExtendedId(), (Component)form);
 186  0
             if (match != null)
 187  0
                 return form;
 188  
         }
 189  
 
 190  0
         return null;
 191  
     }
 192  
 
 193  
     IComponent findContainedComponent(String idPath, Component container)
 194  
     {
 195  0
         IComponent comp = (IComponent) container;
 196  
 
 197  0
         if (idPath.equals(comp.getExtendedId()))
 198  0
             return comp;
 199  
 
 200  0
         IRender[] children = container.getContainedRenderers();
 201  0
         if (children == null)
 202  0
             return null;
 203  
 
 204  0
         for (int i=0; i < children.length; i++) {
 205  
 
 206  0
             if (children[i] == null)
 207  0
                 return null;
 208  
 
 209  0
             if (!Component.class.isInstance(children[i]))
 210  0
                 continue;
 211  
 
 212  0
             IComponent found = findContainedComponent(idPath, (Component)children[i]);
 213  0
             if (found != null)
 214  0
                 return found;
 215  
         }
 216  
         
 217  0
         return null;
 218  
     }
 219  
 
 220  
     void checkComponentPage(IComponent component)
 221  
     {
 222  4
         if (_currentPage == null) {
 223  
 
 224  3
             _currentPage = component.getPage();
 225  3
             _forms.clear();
 226  1
         } else if (component.getPage() != _currentPage) {
 227  
 
 228  0
             _currentPage = component.getPage();
 229  0
             _forms.clear();
 230  
         }
 231  4
     }
 232  
 
 233  
     public void activateService()
 234  
     {
 235  0
         _currentPage = null;
 236  0
         _forms.clear();
 237  0
     }
 238  
 
 239  
     public void passivateService()
 240  
     {
 241  0
         _currentPage = null;
 242  0
         _forms.clear();
 243  0
     }
 244  
 
 245  
     // injected
 246  
     public void setEventInvoker(IComponentEventInvoker invoker)
 247  
     {
 248  3
         _invoker = invoker;
 249  3
     }
 250  
 }