001    package org.trails.finder;
002    
003    import java.util.Map;
004    
005    import ognl.Ognl;
006    import ognl.OgnlException;
007    import org.apache.tapestry.IRequestCycle;
008    import org.apache.tapestry.components.Block;
009    import org.apache.tapestry.util.ComponentAddress;
010    import org.trails.page.IEditorBlockPage;
011    import org.trails.descriptor.IPropertyDescriptor;
012    
013    public class BaseBlockFinder implements BlockFinder
014    {
015    
016            private Map<String, ComponentAddress> editorMap;
017            private ComponentAddress defaultEditor;
018    
019            public Map<String, ComponentAddress> getEditorMap()
020            {
021                    return editorMap;
022            }
023    
024            /**
025             * This a map where the keys are ognl expressions and the values are component address.
026             *
027             * @param editorMap
028             */
029            public void setEditorMap(Map<String, ComponentAddress> editorMap)
030            {
031                    this.editorMap = editorMap;
032            }
033    
034            /**
035             * @param descriptor
036             * @return The first component address in the editorMap whose key evaluates to true for descriptor. This will be used
037             *         to load an editor for the descriptor. Returns default editor if no match is found.
038             * @see BlockFinder#findBlockAddress(org.trails.descriptor.IPropertyDescriptor)
039             */
040            public ComponentAddress findBlockAddress(IPropertyDescriptor descriptor)
041            {
042                    ComponentAddress componentAddress = findBlockAddress(editorMap, descriptor);
043                    return componentAddress != null ? componentAddress : getDefaultBlockAddress();
044            }
045    
046            protected ComponentAddress findBlockAddress(Map<String, ComponentAddress> map, IPropertyDescriptor descriptor)
047            {
048                    for (Map.Entry<String, ComponentAddress> entry : map.entrySet())
049                    {
050                            try
051                            {
052                                    if ((Boolean) Ognl.getValue(entry.getKey(), descriptor))
053                                    {
054                                            return entry.getValue();
055                                    }
056                            } catch (OgnlException e)
057                            {
058                            }
059                    }
060                    return null;
061            }
062    
063            public Block findBlock(IRequestCycle cycle, IPropertyDescriptor descriptor)
064            {
065                    if (cycle.getPage().getComponents().containsKey(descriptor.getName()))
066                    {
067                            Block block = (Block) cycle.getPage().getComponent(descriptor.getName());
068                            return block;
069                    } else
070                    {
071                            // since it came from a block container page, we need to set
072                            // the model and descriptor on the container page so its visible to the
073                            // block
074                            ComponentAddress blockAddress = findBlockAddress(descriptor);
075                            Block block = (Block) blockAddress.findComponent(cycle);
076                            ((IEditorBlockPage) block.getPage()).setDescriptor(descriptor);
077                            return block;
078                    }
079            }
080    
081            public ComponentAddress getDefaultBlockAddress()
082            {
083                    return defaultEditor;
084            }
085    
086            public void setDefaultBlockAddress(ComponentAddress defaultEditor)
087            {
088                    this.defaultEditor = defaultEditor;
089            }
090    
091    }