001    // Copyright 2004, 2005 The Apache Software Foundation
002    //
003    // Licensed under the Apache License, Version 2.0 (the "License");
004    // you may not use this file except in compliance with the License.
005    // You may obtain a copy of the License at
006    //
007    //     http://www.apache.org/licenses/LICENSE-2.0
008    //
009    // Unless required by applicable law or agreed to in writing, software
010    // distributed under the License is distributed on an "AS IS" BASIS,
011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    // See the License for the specific language governing permissions and
013    // limitations under the License.
014    
015    package org.apache.tapestry.contrib.inspector;
016    
017    import java.util.ArrayList;
018    import java.util.Collections;
019    import java.util.HashSet;
020    import java.util.List;
021    import java.util.Set;
022    
023    import org.apache.tapestry.BaseComponent;
024    import org.apache.tapestry.IComponent;
025    import org.apache.tapestry.INamespace;
026    import org.apache.tapestry.IRequestCycle;
027    import org.apache.tapestry.engine.ISpecificationSource;
028    import org.apache.tapestry.form.IPropertySelectionModel;
029    import org.apache.tapestry.form.StringPropertySelectionModel;
030    
031    /**
032     *  Component of the {@link Inspector} page used to select the page and "crumb trail"
033     *  of the inspected component.
034     *
035     *  @author Howard Lewis Ship
036     *
037     **/
038    
039    public abstract class Selector extends BaseComponent
040    {
041        public abstract ISpecificationSource getSpecificationSource();
042        
043        /**
044         *  When the form is submitted,
045         *  the inspectedPageName of the {@link Inspector} page will be updated,
046         *  but we need to reset the inspectedIdPath as well.
047         *
048         **/
049    
050        public void formSubmit(IRequestCycle cycle)
051        {
052            Inspector inspector = (Inspector) getPage();
053    
054            inspector.selectComponent((String) null);
055        }
056    
057        /**
058         *  Returns an {IPropertySelectionModel} used to select the name of the page
059         *  to inspect.  The page names are sorted.
060         *
061         **/
062    
063        public IPropertySelectionModel getPageModel()
064        {
065            return new StringPropertySelectionModel(getPageNames());
066        }
067    
068        /**
069         *  The crumb trail is all the components from the inspected component up to
070         *  (but not including) the page.
071         *
072         **/
073    
074        public List getCrumbTrail()
075        {
076            List result = null;
077    
078            Inspector inspector = (Inspector) getPage();
079            IComponent component = inspector.getInspectedComponent();
080            IComponent container = null;
081    
082            while (true)
083            {
084                container = component.getContainer();
085                if (container == null)
086                    break;
087    
088                if (result == null)
089                    result = new ArrayList();
090    
091                result.add(component);
092    
093                component = container;
094            }
095    
096            if (result == null)
097                return null;
098    
099            // Reverse the list, such that the inspected component is last, and the
100            // top-most container is first.
101    
102            Collections.reverse(result);
103    
104            return result;
105        }
106        
107        private String[] getPageNames()
108        {
109            Set names = new HashSet();
110            
111            ISpecificationSource source = getSpecificationSource();
112            
113            addPageNames(names, source.getFrameworkNamespace());
114            addPageNames(names, source.getApplicationNamespace());
115            
116            List l = new ArrayList(names);
117            Collections.sort(l);
118    
119            return (String[]) l.toArray(new String[l.size()]);
120        }
121    
122        private void addPageNames(Set names, INamespace namespace)
123        {
124            String idPrefix = namespace.getExtendedId();
125    
126            List pageNames = namespace.getPageNames();
127            int count = pageNames.size();
128    
129            for (int i = 0; i < count; i++)
130            {
131                String name = (String) pageNames.get(i);
132    
133                if (idPrefix == null)
134                    names.add(name);
135                else
136                    names.add(idPrefix + ":" + name);
137            }
138            
139            List ids = namespace.getChildIds();
140            count = ids.size();
141    
142            for (int i = 0; i < count; i++)
143            {
144                String id = (String) ids.get(i);
145    
146                addPageNames(names, namespace.getChildNamespace(id));
147            }
148        }
149    
150    }